From 3a5ed90ae5d9d2cc80ba08a97711441f72c49f56 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 8 Sep 2009 10:03:36 +0200 Subject: mplayer: bump SRCREV --- recipes/mplayer/files/vo_omapfb.c | 18 ++++++++++++++++++ recipes/mplayer/mplayer_svn.bb | 5 ++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/recipes/mplayer/files/vo_omapfb.c b/recipes/mplayer/files/vo_omapfb.c index 127e550cae..0fb32d811e 100644 --- a/recipes/mplayer/files/vo_omapfb.c +++ b/recipes/mplayer/files/vo_omapfb.c @@ -118,6 +118,24 @@ static Window parent = 0; // pointer to the newly created window. /* This is used to intercept window closing requests. */ static Atom wm_delete_window; + +void vo_calc_drwXY(uint32_t *drwX, uint32_t *drwY) +{ + *drwX = *drwY = 0; + if (vo_fs) { + aspect(&vo_dwidth, &vo_dheight, A_ZOOM); + vo_dwidth = FFMIN(vo_dwidth, vo_screenwidth); + vo_dheight = FFMIN(vo_dheight, vo_screenheight); + *drwX = (vo_screenwidth - vo_dwidth) / 2; + *drwY = (vo_screenheight - vo_dheight) / 2; + mp_msg(MSGT_VO, MSGL_V, "[vo-fs] dx: %d dy: %d dw: %d dh: %d\n", + *drwX, *drwY, vo_dwidth, vo_dheight); + } else if (WinID == 0) { + *drwX = vo_dx; + *drwY = vo_dy; + } +} + /** * Function to get the offset to be used when in windowed mode * or when using -wid option diff --git a/recipes/mplayer/mplayer_svn.bb b/recipes/mplayer/mplayer_svn.bb index d26302e65b..d0658372d4 100644 --- a/recipes/mplayer/mplayer_svn.bb +++ b/recipes/mplayer/mplayer_svn.bb @@ -8,7 +8,7 @@ DEPENDS = "live555 libdvdread libtheora virtual/libsdl ffmpeg xsp zlib libpng jp RDEPENDS = "mplayer-common" LICENSE = "GPL" SRC_URI = "svn://svn.mplayerhq.hu/mplayer;module=trunk \ - file://Makefile-codec-cfg.patch;patch=1 \ +# file://Makefile-codec-cfg.patch;patch=1 \ file://pld-onlyarm5-svn.patch;patch=1 \ file://makefile-nostrip-svn.patch;patch=1 \ file://configh \ @@ -87,8 +87,6 @@ EXTRA_OECONF = " \ --enable-sortsub \ --disable-fribidi \ --disable-enca \ - --disable-macosx \ - --disable-macosx-bundle \ --disable-ftp \ --disable-vstream \ \ @@ -210,6 +208,7 @@ do_configure() { sed -i 's|/usr/lib|${STAGING_LIBDIR}|g' ${S}/configure sed -i 's|/usr/\S*include[\w/]*||g' ${S}/configure sed -i 's|/usr/\S*lib[\w/]*||g' ${S}/configure + sed -i 's|HOST_CC|BUILD_CC|' ${S}/Makefile export SIMPLE_TARGET_SYS="$(echo ${TARGET_SYS} | sed s:${TARGET_VENDOR}::g)" ./configure ${EXTRA_OECONF} -- cgit v1.2.3 From ba7d5bb676fd61e71ead1fb050cef03c85174a73 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 8 Sep 2009 10:16:31 +0200 Subject: sane-srcrevs: bump mplayer SRCREV --- conf/distro/include/sane-srcrevs.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/distro/include/sane-srcrevs.inc b/conf/distro/include/sane-srcrevs.inc index a9cc84fde4..b88ac9bc8c 100644 --- a/conf/distro/include/sane-srcrevs.inc +++ b/conf/distro/include/sane-srcrevs.inc @@ -123,7 +123,7 @@ SRCREV_pn-moblin-proto ?= "8f2cb524fe06555182c25b4ba3202d7b368ac0ce" SRCREV_pn-moko-gtk-engine ?= "4734" SRCREV_pn-mokoko ?= "127" SRCREV_pn-mpd-alsa ?= "6952" -SRCREV_pn-mplayer ?= "28346" +SRCREV_pn-mplayer ?= "29653" SRCREV_pn-mplayer-maemo ?= "342" SRCREV_pn-multicat ?= "f894801916cc4d0e912e4553490dc215276c52a9" SRCREV_pn-multitap-pad ?= "373" -- cgit v1.2.3 From 4cb31399a010a3ef332376cd3aa184d4aa6a1791 Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Tue, 8 Sep 2009 12:31:02 +0200 Subject: linux-kirkwood: added 2.6.30.5 tested on sheevaplug --- recipes/linux/linux-kirkwood_2.6.30.5.bb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 recipes/linux/linux-kirkwood_2.6.30.5.bb diff --git a/recipes/linux/linux-kirkwood_2.6.30.5.bb b/recipes/linux/linux-kirkwood_2.6.30.5.bb new file mode 100644 index 0000000000..d47b8e4537 --- /dev/null +++ b/recipes/linux/linux-kirkwood_2.6.30.5.bb @@ -0,0 +1,18 @@ +DESCRIPTION = "Linux Kernel for Marvell Kirkwood based devices" +SECTION = "kernel" +LICENSE = "GPL" +COMPATIBLE_MACHINE = "sheevaplug" + +require linux.inc + +# Change MACHINE_KERNEL_PR in conf/machine/include/kirkwood.inc +PV = "2.6.30.5" + +SRCREV = "6fa23e56edcb79a348c968aada8190944f4f3633" +SRC_URI = "git://git.marvell.com/orion.git;protocol=git;branch=stable-2.6.29 \ + file://defconfig \ + " + +S = "${WORKDIR}/git" + +KERNEL_IMAGETYPE ?= "uImage" -- cgit v1.2.3 From a72b72a409d0ba3a3fa55d3af3ff4ca19d4267d2 Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Tue, 8 Sep 2009 13:29:44 +0200 Subject: source-checker: added small script to generate list of files for mirroring oe-source-mirror-build.py compares checksums stored in checksums.ini with files in DL_DIR and outputs list of good ones. Such list can be used for populating local OE sources mirror. --- contrib/source-checker/oe-source-mirror-build.py | 96 ++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 contrib/source-checker/oe-source-mirror-build.py diff --git a/contrib/source-checker/oe-source-mirror-build.py b/contrib/source-checker/oe-source-mirror-build.py new file mode 100644 index 0000000000..6ef599294b --- /dev/null +++ b/contrib/source-checker/oe-source-mirror-build.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python +# ex:ts=4:sw=4:sts=4:et + +# Copyright (C) 2009 Marcin Juszkiewicz +# +# based on my oe-source-checker.py which is (C) OpenedHand +# +# 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. +# +# 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# +# OpenEmbedded source mirror build script +# +# This script parse conf/checksums.ini and check does files contained in +# source archive are the same as the one used to generate checksums. +# If they are then their names are output. +# +# Run it: +# +# oe-source-mirror-build.py path-to-conf/checksums.ini path-to-sources +# + +import sys + +if len(sys.argv) < 3: + print """ + OpenEmbedded source checker script require two arguments: + + 1. location of conf/checksums.ini + 2. path to DL_DIR (without "/" at the end) + """ + sys.exit(0) + +import ConfigParser, os, itertools + +checksums_parser = ConfigParser.ConfigParser() +checksums_parser.read(sys.argv[1]) + +parsespin = itertools.cycle( r'|/-\\' ) + +item = 1; +files_total = len(checksums_parser.sections()) +files_checked = 0 +files_good = 0 +files_mirror = [] + +for source in checksums_parser.sections(): + archive = source.split("/")[-1] + localpath = os.path.join(sys.argv[2], archive) + md5 = checksums_parser.get(source, "md5") + + if os.isatty(sys.stdout.fileno()): + sys.stdout.write("\rChecking files: %s (%04d/%04d) [%2d %%]" % ( parsespin.next(), item, files_total, item*100/files_total ) ) + sys.stdout.flush() + item += 1 + + try: + os.stat(localpath) + except: + continue + + files_checked += 1 + file_ok = True + + try: + md5pipe = os.popen('md5sum ' + localpath) + md5data = (md5pipe.readline().split() or [ "" ])[0] + md5pipe.close() + + if md5 != md5data: + file_ok = False + + if file_ok: + files_good += 1 + files_mirror += [ archive ] + except: + pass + +print "\nChecked %d files. %d was OK." % (files_checked, files_good) + +if len(files_mirror) > 0: + + print "\n" + + for entry in files_mirror: + print "%s " % entry -- cgit v1.2.3 From 9ec5b998debc13e68d12cdc64f3ffc3f98da2949 Mon Sep 17 00:00:00 2001 From: Florian Boor Date: Tue, 8 Sep 2009 15:46:03 +0200 Subject: checksums.ini: add missing checksum --- conf/checksums.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/conf/checksums.ini b/conf/checksums.ini index 053a2ad932..863b3456ee 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -28414,6 +28414,10 @@ sha256=f0391d08a6763598066e21d83460493973fe24fc65e3f0d2b534ef2497946a34 md5=b55e9347b9aed725cc7baf91701cdd83 sha256=177b5a3e65d7a64b5a0fbbf1b10f8e3d020a20c823b1bb9f3269dc835df213e1 +[http://gpe.linuxtogo.org/download/source/xserver-common-1.31.tar.gz] +md5=ac2515a68bc3c5cf3729aa2ff4edebdf +sha256=d9991f22b5f52bc4cfe579f4e3fbb6d04f8d7ce575bd04a94372c14584ddfd34 + [http://gpe.linuxtogo.org/download/source/xserver-common-1.8.tar.gz] md5=1e2b9633a0cef8c525d66026a9f22c87 sha256=cfbe37b066beee3c3a6e85806fc1588aa737b7bd7b3647e9eb91e03f21571527 -- cgit v1.2.3 From 462349b784d98fe99b2a0539631e86efdfeecd7a Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 8 Sep 2009 15:47:23 +0200 Subject: x-load: git has moved, update SRCREV and remove obsolete patches --- recipes/x-load/x-load-git/beagleboard/armv7-a.patch | 11 ----------- recipes/x-load/x-load-git/omap3evm/armv7-a.patch | 11 ----------- recipes/x-load/x-load-git/overo/armv7-a.patch | 11 ----------- recipes/x-load/x-load_git.bb | 15 +++------------ 4 files changed, 3 insertions(+), 45 deletions(-) delete mode 100644 recipes/x-load/x-load-git/beagleboard/armv7-a.patch delete mode 100644 recipes/x-load/x-load-git/omap3evm/armv7-a.patch delete mode 100644 recipes/x-load/x-load-git/overo/armv7-a.patch diff --git a/recipes/x-load/x-load-git/beagleboard/armv7-a.patch b/recipes/x-load/x-load-git/beagleboard/armv7-a.patch deleted file mode 100644 index 3131cda6bb..0000000000 --- a/recipes/x-load/x-load-git/beagleboard/armv7-a.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- git/cpu/omap3/config.mk-orig 2008-05-27 16:46:45.000000000 -0700 -+++ git/cpu/omap3/config.mk 2008-05-29 12:50:49.000000000 -0700 -@@ -23,7 +23,7 @@ - PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \ - -msoft-float - --PLATFORM_CPPFLAGS += -march=armv7a -+PLATFORM_CPPFLAGS += -march=armv7-a - # ========================================================================= - # - # Supply options according to compiler version diff --git a/recipes/x-load/x-load-git/omap3evm/armv7-a.patch b/recipes/x-load/x-load-git/omap3evm/armv7-a.patch deleted file mode 100644 index 3131cda6bb..0000000000 --- a/recipes/x-load/x-load-git/omap3evm/armv7-a.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- git/cpu/omap3/config.mk-orig 2008-05-27 16:46:45.000000000 -0700 -+++ git/cpu/omap3/config.mk 2008-05-29 12:50:49.000000000 -0700 -@@ -23,7 +23,7 @@ - PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \ - -msoft-float - --PLATFORM_CPPFLAGS += -march=armv7a -+PLATFORM_CPPFLAGS += -march=armv7-a - # ========================================================================= - # - # Supply options according to compiler version diff --git a/recipes/x-load/x-load-git/overo/armv7-a.patch b/recipes/x-load/x-load-git/overo/armv7-a.patch deleted file mode 100644 index 3131cda6bb..0000000000 --- a/recipes/x-load/x-load-git/overo/armv7-a.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- git/cpu/omap3/config.mk-orig 2008-05-27 16:46:45.000000000 -0700 -+++ git/cpu/omap3/config.mk 2008-05-29 12:50:49.000000000 -0700 -@@ -23,7 +23,7 @@ - PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \ - -msoft-float - --PLATFORM_CPPFLAGS += -march=armv7a -+PLATFORM_CPPFLAGS += -march=armv7-a - # ========================================================================= - # - # Supply options according to compiler version diff --git a/recipes/x-load/x-load_git.bb b/recipes/x-load/x-load_git.bb index d7c7a642a5..d7ffd20d69 100644 --- a/recipes/x-load/x-load_git.bb +++ b/recipes/x-load/x-load_git.bb @@ -2,25 +2,16 @@ require x-load.inc FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/x-load-git/${MACHINE}" -SRCREV = "73eb0caf065b3b3f407d8af5c4836624e5cc7b69" +SRCREV = "319b26586fafb86f919f514bcd175838aaab96b3" PV = "1.42+${PR}+gitr${SRCREV}" -PR ="r7" +PR ="r8" PE = "1" -SRC_URI = "git://www.sakoman.net/git/x-load-omap3.git;branch=master;protocol=git" +SRC_URI = "git://gitorious.org/x-load-omap3/mainline.git;branch=master;protocol=git" SRC_URI_append_beagleboard = " \ file://name.patch;patch=1 \ - file://armv7-a.patch;patch=1 \ - " - -SRC_URI_append_omap3evm = " \ - file://armv7-a.patch;patch=1 \ - " - -SRC_URI_append_overo = " \ - file://armv7-a.patch;patch=1 \ " S = "${WORKDIR}/git" -- cgit v1.2.3 From e9ee201981bbdb939bd1c4081962dff3f118167c Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Tue, 8 Sep 2009 11:37:44 -0400 Subject: marvel-sdio-fw: added firmware for WiFi powered BUGBase --- recipes/firmwares/files/Marvell-Licence.txt | 40 +++++++++++++++++++++ .../firmwares/marvell-gspi-fw/Marvell-Licence.txt | 40 --------------------- .../firmwares/marvell-sdio-fw/9.70.3-p37.tar.gz | Bin 0 -> 88003 bytes recipes/firmwares/marvell-sdio-fw_9.70.3-p37.bb | 19 ++++++++++ 4 files changed, 59 insertions(+), 40 deletions(-) create mode 100644 recipes/firmwares/files/Marvell-Licence.txt delete mode 100644 recipes/firmwares/marvell-gspi-fw/Marvell-Licence.txt create mode 100644 recipes/firmwares/marvell-sdio-fw/9.70.3-p37.tar.gz create mode 100644 recipes/firmwares/marvell-sdio-fw_9.70.3-p37.bb diff --git a/recipes/firmwares/files/Marvell-Licence.txt b/recipes/firmwares/files/Marvell-Licence.txt new file mode 100644 index 0000000000..87035b055a --- /dev/null +++ b/recipes/firmwares/files/Marvell-Licence.txt @@ -0,0 +1,40 @@ +FIRMWARE LICENSE TERMS* + +Copyright (c) Marvell International Ltd. + +All rights reserved. + +Redistribution. Redistribution and use in binary form, without modification, +are permitted provided that the following conditions are met: + +* Redistributions must reproduce the above copyright notice and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + +* Neither the name of Marvell International Ltd. nor the names of its suppliers + may be used to endorse or promote products derived from this software without + specific prior written permission. + +* No reverse engineering, decompilation, or disassembly of this software is + permitted. + +Limited patent license. Marvell International Ltd. grants a world-wide, +royalty-free, non-exclusive license under patents it now or hereafter owns or +controls to make, have made, use, import, offer to sell and sell ("Utilize") +this software, but solely to the extent that any such patent is necessary to +Utilize the software alone, or in combination with an operating system licensed +under an approved Open Source license as listed by the Open Source Initiative +at http://opensource.org/licenses. The patent license shall not apply to any +other combinations which include this software. No hardware per se is licensed +hereunder. + +DISCLAIMER. 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.* diff --git a/recipes/firmwares/marvell-gspi-fw/Marvell-Licence.txt b/recipes/firmwares/marvell-gspi-fw/Marvell-Licence.txt deleted file mode 100644 index 87035b055a..0000000000 --- a/recipes/firmwares/marvell-gspi-fw/Marvell-Licence.txt +++ /dev/null @@ -1,40 +0,0 @@ -FIRMWARE LICENSE TERMS* - -Copyright (c) Marvell International Ltd. - -All rights reserved. - -Redistribution. Redistribution and use in binary form, without modification, -are permitted provided that the following conditions are met: - -* Redistributions must reproduce the above copyright notice and the following - disclaimer in the documentation and/or other materials provided with the - distribution. - -* Neither the name of Marvell International Ltd. nor the names of its suppliers - may be used to endorse or promote products derived from this software without - specific prior written permission. - -* No reverse engineering, decompilation, or disassembly of this software is - permitted. - -Limited patent license. Marvell International Ltd. grants a world-wide, -royalty-free, non-exclusive license under patents it now or hereafter owns or -controls to make, have made, use, import, offer to sell and sell ("Utilize") -this software, but solely to the extent that any such patent is necessary to -Utilize the software alone, or in combination with an operating system licensed -under an approved Open Source license as listed by the Open Source Initiative -at http://opensource.org/licenses. The patent license shall not apply to any -other combinations which include this software. No hardware per se is licensed -hereunder. - -DISCLAIMER. 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.* diff --git a/recipes/firmwares/marvell-sdio-fw/9.70.3-p37.tar.gz b/recipes/firmwares/marvell-sdio-fw/9.70.3-p37.tar.gz new file mode 100644 index 0000000000..3efd73fdb5 Binary files /dev/null and b/recipes/firmwares/marvell-sdio-fw/9.70.3-p37.tar.gz differ diff --git a/recipes/firmwares/marvell-sdio-fw_9.70.3-p37.bb b/recipes/firmwares/marvell-sdio-fw_9.70.3-p37.bb new file mode 100644 index 0000000000..c3ccaf78c5 --- /dev/null +++ b/recipes/firmwares/marvell-sdio-fw_9.70.3-p37.bb @@ -0,0 +1,19 @@ +DESCRIPTION = "Firmware for Marvel 8686 gspi wifi chipset" +LICENCE = "closed" + +SRC_URI = "file://${PV}.tar.gz \ + file://Marvell-Licence.txt" + +S = "${WORKDIR}/${PV}/FwImage" + +do_install() { + + install -d ${D}${base_libdir}/firmware + install -m 0644 sd8686.bin sd8686_helper.bin ${D}${base_libdir}/firmware + install -m 0644 ${WORKDIR}/Marvell-Licence.txt ${D}${base_libdir}/firmware +} + +PACKAGES = "${PN}" +FILES_${PN} += "${base_libdir}/firmware" + +PACKAGE_ARCH = "all" -- cgit v1.2.3 From 51ddada3f458e9a3553cf0d952490af651ae3e7d Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Tue, 8 Sep 2009 18:39:05 +0200 Subject: linux-kirkwood: use proper branch for 2.6.30 (thx Koen for spotting) --- conf/machine/include/kirkwood.inc | 2 +- recipes/linux/linux-kirkwood_2.6.30.5.bb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/machine/include/kirkwood.inc b/conf/machine/include/kirkwood.inc index c185deb555..64ef38b16c 100644 --- a/conf/machine/include/kirkwood.inc +++ b/conf/machine/include/kirkwood.inc @@ -11,7 +11,7 @@ USE_DEVFS = "0" PREFERRED_PROVIDER_virtual/bootloader = "" PREFERRED_PROVIDER_virtual/kernel = "linux-kirkwood" -MACHINE_KERNEL_PR = "r8" +MACHINE_KERNEL_PR = "r9" IMAGE_FSTYPES += "tar.gz ubi" SERIAL_CONSOLE = "ttyS0 115200" diff --git a/recipes/linux/linux-kirkwood_2.6.30.5.bb b/recipes/linux/linux-kirkwood_2.6.30.5.bb index d47b8e4537..43898c81eb 100644 --- a/recipes/linux/linux-kirkwood_2.6.30.5.bb +++ b/recipes/linux/linux-kirkwood_2.6.30.5.bb @@ -9,7 +9,7 @@ require linux.inc PV = "2.6.30.5" SRCREV = "6fa23e56edcb79a348c968aada8190944f4f3633" -SRC_URI = "git://git.marvell.com/orion.git;protocol=git;branch=stable-2.6.29 \ +SRC_URI = "git://git.marvell.com/orion.git;protocol=git;branch=stable-2.6.30 \ file://defconfig \ " -- cgit v1.2.3 From e492707aff890e6ef04ad1815733019a2718fcad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20L=C3=BCbbe?= Date: Tue, 8 Sep 2009 10:43:41 +0000 Subject: libdbi: disable building docs (would need docbook/openjade) --- recipes/libdbi/libdbi.inc | 4 ++++ recipes/libdbi/libdbi_0.7.2.bb | 2 ++ recipes/libdbi/libdbi_0.8.3.bb | 2 ++ 3 files changed, 8 insertions(+) diff --git a/recipes/libdbi/libdbi.inc b/recipes/libdbi/libdbi.inc index 9d533d94b0..6df9b66a78 100644 --- a/recipes/libdbi/libdbi.inc +++ b/recipes/libdbi/libdbi.inc @@ -7,10 +7,14 @@ HOMEPAGE = "http://libdbi.sourceforge.net/" LICENSE = "LGPL" SECTION = "libs" +INC_PR = "r1" + SRC_URI = "${SOURCEFORGE_MIRROR}/libdbi/libdbi-${PV}.tar.gz" inherit autotools +EXTRA_OECONF = "--disable-docs" + do_stage () { autotools_stage_includes cd ./src/.libs/ diff --git a/recipes/libdbi/libdbi_0.7.2.bb b/recipes/libdbi/libdbi_0.7.2.bb index bd54419686..d5803c0ec4 100644 --- a/recipes/libdbi/libdbi_0.7.2.bb +++ b/recipes/libdbi/libdbi_0.7.2.bb @@ -1 +1,3 @@ require ${PN}.inc + +PR = "${INC_PR}.0" diff --git a/recipes/libdbi/libdbi_0.8.3.bb b/recipes/libdbi/libdbi_0.8.3.bb index bd54419686..d5803c0ec4 100644 --- a/recipes/libdbi/libdbi_0.8.3.bb +++ b/recipes/libdbi/libdbi_0.8.3.bb @@ -1 +1,3 @@ require ${PN}.inc + +PR = "${INC_PR}.0" -- cgit v1.2.3 From ec7970eea4971d0da8f4db8bb5797606feb5f8ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20L=C3=BCbbe?= Date: Tue, 8 Sep 2009 12:39:50 +0000 Subject: libdbi-drivers: set libdir for libdbi and don't build docs --- recipes/libdbi/libdbi-drivers.inc | 4 +++- recipes/libdbi/libdbi-drivers_0.8.3-1.bb | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/recipes/libdbi/libdbi-drivers.inc b/recipes/libdbi/libdbi-drivers.inc index b5875eb893..6dd70e02c6 100644 --- a/recipes/libdbi/libdbi-drivers.inc +++ b/recipes/libdbi/libdbi-drivers.inc @@ -17,6 +17,7 @@ inherit autotools PACKAGES += "libdbd-sqlite3 libdbd-sqlite libdbd-pgsql libdbd-mysql" EXTRA_OECONF = "--with-dbi-incdir=${STAGING_INCDIR} \ + --with-dbi-libdir=${STAGING_LIBDIR} \ --with-sqlite \ --with-sqlite3 \ --with-pgsql \ @@ -28,7 +29,8 @@ EXTRA_OECONF = "--with-dbi-incdir=${STAGING_INCDIR} \ --with-mysql-incdir=${STAGING_INCDIR} \ --with-mysql-libdir=${STAGING_LIBDIR} \ --with-pgsql-incdir=${STAGING_INCDIR} \ - --with-pgsql-libdir=${STAGING_LIBDIR}" + --with-pgsql-libdir=${STAGING_LIBDIR} \ + --disable-docs" FILES_${PN}-dbg += " ${libdir}/dbd/.debug/*.so" FILES_${PN}-dev += " ${libdir}/dbd/*.la ${libdir}/dbd/*.a" diff --git a/recipes/libdbi/libdbi-drivers_0.8.3-1.bb b/recipes/libdbi/libdbi-drivers_0.8.3-1.bb index efbc61f5c0..796cefb1ae 100644 --- a/recipes/libdbi/libdbi-drivers_0.8.3-1.bb +++ b/recipes/libdbi/libdbi-drivers_0.8.3-1.bb @@ -1,2 +1,4 @@ require ${PN}.inc LICENSE = "LGPL" + +PR = "r1" -- cgit v1.2.3 From 3355a700693403934e58c99b7b53d2b7ffeea41b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20L=C3=BCbbe?= Date: Tue, 8 Sep 2009 15:44:06 +0000 Subject: libconfig-general-perl: add recipe --- conf/checksums.ini | 4 ++++ recipes/perl/libconfig-general-perl_2.42.bb | 10 ++++++++++ 2 files changed, 14 insertions(+) create mode 100644 recipes/perl/libconfig-general-perl_2.42.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index 863b3456ee..276c4a0411 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -150,6 +150,10 @@ sha256=1cb99720527ea0a5906f5e75152634b1797ff44bcc31f4014285bd5da41589cc md5=1ab76bfd6731d80f6abbd1643c90cabd sha256=7794d91711e8c9e526431da72c53bb08e14790f326d0e330d9e9d651f3f6fc6c +[http://search.cpan.org/CPAN/authors/id/T/TL/TLINDEN/Config-General-2.42.tar.gz] +md5=2b4d586151de7de521dd415be08b4cd5 +sha256=a978f94781dd91e6e289df492b71609fc73f12d5de8b93856a8cba0a2d91f864 + [http://people.freedesktop.org/~mccann/dist/ConsoleKit-0.3.0.tar.bz2] md5=43b02a52212330b54cfb34c4044d9ce0 sha256=cbcfbb3df2dc76855c99c1cdff04a257ec5270fa62e1d21b0d057b08d88c0fd4 diff --git a/recipes/perl/libconfig-general-perl_2.42.bb b/recipes/perl/libconfig-general-perl_2.42.bb new file mode 100644 index 0000000000..fe486a33eb --- /dev/null +++ b/recipes/perl/libconfig-general-perl_2.42.bb @@ -0,0 +1,10 @@ +DESCRIPTION = "Generic Configuration Module" +SECTION = "libs" +LICENSE = "Artistic|GPL" +PR = "r0" + +SRC_URI = "http://search.cpan.org/CPAN/authors/id/T/TL/TLINDEN/Config-General-${PV}.tar.gz" + +S = "${WORKDIR}/Config-General-${PV}" + +inherit cpan -- cgit v1.2.3 From f965b272a86350f55156a14da5ec5ef052d7d045 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20L=C3=BCbbe?= Date: Tue, 8 Sep 2009 16:49:08 +0000 Subject: libsnmp-session-perl: add recipe --- conf/checksums.ini | 4 ++++ recipes/perl/libsnmp-session-perl_1.12.bb | 10 ++++++++++ 2 files changed, 14 insertions(+) create mode 100644 recipes/perl/libsnmp-session-perl_1.12.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index 276c4a0411..da7e55fb8a 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -974,6 +974,10 @@ sha256=7e2e7b46088a7b9594b255b58123598d49c5c3d11bcc3c9a8f80969cd9caa6c5 md5=5bcb197fd42e67d51c739b1414d514a7 sha256=f06895c0206dada9f9e7f07ecaeb6a3651fd648f4820f49c1f76bfeaec2f2913 +[http://www.switch.ch/misc/leinen/snmp/perl/dist/SNMP_Session-1.12.tar.gz] +md5=5f6b365b4c3815b13d7a902d94e254af +sha256=957053683ca36129565db5018dd219bcc740ae781c4fbc9bc03f263f691730e8 + [http://downloads.sourceforge.net/pywebsvcs/SOAPpy-0.11.3.tar.gz] md5=dbdcafe76f73dffaa6948b026607d51b sha256=a4a0984583c32fbf69e6f9495590b9e0c8a2a4aa42cb83f20b63a75208590845 diff --git a/recipes/perl/libsnmp-session-perl_1.12.bb b/recipes/perl/libsnmp-session-perl_1.12.bb new file mode 100644 index 0000000000..30f669e690 --- /dev/null +++ b/recipes/perl/libsnmp-session-perl_1.12.bb @@ -0,0 +1,10 @@ +DESCRIPTION = "Perl support for accessing SNMP-aware devices" +SECTION = "libs" +LICENSE = "Artistic" +PR = "r0" + +SRC_URI = "http://www.switch.ch/misc/leinen/snmp/perl/dist/SNMP_Session-${PV}.tar.gz" + +S = "${WORKDIR}/SNMP_Session-${PV}" + +inherit cpan -- cgit v1.2.3 From 77e0f4c204a8b7d2471d77f8d69b2c85a216fa74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20L=C3=BCbbe?= Date: Tue, 8 Sep 2009 17:29:25 +0000 Subject: libio-pty-perl libio-stty-perl: add recipes --- conf/checksums.ini | 8 ++++++++ recipes/perl/libio-pty-perl_1.07.bb | 10 ++++++++++ recipes/perl/libio-stty-perl_0.02.bb | 10 ++++++++++ 3 files changed, 28 insertions(+) create mode 100644 recipes/perl/libio-pty-perl_1.07.bb create mode 100644 recipes/perl/libio-stty-perl_0.02.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index da7e55fb8a..01e625aecb 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -394,6 +394,14 @@ sha256=dd88d2f2b33855588471b6e60814c82136a2ca6d67260924f79d840d10a59eb4 md5=8c7bef46f54451c809ffd99e2f1eee2d sha256=b677e2f0539b90d1c0a844b9ab0f19ac41424c7c2b9335d17695765f2d7b1b80 +[http://www.cpan.org/modules/by-module/IO/IO-Stty-.02.tar.gz] +md5=db2919cf267fce93682f0f854359f04e +sha256=5095bfac4c610e9e83b31a313c0e3a4a1280bbf39f17a274f5f25dfd8caf2b83 + +[http://www.cpan.org/modules/by-module/IO/IO-Tty-1.07.tar.gz] +md5=2a54e49b60a4092e93af5b8073ec5325 +sha256=44c3b00c7b33db6fc4d11e0d096520f2e870f8557f2e2a8f0e8d2efcf9506906 + [http://search.cpan.org/CPAN/authors/id/T/TO/TOMHUGHES/IO-Zlib-1.04.tar.gz] md5=1abf9e6161cc6c52ccd4c629e32e582e sha256=8401b31d22605e787edef75025eb048b2b3cfaee92ed8358bdcaedca5761f7ea diff --git a/recipes/perl/libio-pty-perl_1.07.bb b/recipes/perl/libio-pty-perl_1.07.bb new file mode 100644 index 0000000000..a054ab7111 --- /dev/null +++ b/recipes/perl/libio-pty-perl_1.07.bb @@ -0,0 +1,10 @@ +DESCRIPTION = "Perl module for pseudo tty IO" +SECTION = "libs" +LICENSE = "Artistic|GPL" +PR = "r0" + +SRC_URI = "http://www.cpan.org/modules/by-module/IO/IO-Tty-${PV}.tar.gz" + +S = "${WORKDIR}/IO-Tty-${PV}" + +inherit cpan diff --git a/recipes/perl/libio-stty-perl_0.02.bb b/recipes/perl/libio-stty-perl_0.02.bb new file mode 100644 index 0000000000..9412593611 --- /dev/null +++ b/recipes/perl/libio-stty-perl_0.02.bb @@ -0,0 +1,10 @@ +DESCRIPTION = "Interface to secure pseudo ttys" +SECTION = "libs" +LICENSE = "Artistic|GPL" +PR = "r0" + +SRC_URI = "http://www.cpan.org/modules/by-module/IO/IO-Stty-.02.tar.gz" + +S = "${WORKDIR}/IO-Stty-.02" + +inherit cpan -- cgit v1.2.3 From d5345f88b5ffdca098e0281f42f51e42ef43e79d Mon Sep 17 00:00:00 2001 From: Stanislav Brabec Date: Tue, 8 Sep 2009 19:44:14 +0000 Subject: more files: Fixed unpack dependencies on unzip-native, see: * http://lists.linuxtogo.org/pipermail/openembedded-devel/2009-August/013505.html * http://lists.linuxtogo.org/pipermail/openembedded-devel/2009-September/013620.html --- recipes/faad2/faad2_2.0.bb | 2 +- recipes/freedoom/freedoom_0.3.bb | 1 + recipes/freedoom/freedoom_0.6.2.bb | 1 + recipes/ixp4xx/ixp4xx-npe-native_2.1.bb | 1 + recipes/ixp4xx/ixp4xx-npe-native_2.3.2.bb | 1 + recipes/ixp4xx/ixp4xx-npe-native_2.4.bb | 1 + recipes/ixp4xx/ixp4xx-npe_2.1.bb | 1 + recipes/ixp4xx/ixp4xx-npe_2.3.2.bb | 1 + recipes/ixp4xx/ixp4xx-npe_2.4.bb | 1 + recipes/jpeg/jasper_1.900.1.bb | 3 +-- recipes/juce/juce_1.29.bb | 2 +- recipes/klimt/klimt_0.6.1.bb | 1 + recipes/librcf/librcf_0.4.bb | 1 + recipes/linux/compulab-pxa270_2.6.16.bb | 1 + recipes/miglayout/miglayout_3.0.3.bb | 3 ++- recipes/misc-binary-only/tda1004x-firmware.bb | 2 +- recipes/ogre/freeimage_3.11.0.bb | 1 + recipes/orinoco/spectrum-fw.bb | 2 +- 18 files changed, 19 insertions(+), 7 deletions(-) diff --git a/recipes/faad2/faad2_2.0.bb b/recipes/faad2/faad2_2.0.bb index 90255b3fd8..1db939ce22 100644 --- a/recipes/faad2/faad2_2.0.bb +++ b/recipes/faad2/faad2_2.0.bb @@ -1,9 +1,9 @@ - DESCRIPTION = "Library for reading some sort of media format." SECTION = "libs" LICENSE = "LGPL" PRIORITY = "optional" DEPENDS = "" +do_unpack[depends] += "unzip-native:do_populate_staging" PR ="r2" inherit autotools diff --git a/recipes/freedoom/freedoom_0.3.bb b/recipes/freedoom/freedoom_0.3.bb index daef13fc8a..f44bde1bf3 100644 --- a/recipes/freedoom/freedoom_0.3.bb +++ b/recipes/freedoom/freedoom_0.3.bb @@ -5,6 +5,7 @@ DESCRIPTION = "The Freedoom project aims at collaboratively creating a Free IWAD HOMEPAGE = "http://freedoom.sourceforge.net/" PRIORITY = "optional" LICENSE = "GPL" +do_unpack[depends] += "unzip-native:do_populate_staging" SRC_URI = "http://ovh.dl.sourceforge.net/sourceforge/freedoom/freedoom-iwad-0.3.zip" diff --git a/recipes/freedoom/freedoom_0.6.2.bb b/recipes/freedoom/freedoom_0.6.2.bb index 0a3be04410..26792de2b1 100644 --- a/recipes/freedoom/freedoom_0.6.2.bb +++ b/recipes/freedoom/freedoom_0.6.2.bb @@ -5,6 +5,7 @@ DESCRIPTION = "The Freedoom project aims at collaboratively creating a Free IWAD HOMEPAGE = "http://freedoom.sourceforge.net/" PRIORITY = "optional" LICENSE = "GPL" +do_unpack[depends] += "unzip-native:do_populate_staging" SRC_URI = "${SOURCEFORGE_MIRROR}/freedoom/freedoom-iwad-${PV}.zip" diff --git a/recipes/ixp4xx/ixp4xx-npe-native_2.1.bb b/recipes/ixp4xx/ixp4xx-npe-native_2.1.bb index 4f1d9383a5..1510a750a9 100644 --- a/recipes/ixp4xx/ixp4xx-npe-native_2.1.bb +++ b/recipes/ixp4xx/ixp4xx-npe-native_2.1.bb @@ -4,6 +4,7 @@ PR = "r3" SRC_URI = "http://www.intel.com/Please-Read-The-BB-File/IPL_ixp400NpeLibrary-2_1.zip" SRC_URI += "file://IxNpeMicrocode.h" +do_unpack[depends] += "unzip-native:do_populate_staging" inherit native S = "${WORKDIR}/ixp400_xscale_sw/src/npeDl" diff --git a/recipes/ixp4xx/ixp4xx-npe-native_2.3.2.bb b/recipes/ixp4xx/ixp4xx-npe-native_2.3.2.bb index 9db83352c4..710716392d 100644 --- a/recipes/ixp4xx/ixp4xx-npe-native_2.3.2.bb +++ b/recipes/ixp4xx/ixp4xx-npe-native_2.3.2.bb @@ -4,6 +4,7 @@ PR = "r1" SRC_URI = "http://You-Have-To-Download-The-Microcode-Manually-So-Please-Read-ixp4xx-npe_2.3.2.bb-For-Instructions/IPL_ixp400NpeLibrary-2_3_2.zip" SRC_URI += "file://IxNpeMicrocode.h" +do_unpack[depends] += "unzip-native:do_populate_staging" inherit native S = "${WORKDIR}/ixp400_xscale_sw/src/npeDl" diff --git a/recipes/ixp4xx/ixp4xx-npe-native_2.4.bb b/recipes/ixp4xx/ixp4xx-npe-native_2.4.bb index 2b3da60b5d..00a5d872c5 100644 --- a/recipes/ixp4xx/ixp4xx-npe-native_2.4.bb +++ b/recipes/ixp4xx/ixp4xx-npe-native_2.4.bb @@ -4,6 +4,7 @@ PR = "r0" SRC_URI = "http://You-Have-To-Download-The-Microcode-Manually-So-Please-Read-ixp4xx-npe_2.4.bb-For-Instructions/IPL_ixp400NpeLibrary-2_4.zip" SRC_URI += "file://IxNpeMicrocode.h" +do_unpack[depends] += "unzip-native:do_populate_staging" inherit native S = "${WORKDIR}/ixp400_xscale_sw/src/npeDl" diff --git a/recipes/ixp4xx/ixp4xx-npe_2.1.bb b/recipes/ixp4xx/ixp4xx-npe_2.1.bb index 7fdc3abf63..7eb3a3dbe0 100644 --- a/recipes/ixp4xx/ixp4xx-npe_2.1.bb +++ b/recipes/ixp4xx/ixp4xx-npe_2.1.bb @@ -4,6 +4,7 @@ PR = "r6" DEPENDS = "ixp4xx-npe-native" SRC_URI = "http://www.intel.com/Please-Read-The-BB-File/IPL_ixp400NpeLibrary-2_1.zip" +do_unpack[depends] += "unzip-native:do_populate_staging" S = "${WORKDIR}/ixp400_xscale_sw/src/npeDl" COMPATIBLE_MACHINE = "(nslu2|ixp4xx)" diff --git a/recipes/ixp4xx/ixp4xx-npe_2.3.2.bb b/recipes/ixp4xx/ixp4xx-npe_2.3.2.bb index a53b9d703b..a4426886f3 100644 --- a/recipes/ixp4xx/ixp4xx-npe_2.3.2.bb +++ b/recipes/ixp4xx/ixp4xx-npe_2.3.2.bb @@ -9,6 +9,7 @@ DEPENDS = "ixp4xx-npe-native" # Make sure you *read* and accept the license - it is not a standard one. SRC_URI = "http://You-Have-To-Download-The-Microcode-Manually-So-Please-Read-ixp4xx-npe_2.3.2.bb-For-Instructions/IPL_ixp400NpeLibrary-2_3_2.zip" +do_unpack[depends] += "unzip-native:do_populate_staging" S = "${WORKDIR}/ixp400_xscale_sw/src/npeDl" COMPATIBLE_MACHINE = "(nslu2|ixp4xx)" diff --git a/recipes/ixp4xx/ixp4xx-npe_2.4.bb b/recipes/ixp4xx/ixp4xx-npe_2.4.bb index 4d8d80f92e..b3e918b32a 100644 --- a/recipes/ixp4xx/ixp4xx-npe_2.4.bb +++ b/recipes/ixp4xx/ixp4xx-npe_2.4.bb @@ -11,6 +11,7 @@ DEPENDS = "ixp4xx-npe-native" SRC_URI = "http://You-Have-To-Download-The-Microcode-Manually-So-Please-Read-ixp4xx-npe_2.4.bb-For-Instructions/IPL_ixp400NpeLibrary-2_4.zip \ file://Intel" +do_unpack[depends] += "unzip-native:do_populate_staging" S = "${WORKDIR}/ixp400_xscale_sw/src/npeDl" COMPATIBLE_MACHINE = "(nslu2|ixp4xx|kixrp435)" diff --git a/recipes/jpeg/jasper_1.900.1.bb b/recipes/jpeg/jasper_1.900.1.bb index 9f1f5eeebc..aee948db87 100644 --- a/recipes/jpeg/jasper_1.900.1.bb +++ b/recipes/jpeg/jasper_1.900.1.bb @@ -1,6 +1,6 @@ DESCRIPTION = "Jpeg 2000 implementation" LICENSE = "MIT" -DEPENDS = "unzip-native" +do_unpack[depends] += "unzip-native:do_populate_staging" SRC_URI = "http://www.ece.uvic.ca/~mdadams/jasper/software/jasper-${PV}.zip" @@ -12,4 +12,3 @@ AUTOTOOLS_STAGE_PKGCONFIG = "1" do_stage() { autotools_stage_all } - diff --git a/recipes/juce/juce_1.29.bb b/recipes/juce/juce_1.29.bb index 6aca160262..a007313005 100644 --- a/recipes/juce/juce_1.29.bb +++ b/recipes/juce/juce_1.29.bb @@ -3,6 +3,7 @@ HOMEPAGE = "http://www.rawmaterialsoftware.com/juce" AUTHOR = "Julian Stoerer" LICENSE = "GPL" DEPENDS = "alsa-lib freetype virtual/libx11" +do_unpack[depends] += "unzip-native:do_populate_staging" PR = "r0" #FIXME the patches are a) HACKS and b) something's wrong with lineend conversion @@ -30,4 +31,3 @@ do_install() { PACKAGES = "${PN}-dbg jucedemo ${PN}" FILES_jucedemo = "${bindir}" - diff --git a/recipes/klimt/klimt_0.6.1.bb b/recipes/klimt/klimt_0.6.1.bb index 4e516fc90d..a2eccb67b2 100644 --- a/recipes/klimt/klimt_0.6.1.bb +++ b/recipes/klimt/klimt_0.6.1.bb @@ -5,6 +5,7 @@ LICENSE = "GPL" PR = "r1" SRC_URI = "${SOURCEFORGE_MIRROR}/klimt/klimt-src-${PV}.zip" +do_unpack[depends] += "unzip-native:do_populate_staging" S = "${WORKDIR}/klimt/build/LinuxQTE" EXTRA_QMAKEVARS_POST += " QMAKE_CXXFLAGS+=-fpermissive" diff --git a/recipes/librcf/librcf_0.4.bb b/recipes/librcf/librcf_0.4.bb index 6b0612c86b..6e444c0af0 100644 --- a/recipes/librcf/librcf_0.4.bb +++ b/recipes/librcf/librcf_0.4.bb @@ -3,6 +3,7 @@ SECTION = "base" PRIORITY = "optional" LICENSE = "unknown" DEPENDS="zlib openssl boost-asio" +do_unpack[depends] += "unzip-native:do_populate_staging" # the SOURCE_URI requires authentication via web browser and cookie (gasp) # all we can do right now is download the file and save it under sources/ diff --git a/recipes/linux/compulab-pxa270_2.6.16.bb b/recipes/linux/compulab-pxa270_2.6.16.bb index fe72df8213..6dc92f69b6 100644 --- a/recipes/linux/compulab-pxa270_2.6.16.bb +++ b/recipes/linux/compulab-pxa270_2.6.16.bb @@ -2,6 +2,7 @@ SECTION = "kernel" DESCRIPTION = "Linux kernel for the Compulab PXA270 system" LICENSE = "GPL" PR = "r6" +do_unpack[depends] += "unzip-native:do_populate_staging" # Note, the compulab package contains a binary NAND driver that is not # EABI compatible diff --git a/recipes/miglayout/miglayout_3.0.3.bb b/recipes/miglayout/miglayout_3.0.3.bb index 2450a7e01f..44fce0c845 100644 --- a/recipes/miglayout/miglayout_3.0.3.bb +++ b/recipes/miglayout/miglayout_3.0.3.bb @@ -10,7 +10,8 @@ S = "${WORKDIR}" inherit java-library -DEPENDS = "unzip-native fastjar-native classpath swt3.4-gtk" +DEPENDS = "fastjar-native classpath swt3.4-gtk" +do_unpack[depends] += "unzip-native:do_populate_staging" do_unpackpost() { find -name "*.jar" -exec rm {} \; diff --git a/recipes/misc-binary-only/tda1004x-firmware.bb b/recipes/misc-binary-only/tda1004x-firmware.bb index 1e4d68532f..1d3b467a75 100644 --- a/recipes/misc-binary-only/tda1004x-firmware.bb +++ b/recipes/misc-binary-only/tda1004x-firmware.bb @@ -1,5 +1,5 @@ SECTION = "base" -DEPENDS = "unzip-native" +do_unpack[depends] += "unzip-native:do_populate_staging" SRC_URI = "http://hauppauge.lightpath.net/de/nova-pci218c.exe" FILES_${PN} = '*' diff --git a/recipes/ogre/freeimage_3.11.0.bb b/recipes/ogre/freeimage_3.11.0.bb index 8281aaf371..2d7f4f0688 100644 --- a/recipes/ogre/freeimage_3.11.0.bb +++ b/recipes/ogre/freeimage_3.11.0.bb @@ -1,4 +1,5 @@ LICENSE = "MIT" +do_unpack[depends] += "unzip-native:do_populate_staging" SRC_URI = "${SOURCEFORGE_MIRROR}/freeimage/FreeImage3110.zip" diff --git a/recipes/orinoco/spectrum-fw.bb b/recipes/orinoco/spectrum-fw.bb index f2e11eea74..cedb0e35fe 100644 --- a/recipes/orinoco/spectrum-fw.bb +++ b/recipes/orinoco/spectrum-fw.bb @@ -1,5 +1,5 @@ DESCRIPTION = "Firmware for Spectrum Wireless LAN cards" -DEPENDS += " unzip-native " +do_unpack[depends] += "unzip-native:do_populate_staging" LICENSE = "unknown" PR = "r1" -- cgit v1.2.3 From d891babf907584bae254d93ab7732f8fb1d352f0 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Sat, 5 Sep 2009 19:21:53 -0700 Subject: uclibc_0.9.30.1: Disable STDIO_GETC|PUTC MACROs * There is a problem with threads enabled and hiding __fgetc_unlocked and __fputc_unlocked which gets pulled in with the macros. This patch disables the macros and it will use the functions to perform these functions Signed-off-by: Khem Raj --- recipes/uclibc/uclibc-0.9.30.1/uClibc.distro | 4 ++-- recipes/uclibc/uclibc_0.9.30.1.bb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/recipes/uclibc/uclibc-0.9.30.1/uClibc.distro b/recipes/uclibc/uclibc-0.9.30.1/uClibc.distro index 31029a3dca..042ea4c547 100644 --- a/recipes/uclibc/uclibc-0.9.30.1/uClibc.distro +++ b/recipes/uclibc/uclibc-0.9.30.1/uClibc.distro @@ -83,8 +83,8 @@ UCLIBC_HAS_STDIO_BUILTIN_BUFFER_NONE=y # UCLIBC_HAS_STDIO_BUILTIN_BUFFER_4 is not set # UCLIBC_HAS_STDIO_BUILTIN_BUFFER_8 is not set # UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT is not set -UCLIBC_HAS_STDIO_GETC_MACRO=y -UCLIBC_HAS_STDIO_PUTC_MACRO=y +# UCLIBC_HAS_STDIO_GETC_MACRO is not set +# UCLIBC_HAS_STDIO_PUTC_MACRO is not set UCLIBC_HAS_STDIO_AUTO_RW_TRANSITION=y # UCLIBC_HAS_FOPEN_LARGEFILE_MODE is not set UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE=y diff --git a/recipes/uclibc/uclibc_0.9.30.1.bb b/recipes/uclibc/uclibc_0.9.30.1.bb index 821e06e8bb..ae558e01f1 100644 --- a/recipes/uclibc/uclibc_0.9.30.1.bb +++ b/recipes/uclibc/uclibc_0.9.30.1.bb @@ -9,7 +9,7 @@ UCLIBC_BASE ?= "0.9.30.1" require uclibc.inc -PR = "${INC_PR}.0" +PR = "${INC_PR}.1" PROVIDES += "virtual/${TARGET_PREFIX}libc-for-gcc" -- cgit v1.2.3 From 071f70343a27aa25dcd2344118389071025ad9a7 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Sat, 5 Sep 2009 19:33:11 -0700 Subject: autoconf: Fix canadian cross build * Remove RDEPENDS and DEPENDS duplication. * path_prog_fixes.patch is not needed for 2.61 * Use INC_PR Signed-off-by: Khem Raj --- recipes/autoconf/autoconf-native_2.59.bb | 2 ++ recipes/autoconf/autoconf-native_2.61.bb | 1 + recipes/autoconf/autoconf-native_2.63.bb | 1 + recipes/autoconf/autoconf.inc | 1 + recipes/autoconf/autoconf213-native_2.13.bb | 2 ++ recipes/autoconf/autoconf213_2.13.bb | 2 +- recipes/autoconf/autoconf_2.57.bb | 2 +- recipes/autoconf/autoconf_2.59.bb | 4 +--- recipes/autoconf/autoconf_2.61.bb | 8 ++------ recipes/autoconf/autoconf_2.63.bb | 5 ++--- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/recipes/autoconf/autoconf-native_2.59.bb b/recipes/autoconf/autoconf-native_2.59.bb index aa4871e194..a2b9dfa2d0 100644 --- a/recipes/autoconf/autoconf-native_2.59.bb +++ b/recipes/autoconf/autoconf-native_2.59.bb @@ -1,5 +1,7 @@ require autoconf_${PV}.bb +PR = "${INC_PR}.0" + DEPENDS = "m4-native gnu-config-native" RDEPENDS_${PN} = "m4-native gnu-config-native" diff --git a/recipes/autoconf/autoconf-native_2.61.bb b/recipes/autoconf/autoconf-native_2.61.bb index ad6cb79445..b7480cdc11 100644 --- a/recipes/autoconf/autoconf-native_2.61.bb +++ b/recipes/autoconf/autoconf-native_2.61.bb @@ -1,4 +1,5 @@ require autoconf_${PV}.bb +PR = "${INC_PR}.0" DEPENDS = "m4-native gnu-config-native" RDEPENDS_${PN} = "m4-native gnu-config-native" diff --git a/recipes/autoconf/autoconf-native_2.63.bb b/recipes/autoconf/autoconf-native_2.63.bb index ad6cb79445..b7480cdc11 100644 --- a/recipes/autoconf/autoconf-native_2.63.bb +++ b/recipes/autoconf/autoconf-native_2.63.bb @@ -1,4 +1,5 @@ require autoconf_${PV}.bb +PR = "${INC_PR}.0" DEPENDS = "m4-native gnu-config-native" RDEPENDS_${PN} = "m4-native gnu-config-native" diff --git a/recipes/autoconf/autoconf.inc b/recipes/autoconf/autoconf.inc index 7761af06d7..a05f2ae7db 100644 --- a/recipes/autoconf/autoconf.inc +++ b/recipes/autoconf/autoconf.inc @@ -10,3 +10,4 @@ SRC_URI = "${GNU_MIRROR}/autoconf/autoconf-${PV}.tar.bz2 \ file://program_prefix.patch;patch=1" inherit autotools +INC_PR = "r6" diff --git a/recipes/autoconf/autoconf213-native_2.13.bb b/recipes/autoconf/autoconf213-native_2.13.bb index 3954ef3b16..97d441397e 100644 --- a/recipes/autoconf/autoconf213-native_2.13.bb +++ b/recipes/autoconf/autoconf213-native_2.13.bb @@ -7,3 +7,5 @@ S = "${WORKDIR}/autoconf-${PV}" FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/autoconf-${PV}" inherit native +PR = "${INC_PR}.0" + diff --git a/recipes/autoconf/autoconf213_2.13.bb b/recipes/autoconf/autoconf213_2.13.bb index 022f696f1d..d06822c7c9 100644 --- a/recipes/autoconf/autoconf213_2.13.bb +++ b/recipes/autoconf/autoconf213_2.13.bb @@ -1,5 +1,5 @@ require autoconf.inc SRC_URI = "${GNU_MIRROR}/autoconf/autoconf-${PV}.tar.gz" -PR = "r1" EXTRA_OECONF = "--program-transform-name=s/\$/2.13/" EXTRA_OEMAKE = 'acdatadir="${datadir}/autoconf-${PV}" infodir="${datadir}/autoconf-${PV}/info"' +PR = "${INC_PR}.0" diff --git a/recipes/autoconf/autoconf_2.57.bb b/recipes/autoconf/autoconf_2.57.bb index 6c2906a362..0fc5f94b83 100644 --- a/recipes/autoconf/autoconf_2.57.bb +++ b/recipes/autoconf/autoconf_2.57.bb @@ -1,2 +1,2 @@ require autoconf.inc -PR = "r1" +PR = "${INC_PR}.0" diff --git a/recipes/autoconf/autoconf_2.59.bb b/recipes/autoconf/autoconf_2.59.bb index f59f8fa5c9..a8f357fc5f 100644 --- a/recipes/autoconf/autoconf_2.59.bb +++ b/recipes/autoconf/autoconf_2.59.bb @@ -1,8 +1,6 @@ require autoconf.inc -DEPENDS += "m4-native" -RDEPENDS_${PN} = "m4 gnu-config" -PR = "r6" +PR = "${INC_PR}.0" SRC_URI += "file://autoreconf-include.patch;patch=1 \ file://autoreconf-exclude.patch;patch=1 \ diff --git a/recipes/autoconf/autoconf_2.61.bb b/recipes/autoconf/autoconf_2.61.bb index 6b92dc8120..c3ccacd329 100644 --- a/recipes/autoconf/autoconf_2.61.bb +++ b/recipes/autoconf/autoconf_2.61.bb @@ -1,16 +1,12 @@ require autoconf.inc -PR = "r1" +PR = "${INC_PR}.1" PARALLEL_MAKE = "" -DEPENDS += "m4-native" -RDEPENDS_${PN} = "m4 gnu-config" - SRC_URI += "file://autoreconf-include.patch;patch=1 \ file://autoreconf-exclude.patch;patch=1 \ file://autoreconf-foreign.patch;patch=1 \ file://autoreconf-gnuconfigize.patch;patch=1 \ file://autoheader-nonfatal-warnings.patch;patch=1 \ - file://config-site.patch;patch=1 \ - ${@['file://path_prog_fixes.patch;patch=1', ''][bb.data.inherits_class('native', d)]}" + file://config-site.patch;patch=1 " diff --git a/recipes/autoconf/autoconf_2.63.bb b/recipes/autoconf/autoconf_2.63.bb index 0230d790b1..6963baf169 100644 --- a/recipes/autoconf/autoconf_2.63.bb +++ b/recipes/autoconf/autoconf_2.63.bb @@ -1,12 +1,11 @@ require autoconf.inc +PR = "${INC_PR}.0" + DEFAULT_PREFERENCE = "-1" PARALLEL_MAKE = "" -DEPENDS += "m4-native" -RDEPENDS_${PN} = "m4 gnu-config" - SRC_URI += " \ file://autoreconf-exclude.patch;patch=1 \ file://autoreconf-foreign.patch;patch=1 \ -- cgit v1.2.3 From b4bb4f34f7f066ff0090739773168dc5610d12fd Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Mon, 7 Sep 2009 09:17:38 -0700 Subject: tar_1.22.bb: Add recipe for 1.22 release. Signed-off-by: Khem Raj --- conf/checksums.ini | 4 ++++ recipes/tar/tar_1.22.bb | 1 + 2 files changed, 5 insertions(+) create mode 100644 recipes/tar/tar_1.22.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index 01e625aecb..3c8e48d6f0 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -23750,6 +23750,10 @@ sha256=44944ee0427c8e0d8dbaa0b8f900073a7456819610cc521c53630c3eb117cf5e md5=1a7e17f27abf583b3b0bc059a827e68b sha256=be8bf33afb5adc2377e45d94693ffd46b75f267f9b808df0c7006e51211f9deb +[ftp://ftp.gnu.org/gnu/tar/tar-1.22.tar.bz2] +md5=07fa517027f426bb80f5f5ff91b63585 +sha256=3cefb67f197a3f8f5235999fe749ced0889466a71ddcbc96fddca84e5d53aa4d + [http://downloads.sourceforge.net/subapplet/tasklist-105.tar.gz] md5=dc62a061d83cf72d1eca7e8ae2c8e1a6 sha256=4078c44beebfd298995983b9e2ea189167a1ab081d96a7c485a67b65a974e878 diff --git a/recipes/tar/tar_1.22.bb b/recipes/tar/tar_1.22.bb new file mode 100644 index 0000000000..25163acdad --- /dev/null +++ b/recipes/tar/tar_1.22.bb @@ -0,0 +1 @@ +require tar.inc -- cgit v1.2.3 From 3e0e303e7ad1c6e34a446e37c7ba8fcfb3b72125 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Mon, 7 Sep 2009 12:09:18 -0700 Subject: tune-xscale.inc: Use TARGET_ARCH to find endianness * Use TARGET_ARCH to find endianness instead of SITEINFO_ENDIANNESS which is not yet evaluated. Signed-off-by: Khem Raj --- conf/machine/include/tune-xscale.inc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/conf/machine/include/tune-xscale.inc b/conf/machine/include/tune-xscale.inc index 7fa6447648..3a6bd0e659 100644 --- a/conf/machine/include/tune-xscale.inc +++ b/conf/machine/include/tune-xscale.inc @@ -1,9 +1,12 @@ -FEED_ARCH = "${@['armv5teb', 'armv5te'][bb.data.getVar('SITEINFO_ENDIANESS', d, 1) == 'le']}" +# this depends on fact that for ARM the TARGET_ARCH is 'arm' for little endian and 'armeb' for bigendian +# this is the case as of now for all arm machines in OE. + +FEED_ARCH = "${@['armv5teb', 'armv5te'][bb.data.getVar('TARGET_ARCH', d, 1) == 'arm']}" TARGET_CC_ARCH = "-march=armv5te -mtune=xscale" TARGET_CC_KERNEL_ARCH = "-march=armv5te -mtune=xscale" -PACKAGE_EXTRA_ARCHS += "${@['armv4b armv4tb armv5teb', 'armv4 armv4t armv5te'][bb.data.getVar('SITEINFO_ENDIANESS', d, 1) == 'le']}" -BASE_PACKAGE_ARCH := "${@['armv5teb', 'armv5te'][bb.data.getVar('SITEINFO_ENDIANESS', d, 1) == 'le']}" +PACKAGE_EXTRA_ARCHS += "${@['armv4b armv4tb armv5teb', 'armv4 armv4t armv5te'][ bb.data.getVar('TARGET_ARCH', d, 1) == 'arm']}" +BASE_PACKAGE_ARCH = "${@['armv5teb', 'armv5te'][bb.data.getVar('TARGET_ARCH', d, 1) == 'arm']}" # Include tune file for thumb support, it defaults to off so DISTROs can turn it on if they wish require conf/machine/include/tune-thumb.inc -- cgit v1.2.3 From 30c1e63389bb65008f8fec09ff5e12b19609c3e8 Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Wed, 9 Sep 2009 10:55:18 +0200 Subject: linux-omap: added support for BeagleBUG extension board This is initial version of BeagleBUG extension board support. So far boards are not available for people outside of BugLabs and Texas Instruments companies. Patch adds support for few modules but not all of them will build for OMAP3 - some are still BUG only. --- conf/machine/include/omap3.inc | 2 +- .../linux/linux-omap-2.6.29/beagleboard/defconfig | 24 +- .../beaglebug/beaglebug-full.patch | 35774 +++++++++++++++++++ recipes/linux/linux-omap_2.6.29.bb | 1 + 4 files changed, 35798 insertions(+), 3 deletions(-) create mode 100644 recipes/linux/linux-omap-2.6.29/beaglebug/beaglebug-full.patch diff --git a/conf/machine/include/omap3.inc b/conf/machine/include/omap3.inc index 889e0f6478..c52cbddf18 100644 --- a/conf/machine/include/omap3.inc +++ b/conf/machine/include/omap3.inc @@ -1,7 +1,7 @@ require conf/machine/include/tune-cortexa8.inc PREFERRED_PROVIDER_virtual/kernel = "linux-omap" # Increase this everytime you change something in the kernel -MACHINE_KERNEL_PR = "r44" +MACHINE_KERNEL_PR = "r45" KERNEL_IMAGETYPE = "uImage" diff --git a/recipes/linux/linux-omap-2.6.29/beagleboard/defconfig b/recipes/linux/linux-omap-2.6.29/beagleboard/defconfig index c9f8e9962b..a1848d59a4 100644 --- a/recipes/linux/linux-omap-2.6.29/beagleboard/defconfig +++ b/recipes/linux/linux-omap-2.6.29/beagleboard/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.29-omap1 -# Thu Aug 13 12:58:49 2009 +# Wed Sep 9 09:58:54 2009 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -249,6 +249,7 @@ CONFIG_ARM_THUMBEE=y # CONFIG_CPU_BPREDICT_DISABLE is not set CONFIG_HAS_TLS_REG=y # CONFIG_OUTER_CACHE is not set +CONFIG_ARM_L1_CACHE_SHIFT=6 # # Bus support @@ -272,7 +273,7 @@ CONFIG_PREEMPT=y CONFIG_HZ=128 CONFIG_AEABI=y # CONFIG_OABI_COMPAT is not set -CONFIG_ARCH_FLATMEM_HAS_HOLES=y +CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set CONFIG_SELECT_MEMORY_MODEL=y @@ -2274,6 +2275,25 @@ CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE=y # CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT is not set CONFIG_ANDROID_TIMED_GPIO=m CONFIG_ANDROID_LOW_MEMORY_KILLER=y +CONFIG_BMI=y + +# +# BMI Hardware Slot support +# +CONFIG_OMAP_SLOT=m +CONFIG_BMI_PIMS=m + +# +# BMI PIMS +# +# CONFIG_BUG_FACTORY_TEST is not set +CONFIG_BMI_GPS=m +CONFIG_BMI_MDACC=m +# CONFIG_BMI_AUDIO is not set +CONFIG_BMI_VH=m +# CONFIG_BMI_SENSOR is not set +# CONFIG_BMI_ZB is not set +CONFIG_BMI_GSM=m # # CBUS support diff --git a/recipes/linux/linux-omap-2.6.29/beaglebug/beaglebug-full.patch b/recipes/linux/linux-omap-2.6.29/beaglebug/beaglebug-full.patch new file mode 100644 index 0000000000..f556f420e4 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/beaglebug/beaglebug-full.patch @@ -0,0 +1,35774 @@ +--- + arch/arm/Kconfig | 2 + arch/arm/mach-omap2/board-omap3beagle.c | 52 + arch/arm/mach-omap2/mux.c | 25 + arch/arm/plat-omap/include/mach/mux.h | 7 + drivers/Kconfig | 3 + drivers/Makefile | 1 + drivers/bmi/Kconfig | 17 + drivers/bmi/Makefile | 8 + drivers/bmi/core/Makefile | 7 + drivers/bmi/core/core.c | 319 + + drivers/bmi/core/device.c | 35 + drivers/bmi/core/driver.c | 27 + drivers/bmi/core/eeprom.c | 32 + drivers/bmi/core/slot.c | 469 ++ + drivers/bmi/pims/Kconfig | 104 + drivers/bmi/pims/Makefile | 17 + drivers/bmi/pims/camera/Kconfig | 23 + drivers/bmi/pims/camera/Makefile | 12 + drivers/bmi/pims/camera/bmi_ov2640.c | 929 +++++ + drivers/bmi/pims/camera/bmi_vs6624.c | 915 +++++ + drivers/bmi/pims/camera/bug_camera.c | 611 +++ + drivers/bmi/pims/camera/bug_camera.h | 72 + drivers/bmi/pims/camera/ov2640.c | 301 + + drivers/bmi/pims/camera/ov2640.h | 14 + drivers/bmi/pims/camera/vs6624_access.c | 597 +++ + drivers/bmi/pims/camera/vs6624_access.h | 17 + drivers/bmi/pims/camera/vs6624_patch.c | 373 ++ + drivers/bmi/pims/camera/vs6624_regs.h | 467 ++ + drivers/bmi/pims/factory_test/Makefile | 6 + drivers/bmi/pims/factory_test/factory_test.c | 952 +++++ + drivers/bmi/pims/gps/Makefile | 6 + drivers/bmi/pims/gps/bmi_gps.c | 468 ++ + drivers/bmi/pims/gsm/Makefile | 6 + drivers/bmi/pims/gsm/bmi_gsm.c | 301 + + drivers/bmi/pims/lcd/Makefile | 9 + drivers/bmi/pims/lcd/acc.c | 114 + drivers/bmi/pims/lcd/acc.h | 35 + drivers/bmi/pims/lcd/bmi_lcd.c | 1790 ++++++++++ + drivers/bmi/pims/lcd/bmi_lcd_inf.c | 1775 ++++++++++ + drivers/bmi/pims/lcd/bmi_lcd_mi.c | 1855 +++++++++++ + drivers/bmi/pims/lcd/bmi_s320x240.c | 632 +++ + drivers/bmi/pims/lcd/lcd_ctl.c | 421 ++ + drivers/bmi/pims/lcd/lcd_ctl.h | 87 + drivers/bmi/pims/mdacc/Kconfig | 6 + drivers/bmi/pims/mdacc/Makefile | 9 + drivers/bmi/pims/mdacc/acc.c | 381 ++ + drivers/bmi/pims/mdacc/acc.h | 54 + drivers/bmi/pims/mdacc/avr.c | 511 +++ + drivers/bmi/pims/mdacc/avr.h | 54 + drivers/bmi/pims/mdacc/cque.c | 150 + drivers/bmi/pims/mdacc/cque.h | 42 + drivers/bmi/pims/mdacc/ctl.c | 176 + + drivers/bmi/pims/mdacc/ctl.h | 43 + drivers/bmi/pims/mdacc/md.c | 333 ++ + drivers/bmi/pims/mdacc/md.h | 60 + drivers/bmi/pims/mdacc/mdacc.c | 333 ++ + drivers/bmi/pims/mdacc/mdacc.h | 43 + drivers/bmi/pims/mdacc/mon.c | 474 ++ + drivers/bmi/pims/mdacc/mon.h | 61 + drivers/bmi/pims/projector/Makefile | 7 + drivers/bmi/pims/projector/bmi_projector.c | 674 ++++ + drivers/bmi/pims/projector/ch7024.c | 476 ++ + drivers/bmi/pims/projector/ch7024.h | 166 + + drivers/bmi/pims/sensor/Makefile | 6 + drivers/bmi/pims/sensor/bmi_sensor.c | 4321 ++++++++++++++++++++++++++ + drivers/bmi/pims/sound/Makefile | 6 + drivers/bmi/pims/sound/bmi_audio.c | 4434 +++++++++++++++++++++++++++ + drivers/bmi/pims/vonhippel/Makefile | 6 + drivers/bmi/pims/vonhippel/bmi_vh.c | 942 +++++ + drivers/bmi/pims/zb/Makefile | 5 + drivers/bmi/pims/zb/bmi_zaccel.c | 684 ++++ + drivers/bmi/pims/zb/bmi_zaccel.h | 288 + + drivers/bmi/pims/zb/bmi_zigbee.c | 1296 +++++++ + drivers/bmi/pims/zb/bmi_zigbee.h | 194 + + drivers/bmi/pims/zb/bmi_znetdev.c | 977 +++++ + drivers/bmi/pims/zb/bmi_zprotocol.c | 619 +++ + drivers/bmi/slots/Kconfig | 21 + drivers/bmi/slots/Makefile | 6 + drivers/bmi/slots/slots_beagle.c | 267 + + drivers/bmi/slots/slots_bug.c | 231 + + include/linux/bmi-ids.h | 30 + include/linux/bmi.h | 142 + include/linux/bmi/at24c02.h | 26 + include/linux/bmi/bmi-bus.h | 21 + include/linux/bmi/bmi-control.h | 303 + + include/linux/bmi/bmi-eeprom-data.h | 83 + include/linux/bmi/bmi-eeprom-driver.h | 113 + include/linux/bmi/bmi-eeprom.h | 75 + include/linux/bmi/bmi-slot.h | 29 + include/linux/bmi/bmi_audio.h | 449 ++ + include/linux/bmi/bmi_camera.h | 36 + include/linux/bmi/bmi_gps.h | 30 + include/linux/bmi/bmi_gsm.h | 33 + include/linux/bmi/bmi_ioctl.h | 27 + include/linux/bmi/bmi_lcd.h | 71 + include/linux/bmi/bmi_mdacc.h | 518 +++ + include/linux/bmi/bmi_projector.h | 33 + include/linux/bmi/bmi_sensor.h | 673 ++++ + include/linux/bmi/bmi_vh.h | 135 + include/linux/bmi/bmi_zb.h | 83 + include/linux/mod_devicetable.h | 13 + scripts/mod/file2alias.c | 20 + 102 files changed, 35212 insertions(+) + +--- git.orig/arch/arm/Kconfig ++++ git/arch/arm/Kconfig +@@ -1342,10 +1342,12 @@ source "drivers/regulator/Kconfig" + + source "drivers/uio/Kconfig" + + source "drivers/staging/Kconfig" + ++source "drivers/bmi/Kconfig" ++ + if ARCH_OMAP + source "drivers/cbus/Kconfig" + endif + + endmenu +--- git.orig/arch/arm/mach-omap2/board-omap3beagle.c ++++ git/arch/arm/mach-omap2/board-omap3beagle.c +@@ -23,10 +23,12 @@ + #include + #include + #include + #include + ++ ++#include + #include + #include + #include + + #include +@@ -404,10 +406,16 @@ static struct gpio_led gpio_leds[] = { + { + .name = "beagleboard::usr0", + .default_trigger = "heartbeat", + .gpio = 150, + }, ++ /*{ ++ .name = "beagleboard::exp21", ++ .default_trigger = "heartbeat", ++ .gpio = 130, ++ }, ++ */ + { + .name = "beagleboard::usr1", + .default_trigger = "mmc0", + .gpio = 149, + }, +@@ -537,20 +545,54 @@ static void __init beagle_display_init(v + } + + gpio_direction_output(beagle_display_data_dvi.panel_reset_gpio, 0); + } + ++ ++static struct resource bmi_slot1_resources[] = { ++ [0] = { ++ .start = 161, ++ .flags = IORESOURCE_IRQ, ++ }, ++ [1] = { ++ .start = 134, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device bmi_slot_devices[] = { ++ { ++ .name = "omap_bmi_slot", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bmi_slot1_resources), ++ .resource = bmi_slot1_resources, ++ }, ++}; ++ ++ ++static void omap_init_bmi_slots(void) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(bmi_slot_devices); i++) { ++ if (platform_device_register(&bmi_slot_devices[i]) < 0) ++ dev_err(&bmi_slot_devices[i].dev, ++ "Unable to register BMI slot\n"); ++ } ++} ++ + static struct omap_board_config_kernel omap3_beagle_config[] __initdata = { + { OMAP_TAG_UART, &omap3_beagle_uart_config }, + }; + + static struct platform_device *omap3_beagle_devices[] __initdata = { + &beagle_dss_device, + &leds_gpio, + &keys_gpio, + }; + ++ + static void __init omap3beagle_flash_init(void) + { + u8 cs = 0; + u8 nandcs = GPMC_CS_NUM + 1; + +@@ -598,14 +640,24 @@ static void __init omap3_beagle_init(voi + + omap_cfg_reg(J25_34XX_GPIO170); + + omap3beagle_enc28j60_init(); + ++ omap_cfg_reg(AG4_3530_GPIO134); ++ omap_cfg_reg(K26_34XX_GPIO161); ++ omap_cfg_reg(Y21_3530_GPIO156_OUT); ++ omap_cfg_reg(AF14_34XX_I2C3_SCL); ++ omap_cfg_reg(AG14_34XX_I2C3_SDA); ++ omap_cfg_reg(U21_3530_GPIO159_OUT); ++ gpio_direction_output(156, false); ++ gpio_direction_output(159, false); ++ // BMI Presence and Status + usb_musb_init(); + usb_ehci_init(); + omap3beagle_flash_init(); + beagle_display_init(); ++ omap_init_bmi_slots(); + } + + static void __init omap3_beagle_map_io(void) + { + omap2_set_globals_343x(); +--- git.orig/arch/arm/mach-omap2/mux.c ++++ git/arch/arm/mach-omap2/mux.c +@@ -480,14 +480,39 @@ MUX_CFG_34XX("AE6_34XX_GPIO141", 0x16e, + OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) + MUX_CFG_34XX("AF5_34XX_GPIO142", 0x170, + OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) + MUX_CFG_34XX("AE5_34XX_GPIO143", 0x172, + OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) ++MUX_CFG_34XX("K26_34XX_GPIO161", 0x196, ++ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) + MUX_CFG_34XX("H19_34XX_GPIO164_OUT", 0x19c, + OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) + MUX_CFG_34XX("J25_34XX_GPIO170", 0x1c6, + OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) ++ ++/*BeagleBoard/BUG-Hybrid specific GPIO stuff*/ ++ ++MUX_CFG_34XX("AE2_3530_GPIO130", 0x158, ++ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) ++/* ++MUX_CFG_34XX("AG5_3530_GPIO131", 0x15A, ++ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) ++MUX_CFG_34XX("AH5_3530_GPIO132", 0x15C, ++ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) ++MUX_CFG_34XX("AH4_3530_GPIO133", 0x15E, ++ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) ++*/ ++MUX_CFG_34XX("AG4_3530_GPIO134", 0x160, ++ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) ++MUX_CFG_34XX("AF4_3530_GPIO135", 0x162, ++ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) ++MUX_CFG_34XX("Y21_3530_GPIO156_OUT", 0x18C, ++ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) ++MUX_CFG_34XX("AA21_3530_GPIO157", 0x18E, ++ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) ++MUX_CFG_34XX("U21_3530_GPIO159_OUT", 0x192, ++ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) + }; + + #define OMAP34XX_PINS_SZ ARRAY_SIZE(omap34xx_pins) + + #else +--- git.orig/arch/arm/plat-omap/include/mach/mux.h ++++ git/arch/arm/plat-omap/include/mach/mux.h +@@ -799,12 +799,19 @@ enum omap34xx_index { + AE4_34XX_GPIO136_OUT, + AF6_34XX_GPIO140_UP, + AE6_34XX_GPIO141, + AF5_34XX_GPIO142, + AE5_34XX_GPIO143, ++ K26_34XX_GPIO161, + H19_34XX_GPIO164_OUT, + J25_34XX_GPIO170, ++ AE2_3530_GPIO130, ++ AG4_3530_GPIO134, ++ AF4_3530_GPIO135, ++ Y21_3530_GPIO156_OUT, ++ AA21_3530_GPIO157, ++ U21_3530_GPIO159_OUT + }; + + struct omap_mux_cfg { + struct pin_config *pins; + unsigned long size; +--- git.orig/drivers/Kconfig ++++ git/drivers/Kconfig +@@ -4,10 +4,12 @@ menu "Device Drivers" + + source "drivers/base/Kconfig" + + source "drivers/connector/Kconfig" + ++source "drivers/bmi/Kconfig" ++ + source "drivers/mtd/Kconfig" + + source "drivers/of/Kconfig" + + source "drivers/parport/Kconfig" +@@ -107,6 +109,7 @@ source "drivers/uio/Kconfig" + source "drivers/xen/Kconfig" + + source "drivers/staging/Kconfig" + + source "drivers/platform/Kconfig" ++ + endmenu +--- git.orig/drivers/Makefile ++++ git/drivers/Makefile +@@ -91,10 +91,11 @@ obj-y += lguest/ + obj-$(CONFIG_CPU_FREQ) += cpufreq/ + obj-$(CONFIG_CPU_IDLE) += cpuidle/ + obj-y += idle/ + obj-$(CONFIG_MMC) += mmc/ + obj-$(CONFIG_MEMSTICK) += memstick/ ++obj-$(CONFIG_BMI) += bmi/ + obj-$(CONFIG_NEW_LEDS) += leds/ + obj-$(CONFIG_INFINIBAND) += infiniband/ + obj-$(CONFIG_SGI_SN) += sn/ + obj-y += firmware/ + obj-$(CONFIG_CRYPTO) += crypto/ +--- /dev/null ++++ git/drivers/bmi/Kconfig +@@ -0,0 +1,17 @@ ++# ++# BMI Infrastructure ++# ++ ++menuconfig BMI ++ tristate "BMI" ++ depends on I2C ++ default n ++ ---help--- ++ BMI bus infrastructure ++ ++if BMI ++ ++source drivers/bmi/slots/Kconfig ++source drivers/bmi/pims/Kconfig ++ ++endif # BMI +--- /dev/null ++++ git/drivers/bmi/Makefile +@@ -0,0 +1,8 @@ ++# ++# Makefile for the bmi bus drivers. ++# ++ ++obj-$(CONFIG_BMI) += core/ ++obj-$(CONFIG_BMI) += slots/ ++obj-$(CONFIG_BMI) += pims/ ++ +--- /dev/null ++++ git/drivers/bmi/core/Makefile +@@ -0,0 +1,7 @@ ++# ++# Makefile for BMI subsystem core ++# ++ ++#bmicore-objs := core.o slot.o ++ ++obj-$(CONFIG_BMI) += core.o driver.o slot.o eeprom.o +--- /dev/null ++++ git/drivers/bmi/core/core.c +@@ -0,0 +1,319 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++static DEFINE_MUTEX(core_lock); ++ ++static struct class *bmi_class; ++ ++ ++struct class* bmi_get_class (void) ++{ ++ return bmi_class; ++}; ++EXPORT_SYMBOL(bmi_get_class); ++ ++ ++/** ++ * bmi_device_get - increments the reference count of the bmi device structure ++ * @dev: the device being referenced ++ * ++ * Each live reference to a device should be refcounted. ++ * ++ * Drivers for BMI devices should normally record such references in ++ * their probe() methods, when they bind to a device, and release ++ * them by calling bmi_dev_put(), in their disconnect() methods. ++ * ++ * A pointer to the device with the incremented reference counter is returned. ++ */ ++struct bmi_device *bmi_dev_get(struct bmi_device *dev) ++{ ++ if (dev) ++ get_device(&dev->dev); ++ return dev; ++} ++ ++ ++/** ++ * bmi_device_put - release a use of the bmi device structure ++ * @dev: device that's been disconnected ++ * ++ * Must be called when a user of a device is finished with it. When the last ++ * user of the device calls this function, the memory of the device is freed. ++ */ ++void bmi_dev_put(struct bmi_device *dev) ++{ ++ if (dev) ++ put_device(&dev->dev); ++} ++ ++ ++/** ++ * bmi_match_one_id - Tell if a BMI device structure has a matching ++ * BMI device id structure ++ * @id: single BMI device id structure to match ++ * @bdev: the BMI device structure to match against ++ * ++ * Returns the matching bmi_device_id structure or %NULL if there is no match. ++ */ ++ ++static const struct bmi_device_id *bmi_match_one_id(const struct bmi_device_id *id, ++ const struct bmi_device *bdev) ++{ ++ if ((id->vendor == bdev->vendor) && ++ (id->product == bdev->product) && ++ ((id->revision == bdev->revision) || (id->revision == BMI_ANY))) ++ return id; ++ return NULL; ++} ++ ++ ++/** ++ * bmi_match_id - See if a BMI device matches a given bmi_device_id table ++ * @ids: array of BMI device id structures to search in ++ * @bdev: the BMI device structure to match against. ++ * ++ * Used by a driver to check whether a BMI device present in the ++ * system is in its list of supported devices. Returns the matching ++ * bmi_device_id structure or %NULL if there is no match. ++ * ++ */ ++ ++ ++const struct bmi_device_id *bmi_match_id(const struct bmi_device_id *ids, ++ struct bmi_device *bdev) ++{ ++ if (ids) { ++ while (ids->vendor) { ++ if (bmi_match_one_id(ids, bdev)) ++ return ids; ++ ids++; ++ } ++ } ++ return NULL; ++} ++ ++/** ++ * bmi_device_match - Tell if a BMI device structure has a matching BMI device id structure ++ * @dev: the BMI device structure to match against ++ * @drv: the device driver to search for matching PCI device id structures ++ * ++ * Used by a driver to check whether a BMI device present in the ++ * system is in its list of supported devices. Returns the matching ++ * bmi_device_id structure or %NULL if there is no match. ++ */ ++ ++ ++static int bmi_device_match(struct device *dev, struct device_driver *driver) ++{ ++ struct bmi_device *bmi_dev = to_bmi_device(dev); ++ struct bmi_driver *bmi_drv = to_bmi_driver(driver); ++ const struct bmi_device_id *found_id; ++ ++ found_id = bmi_match_id(bmi_drv->id_table, bmi_dev); ++ ++ if (found_id) ++ return 1; ++ ++ printk(KERN_INFO "BMI: No matching Driver..."); ++ return 0; ++} ++ ++/* ++ * Uevent Generation for hotplug ++ */ ++ ++static int bmi_device_uevent(struct device *dev, struct kobj_uevent_env *env) ++{ ++ struct bmi_device *bdev = to_bmi_device(dev); ++ ++ if (!dev) ++ return -ENODEV; ++ ++ if (add_uevent_var(env, "BMIBUS_SLOT=%01X", bdev->slot->slotnum)) { ++ return -ENOMEM; ++ } ++ if (add_uevent_var(env, "BMIBUS_VENDOR=%04X", bdev->vendor)) { ++ return -ENOMEM; ++ } ++ if (add_uevent_var(env, "BMIBUS_PRODUCT=%04X", bdev->product)) { ++ return -ENOMEM; ++ } ++ if (add_uevent_var(env, "BMIBUS_REV=%04X", bdev->revision)) { ++ return -ENOMEM; ++ } ++ if (add_uevent_var(env, "MODALIAS=bmi:v%04Xp%04Xr%04X", ++ bdev->vendor, bdev->product, ++ bdev->revision)) { ++ return -ENOMEM; ++ } ++ return 0; ++} ++ ++ ++struct bmi_device *bmi_alloc_dev(struct bmi_slot *slot) ++{ ++ struct bmi_device *dev; ++ ++ dev = kzalloc(sizeof(*dev), GFP_KERNEL); ++ if (!dev) { ++ printk(KERN_ERR "BMI: Couldn't Allocate bmi_device structure...\n"); ++ return NULL; ++ } ++ ++ device_initialize(&dev->dev); ++ dev->dev.bus = &bmi_bus_type; ++ dev_set_name(&dev->dev, "bmi-dev-%d",slot->slotnum); ++ dev->dev.parent = &slot->slotdev; ++ dev->slot = slot; ++ ++ return dev; ++} ++ ++ ++ ++/** ++ * __bmi_probe() ++ * @drv: driver to call to check if it wants the BMI device ++ * @bmi_dev: BMI device being probed ++ * ++ * returns 0 on success, else error. ++ * side-effect: bmi_dev->driver is set to drv when drv claims bmi_dev. ++ */ ++static int ++__bmi_probe(struct bmi_driver *driver, struct bmi_device *bmi_dev) ++{ ++ int error = 0; ++ ++ if (!bmi_dev->driver && driver->probe) { ++ ++ error = driver->probe(bmi_dev); ++ if (error >= 0) { ++ // bmi_device -> bmi_driver (bmi-bus level ) ++ bmi_dev->driver = driver; ++ error = 0; ++ } ++ } ++ return error; ++} ++ ++static int bmi_device_probe (struct device *dev) ++{ ++ int error = 0; ++ struct bmi_driver *drv; ++ struct bmi_device *bmi_dev; ++ ++ //By this time, we have already been match()ed against a driver. ++ ++ // device -> device_driver. (driver-core level) ++ ++ drv = to_bmi_driver(dev->driver); ++ bmi_dev = to_bmi_device(dev); ++ ++ ++ bmi_dev_get(bmi_dev); ++ ++ error = __bmi_probe(drv, bmi_dev); ++ if (error) ++ bmi_dev_put(bmi_dev); ++ else ++ kobject_uevent(&dev->kobj, KOBJ_ADD); ++ ++ return error; ++} ++ ++ ++ ++static int bmi_device_remove (struct device *dev) ++{ ++ struct bmi_device * bmi_dev; ++ struct bmi_driver * driver; ++ ++ bmi_dev = to_bmi_device(dev); ++ driver = bmi_dev->driver; ++ ++ if (driver) { ++ if (driver->remove) ++ driver->remove(bmi_dev); ++ bmi_dev->driver = NULL; ++ } ++ ++ kobject_uevent(&dev->kobj, KOBJ_REMOVE); ++ bmi_dev_put(bmi_dev); ++ return 0; ++} ++ ++static void bmi_device_shutdown(struct device * dev) ++{ ++ return; ++} ++ ++static int bmi_device_suspend (struct device * dev, pm_message_t state) ++{ ++ return -1; ++} ++ ++static int bmi_device_suspend_late (struct device * dev, pm_message_t state) ++{ ++ return -1; ++} ++ ++static int bmi_device_resume_early (struct device * dev) ++{ ++ return -1; ++} ++ ++static int bmi_device_resume (struct device * dev) ++{ ++ return -1; ++} ++ ++ ++ ++struct bus_type bmi_bus_type = { ++ .name = "bmi", ++ .match = bmi_device_match, ++ .uevent = bmi_device_uevent, ++ .probe = bmi_device_probe, ++ .remove = bmi_device_remove, ++ .shutdown = bmi_device_shutdown, ++ .suspend = bmi_device_suspend, ++ .suspend_late = bmi_device_suspend_late, ++ .resume_early = bmi_device_resume_early, ++ .resume = bmi_device_resume, ++}; ++ ++static int __init bmi_init(void) ++{ ++ int ret = 0; ++ ++ ret = bus_register(&bmi_bus_type); ++ if (ret) { ++ printk(KERN_ERR "BMI: (bmi_init) - Bus registration failed...\n"); ++ return ret; ++ } ++ ++ // ret = class_register(&bmi_class); ++ bmi_class = class_create(THIS_MODULE, "bmi"); ++ if (ret) { ++ printk(KERN_ERR "BMI: (bmi_init) - Failed to register BMI Class...\n"); ++ bmi_class = NULL; ++ bus_unregister(&bmi_bus_type); ++ } ++ return ret; ++} ++ ++static void __exit bmi_cleanup(void) ++{ ++ bmi_class = NULL; ++ bus_unregister(&bmi_bus_type); ++} ++ ++//subsys_initcall(bmi_init); ++module_init(bmi_init); ++module_exit(bmi_cleanup); +--- /dev/null ++++ git/drivers/bmi/core/device.c +@@ -0,0 +1,35 @@ ++ ++ ++// bmi_device accessors ++static inline int bmi_device_get_status_irq (struct bmi_device *bdev) ++{ ++ return (bdev->slot->status_irq); ++} ++ ++static inline int bmi_device_get_present_irq (struct bmi_device *bdev) ++{ ++ return (bdev->slot->present_irq); ++} ++ ++static inline struct i2c_adapter* bmi_device_get_i2c_adapter (struct bmi_device *bdev) ++{ ++ return (&bdev->slot->adap); ++} ++ ++static inline int bmi_device_get_slot (struct bmi_device *bdev) ++{ ++ return (bdev->slot->slotnum); ++} ++ ++int bmi_device_present (struct bmi_device *bdev); ++struct bmi_device *bmi_device_get(struct bmi_device *dev); ++void bmi_device_put(struct bmi_device *dev); ++ ++int bmi_device_read_inventory_eeprom ( struct bmi_device *bdev ); ++int bmi_device_init ( struct bmi_device *bdev, struct bmi_info *info, struct bus_type *bmi_bus_type); ++void bmi_device_cleanup( struct bmi_device* bdev); ++int bmi_device_i2c_setup( struct bmi_device *bdev); ++void bmi_device_i2c_cleanup( struct bmi_device* bdev); ++int bmi_device_spi_setup( struct bmi_device *bdev, u32 speed, u8 mode, u8 bits_per_word); ++void bmi_device_spi_cleanup( struct bmi_device* bdev); ++struct spi_device *bmi_device_get_spi( struct bmi_device *bdev); +--- /dev/null ++++ git/drivers/bmi/core/driver.c +@@ -0,0 +1,27 @@ ++#include ++ ++int __bmi_register_driver(struct bmi_driver *drv, struct module *owner) ++{ ++ int error; ++ ++ /* initialize common driver fields */ ++ drv->driver.name = drv->name; ++ drv->driver.bus = &bmi_bus_type; ++ drv->driver.owner = owner; ++ ++ /* register with core */ ++ error = driver_register(&drv->driver); ++ ++ return error; ++} ++ ++ ++void ++bmi_unregister_driver(struct bmi_driver *drv) ++{ ++ driver_unregister(&drv->driver); ++} ++ ++EXPORT_SYMBOL(__bmi_register_driver); ++EXPORT_SYMBOL(bmi_unregister_driver); ++ +--- /dev/null ++++ git/drivers/bmi/core/eeprom.c +@@ -0,0 +1,32 @@ ++#include ++#include ++ ++ ++static inline __u8 bmi_eeprom_checksum (struct bmi_eeprom_data *raw) ++{ ++ int i; ++ __u8 sum = 0; ++ __u8 *buf = (__u8*)raw; ++ ++ for (i = 0; i < (sizeof (struct bmi_eeprom_data) - 1); i++) { ++ sum ^= *buf++; ++ } ++ return sum; ++} ++ ++ ++int bmi_eeprom_checksum_validate (struct bmi_eeprom_data *raw) ++{ ++ int ret = 0; ++ u8 calcsum; ++ ++ calcsum = bmi_eeprom_checksum (raw); ++ ++ if (calcsum != raw->checksum) { ++ //Rework: add conditional debug messages here ++ ret = -1; ++ } ++ return ret; ++} ++ ++ +--- /dev/null ++++ git/drivers/bmi/core/slot.c +@@ -0,0 +1,469 @@ ++/* Matt Isaacs - Kick ass platform independant BMI implementation */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static DEFINE_MUTEX(slot_lock); ++static DEFINE_IDR(bmi_slot_idr); ++ ++ ++//#include "slot.h" ++ ++/* ++struct slot_driver { ++ const char *description; ++ ++ irq_return_t (*irq) (struct bmi_slot); ++ int (*start) (struct bmi_slot); ++ int (*stop) (struct bmi_slot); ++} ++*/ ++ ++static struct task_struct *kslotd_task; ++ ++static DEFINE_SPINLOCK(slot_event_lock); ++static LIST_HEAD(slot_event_list); ++static DECLARE_WAIT_QUEUE_HEAD(kslotd_wait); ++ ++static struct i2c_board_info at24c02_info = { ++ I2C_BOARD_INFO("at24c02", 0XA0 >> 1), ++}; ++ ++static void bmi_slot_work_handler(struct work_struct * work); ++ ++struct bmi_slot* bmi_get_slot(int slotnum) ++{ ++ struct bmi_slot *slot; ++ ++ mutex_lock(&slot_lock); ++ slot = (struct bmi_slot*)idr_find(&bmi_slot_idr, slotnum); ++ if (slot && !try_module_get(slot->owner)) ++ slot = NULL; ++ ++ mutex_unlock(&slot_lock); ++ ++ return slot; ++} ++ ++void bmi_slot_power_on (int num) ++{ ++ struct bmi_slot *slot = bmi_get_slot(num); ++ ++ if (!slot) { ++ printk(KERN_ERR "BMI: Slot %d doesn't exist...\n", num); ++ return; ++ } ++ ++ if (slot->actions->power_on) ++ slot->actions->power_on(slot); ++ else ++ printk(KERN_INFO "BMI: Slot %d power is always on...\n", num); ++ return; ++} ++ ++void bmi_slot_power_off (int num) ++{ ++ struct bmi_slot *slot = bmi_get_slot(num); ++ ++ if (!slot) { ++ printk(KERN_ERR "BMI: Slot %d doesn't exist...\n", num); ++ return; ++ } ++ ++ if (slot->actions->power_off) ++ slot->actions->power_off(slot); ++ else ++ printk(KERN_INFO "BMI: Slot %d power is always on...\n", num); ++ return; ++} ++ ++void bmi_slot_gpio_configure (int num, int gpio) ++{ ++ struct bmi_slot *slot = bmi_get_slot(num); ++ ++ if (!slot) { ++ printk(KERN_ERR "BMI: Slot %d doesn't exist...\n", num); ++ return; ++ } ++ ++ if (slot->actions->gpio_config) ++ slot->actions->gpio_config(slot, gpio); ++ else ++ printk(KERN_INFO "BMI: Slot GPIO not configurable...\n"); ++ return; ++ ++} ++EXPORT_SYMBOL(bmi_slot_gpio_configure); ++ ++int bmi_slot_gpio_get(int num) ++{ ++ struct bmi_slot *slot = bmi_get_slot(num); ++ ++ if (!slot) { ++ printk(KERN_ERR "BMI: Slot %d doesn't exist...\n", num); ++ return -ENODEV; ++ } ++ ++ if (slot->actions->gpio_get) ++ return slot->actions->gpio_get(slot); ++ ++ printk(KERN_INFO "BMI: Slot GPIO not writable...\n"); ++ return -EIO; ++} ++EXPORT_SYMBOL(bmi_slot_gpio_get); ++ ++void bmi_slot_gpio_set(int num, int data) ++{ ++ struct bmi_slot *slot = bmi_get_slot(num); ++ ++ if (!slot) { ++ printk(KERN_ERR "BMI: Slot %d doesn't exist...\n", num); ++ return; ++ } ++ ++ if (slot->actions->gpio_set) ++ slot->actions->gpio_set(slot, data); ++ else ++ printk(KERN_INFO "BMI: Slot GPIO not writable...\n"); ++ return; ++} ++EXPORT_SYMBOL(bmi_slot_gpio_set); ++ ++void bmi_slot_gpio_write_bit(int num, int gpio, int data) ++{ ++ return; ++} ++ ++int bmi_slot_gpio_read_bit (int num, int gpio) ++{ ++ int gpdat; ++ int bit; ++ ++ gpdat = bmi_slot_gpio_get(num); ++ bit = (gpdat & (1 << gpio)) ? 1 : 0; ++ return bit; ++} ++ ++ ++// NOTE: When a plug-in module is removed, the gpios should be returned to inputs. ++// All requested slot resourece should be released. ++// The slot should be powered down. ++ ++void bmi_slot_gpio_configure_all_as_inputs (int slot) ++{ ++ return; ++} ++ ++ ++void bmi_slot_uart_enable (int num) ++{ ++ struct bmi_slot *slot = bmi_get_slot(num); ++ ++ if (!slot) { ++ printk(KERN_ERR "BMI: Slot %d doesn't exist...\n", num); ++ return; ++ } ++ ++ if (slot->actions->uart_enable) ++ return slot->actions->uart_enable(slot); ++ ++ printk(KERN_INFO "BMI: UART always enabled...\n"); ++ return; ++} ++EXPORT_SYMBOL(bmi_slot_uart_enable); ++ ++void bmi_slot_uart_disable (int num) ++{ ++ ++ return; ++} ++EXPORT_SYMBOL(bmi_slot_uart_disable); ++ ++void bmi_slot_spi_enable (int num) ++{ ++ ++ return; ++} ++EXPORT_SYMBOL(bmi_slot_spi_enable); ++ ++void bmi_slot_spi_disable (int num) ++{ ++ return; ++} ++EXPORT_SYMBOL(bmi_slot_spi_disable); ++ ++void bmi_slot_audio_enable (int num) ++{ ++ ++ return; ++} ++EXPORT_SYMBOL(bmi_slot_audio_enable); ++ ++void bmi_slot_audio_disable (int num) ++{ ++ ++ return; ++} ++EXPORT_SYMBOL(bmi_slot_audio_disable); ++ ++void bmi_slot_battery_enable (int num) ++{ ++ ++ return; ++} ++EXPORT_SYMBOL(bmi_slot_battery_enable); ++ ++void bmi_slot_battery_disable (int num) ++{ ++ ++ return; ++} ++EXPORT_SYMBOL(bmi_slot_battery_disable); ++ ++int bmi_slot_module_present (int num) ++{ ++ struct bmi_slot *slot = bmi_get_slot(num); ++ // slot->actions->gpio_set ++ if (slot->actions->present != NULL) ++ return slot->actions->present(slot); ++ else ++ printk(KERN_INFO "BMI: Slot Driver incomplete. No presence detection...\n"); ++ return 0; ++} ++ ++int bmi_slot_read_eeprom(struct bmi_slot *slot, u8* data) ++{ ++ unsigned char i = 0; ++ int ret; ++ ++ if (slot->eeprom == NULL) { ++ printk(KERN_INFO "Can't get eeprom client...\n"); ++ ret = -EIO; ++ } ++ else { ++ ret = i2c_master_send(slot->eeprom, &i, 1); ++ if (ret == 1) ++ ret = i2c_master_recv(slot->eeprom, data, sizeof(struct bmi_eeprom_data)); ++ } ++ return ret; ++} ++ ++int bmi_slot_status_irq_state (int slot) ++{ ++ int state = 0; ++ return state; ++} ++ ++ ++#define DEBOUNCE_DELAY msecs_to_jiffies(1000) ++ ++static irqreturn_t bmi_slot_irq_handler(int irq, void *dev_id) ++{ ++ struct bmi_slot *slot = dev_id; ++ ++ disable_irq_nosync(irq); ++ printk(KERN_INFO " BMI: IRQ Triggered on slot: %d\n", slot->slotnum); ++ schedule_delayed_work(&slot->work, DEBOUNCE_DELAY); ++ return IRQ_HANDLED; ++} ++ ++static void bmi_slot_work_handler(struct work_struct * work) ++{ ++ struct bmi_slot *slot; ++ struct bmi_device *bdev; ++ int ret; ++ struct bmi_eeprom_data data; ++ unsigned char* cdat; ++ ++ slot = work_to_slot(work); ++ ++ mutex_lock(&slot->pres_mutex); ++ if (bmi_slot_module_present(slot->slotnum)) { ++ if (!slot->present) { ++ slot->present = 1; ++ slot->eeprom = i2c_new_device(slot->adap, &at24c02_info); ++ ++ ret = bmi_slot_read_eeprom(slot, (u8*)&data); ++ ++ if (ret < 0) ++ { ++ printk(KERN_INFO "BMI: EEPROM Trouble on Slot %d...\n",slot->slotnum); ++ ++ goto irqenbl; ++ } ++ //Testing stuff here...get rid of this... ++ else ++ printk(KERN_INFO "BMI: EEPROM Found...\n"); ++ cdat = (char*)&data; ++ /*for (i = 0; i < 20; i++) ++ printk(KERN_INFO "0x%x\n", cdat[i]);*/ ++ printk(KERN_INFO "SLOTS: Vendor: 0x%x\n",(data.vendor_msb<<8) | (data.vendor_lsb)); ++ printk(KERN_INFO "SLOTS: Product 0x%x\n",(data.product_msb<<8) | (data.product_lsb)); ++ printk(KERN_INFO "SLOTS: Revision 0x%x\n",(data.revision_msb<<8) | (data.revision_lsb)); ++ ++ //Do new device allocation and hand it over to BMI... ++ bdev = bmi_alloc_dev(slot); ++ bdev->vendor = (data.vendor_msb<<8) | (data.vendor_lsb); ++ bdev->product = (data.product_msb<<8) | (data.product_lsb); ++ bdev->revision = (data.revision_msb<<8) | (data.revision_lsb); ++ ++ //Report module plugin so that udev can load appropriate drivers ++ //kobject_uevent (&bdev->dev.kobj, KOBJ_ADD); ++ ret = device_add(&bdev->dev); ++ if (ret) { ++ printk(KERN_ERR "SLOTS: Failed to add device...%d\n",ret); ++ goto irqenbl; //TODO: Memory allocated for by bmi_alloc_dev ++ } ++ slot->bdev = bdev; ++ /* ++ ret = device_attach(&bdev->dev); ++ if (ret != 1) { ++ printk(KERN_ERR "SLOTS: Failed to attach device...%d\n",ret); ++ goto irqenbl; //TODO: Memory allocated for by bmi_alloc_dev must be freed ++ } ++ */ ++ } ++ else ++ //spurious insertion event.. ++ printk(KERN_INFO "SLOTS: Spurious insertion on Slot %d...\n",slot->slotnum); ++ } ++ else { ++ if (slot->present) { ++ slot->present = 0; ++ printk(KERN_INFO "BMI: Module removed from slot %d...\n", slot->slotnum); ++ if (slot->bdev == NULL) { ++ printk(KERN_ERR "SLOTS: BMI Device NULL...\n"); ++ goto del_eeprom; ++ } ++ //Call BMI device removal stuff here... ++ device_del(&slot->bdev->dev); ++ goto del_eeprom; ++ } ++ } ++ irqenbl: ++ mutex_unlock(&slot->pres_mutex); ++ enable_irq(slot->present_irq); ++ return; ++ del_eeprom: ++ i2c_unregister_device(slot->eeprom); ++ slot->bdev = NULL; ++ slot->eeprom = NULL; ++ goto irqenbl; ++ ++} ++ ++static int bmi_register_slot(struct bmi_slot *slot) ++{ ++ int res = 0; ++ struct class *class; ++ ++ // mutex_init(&slot->state_lock); ++ if (unlikely(WARN_ON(!bmi_bus_type.p))) ++ return -EAGAIN; ++ if (slot->actions == NULL) { ++ printk(KERN_INFO "SLOTS: No Slot actions defined...\n"); ++ goto unlist; ++ } ++ mutex_init(&slot->pres_mutex); ++ mutex_lock(&slot_lock); ++ ++ if (slot->slotdev.parent == NULL) { ++ slot->slotdev.parent = &platform_bus; ++ //debug message here ++ } ++ ++ dev_set_name(&slot->slotdev, "bmi-%d", slot->slotnum); ++ ++ class = bmi_get_class(); ++ if (class == NULL) { ++ printk(KERN_ERR "BMI Class doesn't exist...\n"); ++ goto unlist; ++ } ++ res = device_register(&slot->slotdev); ++ if (res) { ++ printk(KERN_ERR "SLOT: Couldn't register slot... %d\n",res); ++ goto unlist; ++ //quit ++ } ++ ++ //Request IRQ ++ INIT_DELAYED_WORK(&slot->work, bmi_slot_work_handler); ++ ++ printk(KERN_ERR "SLOT: Requesting IRQ...\n"); ++ res = request_irq(slot->present_irq, bmi_slot_irq_handler, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING , slot->name, (void*)slot); ++ ++ if (res) { ++ printk(KERN_ERR "SLOT: IRQ Request failed...\n"); ++ goto unlist; ++ } ++ ++ unlock: ++ mutex_unlock(&slot_lock); ++ return res; ++ unlist: ++ idr_remove(&bmi_slot_idr, slot->slotnum); ++ goto unlock; ++ ++} ++ ++ ++int bmi_add_slot(struct bmi_slot *slot) ++{ ++ int slotnum = 0; ++ int res = 0; ++ ++ retry: ++ if (idr_pre_get(&bmi_slot_idr, GFP_KERNEL) == 0) ++ return -ENOMEM; ++ ++ mutex_lock(&slot_lock); ++ ++ res = idr_get_new_above(&bmi_slot_idr, slot, 0, &slotnum); ++ mutex_unlock(&slot_lock); ++ if (res < 0) { ++ if (res == -EAGAIN) ++ goto retry; ++ return res; ++ } ++ slot->slotnum = slotnum; ++ return bmi_register_slot(slot); ++} ++EXPORT_SYMBOL(bmi_add_slot); ++ ++ ++int bmi_del_slot(struct bmi_slot *slot) ++{ ++ int res = 0; ++ ++ mutex_lock(&slot_lock); ++ if (idr_find(&bmi_slot_idr, slot->slotnum)) { ++ printk(KERN_ERR "BMI: Attempting to delete unregistered slot...\n"); ++ res = -EINVAL; ++ goto unlock; ++ } ++ ++ disable_irq_nosync(slot->present_irq); ++ free_irq(slot->present_irq, slot); ++ device_unregister(&slot->slotdev); ++ idr_remove(&bmi_slot_idr, slot->slotnum); ++ memset(&slot->slotdev, 0, sizeof(slot->slotdev)); ++ ++ unlock: ++ mutex_unlock(&slot_lock); ++ return res; ++} ++EXPORT_SYMBOL(bmi_del_slot); ++ +--- /dev/null ++++ git/drivers/bmi/pims/Kconfig +@@ -0,0 +1,104 @@ ++# ++# BMI PIMS ++# ++ ++config BMI_PIMS ++ tristate "BMI_PIMS" ++ default n ++ ---help--- ++ BMI plug-in module support ++ ++ This driver must be built as a module. ++ ++menu "BMI PIMS" ++ ++config BUG_FACTORY_TEST ++ tristate "BUG_FACTORY_TEST" ++ depends on BMI_PIMS ++ default n ++ ---help--- ++ BMI FACTORY Test plug-in module ++ ++ This driver can also be built as a module. ++ ++config BMI_GPS ++ tristate "BMI_GPS" ++ depends on BMI_PIMS ++ default n ++ ---help--- ++ BMI GPS plug-in module ++ ++ This driver can also be built as a module. ++ ++source "drivers/bmi/pims/mdacc/Kconfig" ++ ++config VIDEO_BMI_LCD ++ tristate "BMI Bus LCD Module support" ++ depends on FB_MXC && MACH_BUG ++ default n ++ ---help--- ++ This is the BMI bus driver for the LCD Plug-In Module. ++ ++config VIDEO_BMI_LCD_S320X240 ++ tristate "BMI support for Sharp 320x240 module" ++ depends on FB_MXC && MACH_BUG && VIDEO_BMI_LCD ++ default n ++ ---help--- ++ This is the BMI LCD driver for the Sharp 320x240 LCD Plug-In Module. ++ ++config VIDEO_BMI_PROJECTOR ++ tristate "BMI Bus PROJECTOR Module support" ++ depends on FB_MXC_PROJECTOR && MACH_BUG ++ default n ++ ---help--- ++ This is the BMI bus driver for the PROJECTOR Plug-In Module. ++ ++config BMI_AUDIO ++ tristate "BMI Bus Audio Module support" ++ depends on BMI_PIMS ++ default n ++ ---help--- ++ This is the BMI bus driver for the Audio Plug-In Module. ++ ++ Select M to make a kernel-loadable module. ++ ++#source "drivers/bmi/pims/camera/Kconfig" ++ ++config BMI_VH ++ tristate "BMI von Hippel Module support" ++ depends on BMI_PIMS ++ default n ++ ---help--- ++ BMI von Hippel plug-in module ++ ++ This driver can also be built as a module. ++ ++config BMI_SENSOR ++ tristate "BMI Sensor Module support" ++ depends on BMI_PIMS ++ default n ++ ---help--- ++ BMI Sensor plug-in module ++ ++ This driver can also be built as a module. ++ ++config BMI_ZB ++ tristate "BMI ZigBee Module support" ++ depends on BMI_PIMS ++ default n ++ ---help--- ++ BMI ZigBee plug-in module ++ ++ This driver can also be built as a module. ++ ++config BMI_GSM ++ tristate "BMI GSM/UMTS Module support" ++ depends on BMI_PIMS ++ default n ++ ---help--- ++ BMI von Hippel plug-in module ++ ++ This driver can also be built as a module. ++ ++endmenu ++ +--- /dev/null ++++ git/drivers/bmi/pims/Makefile +@@ -0,0 +1,17 @@ ++# ++# BMI PIMS ++# ++ ++obj-$(CONFIG_BUG_FACTORY_TEST) += factory_test/ ++obj-$(CONFIG_BMI_GPS) += gps/ ++obj-$(CONFIG_BMI_MDACC) += mdacc/ ++obj-$(CONFIG_VIDEO_BMI_LCD) += lcd/ ++obj-$(CONFIG_BMI_CAMERA) += camera/ ++obj-$(CONFIG_BMI_AUDIO) += sound/ ++obj-$(CONFIG_BMI_VH) += vonhippel/ ++obj-$(CONFIG_BMI_GSM) += gsm/ ++obj-$(CONFIG_BMI_SENSOR) += sensor/ ++obj-$(CONFIG_VIDEO_BMI_PROJECTOR) += projector/ ++obj-$(CONFIG_BMI_ZB) += zb/ ++ ++ +--- /dev/null ++++ git/drivers/bmi/pims/camera/Kconfig +@@ -0,0 +1,23 @@ ++config BMI_CAMERA ++ tristate "BMI Camera" ++ depends on MACH_BUG ++ default n ++ ---help--- ++ This is the BMI Camera driver. ++ ++choice ++ prompt "Select Camera" ++ depends on (BMI_CAMERA) ++ ++config BMI_CAMERA_VS6624 ++ tristate "ST VS6624 camera support" ++ ---help--- ++ If you plan to use the ST VS6624 Camera with your BUG system, say Y here. ++ ++config BMI_CAMERA_OV2640 ++ tristate "Omnivision OV2640 camera support" ++ ---help--- ++ If you plan to use the Omnivision OV2640 Camera with your BUG system, say Y here. ++endchoice ++ ++ +--- /dev/null ++++ git/drivers/bmi/pims/camera/Makefile +@@ -0,0 +1,12 @@ ++#ifeq ($(CONFIG_MACH_BUG),y) ++# obj-$(CONFIG_BMI_CAMERA) += bug_v4l2_capture.o ++#endif ++ ++obj-$(CONFIG_BMI_CAMERA) += bug_camera.o ++ ++bmi_camera_vs6624-objs := bmi_vs6624.o vs6624_access.o ++obj-$(CONFIG_BMI_CAMERA_VS6624) += bmi_camera_vs6624.o ++ ++bmi_camera_ov2640-objs := bmi_ov2640.o ov2640.o ++obj-$(CONFIG_BMI_CAMERA_OV2640) += bmi_camera_ov2640.o ++ +--- /dev/null ++++ git/drivers/bmi/pims/camera/bmi_ov2640.c +@@ -0,0 +1,929 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "bug_camera.h" ++#include "ov2640.h" ++ ++#define BMI_OV2640_VERSION "1.0" ++ ++// BMI device ID table ++static struct bmi_device_id bmi_ov2640_tbl[] = ++{ ++ { .match_flags = BMI_DEVICE_ID_MATCH_VENDOR | BMI_DEVICE_ID_MATCH_PRODUCT, ++ .vendor = BMI_VENDOR_BUG_LABS, ++ .product = BMI_PRODUCT_CAMERA_OV2640, ++ .revision = BMI_ANY, ++ }, ++ { 0, }, /* terminate list */ ++}; ++MODULE_DEVICE_TABLE(bmi, bmi_ov2640_tbl); ++ ++int bmi_ov2640_probe(struct bmi_device *bdev); ++void bmi_ov2640_remove(struct bmi_device *bdev); ++int bmi_ov2640_suspend(struct bmi_device *bdev); ++int bmi_ov2640_resume(struct bmi_device *bdev); ++ ++// BMI driver structure ++static struct bmi_driver bmi_ov2640_driver = ++{ ++ .name = "bmi_ov2640", ++ .id_table = bmi_ov2640_tbl, ++ .probe = bmi_ov2640_probe, ++ .remove = bmi_ov2640_remove, ++ }; ++ ++ ++struct bmi_ov2640 { ++ struct bmi_device *bdev; ++ struct bmi_cam bcam; ++ unsigned int shutter; // shutter button save state ++ unsigned int zoomin; // zoomin button save state ++ unsigned int zoomout; // zoom out button save state ++ unsigned int flash; // state of camera FLASH ++ int irq; ++ struct input_dev *idev; ++ struct work_struct work; ++ ++}; ++ ++#define work_to_bmi_ov2640(w) container_of(w, struct bmi_ov2640, work) ++ ++/* IOX Bits Definitions ++ ++ IOX Bit 7 CAM_RST* Output: 0 = Reset, 1 = Normal Operation ++ IOX Bit 6 GRNLED Output: 0 = Green LED on, 1 = Green LED off ++ IOX Bit 5 SER_SYNC Output: 0 = Normal Operation, 1 = send SYNC ++ IOX Bit 4 FLASH_TORCH* Output: 0 = low beam, 1 = high beam ++ IOX Bit 3 STROBE_R I/O, not used. ++ IOX Bit 2 ZOOMB Input: Zoom OUT Button: 0 = depressed, 1 = released ++ IOX Bit 1 ZOOMA Input: Zoom IN Button 0 = depressed, 1 = released ++ IOX Bit 0 GPIO0_SHUTTER* Input: Shutter Button 0 = depressed, 1 = released ++ ++ GPIO Bits Definitions ++ ++ GPIO Bit 3 REDLED Output: 0 = Red LED on, 1 = Red LED off ++ GPIO Bit 2 FLASHON Output: 0 = Flash LED off, 1 = Flash LED on ++ GPIO Bit 1 SER_RST* Output: 0 = Serializer Reset, 1 = Normal Operation ++ GPIO Bit 0 GPIO0_SHUTTER* Input: Shutter Button: 0 = depressed, 1 = released ++ ++ ++*/ ++ ++ ++ ++ // I2C Slave Address ++#define BMI_IOX_I2C_ADDRESS 0x71 // 7-bit address ++ ++ // I2C IOX register addresses ++#define IOX_INPUT_REG 0x0 ++#define IOX_OUTPUT_REG 0x1 ++#define IOX_POLARITY_REG 0x2 ++#define IOX_CONTROL 0x3 ++ ++ ++// read byte from I2C IO expander ++ ++static int ReadByte_IOX(struct i2c_adapter *adap, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ ++ /* Read Byte with Pointer */ ++ ++ rmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[0].flags = 0; /* write */ ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; /* read */ ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ret = i2c_transfer (adap, rmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "ReadByte_IOX() - i2c_transfer failed\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++ ++// write byte to I2C IO expander ++static int WriteByte_IOX(struct i2c_adapter *adap, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ /* Write Byte with Pointer */ ++ ++ wmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[0].flags = 0; /* write */ ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[1].flags = 0; /* write */ ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ ++ ret = i2c_transfer (adap, wmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "WriteByte_IOX() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++ ++/* ++ * Input interrupt handler and support routines ++ */ ++ ++ ++// work handler ++void bmi_ov2640_buttons_work(struct work_struct * work) ++{ ++ struct i2c_adapter *adap; ++ struct bmi_ov2640 *pim = work_to_bmi_ov2640(work); ++ ++ unsigned char iox_data; ++ unsigned int test_value; ++ int sync_flag = 0; ++ int err; ++ ++ ++ // avoid i2c i/o if camera hardware not present. ++ ++ if (bmi_device_present (pim->bdev) == 0) { ++ goto exit; ++ } ++ ++ adap = bmi_device_get_i2c_adapter (pim->bdev); ++ ++ ++ // read IOX data input ++ err = ReadByte_IOX (adap, IOX_INPUT_REG, &iox_data); ++ if (err) { ++ goto exit; ++ } ++ ++ // zoom in button ++ test_value = !((iox_data & 0x2) >> 1); ++ if (test_value != pim->zoomin) { ++ pim->zoomin = test_value; ++ input_report_key (pim->idev, BN_ZOOMIN, test_value); ++ sync_flag = 1; ++ } ++ ++ ++ // zoom out button ++ test_value = !((iox_data & 0x4) >> 2); ++ if (test_value != pim->zoomout) { ++ pim->zoomout = test_value; ++ input_report_key (pim->idev, BN_ZOOMOUT, test_value); ++ sync_flag = 1; ++ } ++ ++ if ( sync_flag ) { ++ input_sync (pim->idev); ++ } ++exit: ++ enable_irq (pim->irq); ++ return; ++ ++} ++ ++ ++// interrupt handler ++static irqreturn_t module_irq_handler(int irq, void *dummy) ++{ ++ struct bmi_ov2640 *pim = dummy; ++ unsigned int test_value; ++ ++ int slot; ++ ++ disable_irq_nosync(irq); ++ ++ slot = bmi_device_get_slot(pim->bdev); ++ ++ ++ // shutter button on GPIO ++ ++ test_value = !(bmi_read_gpio_data_reg (slot) & 0x1); ++ ++ if (!test_value == pim->shutter) { ++ pim->shutter = test_value; ++ input_report_key (pim->idev, BN_SHUTTER, test_value); ++ input_sync (pim->idev); ++ } ++ ++ // other buttons on I2C IOX ++ schedule_work (&pim->work); ++ return IRQ_HANDLED; ++} ++ ++/* ++ * control functions ++ */ ++ ++ ++// configure IOX IO and states ++void configure_IOX(struct bmi_ov2640 *cam) ++{ ++ struct i2c_adapter *adap; ++ ++ adap = bmi_device_get_i2c_adapter (cam->bdev); ++ ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, 0xC0); // CAMRST* = 1, GRNLED = Off ++ WriteByte_IOX (adap, IOX_CONTROL, 0x0F); // IOX[7:4]=OUT, IOX[3:0]=IN ++ return; ++ ++} ++ ++// configure GPIO IO and states ++void configure_GPIO(struct bmi_ov2640 *cam) ++{ ++ // set states before turning on outputs ++ ++ int slot; ++ ++ ++ slot = bmi_device_get_slot (cam->bdev); ++ ++ bmi_set_module_gpio_data (slot, 3, 1); // Red LED=OFF ++ bmi_set_module_gpio_data (slot, 2, 0); // Flash LED=OFF ++ bmi_set_module_gpio_data (slot, 1, 0); // SER_RST=0 ++ ++ // configure direction ++ bmi_set_module_gpio_dir (slot, 3, BMI_GPIO_OUT); ++ bmi_set_module_gpio_dir (slot, 2, BMI_GPIO_OUT); ++ bmi_set_module_gpio_dir (slot, 1, BMI_GPIO_OUT); ++ bmi_set_module_gpio_dir (slot, 0, BMI_GPIO_IN); // SHUTTER ++ ++ // This is needed. ++ bmi_set_module_gpio_data (slot, 2, 0); // Flash LED off. ++ return; ++ ++} ++ ++// deconfigure IOX and GPIO ++void deconfigure_module(struct bmi_ov2640 *cam) ++{ ++ int slot; ++ struct i2c_adapter *adap; ++ ++ slot = bmi_device_get_slot (cam->bdev); ++ adap = bmi_device_get_i2c_adapter (cam->bdev); ++ ++ ++ if ( bmi_device_present (cam->bdev) ) { ++ WriteByte_IOX (adap, IOX_CONTROL, 0xFF); ++ } ++ bmi_set_module_gpio_dir (slot, 3, BMI_GPIO_IN); ++ bmi_set_module_gpio_dir (slot, 2, BMI_GPIO_IN); ++ bmi_set_module_gpio_dir (slot, 1, BMI_GPIO_IN); ++} ++ ++ ++// configure serializer on plug-in module ++void configure_serializer(struct bmi_ov2640 *cam) ++{ ++ int slot = bmi_device_get_slot (cam->bdev); ++ bmi_set_module_gpio_data (slot, 1, 1); // SER_RST=1 ++} ++ ++void deconfigure_serializer(struct bmi_ov2640 *cam) ++{ ++ int slot = bmi_device_get_slot (cam->bdev); ++ bmi_set_module_gpio_data (slot, 1, 0); // SER_RST=0 ++} ++ ++void enable_camera(struct bmi_ov2640 *cam) ++{ ++ struct i2c_adapter *adap; ++ unsigned char iox_data; ++ ++ adap = bmi_device_get_i2c_adapter (cam->bdev); ++ ++ ReadByte_IOX (adap, IOX_OUTPUT_REG, &iox_data); ++ ++ iox_data |= (0x80); //Set CAM_RST* to 1. ++ ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, iox_data); ++ return; ++} ++ ++// disable camera on plug-in module ++void disable_camera(struct bmi_ov2640 *cam) ++{ ++ struct i2c_adapter *adap; ++ unsigned char iox_data; ++ ++ if (cam == NULL) ++ { ++ printk(KERN_INFO "bmi_camera_ov2640: disable_camera: NULL Pointer on cam\n"); ++ return; ++ } ++ if (cam->bdev == NULL) ++ { ++ printk(KERN_INFO "bmi_camera_ov2640: disable_camera: NULL Pointer on cam->bdev\n"); ++ return; ++ } ++ adap = bmi_device_get_i2c_adapter (cam->bdev); ++ ++ if ( bmi_device_present(cam->bdev) ) { ++ ++ ReadByte_IOX (adap, IOX_OUTPUT_REG, &iox_data); ++ ++ iox_data &= ~(0x80); //Set CAM_RST* to 0; ++ ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, iox_data); ++ } ++ return; ++} ++ ++// generate sync ++void generate_camera_sync(struct i2c_adapter *adap) ++{ ++ unsigned char iox_data[0]; ++ ++ ReadByte_IOX (adap, IOX_OUTPUT_REG, iox_data); ++ ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, *iox_data | 0x20);// SYNC = 1 ++ ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, *iox_data & 0xD0);// SYNC = 0 ++ udelay(20); // 60 MHz * 1024 = ~17 us sync time ++ return; ++} ++ ++void set_sync(struct i2c_adapter *adap) ++{ ++ unsigned char iox_data[0]; ++ ++ ReadByte_IOX (adap, IOX_OUTPUT_REG, iox_data); ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, *iox_data | 0x20);// SYNC = 1 ++ return; ++} ++ ++void clear_sync(struct i2c_adapter *adap) ++{ ++ unsigned char iox_data[0]; ++ ++ ReadByte_IOX (adap, IOX_OUTPUT_REG, iox_data); ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, *iox_data & 0xD0);// SYNC = 0 ++ return; ++} ++ ++ ++// check serializer lock ++int check_camera_lock(void) ++{ ++ return bmi_sensor_lock_status(); ++} ++ ++void bmi_ov2640_set_color(struct bmi_cam *cam, int bright, int saturation, int red, int green, int blue) ++{ ++ ++ struct i2c_adapter *adap; ++ struct bmi_ov2640 *bmi_ov2640; ++ ++ bmi_ov2640 = container_of(cam, struct bmi_ov2640, bcam); ++ adap = &bmi_ov2640->bdev->adap; ++ ++// ov2640_set_color (adap, bright, saturation, red, green, blue); ++ printk (KERN_ERR "bmi_ov2640_set_color() - NOT IMPLEMENTED.\n"); ++ return; ++ ++} ++ ++void bmi_ov2640_get_color(struct bmi_cam *cam, int *bright, int *saturation, int *red, int *green, int *blue) ++{ ++ struct i2c_adapter *adap; ++ struct bmi_ov2640 *bmi_ov2640; ++ ++ bmi_ov2640 = container_of(cam, struct bmi_ov2640, bcam); ++ adap = &bmi_ov2640->bdev->adap; ++ ++// ov2640_get_color (adap, bright, saturation, red, green, blue); ++ printk (KERN_ERR "bmi_ov2640_get_color() - NOT IMPLEMENTED.\n"); ++ return; ++} ++ ++ ++ ++ ++void bmi_ov2640_set_ae_mode (struct bmi_cam *cam, int ae_mode) ++{ ++ printk (KERN_ERR "bmi_ov2640_set_ae_mode() - NOT IMPLEMENTED.\n"); ++} ++ ++ ++void bmi_ov2640_get_ae_mode (struct bmi_cam *cam, int *ae_mode) ++{ ++ printk (KERN_ERR "bmi_ov2640_set_ae_mode() - NOT IMPLEMENTED.\n"); ++} ++ ++ ++sensor_interface * bmi_ov2640_config (struct bmi_cam *cam, int *frame_rate, int high_quality) ++{ ++ ++ struct i2c_adapter *adap; ++ struct bmi_ov2640 *bmi_ov2640; ++ int i; ++ ++ bmi_ov2640 = container_of(cam, struct bmi_ov2640, bcam); ++ adap = &bmi_ov2640->bdev->adap; ++ ++ //Bring up the serial link ++ ++ bmi_sensor_active(1); ++ configure_serializer (bmi_ov2640); ++ ++ adap = &bmi_ov2640->bdev->adap; ++ set_sync (adap); ++ ++ for (i = 0; i < 10; i++) { ++ ++ msleep(10); ++ ++ if(check_camera_lock()) { ++ break; ++ } ++ else { ++ printk(KERN_ERR "bmi_ov2640_config() - camera serializer did not lock,i = %d\n", i); ++ } ++ ++ } ++ clear_sync(adap); ++ ++ ++ if(!check_camera_lock()) { ++ printk(KERN_ERR "bmi_ov2640_config(): camera serializer NOT LOCKED\n"); ++ } ++ ++ return &cam->interface; ++ ++} ++ ++ ++sensor_interface * bmi_ov2640_reset (struct bmi_cam *cam) ++{ ++ struct i2c_adapter *adap; ++ struct bmi_ov2640 *bmi_ov2640; ++ ++ bmi_ov2640 = container_of(cam, struct bmi_ov2640, bcam); ++ ++ ++ adap = bmi_device_get_i2c_adapter (bmi_ov2640->bdev); ++ ++ //disable the serial link ++ ++ deconfigure_serializer (bmi_ov2640); ++ bmi_sensor_inactive(); ++ ++ return &cam->interface; ++} ++ ++int bmi_ov2640_activate (struct bmi_cam *cam, struct input_dev *idev) ++{ ++ int rc = 0; ++ int i; ++ struct i2c_adapter *adap; ++ struct bmi_ov2640 *bmi_ov2640; ++ ++ bmi_ov2640 = container_of(cam, struct bmi_ov2640, bcam); ++ ++ ++ //bmi_ov2640 struct fields ++ bmi_ov2640->idev = idev; ++ ++ bmi_ov2640->shutter = 0; ++ bmi_ov2640->zoomin = 0; ++ bmi_ov2640->zoomout = 0; ++ bmi_ov2640->flash = 0; ++ ++ ++ // install button irq_handler ++ if (request_irq(bmi_ov2640->irq, &module_irq_handler, 0, "bmi_cam_button", bmi_ov2640)) { ++ printk (KERN_ERR ++ "bmi_ov2640_activate() - request_irq (irq = %d) failed.\n", ++ bmi_ov2640->irq); ++ ++ rc = -EBUSY; ++ goto exit; ++ } ++ ++ //Activate serial link ++ bmi_sensor_active(1); // rising edge clock ++ configure_serializer (bmi_ov2640); ++ ++ adap = &bmi_ov2640->bdev->adap; ++ set_sync (adap); ++ ++ ++ for (i = 0; i < 10; i++) { ++ ++ msleep(10); ++ ++ if(check_camera_lock()) { ++ break; ++ } ++ else { ++ printk(KERN_ERR "bmi_ov2640_activate() - camera serializer did not lock,i = %d\n", i); ++ } ++ ++ } ++ clear_sync (adap); ++ ++exit: ++ return rc; ++} ++ ++int bmi_ov2640_deactivate (struct bmi_cam *cam) ++{ ++ struct bmi_ov2640 *bmi_ov2640; ++ bmi_ov2640 = container_of(cam, struct bmi_ov2640, bcam); ++ ++ //De-activate serial link ++ deconfigure_serializer (bmi_ov2640); ++ bmi_sensor_inactive(); ++ ++ //uninstall button irq_handler ++ free_irq(bmi_ov2640->irq, bmi_ov2640); ++ return 0; ++} ++ ++ ++void bmi_ov2640_link_enable (struct bmi_cam *cam) ++{ ++ int i; ++ struct i2c_adapter *adap; ++ struct bmi_ov2640 *bmi_ov2640; ++ bmi_ov2640 = container_of(cam, struct bmi_ov2640, bcam); ++ ++ //Activate serial link ++ bmi_sensor_active(1); // rising edge clock ++ configure_serializer (bmi_ov2640); ++ ++ adap = bmi_device_get_i2c_adapter (bmi_ov2640->bdev); ++ ++ set_sync (adap); ++ ++ ++ //REWORK: Speed this up. (shorten delay) ++ ++ for (i = 0; i < 10; i++) { ++ ++ msleep(10); ++ ++ if(check_camera_lock()) { ++ break; ++ } ++ else { ++ printk(KERN_ERR "bmi_ov2640_activate() - camera serializer did not lock,i = %d\n", i); ++ } ++ ++ } ++ clear_sync (adap); ++ return; ++} ++ ++ ++void bmi_ov2640_link_disable (struct bmi_cam *cam) ++{ ++ struct bmi_ov2640 *bmi_ov2640; ++ bmi_ov2640 = container_of(cam, struct bmi_ov2640, bcam); ++ ++ ++ //De-activate serial link ++ deconfigure_serializer (bmi_ov2640); ++ bmi_sensor_inactive(); ++ ++ return; ++} ++ ++ ++int bmi_ov2640_flash_led_off (struct bmi_cam *cam) ++{ ++ struct bmi_ov2640 *bmi_ov2640; ++ struct bmi_device *bdev; ++ int slot; ++ ++ bmi_ov2640 = container_of(cam, struct bmi_ov2640, bcam); ++ bdev = bmi_ov2640->bdev; ++ ++ slot = bmi_device_get_slot (bdev); ++ ++ bmi_set_module_gpio_data (slot, 2, 0); // Flash LED off. ++ return 0; ++} ++ ++int bmi_ov2640_flash_led_on (struct bmi_cam *cam) ++{ ++ struct bmi_ov2640 *bmi_ov2640; ++ struct bmi_device *bdev; ++ int slot; ++ ++ bmi_ov2640 = container_of(cam, struct bmi_ov2640, bcam); ++ bdev = bmi_ov2640->bdev; ++ ++ slot = bmi_device_get_slot (bdev); ++ ++ bmi_set_module_gpio_data (slot, 2, 1); // Flash LED on. ++ return 0; ++} ++ ++int bmi_ov2640_flash_high_beam (struct bmi_cam *cam) ++{ ++ unsigned char data; ++ struct bmi_ov2640 *bmi_ov2640; ++ struct i2c_adapter *adap; ++ ++ bmi_ov2640 = container_of(cam, struct bmi_ov2640, bcam); ++ adap = bmi_device_get_i2c_adapter (bmi_ov2640->bdev); ++ ++ ReadByte_IOX (adap, IOX_INPUT_REG, &data); ++ data |= 0x10; //High Beam ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, data); ++ ++ return 0; ++} ++ ++int bmi_ov2640_flash_low_beam (struct bmi_cam *cam) ++{ ++ unsigned char data; ++ struct bmi_ov2640 *bmi_ov2640; ++ struct i2c_adapter *adap; ++ ++ bmi_ov2640 = container_of(cam, struct bmi_ov2640, bcam); ++ adap = bmi_device_get_i2c_adapter (bmi_ov2640->bdev); ++ ++ ReadByte_IOX (adap, IOX_INPUT_REG, &data); ++ data &= ~(0x10); // Low Beam ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, data); ++ ++ return 0; ++} ++ ++int bmi_ov2640_red_led_off (struct bmi_cam *cam) ++{ ++ struct bmi_ov2640 *bmi_ov2640; ++ struct bmi_device *bdev; ++ int slot; ++ ++ bmi_ov2640 = container_of(cam, struct bmi_ov2640, bcam); ++ bdev = bmi_ov2640->bdev; ++ ++ slot = bmi_device_get_slot (bdev); ++ ++ bmi_set_module_gpio_data (slot, 3, 1); // Red LED=OFF ++ return 0; ++} ++ ++ ++int bmi_ov2640_red_led_on (struct bmi_cam *cam) ++{ ++ struct bmi_ov2640 *bmi_ov2640; ++ struct bmi_device *bdev; ++ int slot; ++ ++ bmi_ov2640 = container_of(cam, struct bmi_ov2640, bcam); ++ bdev = bmi_ov2640->bdev; ++ ++ slot = bmi_device_get_slot (bdev); ++ ++ bmi_set_module_gpio_data (slot, 3, 0); // Red LED=ON ++ return 0; ++} ++ ++ ++int bmi_ov2640_green_led_off (struct bmi_cam *cam) ++{ ++ struct bmi_ov2640 *bmi_ov2640; ++ struct bmi_device *bdev; ++ struct i2c_adapter *adap; ++ unsigned char iox_data; ++ ++ bmi_ov2640 = container_of(cam, struct bmi_ov2640, bcam); ++ bdev = bmi_ov2640->bdev; ++ ++ adap = bmi_device_get_i2c_adapter (bdev); ++ ++ if ( bmi_device_present(bdev) ) { ++ ++ ReadByte_IOX (adap, IOX_OUTPUT_REG, &iox_data); ++ ++ iox_data |= (0x40); //Set GRNLED to 1.(Off) ++ ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, iox_data); ++ } ++ return 0; ++} ++ ++int bmi_ov2640_green_led_on (struct bmi_cam *cam) ++{ ++ struct bmi_ov2640 *bmi_ov2640; ++ struct bmi_device *bdev; ++ struct i2c_adapter *adap; ++ unsigned char iox_data; ++ ++ bmi_ov2640 = container_of(cam, struct bmi_ov2640, bcam); ++ bdev = bmi_ov2640->bdev; ++ ++ adap = bmi_device_get_i2c_adapter (bdev); ++ ++ if ( bmi_device_present(bdev) ) { ++ ++ ReadByte_IOX (adap, IOX_OUTPUT_REG, &iox_data); ++ ++ iox_data &= ~(0x40); //Set GRNLED to 0.(On) ++ ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, iox_data & 0xF0); ++ } ++ return 0; ++} ++ ++ ++int bmi_ov2640_probe(struct bmi_device *bdev) ++{ ++ ++ int slot = bmi_device_get_slot(bdev); ++ ++ // allocate a driver-specific structure ++ ++ struct bmi_ov2640 *bmi_ov2640 = kzalloc(sizeof(struct bmi_ov2640), GFP_KERNEL); ++ if (!bmi_ov2640) { ++ return -1; ++ } ++ ++ // attach bmi_device structure (so we can find it later). ++ ++ bmi_device_set_drvdata(bdev, bmi_ov2640); ++ printk(KERN_INFO "bmi_ov2640: probe: bmi_ov2640 pointer 0x%p \n",bdev->dev.driver_data); ++ ++ // initialize bmi_ov2640 struct ++ bmi_ov2640->bdev = bdev; ++ ++ // sensor interface struct fields ++ ++ bmi_ov2640->bcam.interface.clk_mode = 0; // gated ++ bmi_ov2640->bcam.interface.ext_vsync = 1; // external vsync ++ bmi_ov2640->bcam.interface.Vsync_pol = 0; // non-inverted ++ bmi_ov2640->bcam.interface.Hsync_pol = 0; // non-inverted ++ bmi_ov2640->bcam.interface.pixclk_pol = 0; // non-inverted ++ bmi_ov2640->bcam.interface.data_pol = 0; // non-inverted ++ bmi_ov2640->bcam.interface.data_width = 1; // 8-bits ++ bmi_ov2640->bcam.interface.width = 1600-1; // 1280 - SXGA 1600 - UXGA ++ bmi_ov2640->bcam.interface.height = 1200-1; // 1024 - SXGA 1200 - UXGA ++ ++ bmi_ov2640->bcam.interface.pixel_fmt = IPU_PIX_FMT_UYVY; // YUV422 ++ bmi_ov2640->bcam.interface.mclk = 12000000; // frequency/src ++ ++ //bmi_camera_sensor struct fields ++ ++ bmi_ov2640->bcam.sensor.set_color = bmi_ov2640_set_color; ++ bmi_ov2640->bcam.sensor.get_color = bmi_ov2640_get_color; ++ bmi_ov2640->bcam.sensor.set_ae_mode = bmi_ov2640_set_ae_mode; ++ bmi_ov2640->bcam.sensor.get_ae_mode = bmi_ov2640_get_ae_mode; ++ bmi_ov2640->bcam.sensor.config = bmi_ov2640_config; ++ bmi_ov2640->bcam.sensor.reset = bmi_ov2640_reset; ++ ++ //bmi_camera_link struct fields ++ ++ bmi_ov2640->bcam.link.enable = bmi_ov2640_link_enable; ++ bmi_ov2640->bcam.link.disable = bmi_ov2640_link_disable; ++ ++ //bmi_camera_cntl struct fields ++ ++ bmi_ov2640->bcam.cntl.flash_led_off = bmi_ov2640_flash_led_off; ++ bmi_ov2640->bcam.cntl.flash_led_on = bmi_ov2640_flash_led_on; ++ bmi_ov2640->bcam.cntl.flash_high_beam = bmi_ov2640_flash_high_beam; ++ bmi_ov2640->bcam.cntl.flash_low_beam = bmi_ov2640_flash_low_beam; ++ bmi_ov2640->bcam.cntl.red_led_off = bmi_ov2640_red_led_off; ++ bmi_ov2640->bcam.cntl.red_led_on = bmi_ov2640_red_led_on; ++ bmi_ov2640->bcam.cntl.green_led_off = bmi_ov2640_green_led_off; ++ bmi_ov2640->bcam.cntl.green_led_on = bmi_ov2640_green_led_on; ++ ++ ++ //bmi_cam struct fields ++ ++ bmi_ov2640->bcam.activate = bmi_ov2640_activate ; ++ bmi_ov2640->bcam.deactivate = bmi_ov2640_deactivate; ++ ++ //bmi_ov2640 struct fields ++ bmi_ov2640->shutter = 0; ++ bmi_ov2640->zoomin = 0; ++ bmi_ov2640->zoomout = 0; ++ bmi_ov2640->flash = 0; ++ ++ bmi_ov2640->irq = bmi_device_get_status_irq (bdev); ++ ++ //initialize struct work_struct ++ INIT_WORK (&bmi_ov2640->work, bmi_ov2640_buttons_work); ++ ++ //Power stablization delay ++ mdelay(500); ++ ++ //Do one-time hw initialization (e.g. patch) ++ ++ // configure IOX ++ configure_IOX (bmi_ov2640); ++ ++ // configure GPIO ++ configure_GPIO (bmi_ov2640); ++ ++ // chip enable camera ++ enable_camera (bmi_ov2640); ++ ++ ov2640_patch (&bmi_ov2640->bdev->adap); ++ ++ //register with bug_camera ++ ++ //REWORK: check return code ++ register_bug_camera (&bmi_ov2640->bcam, slot); ++ ++ return 0; ++} ++ ++void bmi_ov2640_remove(struct bmi_device *bdev) ++{ ++ ++ //get our pointer ++ struct bmi_ov2640 *bmi_ov2640 = (struct bmi_ov2640*)(bmi_device_get_drvdata (bdev)); ++ int slot = bmi_device_get_slot (bdev); ++ ++ if (bdev == NULL) ++ { ++ printk(KERN_INFO "bmi_ov2640: bmi-ov2640_remove: NULL Pointer on bdev\n"); ++ return; ++ } ++ if (bmi_ov2640 == NULL) ++ { ++ printk(KERN_INFO "bmi_ov2640: bmi_ov2640_remove: NULL Pointer on bmi_ov2640\n"); ++ printk(KERN_INFO "bmi_ov2640: bmi_ov2640_remove: bdev->epid.vendor: 0x%x\n",bdev->epid.vendor); ++ printk(KERN_INFO "bmi_ov2640: bmi_ov2640_remove: bdev->epid.product: 0x%x\n",bdev->epid.product); ++ printk(KERN_INFO "bmi_ov2640: bmi_ov2640_remove: bdev->epid.revision: 0x%x\n",bdev->epid.revision); ++ printk(KERN_INFO "bmi_ov3640: bmi_ov2640_remove: bmi_ov2640 pointer 0x%p \n",bdev->dev.driver_data); ++ return; ++ } ++ //unregister with bug_camera ++ unregister_bug_camera ( &bmi_ov2640->bcam, slot); ++ ++ disable_camera (bmi_ov2640); ++ deconfigure_module (bmi_ov2640); ++ ++ ++ flush_scheduled_work(); ++ ++ //de-attach driver-specific struct from bmi_device structure ++ bmi_device_set_drvdata (bdev, 0); ++ ++ //free driver-specific structure ++ kfree (bmi_ov2640); ++ return; ++} ++ ++ ++static __init int bmi_ov2640_init(void) ++{ ++ printk("BMI OV2640 Camera Sensor Driver v%s \n", BMI_OV2640_VERSION); ++ ++// Register with BMI bus. ++ return bmi_register_driver (&bmi_ov2640_driver); ++ ++} ++ ++static void __exit bmi_ov2640_cleanup(void) ++{ ++ ++// UnRegister with BMI bus. ++ bmi_unregister_driver (&bmi_ov2640_driver); ++ return; ++} ++ ++ ++module_init(bmi_ov2640_init); ++module_exit(bmi_ov2640_cleanup); ++ ++MODULE_AUTHOR("EnCADIS Design, Inc."); ++MODULE_DESCRIPTION("OV2640 Camera Driver"); ++MODULE_LICENSE("GPL"); ++ +--- /dev/null ++++ git/drivers/bmi/pims/camera/bmi_vs6624.c +@@ -0,0 +1,915 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "bug_camera.h" ++#include "vs6624_access.h" ++ ++ ++// BMI device ID table ++static struct bmi_device_id bmi_vs6624_tbl[] = ++{ ++ { .match_flags = BMI_DEVICE_ID_MATCH_VENDOR | BMI_DEVICE_ID_MATCH_PRODUCT, ++ .vendor = BMI_VENDOR_BUG_LABS, ++ .product = BMI_PRODUCT_CAMERA_VS6624, ++ .revision = BMI_ANY, ++ }, ++ { 0, }, /* terminate list */ ++}; ++MODULE_DEVICE_TABLE(bmi, bmi_vs6624_tbl); ++ ++int bmi_vs6624_probe(struct bmi_device *bdev); ++void bmi_vs6624_remove(struct bmi_device *bdev); ++int bmi_vs6624_suspend(struct bmi_device *bdev); ++int bmi_vs6624_resume(struct bmi_device *bdev); ++ ++// BMI driver structure ++static struct bmi_driver bmi_vs6624_driver = ++{ ++ .name = "bmi_vs6624", ++ .id_table = bmi_vs6624_tbl, ++ .probe = bmi_vs6624_probe, ++ .remove = bmi_vs6624_remove, ++ }; ++ ++ ++struct bmi_vs6624 { ++ struct bmi_device *bdev; ++ struct bmi_cam bcam; ++ unsigned int shutter; // shutter button save state ++ unsigned int zoomin; // zoomin button save state ++ unsigned int zoomout; // zoom out button save state ++ unsigned int flash; // state of camera FLASH ++ int irq; ++ struct input_dev *idev; ++ struct work_struct work; ++ ++}; ++ ++ // I2C Slave Address ++#define BMI_IOX_I2C_ADDRESS 0x71 // 7-bit address ++ ++ // I2C IOX register addresses ++#define IOX_INPUT_REG 0x0 ++#define IOX_OUTPUT_REG 0x1 ++#define IOX_POLARITY_REG 0x2 ++#define IOX_CONTROL 0x3 ++ ++ ++// read byte from I2C IO expander ++ ++static int ReadByte_IOX(struct i2c_adapter *adap, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ ++ /* Read Byte with Pointer */ ++ ++ rmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[0].flags = 0; /* write */ ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; /* read */ ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ret = i2c_transfer (adap, rmsg, num_msgs); ++ ++ if (ret == 2) { ++ printk (KERN_ERR "ReadByte_IOX() - data = %02X\n", *data); ++ ++ ret = 0; ++ } ++ else { ++ //Rework: add conditional debug messages here ++ printk (KERN_ERR "ReadByte_IOX() - i2c_transfer failed\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++ ++// write byte to I2C IO expander ++static int WriteByte_IOX(struct i2c_adapter *adap, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ /* Write Byte with Pointer */ ++ ++ wmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[0].flags = 0; /* write */ ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[1].flags = 0; /* write */ ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ ++ ret = i2c_transfer (adap, wmsg, num_msgs); ++ ++ if (ret == 2) { ++ printk (KERN_ERR "WriteByte_IOX() - data = %02X\n", data); ++ ret = 0; ++ } ++ else { ++ //Rework: add conditional debug messages here ++ ++ printk (KERN_ERR "WriteByte_IOX() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++ ++/* ++ * Input interrupt handler and support routines ++ */ ++ ++ ++// work handler ++void bmi_vs6624_buttons_work(void *arg) ++{ ++ struct i2c_adapter *adap; ++ struct bmi_vs6624 *pim = (struct bmi_vs6624*)arg; ++ ++ unsigned char iox_data; ++ unsigned int test_value; ++ int sync_flag = 0; ++ int err; ++ ++ printk (KERN_ERR "bmi_vs6624_buttons_work() - enter\n"); ++ ++ ++ // avoid i2c i/o if camera hardware not present. ++ ++ if (bmi_device_present (pim->bdev) == 0) { ++ goto exit; ++ } ++ ++ adap = bmi_device_get_i2c_adapter (pim->bdev); ++ ++ ++ // read IOX data input ++ err = ReadByte_IOX (adap, IOX_INPUT_REG, &iox_data); ++ if (err) { ++ goto exit; ++ } ++ ++ // zoom in button ++ test_value = !((iox_data & 0x2) >> 1); ++ if (test_value != pim->zoomin) { ++ printk (KERN_ERR "bmi_vs6624buttons_work() - report ZOOMIN\n"); ++ pim->zoomin = test_value; ++ input_report_key (pim->idev, BN_ZOOMIN, test_value); ++ sync_flag = 1; ++ } ++ ++ ++ // zoom out button ++ test_value = !((iox_data & 0x4) >> 2); ++ if (test_value != pim->zoomout) { ++ printk (KERN_ERR "bmi_vs6624_buttons_work() - report ZOOMOUT\n"); ++ pim->zoomout = test_value; ++ input_report_key (pim->idev, BN_ZOOMOUT, test_value); ++ sync_flag = 1; ++ } ++#if 0 ++ // flash button ++ test_value = (iox_data & 0x8) >> 3; ++ if (test_value != pim->flash) { ++ printk (KERN_ERR "bmi_vs6624_buttons_work() - report FLASH\n"); ++ pim->flash = test_value; ++ input_report_key (pim->idev, BN_FLASH, test_value); ++ sync_flag = 1; ++ } ++#endif ++ ++ if ( sync_flag ) { ++ printk (KERN_ERR "bmi_vs6624_buttons_work() - input_sync()ing..\n"); ++ input_sync (pim->idev); ++ } ++exit: ++ printk (KERN_ERR "bmi_vs6624_buttons_work() -exit\n"); ++ enable_irq (pim->irq); ++ return; ++ ++} ++ ++ ++// interrupt handler ++static irqreturn_t module_irq_handler(int irq, void *dummy) ++{ ++ struct bmi_vs6624 *pim = dummy; ++ unsigned int test_value; ++ ++ int slot; ++ ++ printk (KERN_ERR "module_irq_handler() - enter\n"); ++ ++ disable_irq_nosync(irq); ++ ++ slot = bmi_device_get_slot(pim->bdev); ++ ++ ++ // shutter button on GPIO ++ ++ test_value = !(bmi_read_gpio_data_reg (slot) & 0x1); ++ ++ if (!test_value == pim->shutter) { ++ pim->shutter = test_value; ++ printk (KERN_ERR "module_irq_handler() - report SHUTTER\n"); ++ input_report_key (pim->idev, BN_SHUTTER, test_value); ++ input_sync (pim->idev); ++ } ++ ++ // other buttons on I2C IOX ++ schedule_work (&pim->work); ++ printk (KERN_ERR "module_irq_handler() - exit\n"); ++ return IRQ_HANDLED; ++} ++ ++/* ++ * control functions ++ */ ++ ++ ++// configure IOX IO and states ++void configure_IOX(struct bmi_vs6624 *cam) ++{ ++ struct i2c_adapter *adap; ++ ++ adap = bmi_device_get_i2c_adapter (cam->bdev); ++ ++ printk (KERN_ERR "configure_IOX() - enter\n"); ++ ++ ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, 0x40); // CE=0, F_CHG=1,SYNC=0, TORCH=0 ++ WriteByte_IOX (adap, IOX_CONTROL, 0x0F); // IOX[7:4]=OUT, IOX[3:0]=IN ++} ++ ++// configure GPIO IO and states ++void configure_GPIO(struct bmi_vs6624 *cam) ++{ ++ // set states before turning on outputs ++ ++ int slot; ++ ++ slot = bmi_device_get_slot (cam->bdev); ++ ++ bmi_set_module_gpio_data (slot, 3, 1); // Red LED=OFF ++ bmi_set_module_gpio_data (slot, 2, 1); // Green LED=OFF ++ bmi_set_module_gpio_data (slot, 1, 0); // SER_RST=0 ++ ++ // configure direction ++ bmi_set_module_gpio_dir (slot, 3, BMI_GPIO_OUT); ++ bmi_set_module_gpio_dir (slot, 2, BMI_GPIO_OUT); ++ bmi_set_module_gpio_dir (slot, 1, BMI_GPIO_OUT); ++ bmi_set_module_gpio_dir (slot, 0, BMI_GPIO_IN); // SHUTTER ++} ++ ++// deconfigure IOX and GPIO ++void deconfigure_module(struct bmi_vs6624 *cam) ++{ ++ int slot; ++ struct i2c_adapter *adap; ++ ++ slot = bmi_device_get_slot (cam->bdev); ++ adap = bmi_device_get_i2c_adapter (cam->bdev); ++ ++ ++ if ( bmi_device_present (cam->bdev) ) { ++ WriteByte_IOX (adap, IOX_CONTROL, 0xFF); ++ } ++ bmi_set_module_gpio_dir (slot, 3, BMI_GPIO_IN); ++ bmi_set_module_gpio_dir (slot, 2, BMI_GPIO_IN); ++ bmi_set_module_gpio_dir (slot, 1, BMI_GPIO_IN); ++} ++ ++ ++// configure serializer on plug-in module ++void configure_serializer(struct bmi_vs6624 *cam) ++{ ++ int slot = bmi_device_get_slot (cam->bdev); ++ bmi_set_module_gpio_data (slot, 1, 1); // SER_RST=1 ++} ++ ++void deconfigure_serializer(struct bmi_vs6624 *cam) ++{ ++ int slot = bmi_device_get_slot (cam->bdev); ++ bmi_set_module_gpio_data (slot, 1, 0); // SER_RST=0 ++} ++ ++void enable_camera(struct bmi_vs6624 *cam) ++{ ++ struct i2c_adapter *adap; ++ unsigned char iox_data; ++ ++ printk (KERN_ERR "enable_camera() enter\n"); ++ ++ adap = bmi_device_get_i2c_adapter (cam->bdev); ++ ++ // The first i2c read seems to mess everything up. ++ ++ ReadByte_IOX (adap, IOX_OUTPUT_REG, &iox_data); ++ printk (KERN_ERR "enable_camera() iox_data = %02X\n", iox_data); ++ ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, iox_data | 0x80); ++ printk (KERN_ERR "enable_camera() exit\n"); ++} ++ ++// disable camera on plug-in module ++void disable_camera(struct bmi_vs6624 *cam) ++{ ++ struct i2c_adapter *adap; ++ unsigned char iox_data; ++ ++ printk (KERN_ERR "disable_camera() enter\n"); ++ ++ adap = bmi_device_get_i2c_adapter (cam->bdev); ++ ++ if ( bmi_device_present(cam->bdev) ) { ++ ++ ReadByte_IOX (adap, IOX_OUTPUT_REG, &iox_data); ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, iox_data & 0x70); ++ } ++ ++ printk (KERN_ERR "disable_camera() exit\n"); ++} ++ ++// generate sync ++void generate_camera_sync(struct i2c_adapter *adap) ++{ ++ unsigned char iox_data[0]; ++ ++ printk(KERN_INFO "generate_camera_sync() - enter\n"); ++ ReadByte_IOX (adap, IOX_OUTPUT_REG, iox_data); ++ ++ printk(KERN_INFO "generate_camera_sync() - read = %02X\n", iox_data[0]); ++ printk(KERN_INFO "generate_camera_sync() - write = %02X\n", *iox_data | 0x20); ++ ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, *iox_data | 0x20);// SYNC = 1 ++ ++ printk(KERN_INFO "generate_camera_sync() - write = %02X\n", *iox_data & 0xD0); ++ ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, *iox_data & 0xD0);// SYNC = 0 ++ udelay(20); // 60 MHz * 1024 = ~17 us sync time ++ ++ printk(KERN_INFO "generate_camera_sync() - exit\n"); ++} ++ ++void set_sync(struct i2c_adapter *adap) ++{ ++ unsigned char iox_data[0]; ++ ++ printk(KERN_INFO "set_sync() - enter\n"); ++ ++ ReadByte_IOX (adap, IOX_OUTPUT_REG, iox_data); ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, *iox_data | 0x20);// SYNC = 1 ++ ++ printk(KERN_INFO "set_sync() - exit\n"); ++} ++ ++void clear_sync(struct i2c_adapter *adap) ++{ ++ unsigned char iox_data[0]; ++ ++ printk(KERN_INFO "clear_sync() - enter\n"); ++ ++ ReadByte_IOX (adap, IOX_OUTPUT_REG, iox_data); ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, *iox_data & 0xD0);// SYNC = 0 ++ ++ printk(KERN_INFO "clear_sync() - exit\n"); ++} ++ ++ ++// check serializer lock ++int check_camera_lock(void) ++{ ++ return bmi_sensor_lock_status(); ++} ++ ++void bmi_vs6624_set_color(struct bmi_cam *cam, int bright, int saturation, int red, int green, int blue) ++{ ++ ++ struct i2c_adapter *adap; ++ struct bmi_vs6624 *bmi_vs6624; ++ ++ bmi_vs6624 = container_of(cam, struct bmi_vs6624, bcam); ++ adap = &bmi_vs6624->bdev->adap; ++ ++ vs6624_set_color (adap, bright, saturation, red, green, blue); ++ return; ++ ++} ++ ++void bmi_vs6624_get_color(struct bmi_cam *cam, int *bright, int *saturation, int *red, int *green, int *blue) ++{ ++ struct i2c_adapter *adap; ++ struct bmi_vs6624 *bmi_vs6624; ++ ++ bmi_vs6624 = container_of(cam, struct bmi_vs6624, bcam); ++ adap = &bmi_vs6624->bdev->adap; ++ ++ vs6624_get_color (adap, bright, saturation, red, green, blue); ++ return; ++} ++ ++ ++ ++ ++void bmi_vs6624_set_ae_mode (struct bmi_cam *cam, int ae_mode) ++{ ++ printk (KERN_ERR "bmi_vs6624_set_ae_mode() - NOT IMPLEMENTED.\n"); ++} ++ ++ ++void bmi_vs6624_get_ae_mode (struct bmi_cam *cam, int *ae_mode) ++{ ++ printk (KERN_ERR "bmi_vs6624_set_ae_mode() - NOT IMPLEMENTED.\n"); ++} ++ ++ ++sensor_interface * bmi_vs6624_config (struct bmi_cam *cam, int *frame_rate, int high_quality) ++{ ++ //REWORK: Add code here ++ struct i2c_adapter *adap; ++ struct bmi_vs6624 *bmi_vs6624; ++ int i; ++ ++ bmi_vs6624 = container_of(cam, struct bmi_vs6624, bcam); ++ adap = &bmi_vs6624->bdev->adap; ++ ++ printk (KERN_ERR "bmi_vs6624_CONFIG() - enter\n"); ++ ++ if(check_camera_lock()) { ++ printk(KERN_INFO "bmi_vs6624_config(): camera serializer LOCKED\n"); ++ } ++ else { ++ printk(KERN_ERR "bmi_vs6624_config(): camera serializer NOT LOCKED\n"); ++ } ++ ++ //Bring up the serial link ++ ++ bmi_sensor_active(1); ++ configure_serializer (bmi_vs6624); ++ ++ adap = &bmi_vs6624->bdev->adap; ++ set_sync (adap); ++ ++ for (i = 0; i < 10; i++) { ++ ++ msleep(10); ++ ++ if(check_camera_lock()) { ++ printk(KERN_INFO "bmi_vs6624_config() - camera serializer locked, i = %d\n", i); ++ break; ++ } ++ else { ++ printk(KERN_ERR "bmi_vs6624_config() - camera serializer did not lock,i = %d\n", i); ++ } ++ ++ } ++ clear_sync (adap); ++ ++ ++ if(check_camera_lock()) { ++ ++ printk(KERN_INFO "bmi_vs6624_config(): camera serializer LOCKED\n"); ++ } ++ else { ++ printk(KERN_ERR "bmi_vs6624_config(): camera serializer NOT LOCKED\n"); ++ } ++ ++ ++ printk (KERN_ERR "bmi_vs6624_CONFIG() - exit\n"); ++ return &cam->interface; ++ ++} ++ ++ ++sensor_interface * bmi_vs6624_reset (struct bmi_cam *cam) ++{ ++ //REWORK: Add code here ++ //REWORK: What is a valid soft reset sequence ? ++ struct i2c_adapter *adap; ++ struct bmi_vs6624 *bmi_vs6624; ++ ++ printk (KERN_ERR "bmi_vs6624_RESET() - enter\n"); ++ ++ bmi_vs6624 = container_of(cam, struct bmi_vs6624, bcam); ++ ++ ++ adap = bmi_device_get_i2c_adapter (bmi_vs6624->bdev); ++ ++ if(check_camera_lock()) { ++ printk(KERN_INFO "bmi_vs6624_reset(): camera serializer LOCKED\n"); ++ } ++ else { ++ printk(KERN_ERR "bmi_vs6624_reset(): camera serializer NOT LOCKED\n"); ++ } ++ //disable the serial link ++ ++ deconfigure_serializer (bmi_vs6624); ++ bmi_sensor_inactive(); ++ ++ if(check_camera_lock()) { ++ ++ printk(KERN_INFO "bmi_vs6624_reset(): camera serializer LOCKED\n"); ++ } ++ else { ++ printk(KERN_ERR "bmi_vs6624_reset(): camera serializer NOT LOCKED\n"); ++ } ++ ++ printk (KERN_ERR "bmi_vs6624_RESET() - exit\n"); ++ ++ return &cam->interface; ++} ++ ++int bmi_vs6624_activate (struct bmi_cam *cam, struct input_dev *idev) ++{ ++ //REWORK: Add code here ++ int rc = 0; ++ int i; ++ struct i2c_adapter *adap; ++ struct bmi_vs6624 *bmi_vs6624; ++ ++ printk (KERN_ERR "int bmi_vs6624_activate () - enter\n"); ++ ++ bmi_vs6624 = container_of(cam, struct bmi_vs6624, bcam); ++ ++ ++ //bmi_vs6624 struct fields ++ bmi_vs6624->idev = idev; ++ ++ bmi_vs6624->shutter = 0; ++ bmi_vs6624->zoomin = 0; ++ bmi_vs6624->zoomout = 0; ++ bmi_vs6624->flash = 0; ++ ++ printk (KERN_ERR "bmi_vs6624_activate () - irq = %d\n", bmi_vs6624->irq); ++ ++ // install button irq_handler ++ if (request_irq(bmi_vs6624->irq, &module_irq_handler, 0, "bmi_cam_button", bmi_vs6624)) { ++ printk (KERN_ERR ++ "bmi_vs6624_activate() - request_irq (irq = %d) failed.\n", ++ bmi_vs6624->irq); ++ ++ rc = -EBUSY; ++ goto exit; ++ } ++ ++ //Activate serial link ++ bmi_sensor_active(1); // rising edge clock ++ configure_serializer (bmi_vs6624); ++ ++ adap = &bmi_vs6624->bdev->adap; ++ set_sync (adap); ++ ++ ++ for (i = 0; i < 10; i++) { ++ ++ msleep(10); ++ ++ if(check_camera_lock()) { ++ printk(KERN_INFO "bmi_vs6624_activate() - camera serializer locked, i = %d\n", i); ++ break; ++ } ++ else { ++ printk(KERN_ERR "bmi_vs6624_activate() - camera serializer did not lock,i = %d\n", i); ++ } ++ ++ } ++ clear_sync (adap); ++ ++ if(check_camera_lock()) { ++ printk(KERN_INFO "bmi_vs6624_activate(): camera serializer LOCKED\n"); ++ } ++ else { ++ printk(KERN_ERR "bmi_vs6624_activate(): camera serializer NOT LOCKED\n"); ++ } ++ ++ ++exit: ++ printk (KERN_ERR "int bmi_vs6624_activate () - exit\n"); ++ return rc; ++} ++ ++int bmi_vs6624_deactivate (struct bmi_cam *cam) ++{ ++ //REWORK: Add code here ++ ++ struct bmi_vs6624 *bmi_vs6624; ++ bmi_vs6624 = container_of(cam, struct bmi_vs6624, bcam); ++ ++ ++ //De-activate serial link ++ deconfigure_serializer (bmi_vs6624); ++ bmi_sensor_inactive(); ++ ++ ++ //uninstall button irq_handler ++ free_irq(bmi_vs6624->irq, bmi_vs6624); ++ ++ ++ return 0; ++} ++ ++ ++void bmi_vs6624_link_enable (struct bmi_cam *cam) ++{ ++ //REWORK: Add code here ++ ++ int i; ++ struct i2c_adapter *adap; ++ struct bmi_vs6624 *bmi_vs6624; ++ bmi_vs6624 = container_of(cam, struct bmi_vs6624, bcam); ++ ++ //Activate serial link ++ bmi_sensor_active(1); // rising edge clock ++ configure_serializer (bmi_vs6624); ++ ++ adap = bmi_device_get_i2c_adapter (bmi_vs6624->bdev); ++ ++ set_sync (adap); ++ ++ ++ //REWORK: Speed this up. (shorten delay) ++ ++ for (i = 0; i < 10; i++) { ++ ++ msleep(10); ++ ++ if(check_camera_lock()) { ++ printk(KERN_INFO "bmi_vs6624_activate() - camera serializer locked, i = %d\n", i); ++ break; ++ } ++ else { ++ printk(KERN_ERR "bmi_vs6624_activate() - camera serializer did not lock,i = %d\n", i); ++ } ++ ++ } ++ clear_sync (adap); ++ ++ if(check_camera_lock()) { ++ printk(KERN_INFO "bmi_vs6624_activate(): camera serializer LOCKED\n"); ++ } ++ else { ++ printk(KERN_ERR "bmi_vs6624_activate(): camera serializer NOT LOCKED\n"); ++ } ++ ++ return; ++} ++ ++ ++void bmi_vs6624_link_disable (struct bmi_cam *cam) ++{ ++ struct bmi_vs6624 *bmi_vs6624; ++ bmi_vs6624 = container_of(cam, struct bmi_vs6624, bcam); ++ ++ ++ //De-activate serial link ++ deconfigure_serializer (bmi_vs6624); ++ bmi_sensor_inactive(); ++ ++ return; ++} ++ ++ ++ ++int bmi_vs6624_red_led_off (struct bmi_cam *cam) ++{ ++ struct bmi_vs6624 *bmi_vs6624; ++ struct bmi_device *bdev; ++ int slot; ++ ++ bmi_vs6624 = container_of(cam, struct bmi_vs6624, bcam); ++ bdev = bmi_vs6624->bdev; ++ ++ slot = bmi_device_get_slot (bdev); ++ ++ bmi_set_module_gpio_data (slot, 3, 1); // Red LED=OFF ++ return 0; ++} ++ ++ ++int bmi_vs6624_red_led_on (struct bmi_cam *cam) ++{ ++ struct bmi_vs6624 *bmi_vs6624; ++ struct bmi_device *bdev; ++ int slot; ++ ++ bmi_vs6624 = container_of(cam, struct bmi_vs6624, bcam); ++ bdev = bmi_vs6624->bdev; ++ ++ slot = bmi_device_get_slot (bdev); ++ ++ bmi_set_module_gpio_data (slot, 3, 0); // Red LED=ON ++ return 0; ++} ++ ++ ++int bmi_vs6624_green_led_off (struct bmi_cam *cam) ++{ ++ struct bmi_vs6624 *bmi_vs6624; ++ struct bmi_device *bdev; ++ int slot; ++ ++ bmi_vs6624 = container_of(cam, struct bmi_vs6624, bcam); ++ bdev = bmi_vs6624->bdev; ++ ++ slot = bmi_device_get_slot (bdev); ++ ++ bmi_set_module_gpio_data (slot, 2, 1); // Green LED=OFF ++ return 0; ++} ++ ++ ++int bmi_vs6624_green_led_on (struct bmi_cam *cam) ++{ ++ struct bmi_vs6624 *bmi_vs6624; ++ struct bmi_device *bdev; ++ int slot; ++ ++ bmi_vs6624 = container_of(cam, struct bmi_vs6624, bcam); ++ bdev = bmi_vs6624->bdev; ++ ++ slot = bmi_device_get_slot (bdev); ++ ++ bmi_set_module_gpio_data (slot, 2, 0); // Green LED=ON ++ return 0; ++} ++ ++ ++int bmi_vs6624_probe(struct bmi_device *bdev) ++{ ++ ++ //REWORK: Add code here ++ ++ int slot = bmi_device_get_slot(bdev); ++ ++ ++ // allocate a driver-specific structure ++ ++ struct bmi_vs6624 *bmi_vs6624 = kzalloc(sizeof(struct bmi_vs6624), GFP_KERNEL); ++ if (!bmi_vs6624) { ++ return -1; ++ } ++ ++ // attach bmi_device structure (so we can find it later). ++ bmi_device_set_drvdata(bdev, bmi_vs6624); ++ ++ ++ // initialize bmi_vs6624 struct ++ bmi_vs6624->bdev = bdev; ++ ++ // sensor interface struct fields ++# if 1 ++ bmi_vs6624->bcam.interface.clk_mode = 0; // gated ++ bmi_vs6624->bcam.interface.ext_vsync = 1; // external vsync ++#else ++ bmi_vs6624->bcam.interface.clk_mode = 2; // progressive ++ bmi_vs6624->bcam.interface.ext_vsync = 0; // internal vsync ++# endif ++ bmi_vs6624->bcam.interface.Vsync_pol = 0; // non-inverted ++ bmi_vs6624->bcam.interface.Hsync_pol = 0; // non-inverted ++ bmi_vs6624->bcam.interface.pixclk_pol = 0; // non-inverted ++ bmi_vs6624->bcam.interface.data_pol = 0; // non-inverted MTW=1 ++ bmi_vs6624->bcam.interface.data_width = 1; // 8-bits ++ bmi_vs6624->bcam.interface.width = 1280-1; // 1280 - SXGA ++ bmi_vs6624->bcam.interface.height = 1024-1; // 1024 - SXGA ++ ++ bmi_vs6624->bcam.interface.pixel_fmt = IPU_PIX_FMT_UYVY; // YUV422 ++ bmi_vs6624->bcam.interface.mclk = 12000000; // frequency/src ++ ++ //bmi_camera_sensor struct fields ++ ++ bmi_vs6624->bcam.sensor.set_color = bmi_vs6624_set_color; ++ bmi_vs6624->bcam.sensor.get_color = bmi_vs6624_get_color; ++ bmi_vs6624->bcam.sensor.set_ae_mode = bmi_vs6624_set_ae_mode; ++ bmi_vs6624->bcam.sensor.get_ae_mode = bmi_vs6624_get_ae_mode; ++ bmi_vs6624->bcam.sensor.config = bmi_vs6624_config; ++ bmi_vs6624->bcam.sensor.reset = bmi_vs6624_reset; ++ ++ //bmi_camera_link struct fields ++ ++ bmi_vs6624->bcam.link.enable = bmi_vs6624_link_enable; ++ bmi_vs6624->bcam.link.disable = bmi_vs6624_link_disable; ++ ++ //bmi_camera_cntl struct fields ++ ++ bmi_vs6624->bcam.cntl.flash_led_off = 0; ++ bmi_vs6624->bcam.cntl.flash_led_off = 0; ++ bmi_vs6624->bcam.cntl.flash_high_beam = 0; ++ bmi_vs6624->bcam.cntl.flash_low_beam = 0; ++ bmi_vs6624->bcam.cntl.red_led_off = bmi_vs6624_red_led_off; ++ bmi_vs6624->bcam.cntl.red_led_on = bmi_vs6624_red_led_on; ++ bmi_vs6624->bcam.cntl.green_led_off = bmi_vs6624_green_led_off; ++ bmi_vs6624->bcam.cntl.green_led_on = bmi_vs6624_green_led_on; ++ ++ ++ //bmi_cam struct fields ++ ++ bmi_vs6624->bcam.activate = bmi_vs6624_activate ; ++ bmi_vs6624->bcam.deactivate = bmi_vs6624_deactivate; ++ ++ //bmi_vs6624 struct fields ++ bmi_vs6624->shutter = 0; ++ bmi_vs6624->zoomin = 0; ++ bmi_vs6624->zoomout = 0; ++ bmi_vs6624->flash = 0; ++ ++ bmi_vs6624->irq = bmi_device_get_status_irq (bdev); ++ ++ //initialize struct work_struct ++ INIT_WORK (&bmi_vs6624->work, bmi_vs6624_buttons_work, bmi_vs6624); ++ ++ //Power stablization delay ++ mdelay(500); ++ ++ //Do one-time hw initialization (e.g. patch) ++ ++ // configure IOX ++ configure_IOX (bmi_vs6624); ++ ++ // configure GPIO ++ configure_GPIO (bmi_vs6624); ++ ++ // chip enable camera ++ enable_camera (bmi_vs6624); ++ ++ vs6624_patch (&bmi_vs6624->bdev->adap); ++ ++ //register with bug_camera ++ ++ //REWORK: check return code ++ register_bug_camera (&bmi_vs6624->bcam, slot); ++ ++ return 0; ++} ++ ++void bmi_vs6624_remove(struct bmi_device *bdev) ++{ ++ //REWORK: Add code here ++ ++ ++ //get our pointer ++ struct bmi_vs6624 *bmi_vs6624 = (struct bmi_vs6624*)(bmi_device_get_drvdata (bdev)); ++ int slot = bmi_device_get_slot (bdev); ++ ++ ++ //unregister with bug_camera ++ unregister_bug_camera ( &bmi_vs6624->bcam, slot); ++ ++ //REWORK: Avoid I2c access if camera module is not present. ++ ++ disable_camera (bmi_vs6624); ++ deconfigure_module (bmi_vs6624); ++ ++ ++ flush_scheduled_work(); ++ ++ //de-attach driver-specific struct from bmi_device structure ++ bmi_device_set_drvdata (bdev, 0); ++ ++ //free driver-specific structure ++ kfree (bmi_vs6624); ++ return; ++} ++ ++ ++static __init int bmi_vs6624_init(void) ++{ ++ ++// Register with BMI bus. ++ return bmi_register_driver (&bmi_vs6624_driver); ++ ++} ++ ++static void __exit bmi_vs6624_cleanup(void) ++{ ++ ++// UnRegister with BMI bus. ++ bmi_unregister_driver (&bmi_vs6624_driver); ++ return; ++} ++ ++ ++module_init(bmi_vs6624_init); ++module_exit(bmi_vs6624_cleanup); ++ ++MODULE_AUTHOR("EnCADIS Design, Inc."); ++MODULE_DESCRIPTION("VS6624 Camera Driver"); ++MODULE_LICENSE("GPL"); ++ +--- /dev/null ++++ git/drivers/bmi/pims/camera/bug_camera.c +@@ -0,0 +1,611 @@ ++#include ++#include ++#include ++#include ++#include ++#include "bug_camera.h" ++ ++#define BUG_CAMERA_VERSION "1.0" ++ ++ ++struct cam_ctl ++{ ++ int slot; ++ struct cdev cdev; ++ struct device *class_dev; ++}; ++ ++// private device structure ++struct bug_cam ++{ ++ unsigned int cam_cnt; //number of cameras present ++ unsigned int active; //active camera slot ++ ++ struct bmi_cam *bcam[4]; //slot-specific behavior ++ ++ struct input_dev *input_dev; // input device ++ struct cam_ctl cntl[4]; // control character device ++ struct device *class_dev; ++ int cntl_devno; // control device number ++ int open_flag; // force single open ++}; ++ ++static struct bug_cam bug_cam; ++ ++static int cntl_open (struct inode *, struct file *); ++static int cntl_release (struct inode *, struct file *); ++static int cntl_ioctl(struct inode *, struct file *, unsigned int, unsigned long); ++// control file operations ++ ++struct file_operations cam_ctl_fops = { ++ .owner = THIS_MODULE, ++ .ioctl = cntl_ioctl, ++ .open = cntl_open, ++ .release = cntl_release, ++}; ++ ++/* ++ * control device operations ++ */ ++ ++static int cam_ctl_major; ++ ++int ctl_init (void) ++{ ++ dev_t dev_id; ++ int retval; ++ ++ // alloc char driver with 4 minor numbers ++ ++ retval = alloc_chrdev_region(&dev_id, 0, 4, "BUG Camera Control"); ++ ++ if (retval) { ++ return -1; ++ } ++ cam_ctl_major = MAJOR(dev_id); ++ return 0; ++} ++ ++void ctl_clean (void) ++{ ++ dev_t dev_id; ++ ++ dev_id = MKDEV(cam_ctl_major, 0); ++ unregister_chrdev_region(dev_id, 4); ++ return; ++} ++ ++int ctl_probe (struct cam_ctl *cam_ctl, int slot) ++{ ++ struct cdev *cdev; ++ dev_t dev_id; ++ int ret; ++ struct class *bmi_class; ++ ++ cdev = &cam_ctl->cdev; ++ cdev_init (cdev, &cam_ctl_fops); ++ ++ dev_id = MKDEV (cam_ctl_major, slot); ++ ret = cdev_add (cdev, dev_id, 1); ++ ++ //Create class device ++ bmi_class = bmi_get_bmi_class (); ++ ++ cam_ctl->class_dev = device_create (bmi_class, NULL, MKDEV(cam_ctl_major, slot), cam_ctl, "bmi_cam_ctl_m%i", slot+1); ++ ++ if (IS_ERR(cam_ctl->class_dev)) { ++ printk(KERN_ERR "Unable to create " ++ "class_device for bmi_cam_ctl_m%i; errno = %ld\n", ++ slot+1, PTR_ERR(cam_ctl->class_dev)); ++ cam_ctl->class_dev = NULL; ++ } ++ cam_ctl->slot = slot; ++ ++ return ret; ++} ++ ++void ctl_remove (struct cam_ctl *cam_ctl, int slot) ++{ ++ struct class *bmi_class; ++ ++ bmi_class = bmi_get_bmi_class (); ++ device_destroy (bmi_class, MKDEV(cam_ctl_major, slot)); ++ ++ cam_ctl->class_dev = 0; ++ ++ cdev_del (&cam_ctl->cdev); ++ return; ++} ++ ++// open ++static int cntl_open(struct inode *inode, struct file *filp) ++{ ++ if (bug_cam.open_flag) { ++ return - EBUSY; ++ } ++ bug_cam.open_flag = 1; ++ filp->private_data = &bug_cam; ++ return 0; ++} ++ ++// release ++static int cntl_release(struct inode *inode, struct file *filp) ++{ ++ bug_cam.open_flag = 0; ++ return 0; ++} ++ ++ ++ ++ ++static struct bmi_cam* get_selected (void) ++{ ++ struct bmi_cam *bcam; ++ ++ if (bug_cam.active == -1) { ++ return 0; ++ } ++ ++ bcam = bug_cam.bcam [bug_cam.active]; ++ return bcam; ++ ++} ++ ++ ++static int select_slot (int slot) ++{ ++ struct bmi_cam *bcam; ++ ++ // validate slot number ++ if ((slot < 0) || slot > 3) { ++ ++ printk(KERN_ERR ++ "bug_camera.c: Invalid value (%d) for camera selection.\n", ++ slot); ++ ++ return -EINVAL; ++ } ++ ++ // error if this slot not registered ++ if ( bug_cam.bcam [slot] == NULL ) { ++ return -ENODEV; ++ } ++ ++ // abort if this slot already active ++ if (bug_cam.active == slot) { ++ return 0; ++ } ++ ++ // if another slot is active, deactivate it. ++ if (bug_cam.active != -1) { ++ bcam = bug_cam.bcam [bug_cam.active]; ++ if ((bcam) && (bcam->deactivate)) { ++ bcam->deactivate (bcam); ++ } ++ } ++ ++ // activate this slot ++ bcam = bug_cam.bcam [slot]; ++ if (bcam->activate) { ++ bcam->activate (bcam, bug_cam.input_dev); ++ } ++ bug_cam.active = slot; ++ return 0; ++} ++ ++ ++// ioctl ++static int cntl_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct bmi_cam *bcam; ++ int err; ++ ++ switch (cmd) { ++ ++ // error if no camera selected. (active) ++ ++ case BMI_CAM_FLASH_LED_ON: ++ ++ bcam = get_selected(); ++ if ((bcam) && (bcam->cntl.flash_led_on)) { ++ bcam->cntl.flash_led_on (bcam); ++ } ++ return 0; ++ ++ case BMI_CAM_FLASH_LED_OFF: ++ ++ bcam = get_selected(); ++ if ((bcam) && (bcam->cntl.flash_led_off)) { ++ bcam->cntl.flash_led_off (bcam); ++ } ++ return 0; ++ ++ ++ case BMI_CAM_FLASH_HIGH_BEAM: ++ ++ bcam = get_selected(); ++ if ((bcam) && (bcam->cntl.flash_high_beam)) { ++ bcam->cntl.flash_high_beam (bcam); ++ } ++ return 0; ++ ++ case BMI_CAM_FLASH_LOW_BEAM: ++ ++ bcam = get_selected(); ++ if ((bcam) && (bcam->cntl.flash_low_beam)) { ++ bcam->cntl.flash_low_beam (bcam); ++ } ++ return 0; ++ ++ case BMI_CAM_RED_LED_OFF: ++ ++ bcam = get_selected(); ++ if ((bcam) && (bcam->cntl.red_led_off)) { ++ bcam->cntl.red_led_off (bcam); ++ } ++ return 0; ++ ++ case BMI_CAM_RED_LED_ON: ++ ++ bcam = get_selected(); ++ if ((bcam) && (bcam->cntl.red_led_on)) { ++ bcam->cntl.red_led_on (bcam); ++ } ++ return 0; ++ ++ case BMI_CAM_GREEN_LED_OFF: ++ ++ bcam = get_selected(); ++ if ((bcam) && (bcam->cntl.green_led_off)) { ++ bcam->cntl.green_led_off (bcam); ++ } ++ return 0; ++ ++ case BMI_CAM_GREEN_LED_ON: ++ ++ bcam = get_selected(); ++ if ((bcam) && (bcam->cntl.green_led_on)) { ++ bcam->cntl.green_led_on (bcam); ++ } ++ return 0; ++ ++ case BMI_CAM_SELECT: ++ ++ err = select_slot (arg); ++ return err; ++ ++ case BMI_CAM_GET_SELECTED: ++ ++ return (int) bug_cam.active; ++ ++ default: ++ return -ENOTTY; ++ } ++ return 0; ++} ++ ++ ++void bug_camera_set_color(int bright, int saturation, int red, int green, int blue) ++{ ++ //delegate to active bmi_cam. ++ ++ struct bmi_cam *bcam; ++ ++ if (bug_cam.active == -1) { ++ return; ++ } ++ ++ bcam = bug_cam.bcam [bug_cam.active]; ++ ++ if ((bcam) && (bcam->sensor.set_color)) { ++ bcam->sensor.set_color (bcam, bright, saturation, red, green, blue); ++ } ++ return; ++ ++} ++ ++void bug_camera_get_color(int *bright, int *saturation, int *red, int *green, int *blue) ++{ ++ //delegate to active bmi_cam. ++ ++ struct bmi_cam *bcam; ++ ++ if (bug_cam.active == -1) { ++ return; ++ } ++ ++ bcam = bug_cam.bcam [bug_cam.active]; ++ ++ if ((bcam) && (bcam->sensor.get_color)) { ++ bcam->sensor.get_color (bcam, bright, saturation, red, green, blue); ++ } ++ return; ++} ++ ++ ++ ++ ++void bug_camera_set_ae_mode (int ae_mode) ++{ ++ //delegate to active bmi_cam. ++ printk (KERN_ERR " bug_camera_set_ae_mode() - NOT IMPLEMENTED.\n"); ++} ++ ++ ++void bug_camera_get_ae_mode (int *ae_mode) ++{ ++ //delegate to active bmi_cam. ++ printk (KERN_ERR " bug_camera_set_ae_mode() - NOT IMPLEMENTED.\n"); ++} ++ ++ ++sensor_interface * bug_camera_config (int *frame_rate, int high_quality) ++{ ++ //delegate to active bmi_cam. ++ ++ struct bmi_cam *bcam; ++ sensor_interface *sensor_if = 0; ++ ++ if (bug_cam.active == -1) { ++ return 0; ++ } ++ ++ bcam = bug_cam.bcam [bug_cam.active]; ++ ++ if ((bcam) && (bcam->sensor.config)) { ++ sensor_if = bcam->sensor.config (bcam, frame_rate, high_quality); ++ } ++ return sensor_if; ++} ++ ++ ++sensor_interface * bug_camera_reset (void) ++{ ++ ++ //delegate to active bmi_cam. ++ ++ struct bmi_cam *bcam; ++ sensor_interface *sensor_if = 0; ++ ++ if (bug_cam.active == -1) { ++ return 0; ++ } ++ ++ bcam = bug_cam.bcam [bug_cam.active]; ++ ++ if ((bcam) && (bcam->sensor.reset)) { ++ sensor_if = bcam->sensor.reset(bcam); ++ } ++ return sensor_if; ++} ++ ++void bug_camera_link_enable (void) ++{ ++ //delegate to active bmi_cam. ++ ++ struct bmi_cam *bcam; ++ ++ if (bug_cam.active == -1) { ++ return; ++ } ++ ++ bcam = bug_cam.bcam [bug_cam.active]; ++ ++ if ((bcam) && (bcam->link.enable)) { ++ bcam->link.enable(bcam); ++ } ++ return; ++} ++ ++void bug_camera_link_disable (void) ++{ ++ //delegate to active bmi_cam. ++ ++ struct bmi_cam *bcam; ++ ++ if (bug_cam.active == -1) { ++ return; ++ } ++ ++ bcam = bug_cam.bcam [bug_cam.active]; ++ ++ if ((bcam) && (bcam->link.disable)) { ++ bcam->link.disable(bcam); ++ } ++ return; ++} ++ ++ ++// Link point for bug_v4l2_capture ++ ++struct camera_sensor camera_sensor_if = { ++ ++ set_color: bug_camera_set_color, ++ get_color: bug_camera_get_color, ++ config: bug_camera_config, ++ reset: bug_camera_reset, ++}; ++ ++ ++struct camera_link camera_link_if = { ++ enable: bug_camera_link_enable, ++ disable: bug_camera_link_disable, ++ ++}; ++ ++int register_bug_camera( struct bmi_cam *bcam, int slot) ++{ ++ printk (KERN_ERR "register_bug_camera() - slot = %d\n", slot); ++ ++ if (!bcam) { ++ return -1; ++ } ++ if ((slot < 0) || (slot > 3)) { ++ return -1; ++ } ++ if ( bug_cam.bcam [slot]) { ++ return -1; ++ } ++ else { ++ bug_cam.bcam [slot] = bcam; ++ bug_cam.cam_cnt += 1; ++ } ++ ++ if (ctl_probe(&bug_cam.cntl[slot], slot)) { ++ printk(KERN_ERR "\n"); ++ } ++ // Activate this camera if no other is active ++ if ( bug_cam.active == -1) { ++ bug_cam.active = slot; ++ bcam->activate( bcam, bug_cam.input_dev); ++ } ++ ++ return 0; ++ ++} ++ ++int unregister_bug_camera( struct bmi_cam *bcam, int slot) ++{ ++ ++ if (!bcam) { ++ return -1; ++ } ++ if ((slot < 0) || (slot > 3)) { ++ return -1; ++ } ++ if ( bug_cam.bcam [slot] != bcam) { ++ return -1; ++ } ++ else { ++ bug_cam.bcam [slot] = 0; ++ bug_cam.cam_cnt -= 1; ++ ++ // Deactivate this camera if active ++ ++ if (bug_cam.active == slot) { ++ bcam->deactivate( bcam); ++ bug_cam.active = -1; ++ } ++ ++ } ++ return 0; ++} ++ ++static __init int bug_camera_init(void) ++{ ++ int err = 0; ++ struct class *bmi_class; ++ ++ printk("BUG Camera Driver v%s \n", BUG_CAMERA_VERSION); ++ ++ memset (&bug_cam, 0, sizeof(struct bug_cam)); ++ ++ //No camera is active. ++ bug_cam.active = -1; ++ ++ //No cameras registered. ++ bug_cam.cam_cnt = 0; ++ ++ // Allocate and Register input device. ++ ++ // allocate input device ++ bug_cam.input_dev = input_allocate_device(); ++ if (!bug_cam.input_dev) { ++ printk(KERN_ERR "bug_camera_init: Can't allocate input_dev\n"); ++ err = -ENOMEM; ++ goto exit; ++ } ++ ++ // set up input device ++ bug_cam.input_dev->name = "bug_cam"; ++ bug_cam.input_dev->phys = "bug_cam"; ++ bug_cam.input_dev->id.bustype = BUS_BMI; ++ //bug_cam.input_dev->private = &bug_cam; ++ bug_cam.input_dev->evbit[0] = BIT(EV_KEY); ++ bug_cam.input_dev->keybit[BIT_WORD(BN_SHUTTER)] = BIT_MASK(BN_SHUTTER) | ++ BIT_MASK(BN_ZOOMIN) | ++ BIT_MASK(BN_ZOOMOUT); ++ // register input device ++ err = input_register_device (bug_cam.input_dev); ++ if (err) { ++ printk(KERN_ERR ++ "bug_camera_init() - input_register_device failed.\n"); ++ input_free_device(bug_cam.input_dev); ++ goto exit; ++ } ++ ++ //Register character device. ++ /* ++ // allocate char device number ++ err = alloc_chrdev_region (&bug_cam.cntl_devno, 0, 1, ++ "bug_camera_control"); ++ if (err < 0) { ++ printk(KERN_ERR "bug_camera_init(): alloc_chrdev_region failed.\n"); ++ goto err_exit; ++ } ++ ++ // init and add control character device ++ cdev_init (&bug_cam.cntl, &cntl_fops); ++ ++ err = cdev_add (&bug_cam.cntl, bug_cam.cntl_devno, 1); ++ if (err ) { ++ printk(KERN_ERR "bmi_camera_init(): cdev_add failed\n"); ++ goto err_exit2; ++ } ++ ++ // create class device ++ bmi_class = bmi_get_bmi_class (); ++ ++ bug_cam.class_dev = device_create (bmi_class, NULL, bug_cam.cntl_devno, &bug_cam, "bug_camera_control"); ++ ++ if (IS_ERR(bug_cam.class_dev)) { ++ printk(KERN_ERR "Unable to create " ++ "class_device for bug_camera; errno = %ld\n", ++ PTR_ERR(bug_cam.class_dev)); ++ bug_cam.class_dev = NULL; ++ goto err_exit2; ++ } ++ */ ++ goto exit; ++ ++err_exit2: ++ unregister_chrdev_region (bug_cam.cntl_devno, 1); ++err_exit: ++ input_unregister_device (bug_cam.input_dev); ++exit: ++ return err; ++} ++ ++static void __exit bug_camera_clean(void) ++{ ++ /* struct class *bmi_class; ++ ++ bmi_class = bmi_get_bmi_class (); ++ device_destroy (bmi_class, bug_cam.cntl_devno);*/ ++ ++ bug_cam.class_dev = 0; ++ // Unregister character device. ++ unregister_chrdev_region (bug_cam.cntl_devno, 1); ++ ++ // Unregister input device. ++ input_unregister_device (bug_cam.input_dev); ++ ++// input_free_device (bug_cam.input_dev); ++ return; ++} ++ ++ ++module_init(bug_camera_init); ++module_exit(bug_camera_clean); ++ ++// Exported symbols ++EXPORT_SYMBOL(camera_sensor_if); ++EXPORT_SYMBOL(camera_link_if); ++EXPORT_SYMBOL(register_bug_camera); ++EXPORT_SYMBOL(unregister_bug_camera); ++ ++MODULE_AUTHOR("EnCADIS Design, Inc."); ++MODULE_DESCRIPTION("Bug Camera Driver"); ++MODULE_LICENSE("GPL"); ++ +--- /dev/null ++++ git/drivers/bmi/pims/camera/bug_camera.h +@@ -0,0 +1,72 @@ ++#ifndef BUG_CAMARA_H ++#define BUG_CAMARA_H ++ ++#include ++#include ++ ++ ++struct bmi_cam; ++struct input_dev; ++ ++# if 1 ++struct bmi_camera_sensor { ++ ++ void (*set_color) (struct bmi_cam *bcam, int bright, int saturation, int red, int green, ++ int blue); ++ ++ void (*get_color) (struct bmi_cam *bcam, int *bright, int *saturation, int *red, int *green, ++ int *blue); ++ ++ void (*set_ae_mode) (struct bmi_cam *bcam, int ae_mode); ++ void (*get_ae_mode) (struct bmi_cam *bcam, int *ae_mode); ++ sensor_interface *(*config) (struct bmi_cam *bcam, int *frame_rate, int high_quality); ++ sensor_interface *(*reset) (struct bmi_cam *bcam); ++}; ++ ++struct bmi_camera_link { ++ ++ void (*enable) (struct bmi_cam *bcam); ++ void (*disable) (struct bmi_cam *bcam); ++ ++}; ++# endif ++ ++struct bmi_camera_cntl { ++ ++ int (*flash_led_on) (struct bmi_cam *bcam); ++ int (*flash_led_off) (struct bmi_cam *bcam); ++ int (*flash_high_beam) (struct bmi_cam *bcam); ++ int (*flash_low_beam ) (struct bmi_cam *bcam); ++ int (*red_led_off) (struct bmi_cam *bcam); ++ int (*red_led_on) (struct bmi_cam *bcam); ++ int (*green_led_off) (struct bmi_cam *bcam); ++ int (*green_led_on) (struct bmi_cam *bcam); ++ ++}; ++ ++struct bmi_cam { ++ ++ sensor_interface interface; // pointer to this struct is returned by config() ++ ++ struct bmi_camera_sensor sensor; // v4l function pointers ++ ++ struct bmi_camera_link link; // bug link control function pointers ++ ++ struct bmi_camera_cntl cntl; // bmi camera control function pointers ++ ++ ++ int (*activate) (struct bmi_cam *cam, struct input_dev *idev); ++ ++ int (*deactivate) (struct bmi_cam *cam); ++ ++ ++}; ++ ++ ++ ++int register_bug_camera( struct bmi_cam *bcam, int slot); ++int unregister_bug_camera( struct bmi_cam *bcam, int slot); ++ ++ ++#endif ++ +--- /dev/null ++++ git/drivers/bmi/pims/camera/ov2640.c +@@ -0,0 +1,301 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* I2C Slave Address */ ++#define OV2640_I2C_ADDRESS 0x30 // 7-bit address ++ ++ ++int ov2640_ReadByte(struct i2c_adapter *adap, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ ++ /* Read Byte with 8-Bit Pointer */ ++ ++ rmsg[0].addr = OV2640_I2C_ADDRESS; ++ rmsg[0].flags = 0; /* write */ ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = OV2640_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; /* read */ ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ++ ret = i2c_transfer(adap, rmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "ov2640_ReadByte() - i2c_transfer failed.\n"); ++ //Rework: add conditional debug messages here ++ ret = -1; ++ } ++ return ret; ++} ++ ++int ov2640_WriteByte(struct i2c_adapter *adap, unsigned char addr, unsigned char offset, unsigned char data) ++{ ++ int ret; ++ struct i2c_msg wmsg; ++ int num_msgs; ++ ++ char buf[2]; ++ ++ buf[0] = (char)offset; ++ buf[1] = (char)data; ++ ++ ++ wmsg.addr = addr >> 1; ++ wmsg.flags = 0; /* write */ ++ wmsg.len = 2; ++ wmsg.buf = buf; ++ num_msgs = 1; ++ ++ ret = i2c_transfer (adap, &wmsg, num_msgs); ++ ++ if (ret == 1) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "ov2640_WriteByte() - i2c_transfer failed.\n"); ++ //Rework: add conditional debug messages here ++ ret = -1; ++ } ++ return ret; ++} ++ ++ ++void load_2640_12MHZ_Initial_UXGA_YUV (struct i2c_adapter *adap) ++ ++{ ++ ++ // ;2640_Initial_100206.ovt ++ ov2640_WriteByte (adap, 0x60, 0xff, 0x01); ++ ov2640_WriteByte (adap, 0x60, 0x12, 0x80); ++ ++ msleep(1); // delay 1ms ++ ++ ov2640_WriteByte (adap, 0x60, 0xff, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x2c, 0xff); ++ ov2640_WriteByte (adap, 0x60, 0x2e, 0xdf); ++ ov2640_WriteByte (adap, 0x60, 0xff, 0x01); ++ ov2640_WriteByte (adap, 0x60, 0x3c, 0x32); ++// ov2640_WriteByte (adap, 0x60, 0x11, 0x01); //7.5fps); ++ ov2640_WriteByte (adap, 0x60, 0x11, 0x00); //7.5fps for 48; ++ ov2640_WriteByte (adap, 0x60, 0x09, 0x02); ++ ov2640_WriteByte (adap, 0x60, 0x04, 0x28); ++ ov2640_WriteByte (adap, 0x60, 0x13, 0xe5); ++ ov2640_WriteByte (adap, 0x60, 0x14, 0x48); ++ ov2640_WriteByte (adap, 0x60, 0x2c, 0x0c); ++ ov2640_WriteByte (adap, 0x60, 0x33, 0x78); ++ ov2640_WriteByte (adap, 0x60, 0x3a, 0x33); ++ ov2640_WriteByte (adap, 0x60, 0x3b, 0xfb); ++ ov2640_WriteByte (adap, 0x60, 0x3e, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x43, 0x11); ++ ov2640_WriteByte (adap, 0x60, 0x16, 0x10); ++ ov2640_WriteByte (adap, 0x60, 0x39, 0x02); ++ ov2640_WriteByte (adap, 0x60, 0x35, 0x88); ++ ov2640_WriteByte (adap, 0x60, 0x22, 0x0a); ++ ov2640_WriteByte (adap, 0x60, 0x37, 0x40); ++ ov2640_WriteByte (adap, 0x60, 0x23, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x34, 0xa0); ++ ov2640_WriteByte (adap, 0x60, 0x36, 0x1a); ++ ov2640_WriteByte (adap, 0x60, 0x06, 0x02); ++ ov2640_WriteByte (adap, 0x60, 0x07, 0xc0); ++ ov2640_WriteByte (adap, 0x60, 0x0d, 0xb7); ++ ov2640_WriteByte (adap, 0x60, 0x0e, 0x01); ++ ov2640_WriteByte (adap, 0x60, 0x4c, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x4a, 0x81); ++ ov2640_WriteByte (adap, 0x60, 0x21, 0x99); ++ ov2640_WriteByte (adap, 0x60, 0x24, 0x3a); ++ ov2640_WriteByte (adap, 0x60, 0x25, 0x32); ++ ov2640_WriteByte (adap, 0x60, 0x26, 0x82); ++ ov2640_WriteByte (adap, 0x60, 0x5c, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x63, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x5d, 0x55); ++ ov2640_WriteByte (adap, 0x60, 0x5e, 0x7d); ++ ov2640_WriteByte (adap, 0x60, 0x5f, 0x7d); ++ ov2640_WriteByte (adap, 0x60, 0x60, 0x55); ++ ov2640_WriteByte (adap, 0x60, 0x61, 0x70); ++ ov2640_WriteByte (adap, 0x60, 0x62, 0x80); ++ ov2640_WriteByte (adap, 0x60, 0x7c, 0x05); ++ ov2640_WriteByte (adap, 0x60, 0x20, 0x80); ++ ov2640_WriteByte (adap, 0x60, 0x28, 0x30); ++ ov2640_WriteByte (adap, 0x60, 0x6c, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x6d, 0x80); ++ ov2640_WriteByte (adap, 0x60, 0x6e, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x70, 0x02); ++ ov2640_WriteByte (adap, 0x60, 0x71, 0x94); ++ ov2640_WriteByte (adap, 0x60, 0x73, 0xc1); ++// ov2640_WriteByte (adap, 0x60, 0x3d, 0x28); //12MHz XVCLK ++ ov2640_WriteByte (adap, 0x60, 0x3d, 0x30); //12MHz XVCLK -> 48 MHz); ++// ov2640_WriteByte (adap, 0x60, 0x3d, 0x38); //12MHz XVCLK -> 24 MHz); //MTW ++ ov2640_WriteByte (adap, 0x60, 0x5a, 0x57); ++ ov2640_WriteByte (adap, 0x60, 0x4f, 0xbb); ++ ov2640_WriteByte (adap, 0x60, 0x50, 0x9c); ++ ov2640_WriteByte (adap, 0x60, 0x12, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x17, 0x11); ++ ov2640_WriteByte (adap, 0x60, 0x18, 0x76); //M+ ++ ov2640_WriteByte (adap, 0x60, 0x19, 0x01); ++ ov2640_WriteByte (adap, 0x60, 0x1a, 0x97); ++ ov2640_WriteByte (adap, 0x60, 0x32, 0x36); ++ ++ ov2640_WriteByte (adap, 0x60, 0xff, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0xe5, 0x7f); ++ ov2640_WriteByte (adap, 0x60, 0xf9, 0xc0); ++ ov2640_WriteByte (adap, 0x60, 0x41, 0x24); ++ ov2640_WriteByte (adap, 0x60, 0xe0, 0x14); ++ ov2640_WriteByte (adap, 0x60, 0x76, 0xff); ++ ov2640_WriteByte (adap, 0x60, 0x33, 0xa0); ++ ov2640_WriteByte (adap, 0x60, 0x42, 0x20); ++ ov2640_WriteByte (adap, 0x60, 0x43, 0x18); ++ ov2640_WriteByte (adap, 0x60, 0x4c, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x87, 0xd0); ++ ov2640_WriteByte (adap, 0x60, 0x88, 0x3f); ++ ov2640_WriteByte (adap, 0x60, 0xd7, 0x03); ++ ov2640_WriteByte (adap, 0x60, 0xd9, 0x10); ++ ov2640_WriteByte (adap, 0x60, 0xd3, 0x82); ++ ov2640_WriteByte (adap, 0x60, 0xc8, 0x08); ++ ov2640_WriteByte (adap, 0x60, 0xc9, 0x80); ++ ov2640_WriteByte (adap, 0x60, 0x7c, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x7d, 0x02); ++ ov2640_WriteByte (adap, 0x60, 0x7c, 0x03); ++ ov2640_WriteByte (adap, 0x60, 0x7d, 0x48); ++ ov2640_WriteByte (adap, 0x60, 0x7d, 0x48); ++ ov2640_WriteByte (adap, 0x60, 0x7c, 0x08); ++ ov2640_WriteByte (adap, 0x60, 0x7d, 0x20); ++ ov2640_WriteByte (adap, 0x60, 0x7d, 0x10); ++ ov2640_WriteByte (adap, 0x60, 0x7d, 0x0e); ++ ov2640_WriteByte (adap, 0x60, 0x90, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x91, 0x0e); ++ ov2640_WriteByte (adap, 0x60, 0x91, 0x1a); ++ ov2640_WriteByte (adap, 0x60, 0x91, 0x31); ++ ov2640_WriteByte (adap, 0x60, 0x91, 0x5a); ++ ov2640_WriteByte (adap, 0x60, 0x91, 0x69); ++ ov2640_WriteByte (adap, 0x60, 0x91, 0x75); ++ ov2640_WriteByte (adap, 0x60, 0x91, 0x7e); ++ ov2640_WriteByte (adap, 0x60, 0x91, 0x88); ++ ov2640_WriteByte (adap, 0x60, 0x91, 0x8f); ++ ov2640_WriteByte (adap, 0x60, 0x91, 0x96); ++ ov2640_WriteByte (adap, 0x60, 0x91, 0xa3); ++ ov2640_WriteByte (adap, 0x60, 0x91, 0xaf); ++ ov2640_WriteByte (adap, 0x60, 0x91, 0xc4); ++ ov2640_WriteByte (adap, 0x60, 0x91, 0xd7); ++ ov2640_WriteByte (adap, 0x60, 0x91, 0xe8); ++ ov2640_WriteByte (adap, 0x60, 0x91, 0x20); ++ ov2640_WriteByte (adap, 0x60, 0x92, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x93, 0x06); ++ ov2640_WriteByte (adap, 0x60, 0x93, 0xe3); ++ ov2640_WriteByte (adap, 0x60, 0x93, 0x05); ++ ov2640_WriteByte (adap, 0x60, 0x93, 0x05); ++ ov2640_WriteByte (adap, 0x60, 0x93, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x93, 0x02); ++ ov2640_WriteByte (adap, 0x60, 0x93, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x93, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x93, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x93, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x93, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x93, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x93, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x96, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x97, 0x08); ++ ov2640_WriteByte (adap, 0x60, 0x97, 0x19); ++ ov2640_WriteByte (adap, 0x60, 0x97, 0x02); ++ ov2640_WriteByte (adap, 0x60, 0x97, 0x0c); ++ ov2640_WriteByte (adap, 0x60, 0x97, 0x24); ++ ov2640_WriteByte (adap, 0x60, 0x97, 0x30); ++ ov2640_WriteByte (adap, 0x60, 0x97, 0x28); ++ ov2640_WriteByte (adap, 0x60, 0x97, 0x26); ++ ov2640_WriteByte (adap, 0x60, 0x97, 0x02); ++ ov2640_WriteByte (adap, 0x60, 0x97, 0x98); ++ ov2640_WriteByte (adap, 0x60, 0x97, 0x80); ++ ov2640_WriteByte (adap, 0x60, 0x97, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x97, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0xc3, 0xed); ++ ov2640_WriteByte (adap, 0x60, 0xa4, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0xa8, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0xc5, 0x11); ++ ov2640_WriteByte (adap, 0x60, 0xc6, 0x51); ++ ov2640_WriteByte (adap, 0x60, 0xbf, 0x80); ++ ov2640_WriteByte (adap, 0x60, 0xc7, 0x10); ++ ov2640_WriteByte (adap, 0x60, 0xb6, 0x66); ++ ov2640_WriteByte (adap, 0x60, 0xb8, 0xa5); ++ ov2640_WriteByte (adap, 0x60, 0xb7, 0x64); ++ ov2640_WriteByte (adap, 0x60, 0xb9, 0x7c); ++ ov2640_WriteByte (adap, 0x60, 0xb3, 0xaf); ++ ov2640_WriteByte (adap, 0x60, 0xb4, 0x97); ++ ov2640_WriteByte (adap, 0x60, 0xb5, 0xff); ++ ov2640_WriteByte (adap, 0x60, 0xb0, 0xc5); ++ ov2640_WriteByte (adap, 0x60, 0xb1, 0x94); ++ ov2640_WriteByte (adap, 0x60, 0xb2, 0x0f); ++ ov2640_WriteByte (adap, 0x60, 0xc4, 0x5c); ++// ++ ov2640_WriteByte (adap, 0x60, 0xc0, 0xca); //M+ ++ ov2640_WriteByte (adap, 0x60, 0xc1, 0x96); ++ ov2640_WriteByte (adap, 0x60, 0x8c, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x86, 0x3d); //2M ++ ov2640_WriteByte (adap, 0x60, 0x50, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x51, 0x90); ++ ov2640_WriteByte (adap, 0x60, 0x52, 0x2c); ++ ov2640_WriteByte (adap, 0x60, 0x53, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x54, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x55, 0x88); ++ ov2640_WriteByte (adap, 0x60, 0x57, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x5a, 0x90); ++ ov2640_WriteByte (adap, 0x60, 0x5b, 0x2c); ++ ov2640_WriteByte (adap, 0x60, 0x5c, 0x05); ++// ++ ov2640_WriteByte (adap, 0x60, 0xc3, 0xed); ++ ov2640_WriteByte (adap, 0x60, 0x7f, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0xda, 0x01); //UYVY ++ ov2640_WriteByte (adap, 0x60, 0xd3, 0x82); ++ ov2640_WriteByte (adap, 0x60, 0xe5, 0x1f); ++ ov2640_WriteByte (adap, 0x60, 0xe1, 0x67); ++ ov2640_WriteByte (adap, 0x60, 0xe0, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0xdd, 0x7f); ++ ov2640_WriteByte (adap, 0x60, 0x05, 0x00); ++// ov2640_WriteByte (adap, 0x60, 0xff, 0x01); ++} ++ ++void load_2640_UXGA(struct i2c_adapter *adap) ++{ ++ ++// ;1600x1200 ++ ov2640_WriteByte (adap, 0x60, 0xc0, 0xca); //M+ ++ ov2640_WriteByte (adap, 0x60, 0xc1, 0x96); ++ ov2640_WriteByte (adap, 0x60, 0x8c, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x86, 0x3d); //2M ++ ov2640_WriteByte (adap, 0x60, 0x50, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x51, 0x90); ++ ov2640_WriteByte (adap, 0x60, 0x52, 0x2c); ++ ov2640_WriteByte (adap, 0x60, 0x53, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x54, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x55, 0x88); ++ ov2640_WriteByte (adap, 0x60, 0x57, 0x00); ++ ov2640_WriteByte (adap, 0x60, 0x5a, 0x90); ++ ov2640_WriteByte (adap, 0x60, 0x5b, 0x2c); ++ ov2640_WriteByte (adap, 0x60, 0x5c, 0x05); ++} ++ ++ ++ ++ ++void ov2640_patch (struct i2c_adapter *adap) ++{ ++ load_2640_12MHZ_Initial_UXGA_YUV (adap); ++ load_2640_UXGA(adap); ++ ++} ++ +--- /dev/null ++++ git/drivers/bmi/pims/camera/ov2640.h +@@ -0,0 +1,14 @@ ++#ifndef VS6624_ACCESS_H ++#define VS6624_ACCESS_H ++ ++#include ++ ++void ov2640_patch (struct i2c_adapter *adap); ++ ++int vs6624_ReadByte(struct i2c_adapter *adap, unsigned short offset, unsigned char *data); ++int vs6624_WriteByte(struct i2c_adapter *adap, unsigned short offset, unsigned char data); ++int vs6624_WriteSequence(struct i2c_adapter *adap, const unsigned short array[][2], unsigned short len); ++void vs6624_dump_regs(struct i2c_adapter *adap); ++ ++#endif ++ +--- /dev/null ++++ git/drivers/bmi/pims/camera/vs6624_access.c +@@ -0,0 +1,597 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "vs6624_regs.h" ++ ++# include "vs6624_patch.c" ++ ++ ++int vs6624_ReadByte(struct i2c_adapter *adap, unsigned short offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ char buf[2]; ++ ++ buf[0] = (offset & 0xFF00) >> 8; ++ buf[1] = (offset & 0x00FF); ++ ++ /* Read Byte with 16-Bit Pointer */ ++ ++ rmsg[0].addr = VS6624_I2C_ADDRESS; ++ rmsg[0].flags = 0; /* write */ ++ rmsg[0].len = 2; ++ rmsg[0].buf = buf; ++ ++ rmsg[1].addr = VS6624_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; /* read */ ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ++ ret = i2c_transfer(adap, rmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "vs6624_ReadByte() - i2c_transfer failed.\n"); ++ //Rework: add conditional debug messages here ++ ret = -1; ++ } ++ return ret; ++} ++ ++int vs6624_WriteByte(struct i2c_adapter *adap, unsigned short offset, unsigned char data) ++{ ++ int ret; ++ char buf[2]; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ buf[0] = (offset & 0xFF00) >> 8; ++ buf[1] = (offset & 0x00FF); ++ ++ wmsg[0].addr = VS6624_I2C_ADDRESS; ++ wmsg[0].flags = 0; /* write */ ++ wmsg[0].len = 2; ++ wmsg[0].buf = buf; ++ ++ wmsg[1].addr = VS6624_I2C_ADDRESS; ++ wmsg[1].flags = 0; /* write */ ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ ret = i2c_transfer (adap, wmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "vs6624_WriteByte() - i2c_transfer failed.\n"); ++ //Rework: add conditional debug messages here ++ ret = -1; ++ } ++ return ret; ++} ++ ++int vs6624_WriteSequence(struct i2c_adapter *adap, const unsigned short array[][2], unsigned short len) ++{ ++ u16 x; ++ ++ for (x = 0; x < len; x++) ++ vs6624_WriteByte (adap, array[x][0], (unsigned char) array[x][1]); ++ ++ return 0; ++} ++ ++ ++static unsigned char get_reg(struct i2c_adapter *adap, unsigned short offset) ++{ ++ unsigned char buf[1]; ++ ++ vs6624_ReadByte (adap, offset, &buf[0]); ++ ++ return buf[0]; ++} ++ ++void ++vs6624_set_color(struct i2c_adapter *adap, int bright, int saturation, int red, int green, int blue) ++{ ++ switch (saturation) { ++ case 150: ++ vs6624_WriteByte(adap, bColourSaturation0, 0xFF & 0xFF); ++ break; ++ case 75: ++ vs6624_WriteByte(adap, bColourSaturation0, 0xC0 & 0xFF); ++ break; ++ case 50: ++ vs6624_WriteByte(adap, bColourSaturation0, 0x80 & 0xFF); ++ break; ++ case 25: ++ vs6624_WriteByte(adap, bColourSaturation0, 0x40 & 0xFF); ++ break; ++ default: ++ vs6624_WriteByte(adap, bColourSaturation0, 0x78 & 0xFF); ++ break; ++ } ++} ++ ++void ++vs6624_get_color(struct i2c_adapter *adap, int *bright, int *saturation, int *red, int *green, int *blue) ++{ ++ *saturation = (int) get_reg( adap, bColourSaturation0); ++ switch (*saturation) { ++ case 0xFF: ++ *saturation = 150; ++ break; ++ case 0xC0: ++ *saturation = 75; ++ break; ++ case 0x80: ++ *saturation = 50; ++ break; ++ case 0x40: ++ *saturation = 25; ++ break; ++ default: ++ *saturation = 100; ++ break; ++ } ++} ++ ++ ++ ++static int vs_probe(struct i2c_adapter *adap) ++{ ++ ++ unsigned char buf[2]; ++ ++ vs6624_ReadByte (adap, DeviceID_MSB, &buf[0]); ++ vs6624_ReadByte (adap, DeviceID_LSB, &buf[1]); ++ ++ if ((((buf[0] & 0xFF) << 8) | (buf[1] & 0xFF)) == VS6624_ID) { ++ ++ printk(KERN_INFO "%s: Firmware Version %d.%d \n", ++ SENSOR_NAME, get_reg(adap, bFirmwareVsnMajor), get_reg (adap, bFirmwareVsnMinor)); ++ printk(KERN_INFO "%s: Patch Version %d.%d \n", ++ SENSOR_NAME, get_reg(adap, bPatchVsnMajor), get_reg(adap, bPatchVsnMinor)); ++ ++ return 0; ++ } ++ ++ printk (KERN_ERR "vs_probe: No VS6624 found.\n"); ++ printk (KERN_ERR "vs_probe: buf[0] = 0x%x\n", (buf[0] & 0xFF) << 8); ++ printk (KERN_ERR "vs_probe: buf[1] = 0x%x\n", (buf[1] & 0xFF)); ++ printk (KERN_ERR "vs_probe: DeviceID = %d\n", ((buf[0] & 0xFF) << 8) | (buf[1] & 0xFF)); ++ ++ return -ENODEV; ++} ++ ++void vs6624_patch (struct i2c_adapter *adap) ++{ ++ printk (KERN_ERR "vs6624_patch() - enter\n"); ++ msleep(100); ++ ++ vs6624_WriteByte (adap, PWR_MAN_SETUP_MODE_SELECT, 0x0); ++ msleep(10); ++ vs_probe (adap); ++ ++ printk (KERN_ERR "vs6624_patch() - applying patch p1\n"); ++ vs6624_WriteSequence (adap, patch_p1, sizeof(patch_p1) / (sizeof(u16) * 2)); ++ msleep(50); ++ ++ printk (KERN_ERR "vs6624_patch() - applying patch p2\n"); ++ vs6624_WriteSequence (adap, patch_p2, sizeof(patch_p2) / (sizeof(u16) * 2)); ++ ++ vs6624_WriteByte (adap, PWR_MAN_SETUP_MODE_SELECT, 0x2); ++ msleep(100); ++ ++ vs6624_WriteByte (adap, PWR_MAN_DIO_ENABLE, 0x1); ++ msleep(1); ++ ++ printk(KERN_INFO "MODE: %d \n", get_reg(adap, bState)); //pjg ++ ++ vs_probe (adap); ++ ++ ++ // Flicker correction ++ vs6624_WriteByte (adap, bLightingFrequencyHz, 0x64); // AC frequency == 100 ++ ++ // Pan step size ++ vs6624_WriteByte (adap, uwPanStepHSizeMSB0, 0x0); // H pan step == 15 ++ vs6624_WriteByte (adap, uwPanStepHSizeLSB0, 0xf); ++ vs6624_WriteByte (adap, uwPanStepVSizeMSB0, 0x0); // V pan step == 15 ++ vs6624_WriteByte (adap, uwPanStepVSizeLSB0, 0xf); ++ ++ vs6624_WriteByte (adap, bSyncCodeSetup, 0x21); // SYNC //pjg ++ vs6624_WriteByte (adap, bHSyncSetup, 0xF); // Active lines only, Automatic //pjg ++ vs6624_WriteByte (adap, bVSyncSetup, 0x7); // Active lines only, Automatic //pjg ++ ++ vs6624_WriteByte (adap, uwDesiredFrameRate_Num_MSB, 0x0); ++ vs6624_WriteByte (adap, uwDesiredFrameRate_Num_LSB, 0x0F); // frame rate numerator == 15 MTW ++ vs6624_WriteByte (adap, bDesiredFrameRate_Den, 0x1); // frame rate denominator == 1 ++ ++ printk(KERN_INFO "MODE: %d \n", get_reg(adap, bState)); //pjg ++ ++ vs6624_WriteByte (adap, uwExternalClockFrequencyMhzNumeratorMSB, 0x0); ++ vs6624_WriteByte (adap, uwExternalClockFrequencyMhzNumeratorLSB, 12); ++ vs6624_WriteByte (adap, bExternalClockFrequencyMhzDenominator, 0x1); ++ ++ vs6624_WriteByte (adap, bPClkSetup, 0x85); // Pix Clk Mode == free run ++ ++ printk(KERN_INFO "MODE: %d \n", get_reg(adap, bState)); //pjg ++ vs6624_WriteByte (adap, bUserCommand, 0x2); // RUN ++ ++ printk(KERN_INFO "MODE: %d \n", get_reg(adap, bState)); //pjg ++ printk (KERN_ERR "vs6624_patch() - writing setup patch\n"); ++ vs6624_WriteSequence (adap, patch_run_setup, sizeof(patch_run_setup) / (sizeof(u16) * 2)); ++ ++ ++ printk(KERN_INFO "MODE: %d \n", get_reg(adap, bState)); //pjg ++ ++ vs_probe (adap); //pjg ++ printk (KERN_ERR "vs6624_patch() - exit\n"); ++ return; ++} ++ ++ ++ ++static int ReadByteV(struct i2c_adapter *adap, unsigned short offset, char* name) ++{ ++ unsigned char tmp[1]; ++ vs6624_ReadByte(adap, offset, &tmp[0]); ++ printk (KERN_ERR "vs6624 offset = %04X, data = %02X %s\n", offset, tmp[0], name); ++ return 0; ++ ++} ++ ++ ++void vs6624_dump_regs(struct i2c_adapter *adap) ++{ ++ ++ printk (KERN_ERR "vs6624_dump_regs() - enter\n"); ++ ++ ReadByteV(adap, 0xc044,"PWR_MAN_DIO_ENABLE "); ++ ReadByteV(adap, 0x0001,"uwDeviceId "); ++ ReadByteV(adap, 0x0001,"DeviceID_MSB "); ++ ReadByteV(adap, 0x0002,"DeviceID_LSB "); ++ ReadByteV(adap, 0x0004,"bFirmwareVsnMajor "); ++ ReadByteV(adap, 0x0006,"bFirmwareVsnMinor "); ++ ReadByteV(adap, 0x0008,"bPatchVsnMajor "); ++ ReadByteV(adap, 0x000a,"bPatchVsnMinor "); ++ ReadByteV(adap, 0x0180,"bUserCommand "); ++ ReadByteV(adap, 0x0186,"bManualNextState "); ++ ReadByteV(adap, 0x0200,"bNextState "); ++ ReadByteV(adap, 0x0202,"bState "); ++ ReadByteV(adap, 0x0280,"fMeteringOn "); ++ ReadByteV(adap, 0x0282,"fExitOnStable "); ++ ReadByteV(adap, 0x0284,"bStreamLength "); ++ ReadByteV(adap, 0x0300,"fIsColdStart "); ++ ReadByteV(adap, 0x0302,"bNonViewLive_ActivePipeSetupBank "); ++ ReadByteV(adap, 0x0304,"bSnapShoot_ActivePipeSetupBank "); ++ ReadByteV(adap, 0x0306,"fSnapShoot_NoWaiting "); ++ ReadByteV(adap, 0x0308,"SensorMode "); ++ ReadByteV(adap, 0x0380,"bImageSize0 "); ++ ReadByteV(adap, 0x0383,"uwManualHSize0 "); ++ ReadByteV(adap, 0x0383,"uwManualHSizeMSB0 "); ++ ReadByteV(adap, 0x0384,"uwManualHSizeLSB0 "); ++ ReadByteV(adap, 0x0387,"uwManualVSize0 "); ++ ReadByteV(adap, 0x0387,"uwManualVSizeMSB0 "); ++ ReadByteV(adap, 0x0388,"uwManualVSizeLSB0 "); ++ ReadByteV(adap, 0x038b,"uwZoomStepHSize0 "); ++ ReadByteV(adap, 0x038b,"uwZoomStepHSizeMSB0 "); ++ ReadByteV(adap, 0x038c,"uwZoomStepHSizeLSB0 "); ++ ReadByteV(adap, 0x038f,"uwZoomStepVSize0 "); ++ ReadByteV(adap, 0x038f,"uwZoomStepVSizeMSB0 "); ++ ReadByteV(adap, 0x0390,"uwZoomStepVSizeLSB0 "); ++ ReadByteV(adap, 0x0392,"bZoomControl0 "); ++ ReadByteV(adap, 0x0395,"uwPanStepHSize0 "); ++ ReadByteV(adap, 0x0395,"uwPanStepHSizeMSB0 "); ++ ReadByteV(adap, 0x0396,"uwPanStepHSizeLSB0 "); ++ ReadByteV(adap, 0x0399,"uwPanStepVSize0 "); ++ ReadByteV(adap, 0x0399,"uwPanStepVSizeMSB0 "); ++ ReadByteV(adap, 0x039a,"uwPanStepVSizeLSB0 "); ++ ReadByteV(adap, 0x039c,"bPanControl0 "); ++ ReadByteV(adap, 0x039e,"bCropControl0 "); ++ ReadByteV(adap, 0x03a1,"uwManualCropHorizontalStart0 "); ++ ReadByteV(adap, 0x03a5,"uwManualCropHorizontalSize0 "); ++ ReadByteV(adap, 0x03a9,"uwManualCropVerticalStart0 "); ++ ReadByteV(adap, 0x03ad,"uwManualCropVerticalSize0 "); ++ ReadByteV(adap, 0x03a1,"bCropHStartMSB0 "); ++ ReadByteV(adap, 0x03a2,"bCropHStartLSB0 "); ++ ReadByteV(adap, 0x03a9,"bCropVStartMSB0 "); ++ ReadByteV(adap, 0x03aa,"bCropVStartLSB0 "); ++ ReadByteV(adap, 0x03a5,"bCropHSizeMSB0 "); ++ ReadByteV(adap, 0x03a6,"bCropHSizeLSB0 "); ++ ReadByteV(adap, 0x03ad,"bCropVSizeMSB0 "); ++ ReadByteV(adap, 0x03ae,"bCropVSizeLSB0 "); ++ ReadByteV(adap, 0x03b0,"bDataFormat0 "); ++ ReadByteV(adap, 0x03b2,"bBayerOutputAlignment0 "); ++ ReadByteV(adap, 0x03b4,"bContrast0 "); ++ ReadByteV(adap, 0x03b6,"bColourSaturation0 "); ++ ReadByteV(adap, 0x03b8,"bGamma0 "); ++ ReadByteV(adap, 0x03ba,"fHorizontalMirror0 "); ++ ReadByteV(adap, 0x03bc,"fVerticalFlip0 "); ++ ReadByteV(adap, 0x03be,"bChannelID0 "); ++ ReadByteV(adap, 0x0400,"bImageSize1 "); ++ ReadByteV(adap, 0x0403,"uwManualHSize1 "); ++ ReadByteV(adap, 0x0407,"uwManualVSize1 "); ++ ReadByteV(adap, 0x040b,"uwZoomStepHSize1 "); ++ ReadByteV(adap, 0x040f,"uwZoomStepVSize1 "); ++ ReadByteV(adap, 0x0412,"bZoomControl1 "); ++ ReadByteV(adap, 0x0415,"uwPanStepHSize1 "); ++ ReadByteV(adap, 0x0419,"uwPanStepVSize1 "); ++ ReadByteV(adap, 0x041c,"bPanControl1 "); ++ ReadByteV(adap, 0x041e,"bCropControl1 "); ++ ReadByteV(adap, 0x0421,"uwManualCropHorizontalStart1 "); ++ ReadByteV(adap, 0x0425,"uwManualCropHorizontalSize1 "); ++ ReadByteV(adap, 0x0429,"uwManualCropVerticalStart1 "); ++ ReadByteV(adap, 0x042d,"uwManualCropVerticalSize1 "); ++ ReadByteV(adap, 0x0421,"bCropHStartMSB1 "); ++ ReadByteV(adap, 0x0422,"bCropHStartLSB1 "); ++ ReadByteV(adap, 0x0429,"bCropVStartMSB1 "); ++ ReadByteV(adap, 0x042a,"bCropVStartLSB1 "); ++ ReadByteV(adap, 0x0425,"bCropHSizeMSB1 "); ++ ReadByteV(adap, 0x0426,"bCropHSizeLSB1 "); ++ ReadByteV(adap, 0x042d,"bCropVSizeMSB1 "); ++ ReadByteV(adap, 0x042e,"bCropVSizeLSB1 "); ++ ReadByteV(adap, 0x0430,"bDataFormat1 "); ++ ReadByteV(adap, 0x0432,"bBayerOutputAlignment1 "); ++ ReadByteV(adap, 0x0434,"bContrast1 "); ++ ReadByteV(adap, 0x0436,"bColourSaturation1 "); ++ ReadByteV(adap, 0x0438,"bGamma1 "); ++ ReadByteV(adap, 0x043a,"fHorizontalMirror1 "); ++ ReadByteV(adap, 0x043c,"fVerticalFlip1 "); ++ ReadByteV(adap, 0x043e,"bChannelID1 "); ++ ReadByteV(adap, 0x0480,"fEnable "); ++ ReadByteV(adap, 0x0482,"bInitialPipeSetupBank "); ++ ReadByteV(adap, 0x0500,"CurrentPipeSetupBank "); ++ ReadByteV(adap, 0x0580,"bTimeToPowerdown "); ++ ReadByteV(adap, 0x058a,"fVRegSleep "); ++ ReadByteV(adap, 0x058c,"fSmoothLineReading "); ++ ReadByteV(adap, 0x0605,"uwExternalClockFrequencyMhzNumerator "); ++ ReadByteV(adap, 0x0605,"uwExternalClockFrequencyMhzNumeratorMSB "); ++ ReadByteV(adap, 0x0606,"uwExternalClockFrequencyMhzNumeratorLSB "); ++ ReadByteV(adap, 0x0608,"bExternalClockFrequencyMhzDenominator "); ++ ReadByteV(adap, 0x0681,"fpExternalClockFrequencyMhz "); ++ ReadByteV(adap, 0x0880,"bSysClkMode "); ++ ReadByteV(adap, 0x0882,"bMode "); ++ ReadByteV(adap, 0x0c80,"bLightingFrequencyHz "); ++ ReadByteV(adap, 0x0c82,"fFlickerCompatibleFrameLength "); ++ ReadByteV(adap, 0x0d05,"fpFlickerFreePeriod_us "); ++ ReadByteV(adap, 0x0d08,"fAntiFlickerEnabled "); ++ ReadByteV(adap, 0x0d81,"uwDesiredFrameRate_Num "); ++ ReadByteV(adap, 0x0d81,"uwDesiredFrameRate_Num_MSB "); ++ ReadByteV(adap, 0x0d82,"uwDesiredFrameRate_Num_LSB "); ++ ReadByteV(adap, 0x0d84,"bDesiredFrameRate_Den "); ++ ReadByteV(adap, 0x0e01,"fpRequestedFrameRate_Hz "); ++ ReadByteV(adap, 0x0e01,"fpRequestedFrameRate_Hz_MSB "); ++ ReadByteV(adap, 0x0e02,"fpRequestedFrameRate_Hz_LSB "); ++ ReadByteV(adap, 0x0e05,"fpMaxFrameRate_Hz "); ++ ReadByteV(adap, 0x0e09,"fpMinFrameRate_Hz "); ++ ReadByteV(adap, 0x0e0c,"fChangePending "); ++ ReadByteV(adap, 0x0e0f,"uwRequiredFrameLength_lines "); ++ ReadByteV(adap, 0x0e12,"ClipFrameRate "); ++ ReadByteV(adap, 0x0e80,"fDisableFrameRateDamper "); ++ ReadByteV(adap, 0x0e82,"bImpliedGainThresholdLow_num "); ++ ReadByteV(adap, 0x0e84,"bImpliedGainThresholdLow_den "); ++ ReadByteV(adap, 0x0e86,"bImpliedGainThresholdHigh_num "); ++ ReadByteV(adap, 0x0e88,"bImpliedGainThresholdHigh_den "); ++ ReadByteV(adap, 0x0e8a,"bUserMinimumFrameRate_Hz "); ++ ReadByteV(adap, 0x0e8c,"bUserMaximumFrameRate_Hz "); ++ ReadByteV(adap, 0x0e8e,"bRelativeChange_num "); ++ ReadByteV(adap, 0x0e90,"bRelativeChange_den "); ++ ReadByteV(adap, 0x0e92,"fDivorceMinFrameRateFromMaxIntegration "); ++ ReadByteV(adap, 0x0f01,"fpImpliedGain "); ++ ReadByteV(adap, 0x0f05,"uwMaximumFrameLength_lines "); ++ ReadByteV(adap, 0x0f09,"uwMinimumFrameLength_lines "); ++ ReadByteV(adap, 0x0f0d,"uwFrameLengthChange_lines "); ++ ReadByteV(adap, 0x0f11,"fpDesiredAutomaticFrameRate_Hz "); ++ ReadByteV(adap, 0x0f15,"uwCurrentFrameLength_lines "); ++ ReadByteV(adap, 0x0f19,"uwDesiredFrameLength_lines "); ++ ReadByteV(adap, 0x0f1c,"fAutomaticFrameRateStable "); ++ ReadByteV(adap, 0x0f1e,"fAutomaticFrameRateClip "); ++ ReadByteV(adap, 0x0f81,"uwXOffset "); ++ ReadByteV(adap, 0x0f85,"uwYOffset "); ++ ReadByteV(adap, 0x0f89,"uwXSize "); ++ ReadByteV(adap, 0x0f8d,"uwYSize "); ++ ReadByteV(adap, 0x1180,"ExposureControls_bMode "); ++ ReadByteV(adap, 0x1182,"bExposureMetering "); ++ ReadByteV(adap, 0x1184,"bManualExposureTime_s_num "); ++ ReadByteV(adap, 0x1186,"bManualExposureTime_s_den "); ++ ReadByteV(adap, 0x1189,"fpManualDesiredExposureTime_us "); ++ ReadByteV(adap, 0x1190,"iExposureCompensation "); ++ ReadByteV(adap, 0x1195,"uwDirectModeCoarseIntegration_lines "); ++ ReadByteV(adap, 0x1199,"uwDirectModeFineIntegration_pixels "); ++ ReadByteV(adap, 0x119d,"uwDirectModeCodedAnalogGain "); ++ ReadByteV(adap, 0x11a1,"fpDirectModeDigitalGain "); ++ ReadByteV(adap, 0x11a5,"uwFlashGunModeCoarseIntegration_lines "); ++ ReadByteV(adap, 0x11a9,"uwFlashGunModeFineIntegration_pixels "); ++ ReadByteV(adap, 0x11ad,"uwFlashGunModeCodedAnalogGain "); ++ ReadByteV(adap, 0x11b1,"fpFlashGunModeDigitalGain "); ++ ReadByteV(adap, 0x11b4,"fFreezeAutoExposure "); ++ ReadByteV(adap, 0x11b7,"fpUserMaximumIntegrationTime_us "); ++ ReadByteV(adap, 0x11bb,"fpRecommendFlashGunAnalogGainThreshold "); ++ ReadByteV(adap, 0x11be,"fEnableHighClipForDesiredExposureTime "); ++ ReadByteV(adap, 0x11c0,"bAntiFlickerMode "); ++ ReadByteV(adap, 0x1201,"fpMaximumStep "); ++ ReadByteV(adap, 0x1205,"fpMinimumStep "); ++ ReadByteV(adap, 0x1209,"fpMinimumDesiredExposureTime_us "); ++ ReadByteV(adap, 0x120d,"fpStepProportion "); ++ ReadByteV(adap, 0x1211,"fpMaximumNegativeStepThreshold "); ++ ReadByteV(adap, 0x1215,"fpRelativeOnTargetStabilityThreshold "); ++ ReadByteV(adap, 0x1219,"fpDigitalGainFloor "); ++ ReadByteV(adap, 0x121d,"fpDigitalGainCeiling "); ++ ReadByteV(adap, 0x1221,"fpRelativeIntTimeHysThreshold "); ++ ReadByteV(adap, 0x1225,"fpRelativeDigitalGainHysThreshold "); ++ ReadByteV(adap, 0x1229,"fpRelativeCompilationProblemThreshold "); ++ ReadByteV(adap, 0x122d,"fpRoundUpBunchFudge "); ++ ReadByteV(adap, 0x1231,"fpFineClampThreshold "); ++ ReadByteV(adap, 0x1235,"fpMaximumManualExposureTime_s "); ++ ReadByteV(adap, 0x1239,"fpRelativeStabilityThresholdForAutoFocus "); ++ ReadByteV(adap, 0x123c,"bLeakShift "); ++ ReadByteV(adap, 0x1281,"fpLeakyEnergy "); ++ ReadByteV(adap, 0x1285,"fpRelativeStep "); ++ ReadByteV(adap, 0x1309,"uwCoarseIntegrationPending_lines "); ++ ReadByteV(adap, 0x130d,"uwFineIntegrationPending_pixels "); ++ ReadByteV(adap, 0x1311,"fpAnalogGainPending "); ++ ReadByteV(adap, 0x1315,"fpDigitalGainPending "); ++ ReadByteV(adap, 0x1319,"fpDesiredExposureTime_us "); ++ ReadByteV(adap, 0x131d,"fpCompiledExposureTime_us "); ++ ReadByteV(adap, 0x132b,"uwCodedAnalogGainPending "); ++ ReadByteV(adap, 0x1480,"bWhiteBalanceMode "); ++ ReadByteV(adap, 0x1482,"bManualRedGain "); ++ ReadByteV(adap, 0x1484,"bManualGreenGain "); ++ ReadByteV(adap, 0x1486,"bManualBlueGain "); ++ ReadByteV(adap, 0x148b,"fpFlashRedGain "); ++ ReadByteV(adap, 0x148f,"fpFlashGreenGain "); ++ ReadByteV(adap, 0x1493,"fpFlashBlueGain "); ++ ReadByteV(adap, 0x1500,"bStatus "); ++ ReadByteV(adap, 0x1505,"fpRedGain "); ++ ReadByteV(adap, 0x1509,"fpGreenGain "); ++ ReadByteV(adap, 0x150d,"fpBlueGain "); ++ ReadByteV(adap, 0x1581,"fpStableTotalStepThreshold "); ++ ReadByteV(adap, 0x1585,"fpMinimumRelativeStep "); ++ ReadByteV(adap, 0x1589,"fpMaximumRelativeStep "); ++ ReadByteV(adap, 0x1601,"fpRedA "); ++ ReadByteV(adap, 0x1605,"fpBlueA "); ++ ReadByteV(adap, 0x1609,"fpRedB "); ++ ReadByteV(adap, 0x160d,"fpBlueB "); ++ ReadByteV(adap, 0x1611,"fpMaximumDistanceAllowedFromLocus "); ++ ReadByteV(adap, 0x1614,"fEnableConstrainedWhiteBalance "); ++ ReadByteV(adap, 0x1616,"bACCSRCCtrl "); ++ ReadByteV(adap, 0x1681,"fpOutputRedGain "); ++ ReadByteV(adap, 0x1685,"fpOutputGreenGain "); ++ ReadByteV(adap, 0x1689,"fpOutputBlueGain "); ++ ReadByteV(adap, 0x168c,"fAreGainsConstrained "); ++ ReadByteV(adap, 0x1701,"fpGradientOfLocusAB "); ++ ReadByteV(adap, 0x1705,"fpDistanceOfInputPointFromLocusAB "); ++ ReadByteV(adap, 0x1709,"fpConstrainedRedPoint "); ++ ReadByteV(adap, 0x170d,"fpConstrainedBluePoint "); ++ ReadByteV(adap, 0x1880,"bMaxNumberOfFramesToWaitForStability "); ++ ReadByteV(adap, 0x1900,"fWhiteBalanceStable "); ++ ReadByteV(adap, 0x1902,"fExposureStable "); ++ ReadByteV(adap, 0x1904,"fDarkCalStable "); ++ ReadByteV(adap, 0x1906,"fStable "); ++ ReadByteV(adap, 0x1908,"fForcedStablility "); ++ ReadByteV(adap, 0x1985,"fpRedTilt "); ++ ReadByteV(adap, 0x1989,"fpGreenTilt "); ++ ReadByteV(adap, 0x198d,"fpBlueTilt "); ++ ReadByteV(adap, 0x1990,"bBlackCorrectionOffset "); ++ ReadByteV(adap, 0x1a01,"uwSensorAnalogGainFloor "); ++ ReadByteV(adap, 0x1a05,"uwSensorAnalogGainCeiling "); ++ ReadByteV(adap, 0x1a80,"bFlashMode "); ++ ReadByteV(adap, 0x1a83,"uwFlashOffLine "); ++ ReadByteV(adap, 0x1b00,"fFlashRecommended "); ++ ReadByteV(adap, 0x1b02,"fFlashGrabComplete "); ++ ReadByteV(adap, 0x1d01,"uwHorizontalOffset "); ++ ReadByteV(adap, 0x1d05,"uwVerticalOffset "); ++ ReadByteV(adap, 0x1d08,"iR2RCoefficient "); ++ ReadByteV(adap, 0x1d0a,"iR2GRCoefficient "); ++ ReadByteV(adap, 0x1d0c,"iR2GBCoefficient "); ++ ReadByteV(adap, 0x1d0e,"iR2BCoefficient "); ++ ReadByteV(adap, 0x1d10,"iR4RCoefficient "); ++ ReadByteV(adap, 0x1d12,"iR4GRCoefficient "); ++ ReadByteV(adap, 0x1d14,"iR4GBCoefficient "); ++ ReadByteV(adap, 0x1d16,"iR4BCoefficient "); ++ ReadByteV(adap, 0x1d80,"ScythefDisableFilter "); ++ ReadByteV(adap, 0x1e00,"JackfDisableFilter "); ++ ReadByteV(adap, 0x1e80,"bAntiAliasFilterSuppress "); ++ ReadByteV(adap, 0x1f00,"ColourMatrixDamperfDisable "); ++ ReadByteV(adap, 0x1f03,"fpLowThreshold "); ++ ReadByteV(adap, 0x1f07,"fpHighThreshold "); ++ ReadByteV(adap, 0x1f0b,"fpMinimumOutput "); ++ ReadByteV(adap, 0x1f81,"fpGInR "); ++ ReadByteV(adap, 0x1f85,"fpBInR "); ++ ReadByteV(adap, 0x1f89,"fpRInG "); ++ ReadByteV(adap, 0x1f8d,"fpBInG "); ++ ReadByteV(adap, 0x1f91,"fpRInB "); ++ ReadByteV(adap, 0x1f95,"fpGInB "); ++ ReadByteV(adap, 0x2000,"bUserPeakGain "); ++ ReadByteV(adap, 0x2002,"fDisableGainDamping "); ++ ReadByteV(adap, 0x2005,"fpDamperLowThreshold_Gain "); ++ ReadByteV(adap, 0x2009,"fpDamperHighThreshold_Gain "); ++ ReadByteV(adap, 0x200d,"fpMinimumDamperOutput_Gain "); ++ ReadByteV(adap, 0x2010,"bUserPeakLoThresh "); ++ ReadByteV(adap, 0x2012,"fDisableCoringDamping "); ++ ReadByteV(adap, 0x2014,"bUserPeakHiThresh "); ++ ReadByteV(adap, 0x2017,"fpDamperLowThreshold_Coring "); ++ ReadByteV(adap, 0x201b,"fpDamperHighThreshold_Coring "); ++ ReadByteV(adap, 0x201f,"fpMinimumDamperOutput_Coring "); ++ ReadByteV(adap, 0x2022,"bBlockControl "); ++ ReadByteV(adap, 0x2280,"fGammaManuCtrl0 "); ++ ReadByteV(adap, 0x2282,"bRPeakGamma0 "); ++ ReadByteV(adap, 0x2284,"bGPeakGamma0 "); ++ ReadByteV(adap, 0x2286,"bBPeakGamma0 "); ++ ReadByteV(adap, 0x2288,"bRUnPeakGamma0 "); ++ ReadByteV(adap, 0x228a,"bGUnPeakGamma0 "); ++ ReadByteV(adap, 0x228c,"bBUnPeakGamma0 "); ++ ReadByteV(adap, 0x2294,"bYuvSetup MTW "); ++ ReadByteV(adap, 0x2300,"fGammaManuCtrl1 "); ++ ReadByteV(adap, 0x2302,"bRPeakGamma1 "); ++ ReadByteV(adap, 0x2304,"bGPeakGamma1 "); ++ ReadByteV(adap, 0x2306,"bBPeakGamma1 "); ++ ReadByteV(adap, 0x2308,"bRUnPeakGamma1 "); ++ ReadByteV(adap, 0x230a,"bGUnPeakGamma1 "); ++ ReadByteV(adap, 0x230c,"bBUnPeakGamma1 "); ++ ReadByteV(adap, 0x2381,"uwLumaExcursion0 "); ++ ReadByteV(adap, 0x2385,"uwLumaMidpointTimes20 "); ++ ReadByteV(adap, 0x2389,"uwChromaExcursion0 "); ++ ReadByteV(adap, 0x238d,"uwChromaMidpointTimes20 "); ++ ReadByteV(adap, 0x2401,"uwLumaExcursion1 "); ++ ReadByteV(adap, 0x2405,"uwLumaMidpointTimes21 "); ++ ReadByteV(adap, 0x2409,"uwChromaExcursion1 "); ++ ReadByteV(adap, 0x240d,"uwChromaMidpointTimes21 "); ++ ReadByteV(adap, 0x2480,"FadeToBlackfDisable "); ++ ReadByteV(adap, 0x2483,"fpBlackValue "); ++ ReadByteV(adap, 0x2487,"fpDamperLowThreshold "); ++ ReadByteV(adap, 0x248b,"fpDamperHighThreshold "); ++ ReadByteV(adap, 0x248f,"fpDamperOutput "); ++ ReadByteV(adap, 0x2580,"bCodeCheckEn "); ++ ReadByteV(adap, 0x2582,"bBlankFormat "); ++ ReadByteV(adap, 0x2584,"bSyncCodeSetup "); ++ ReadByteV(adap, 0x2586,"bHSyncSetup "); ++ ReadByteV(adap, 0x2588,"bVSyncSetup "); ++ ReadByteV(adap, 0x258a,"bPClkSetup "); ++ ReadByteV(adap, 0x258c,"fPclkEn "); ++ ReadByteV(adap, 0x258e,"bOpfSpSetup "); ++ ReadByteV(adap, 0x2590,"bBlankData_MSB "); ++ ReadByteV(adap, 0x2592,"bBlankData_LSB "); ++ ReadByteV(adap, 0x2594,"bRgbSetup "); ++ ReadByteV(adap, 0x2596,"bYuvSetup "); ++ ReadByteV(adap, 0x2598,"bVsyncRisingCoarseH "); ++ ReadByteV(adap, 0x259a,"bVsyncRisingCoarseL "); ++ ReadByteV(adap, 0x259c,"bVsyncRisingFineH "); ++ ReadByteV(adap, 0x259e,"bVsyncRisingFineL "); ++ ReadByteV(adap, 0x25a0,"bVsyncFallingCoarseH "); ++ ReadByteV(adap, 0x25a2,"bVsyncFallingCoarseL "); ++ ReadByteV(adap, 0x25a4,"bVsyncFallingFineH "); ++ ReadByteV(adap, 0x25a6,"bVsyncFallingFineL "); ++ ReadByteV(adap, 0x25a8,"bHsyncRisingH "); ++ ReadByteV(adap, 0x25aa,"bHsyncRisingL "); ++ ReadByteV(adap, 0x25ac,"bHsyncFallingH "); ++ ReadByteV(adap, 0x25ae,"bHsyncFallingL "); ++ ReadByteV(adap, 0x25b0,"bOutputInterface "); ++ ReadByteV(adap, 0x25b2,"bCCPExtraData "); ++ ReadByteV(adap, 0x2600,"NoRAfDisable "); ++ ReadByteV(adap, 0x2602,"bUsage "); ++ ReadByteV(adap, 0x2604,"bSplit_Kn "); ++ ReadByteV(adap, 0x2606,"bSplit_Nl "); ++ ReadByteV(adap, 0x2608,"bTight_Green "); ++ ReadByteV(adap, 0x260a,"fDisableNoraPromoting "); ++ ReadByteV(adap, 0x260d,"DamperLowThreshold "); ++ ReadByteV(adap, 0x2611,"DamperHighThreshold "); ++ ReadByteV(adap, 0x2615,"MinimumDamperOutput "); ++ ++ return; ++} +--- /dev/null ++++ git/drivers/bmi/pims/camera/vs6624_access.h +@@ -0,0 +1,17 @@ ++#ifndef VS6624_ACCESS_H ++#define VS6624_ACCESS_H ++ ++#include ++void vs6624_get_color(struct i2c_adapter *adap, int *bright, int *saturation, int *red, int *green, int *blue); ++void vs6624_set_color(struct i2c_adapter *adap, int bright, int saturation, int red, int green, int blue); ++ ++ ++ ++void vs6624_patch (struct i2c_adapter *adap); ++int vs6624_ReadByte(struct i2c_adapter *adap, unsigned short offset, unsigned char *data); ++int vs6624_WriteByte(struct i2c_adapter *adap, unsigned short offset, unsigned char data); ++int vs6624_WriteSequence(struct i2c_adapter *adap, const unsigned short array[][2], unsigned short len); ++void vs6624_dump_regs(struct i2c_adapter *adap); ++ ++#endif ++ +--- /dev/null ++++ git/drivers/bmi/pims/camera/vs6624_patch.c +@@ -0,0 +1,373 @@ ++static const unsigned short patch_p1[][2] = { ++ {0x8104, 3}, ++ {0x8105, 1}, ++ {0xc900, 0x03}, ++ {0xc904, 0x47}, ++ {0xc905, 0x10}, ++ {0xc906, 0x80}, ++ {0xc907, 0x3a}, ++ {0x903a, 0x02}, ++ {0x903b, 0x47}, ++ {0x903c, 0x15}, ++ {0xc908, 0x31}, ++ {0xc909, 0xdc}, ++ {0xc90a, 0x80}, ++ {0xc90b, 0x44}, ++ {0x9044, 0x02}, ++ {0x9045, 0x31}, ++ {0x9046, 0xe2}, ++ {0xc90c, 0x07}, ++ {0xc90d, 0xe0}, ++ {0xc90e, 0x80}, ++ {0xc90f, 0x47}, ++ {0x9047, 0x90}, ++ {0x9048, 0x83}, ++ {0x9049, 0x81}, ++ {0x904a, 0xe0}, ++ {0x904b, 0x60}, ++ {0x904c, 0x08}, ++ {0x904d, 0x90}, ++ {0x904e, 0xc0}, ++ {0x904f, 0x43}, ++ {0x9050, 0x74}, ++ {0x9051, 0x01}, ++ {0x9052, 0xf0}, ++ {0x9053, 0x80}, ++ {0x9054, 0x05}, ++ {0x9055, 0xE4}, ++ {0x9056, 0x90}, ++ {0x9057, 0xc0}, ++ {0x9058, 0x43}, ++ {0x9059, 0xf0}, ++ {0x905a, 0x02}, ++ {0x905b, 0x07}, ++ {0x905c, 0xec}, ++ {0xc910, 0x5d}, ++ {0xc911, 0xca}, ++ {0xc912, 0x80}, ++ {0xc913, 0x5d}, ++ {0x905d, 0xa3}, ++ {0x905e, 0x04}, ++ {0x905f, 0xf0}, ++ {0x9060, 0xa3}, ++ {0x9061, 0x04}, ++ {0x9062, 0xf0}, ++ {0x9063, 0x22}, ++ {0xc914, 0x72}, ++ {0xc915, 0x92}, ++ {0xc916, 0x80}, ++ {0xc917, 0x64}, ++ {0x9064, 0x74}, ++ {0x9065, 0x01}, ++ {0x9066, 0x02}, ++ {0x9067, 0x72}, ++ {0x9068, 0x95}, ++ {0xc918, 0x47}, ++ {0xc919, 0xf2}, ++ {0xc91a, 0x81}, ++ {0xc91b, 0x69}, ++ {0x9169, 0x74}, ++ {0x916a, 0x02}, ++ {0x916b, 0xf0}, ++ {0x916c, 0xec}, ++ {0x916d, 0xb4}, ++ {0x916e, 0x10}, ++ {0x916f, 0x0a}, ++ {0x9170, 0x90}, ++ {0x9171, 0x80}, ++ {0x9172, 0x16}, ++ {0x9173, 0xe0}, ++ {0x9174, 0x70}, ++ {0x9175, 0x04}, ++ {0x9176, 0x90}, ++ {0x9177, 0xd3}, ++ {0x9178, 0xc4}, ++ {0x9179, 0xf0}, ++ {0x917a, 0x22}, ++ {0xc91c, 0x0a}, ++ {0xc91d, 0xbe}, ++ {0xc91e, 0x80}, ++ {0xc91f, 0x73}, ++ {0x9073, 0xfc}, ++ {0x9074, 0xa3}, ++ {0x9075, 0xe0}, ++ {0x9076, 0xf5}, ++ {0x9077, 0x82}, ++ {0x9078, 0x8c}, ++ {0x9079, 0x83}, ++ {0x907a, 0xa3}, ++ {0x907b, 0xa3}, ++ {0x907c, 0xe0}, ++ {0x907d, 0xfc}, ++ {0x907e, 0xa3}, ++ {0x907f, 0xe0}, ++ {0x9080, 0xc3}, ++ {0x9081, 0x9f}, ++ {0x9082, 0xff}, ++ {0x9083, 0xec}, ++ {0x9084, 0x9e}, ++ {0x9085, 0xfe}, ++ {0x9086, 0x02}, ++ {0x9087, 0x0a}, ++ {0x9088, 0xea}, ++ {0xc920, 0x47}, ++ {0xc921, 0x38}, ++ {0xc922, 0x80}, ++ {0xc923, 0x89}, ++ {0x9089, 0xec}, ++ {0x908a, 0xd3}, ++ {0x908b, 0x94}, ++ {0x908c, 0x20}, ++ {0x908d, 0x40}, ++ {0x908e, 0x01}, ++ {0x908f, 0x1c}, ++ {0x9090, 0x90}, ++ {0x9091, 0xd3}, ++ {0x9092, 0xd4}, ++ {0x9093, 0xec}, ++ {0x9094, 0xf0}, ++ {0x9095, 0x02}, ++ {0x9096, 0x47}, ++ {0x9097, 0x3d}, ++ {0xc924, 0x45}, ++ {0xc925, 0xca}, ++ {0xc926, 0x80}, ++ {0xc927, 0x98}, ++ {0x9098, 0x12}, ++ {0x9099, 0x77}, ++ {0x909a, 0xd6}, ++ {0x909b, 0x02}, ++ {0x909c, 0x45}, ++ {0x909d, 0xcd}, ++ {0xc928, 0x20}, ++ {0xc929, 0xd5}, ++ {0xc92a, 0x80}, ++ {0xc92b, 0x9e}, ++ {0x909e, 0x90}, ++ {0x909f, 0x82}, ++ {0x90a0, 0x18}, ++ {0x90a1, 0xe0}, ++ {0x90a2, 0xb4}, ++ {0x90a3, 0x03}, ++ {0x90a4, 0x0e}, ++ {0x90a5, 0x90}, ++ {0x90a6, 0x83}, ++ {0x90a7, 0xbf}, ++ {0x90a8, 0xe0}, ++ {0x90a9, 0x60}, ++ {0x90aa, 0x08}, ++ {0x90ab, 0x90}, ++ {0x90ac, 0x81}, ++ {0x90ad, 0xfc}, ++ {0x90ae, 0xe0}, ++ {0x90af, 0xff}, ++ {0x90b0, 0xc3}, ++ {0x90b1, 0x13}, ++ {0x90b2, 0xf0}, ++ {0x90b3, 0x90}, ++ {0x90b4, 0x81}, ++ {0x90b5, 0xfc}, ++ {0x90b6, 0xe0}, ++ {0x90b7, 0xff}, ++ {0x90b8, 0x02}, ++ {0x90b9, 0x20}, ++ {0x90ba, 0xda}, ++ {0xc92c, 0x70}, ++ {0xc92d, 0xbc}, ++ {0xc92e, 0x80}, ++ {0xc92f, 0xbb}, ++ {0x90bb, 0x90}, ++ {0x90bc, 0x82}, ++ {0x90bd, 0x18}, ++ {0x90be, 0xe0}, ++ {0x90bf, 0xb4}, ++ {0x90c0, 0x03}, ++ {0x90c1, 0x06}, ++ {0x90c2, 0x90}, ++ {0x90c3, 0xc1}, ++ {0x90c4, 0x06}, ++ {0x90c5, 0x74}, ++ {0x90c6, 0x05}, ++ {0x90c7, 0xf0}, ++ {0x90c8, 0x90}, ++ {0x90c9, 0xd3}, ++ {0x90ca, 0xa0}, ++ {0x90cb, 0x02}, ++ {0x90cc, 0x70}, ++ {0x90cd, 0xbf}, ++ {0xc930, 0x72}, ++ {0xc931, 0x21}, ++ {0xc932, 0x81}, ++ {0xc933, 0x3b}, ++ {0x913b, 0x7d}, ++ {0x913c, 0x02}, ++ {0x913d, 0x7f}, ++ {0x913e, 0x7b}, ++ {0x913f, 0x02}, ++ {0x9140, 0x72}, ++ {0x9141, 0x25}, ++ {0xc934, 0x28}, ++ {0xc935, 0xae}, ++ {0xc936, 0x80}, ++ {0xc937, 0xd2}, ++ {0x90d2, 0xf0}, ++ {0x90d3, 0x90}, ++ {0x90d4, 0xd2}, ++ {0x90d5, 0x0a}, ++ {0x90d6, 0x02}, ++ {0x90d7, 0x28}, ++ {0x90d8, 0xb4}, ++ {0xc938, 0x28}, ++ {0xc939, 0xb1}, ++ {0xc93a, 0x80}, ++ {0xc93b, 0xd9}, ++ {0x90d9, 0x90}, ++ {0x90da, 0x83}, ++ {0x90db, 0xba}, ++ {0x90dc, 0xe0}, ++ {0x90dd, 0xff}, ++ {0x90de, 0x90}, ++ {0x90df, 0xd2}, ++ {0x90e0, 0x08}, ++ {0x90e1, 0xe0}, ++ {0x90e2, 0xe4}, ++ {0x90e3, 0xef}, ++ {0x90e4, 0xf0}, ++ {0x90e5, 0xa3}, ++ {0x90e6, 0xe0}, ++ {0x90e7, 0x74}, ++ {0x90e8, 0xff}, ++ {0x90e9, 0xf0}, ++ {0x90ea, 0x90}, ++ {0x90eb, 0xd2}, ++ {0x90ec, 0x0a}, ++ {0x90ed, 0x02}, ++ {0x90ee, 0x28}, ++ {0x90ef, 0xb4}, ++ {0xc93c, 0x29}, ++ {0xc93d, 0x79}, ++ {0xc93e, 0x80}, ++ {0xc93f, 0xf0}, ++ {0x90f0, 0xf0}, ++ {0x90f1, 0x90}, ++ {0x90f2, 0xd2}, ++ {0x90f3, 0x0e}, ++ {0x90f4, 0x02}, ++ {0x90f5, 0x29}, ++ {0x90f6, 0x7f}, ++ {0xc940, 0x29}, ++ {0xc941, 0x7c}, ++ {0xc942, 0x80}, ++ {0xc943, 0xf7}, ++ {0x90f7, 0x90}, ++ {0x90f8, 0x83}, ++ {0x90f9, 0xba}, ++ {0x90fa, 0xe0}, ++ {0x90fb, 0xff}, ++ {0x90fc, 0x90}, ++ {0x90fd, 0xd2}, ++ {0x90fe, 0x0c}, ++ {0x90ff, 0xe0}, ++ {0x9100, 0xe4}, ++ {0x9101, 0xef}, ++ {0x9102, 0xf0}, ++ {0x9103, 0xa3}, ++ {0x9104, 0xe0}, ++ {0x9105, 0x74}, ++ {0x9106, 0xff}, ++ {0x9107, 0xf0}, ++ {0x9108, 0x90}, ++ {0x9109, 0xd2}, ++ {0x910a, 0x0e}, ++ {0x910b, 0x02}, ++ {0x910c, 0x29}, ++ {0x910d, 0x7f}, ++ {0xc944, 0x2a}, ++ {0xc945, 0x42}, ++ {0xc946, 0x81}, ++ {0xc947, 0x0e}, ++ {0x910e, 0xf0}, ++ {0x910f, 0x90}, ++ {0x9110, 0xd2}, ++ {0x9111, 0x12}, ++ {0x9112, 0x02}, ++ {0x9113, 0x2a}, ++ {0x9114, 0x48}, ++ {0xc948, 0x2a}, ++ {0xc949, 0x45}, ++ {0xc94a, 0x81}, ++ {0xc94b, 0x15}, ++ {0x9115, 0x90}, ++ {0x9116, 0x83}, ++ {0x9117, 0xba}, ++ {0x9118, 0xe0}, ++ {0x9119, 0xff}, ++ {0x911a, 0x90}, ++ {0x911b, 0xd2}, ++ {0x911c, 0x10}, ++ {0x911d, 0xe0}, ++ {0x911e, 0xe4}, ++ {0x911f, 0xef}, ++ {0x9120, 0xf0}, ++ {0x9121, 0xa3}, ++ {0x9122, 0xe0}, ++ {0x9123, 0x74}, ++ {0x9124, 0xff}, ++ {0x9125, 0xf0}, ++ {0x9126, 0x90}, ++ {0x9127, 0xd2}, ++ {0x9128, 0x12}, ++ {0x9129, 0x02}, ++ {0x912a, 0x2a}, ++ {0x912b, 0x48}, ++ {0xc900, 0x01} ++}; ++ ++static const unsigned short patch_p2[][2] = { ++ {0x806f, 0x01}, ++ {0x058c, 0x01} ++}; ++ ++static const unsigned short patch_run_setup[][2] = { ++ {0x2596, 0x01}, /* U first */ ++ {0x1d18, 0x00}, /* Enableconstrainedwhitebalance */ ++ {0x200d, 0x3c}, /* Damper PeakGain Output MSB */ ++ {0x200e, 0x66}, /* Damper PeakGain Output LSB */ ++ {0x1f03, 0x65}, /* Damper Low MSB */ ++ {0x1f04, 0xd1}, /* Damper Low LSB */ ++ {0x1f07, 0x66}, /* Damper High MSB */ ++ {0x1f08, 0x62}, /* Damper High LSB */ ++ {0x1f0b, 0x00}, /* Damper Min output MSB */ ++ {0x1f0c, 0x00}, /* Damper Min output LSB */ ++ {0x2600, 0x00}, /* Nora fDisable */ ++ {0x2602, 0x04}, /* Nora usage */ ++ {0x260d, 0x63}, /* Damper Low MSB Changed 0x63 to 0x65 */ ++ {0x260e, 0xd1}, /* Damper Low LSB */ ++ {0x2611, 0x68}, /* Damper High MSB */ ++ {0x2612, 0xdd}, /* Damper High LSB */ ++ {0x2615, 0x3a}, /* Damper Min output MSB */ ++ {0x2616, 0x00}, /* Damper Min output LSB */ ++ {0x2480, 0x00}, /* Disable */ ++ {0x1d8a, 0x30}, /* MAXWeightHigh */ ++ {0x1d91, 0x62}, /* fpDamperLowThresholdHigh MSB */ ++ {0x1d92, 0x4a}, /* fpDamperLowThresholdHigh LSB */ ++ {0x1d95, 0x65}, /* fpDamperHighThresholdHigh MSB */ ++ {0x1d96, 0x0e}, /* fpDamperHighThresholdHigh LSB */ ++ {0x1da1, 0x3a}, /* fpMinimumDamperOutputLow MSB */ ++ {0x1da2, 0xb8}, /* fpMinimumDamperOutputLow LSB */ ++ {0x1e08, 0x06}, /* MAXWeightLow */ ++ {0x1e0a, 0x0a}, /* MAXWeightHigh */ ++ {0x1601, 0x3a}, /* Red A MSB */ ++ {0x1602, 0x14}, /* Red A LSB */ ++ {0x1605, 0x3b}, /* Blue A MSB */ ++ {0x1606, 0x85}, /* BLue A LSB */ ++ {0x1609, 0x3b}, /* RED B MSB */ ++ {0x160a, 0x85}, /* RED B LSB */ ++ {0x160d, 0x3a}, /* Blue B MSB */ ++ {0x160e, 0x14}, /* Blue B LSB */ ++ {0x1611, 0x30}, /* Max Distance from Locus MSB */ ++ {0x1612, 0x8f}, /* Max Distance from Locus MSB */ ++ {0x1614, 0x01} /* Enable constrainer */ ++}; ++ ++ +--- /dev/null ++++ git/drivers/bmi/pims/camera/vs6624_regs.h +@@ -0,0 +1,467 @@ ++/* ++ * File: drivers/media/video/mxc/capture/_vs6624.h ++ * Author: Peter Giacomini ++ * ++ * This is the header file for the ST VS6624 camera on the ++ * MX31 BUG platform. It is derived from the following ++ * Blackfin and MX31 sources: ++ * ++ */ ++ ++/* ++ * ++ * ++ * Based on: drivers/media/video/blackfin/vs6624.h ++ * Author: Michael Hennerich ++ * ++ * Created: ++ * Description: Command driver for STM VS6624 sensor ++ * ++ * ++ * Modified: ++ * Copyright 2004-2007 Analog Devices Inc. ++ * ++ * Bugs: Enter bugs at http://blackfin.uclinux.org/ ++ * ++ * 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, see the file COPYING, or write ++ * to the Free Software Foundation, Inc., ++ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * ++ * ++ * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*! ++ * @defgroup Camera Sensor Drivers ++ */ ++ ++/*! ++ * @file mt9v111.h ++ * ++ * @brief MT9V111 Camera Header file ++ * ++ * It include all the defines for bitmaps operations, also two main structure ++ * one for IFP interface structure, other for sensor core registers. ++ * ++ * @ingroup Camera ++ */ ++ ++#ifndef _VS6624_H ++#define _VS6624_H ++ ++/* I2C Slave Address */ ++#define VS6624_I2C_ADDRESS 0x10 // 7-bit address ++#define SENSOR_NAME "VS6624" ++ ++//pjg #define USE_ITU656 ++ ++/* VS6624 register definitions */ ++#define VS6624_ID 624 ++#define PWR_MAN_SETUP_MODE_SELECT 0xc003 /* (7:0) */ ++#define PWR_MAN_DIO_ENABLE 0xc044 /* (7:0) */ ++#define uwDeviceId 0x0001 /* (7:0) IndexLo 0x0002 */ ++#define DeviceID_MSB 0x0001 /* (7:0) */ ++#define DeviceID_LSB 0x0002 /* (7:0) */ ++#define bFirmwareVsnMajor 0x0004 /* (7:0) */ ++#define bFirmwareVsnMinor 0x0006 /* (7:0) */ ++#define bPatchVsnMajor 0x0008 /* (7:0) */ ++#define bPatchVsnMinor 0x000a /* (7:0) */ ++ ++#define bUserCommand 0x0180 /* (7:0) */ ++#define bManualNextState 0x0186 /* (7:0) */ ++ ++#define bNextState 0x0200 /* (7:0) */ ++#define bState 0x0202 /* (7:0) */ ++ ++#define fMeteringOn 0x0280 /* (7:0) */ ++#define fExitOnStable 0x0282 /* (7:0) */ ++#define bStreamLength 0x0284 /* (7:0) */ ++ ++#define fIsColdStart 0x0300 /* (7:0) */ ++#define bNonViewLive_ActivePipeSetupBank 0x0302 /* (7:0) */ ++#define bSnapShoot_ActivePipeSetupBank 0x0304 /* (7:0) */ ++#define fSnapShoot_NoWaiting 0x0306 /* (7:0) */ ++#define SensorMode 0x0308 /* (7:0) */ ++ ++#define bImageSize0 0x0380 /* (7:0) */ ++#define uwManualHSize0 0x0383 /* (7:0) IndexLo 0x0384 */ ++#define uwManualHSizeMSB0 0x0383 /* (7:0) */ ++#define uwManualHSizeLSB0 0x0384 /* (7:0) */ ++#define uwManualVSize0 0x0387 /* (7:0) IndexLo 0x0388 */ ++#define uwManualVSizeMSB0 0x0387 /* (7:0) */ ++#define uwManualVSizeLSB0 0x0388 /* (7:0) */ ++#define uwZoomStepHSize0 0x038b /* (7:0) IndexLo 0x038c */ ++#define uwZoomStepHSizeMSB0 0x038b /* (7:0) */ ++#define uwZoomStepHSizeLSB0 0x038c /* (7:0) */ ++#define uwZoomStepVSize0 0x038f /* (7:0) IndexLo 0x0390 */ ++#define uwZoomStepVSizeMSB0 0x038f /* (7:0) */ ++#define uwZoomStepVSizeLSB0 0x0390 /* (7:0) */ ++#define bZoomControl0 0x0392 /* (7:0) */ ++#define uwPanStepHSize0 0x0395 /* (7:0) IndexLo 0x0396 */ ++#define uwPanStepHSizeMSB0 0x0395 /* (7:0) */ ++#define uwPanStepHSizeLSB0 0x0396 /* (7:0) */ ++#define uwPanStepVSize0 0x0399 /* (7:0) IndexLo 0x039a */ ++#define uwPanStepVSizeMSB0 0x0399 /* (7:0) */ ++#define uwPanStepVSizeLSB0 0x039a /* (7:0) */ ++#define bPanControl0 0x039c /* (7:0) */ ++#define bCropControl0 0x039e /* (7:0) */ ++#define uwManualCropHorizontalStart0 0x03a1 /* (7:0) IndexLo 0x03a2 */ ++#define uwManualCropHorizontalSize0 0x03a5 /* (7:0) IndexLo 0x03a6 */ ++#define uwManualCropVerticalStart0 0x03a9 /* (7:0) IndexLo 0x03aa */ ++#define uwManualCropVerticalSize0 0x03ad /* (7:0) IndexLo 0x03ae */ ++#define bCropHStartMSB0 0x03a1 /* (7:0) */ ++#define bCropHStartLSB0 0x03a2 /* (7:0) */ ++#define bCropVStartMSB0 0x03a9 /* (7:0) */ ++#define bCropVStartLSB0 0x03aa /* (7:0) */ ++#define bCropHSizeMSB0 0x03a5 /* (7:0) */ ++#define bCropHSizeLSB0 0x03a6 /* (7:0) */ ++#define bCropVSizeMSB0 0x03ad /* (7:0) */ ++#define bCropVSizeLSB0 0x03ae /* (7:0) */ ++#define bDataFormat0 0x03b0 /* (7:0) */ ++#define bBayerOutputAlignment0 0x03b2 /* (7:0) */ ++#define bContrast0 0x03b4 /* (7:0) */ ++#define bColourSaturation0 0x03b6 /* (7:0) */ ++#define bGamma0 0x03b8 /* (7:0) */ ++#define fHorizontalMirror0 0x03ba /* (7:0) */ ++#define fVerticalFlip0 0x03bc /* (7:0) */ ++#define bChannelID0 0x03be /* (7:0) */ ++ ++#define bImageSize1 0x0400 /* (7:0) */ ++#define uwManualHSize1 0x0403 /* (7:0) IndexLo 0x0404 */ ++#define uwManualVSize1 0x0407 /* (7:0) IndexLo 0x0408 */ ++#define uwZoomStepHSize1 0x040b /* (7:0) IndexLo 0x040c */ ++#define uwZoomStepVSize1 0x040f /* (7:0) IndexLo 0x0410 */ ++#define bZoomControl1 0x0412 /* (7:0) */ ++#define uwPanStepHSize1 0x0415 /* (7:0) IndexLo 0x0416 */ ++#define uwPanStepVSize1 0x0419 /* (7:0) IndexLo 0x041a */ ++#define bPanControl1 0x041c /* (7:0) */ ++#define bCropControl1 0x041e /* (7:0) */ ++#define uwManualCropHorizontalStart1 0x0421 /* (7:0) IndexLo 0x0422 */ ++#define uwManualCropHorizontalSize1 0x0425 /* (7:0) IndexLo 0x0426 */ ++#define uwManualCropVerticalStart1 0x0429 /* (7:0) IndexLo 0x042a */ ++#define uwManualCropVerticalSize1 0x042d /* (7:0) IndexLo 0x042e */ ++#define bCropHStartMSB1 0x0421 /* (7:0) */ ++#define bCropHStartLSB1 0x0422 /* (7:0) */ ++#define bCropVStartMSB1 0x0429 /* (7:0) */ ++#define bCropVStartLSB1 0x042a /* (7:0) */ ++#define bCropHSizeMSB1 0x0425 /* (7:0) */ ++#define bCropHSizeLSB1 0x0426 /* (7:0) */ ++#define bCropVSizeMSB1 0x042d /* (7:0) */ ++#define bCropVSizeLSB1 0x042e /* (7:0) */ ++#define bDataFormat1 0x0430 /* (7:0) */ ++#define bBayerOutputAlignment1 0x0432 /* (7:0) */ ++#define bContrast1 0x0434 /* (7:0) */ ++#define bColourSaturation1 0x0436 /* (7:0) */ ++#define bGamma1 0x0438 /* (7:0) */ ++#define fHorizontalMirror1 0x043a /* (7:0) */ ++#define fVerticalFlip1 0x043c /* (7:0) */ ++#define bChannelID1 0x043e /* (7:0) */ ++ ++#define fEnable 0x0480 /* (7:0) */ ++#define bInitialPipeSetupBank 0x0482 /* (7:0) */ ++ ++#define CurrentPipeSetupBank 0x0500 /* (7:0) */ ++ ++#define bTimeToPowerdown 0x0580 /* (7:0) */ ++#define fVRegSleep 0x058a /* (7:0) */ ++#define fSmoothLineReading 0x058c /* (7:0) */ ++ ++#define uwExternalClockFrequencyMhzNumerator 0x0605 /* (7:0) IndexLo 0x0606 */ ++#define uwExternalClockFrequencyMhzNumeratorMSB 0x0605 /* (7:0) IndexLo 0x0606 */ ++#define uwExternalClockFrequencyMhzNumeratorLSB 0x0606 /* (7:0) IndexLo 0x0606 */ ++#define bExternalClockFrequencyMhzDenominator 0x0608 /* (7:0) */ ++ ++#define fpExternalClockFrequencyMhz 0x0681 /* (7:0) IndexLo 0x0682 */ ++ ++#define bSysClkMode 0x0880 /* (7:0) */ ++#define bMode 0x0882 /* (7:0) */ ++#define bLightingFrequencyHz 0x0c80 /* (7:0) */ ++#define fFlickerCompatibleFrameLength 0x0c82 /* (7:0) */ ++ ++#define fpFlickerFreePeriod_us 0x0d05 /* (7:0) IndexLo 0x0d06 */ ++#define fAntiFlickerEnabled 0x0d08 /* (7:0) */ ++ ++#define uwDesiredFrameRate_Num 0x0d81 /* (7:0) IndexLo 0x0d82 */ ++#define uwDesiredFrameRate_Num_MSB 0x0d81 /* (7:0) */ ++#define uwDesiredFrameRate_Num_LSB 0x0d82 /* (7:0) */ ++#define bDesiredFrameRate_Den 0x0d84 /* (7:0) */ ++ ++#define fpRequestedFrameRate_Hz 0x0e01 /* (7:0) IndexLo 0x0e02 */ ++#define fpRequestedFrameRate_Hz_MSB 0x0e01 /* (7:0) */ ++#define fpRequestedFrameRate_Hz_LSB 0x0e02 /* (7:0) */ ++#define fpMaxFrameRate_Hz 0x0e05 /* (7:0) IndexLo 0x0e06 */ ++#define fpMinFrameRate_Hz 0x0e09 /* (7:0) IndexLo 0x0e0a */ ++#define fChangePending 0x0e0c /* (7:0) */ ++#define uwRequiredFrameLength_lines 0x0e0f /* (7:0) IndexLo 0x0e10 */ ++#define ClipFrameRate 0x0e12 /* (7:0) */ ++ ++#define fDisableFrameRateDamper 0x0e80 /* (7:0) */ ++#define bImpliedGainThresholdLow_num 0x0e82 /* (7:0) */ ++#define bImpliedGainThresholdLow_den 0x0e84 /* (7:0) */ ++#define bImpliedGainThresholdHigh_num 0x0e86 /* (7:0) */ ++#define bImpliedGainThresholdHigh_den 0x0e88 /* (7:0) */ ++#define bUserMinimumFrameRate_Hz 0x0e8a /* (7:0) */ ++#define bUserMaximumFrameRate_Hz 0x0e8c /* (7:0) */ ++#define bRelativeChange_num 0x0e8e /* (7:0) */ ++#define bRelativeChange_den 0x0e90 /* (7:0) */ ++#define fDivorceMinFrameRateFromMaxIntegration 0x0e92 /* (7:0) */ ++ ++#define fpImpliedGain 0x0f01 /* (7:0) IndexLo 0x0f02 */ ++#define uwMaximumFrameLength_lines 0x0f05 /* (7:0) IndexLo 0x0f06 */ ++#define uwMinimumFrameLength_lines 0x0f09 /* (7:0) IndexLo 0x0f0a */ ++#define uwFrameLengthChange_lines 0x0f0d /* (7:0) IndexLo 0x0f0e */ ++#define fpDesiredAutomaticFrameRate_Hz 0x0f11 /* (7:0) IndexLo 0x0f12 */ ++#define uwCurrentFrameLength_lines 0x0f15 /* (7:0) IndexLo 0x0f16 */ ++#define uwDesiredFrameLength_lines 0x0f19 /* (7:0) IndexLo 0x0f1a */ ++#define fAutomaticFrameRateStable 0x0f1c /* (7:0) */ ++#define fAutomaticFrameRateClip 0x0f1e /* (7:0) */ ++ ++#define uwXOffset 0x0f81 /* (7:0) IndexLo 0x0f82 */ ++#define uwYOffset 0x0f85 /* (7:0) IndexLo 0x0f86 */ ++#define uwXSize 0x0f89 /* (7:0) IndexLo 0x0f8a */ ++#define uwYSize 0x0f8d /* (7:0) IndexLo 0x0f8e */ ++ ++#define ExposureControls_bMode 0x1180 /* (7:0) */ ++#define bExposureMetering 0x1182 /* (7:0) */ ++#define bManualExposureTime_s_num 0x1184 /* (7:0) */ ++#define bManualExposureTime_s_den 0x1186 /* (7:0) */ ++#define fpManualDesiredExposureTime_us 0x1189 /* (7:0) IndexLo 0x118a */ ++#define iExposureCompensation 0x1190 /* (7:0) Signed */ ++#define uwDirectModeCoarseIntegration_lines 0x1195 /* (7:0) IndexLo 0x1196 */ ++#define uwDirectModeFineIntegration_pixels 0x1199 /* (7:0) IndexLo 0x119a */ ++#define uwDirectModeCodedAnalogGain 0x119d /* (7:0) IndexLo 0x119e */ ++#define fpDirectModeDigitalGain 0x11a1 /* (7:0) IndexLo 0x11a2 */ ++#define uwFlashGunModeCoarseIntegration_lines 0x11a5 /* (7:0) IndexLo 0x11a6 */ ++#define uwFlashGunModeFineIntegration_pixels 0x11a9 /* (7:0) IndexLo 0x11aa */ ++#define uwFlashGunModeCodedAnalogGain 0x11ad /* (7:0) IndexLo 0x11ae */ ++#define fpFlashGunModeDigitalGain 0x11b1 /* (7:0) IndexLo 0x11b2 */ ++#define fFreezeAutoExposure 0x11b4 /* (7:0) */ ++#define fpUserMaximumIntegrationTime_us 0x11b7 /* (7:0) IndexLo 0x11b8 */ ++#define fpRecommendFlashGunAnalogGainThreshold 0x11bb /* (7:0) IndexLo 0x11bc */ ++#define fEnableHighClipForDesiredExposureTime 0x11be /* (7:0) */ ++#define bAntiFlickerMode 0x11c0 /* (7:0) */ ++ ++#define fpMaximumStep 0x1201 /* (7:0) IndexLo 0x1202 */ ++#define fpMinimumStep 0x1205 /* (7:0) IndexLo 0x1206 */ ++#define fpMinimumDesiredExposureTime_us 0x1209 /* (7:0) IndexLo 0x120a */ ++#define fpStepProportion 0x120d /* (7:0) IndexLo 0x120e */ ++#define fpMaximumNegativeStepThreshold 0x1211 /* (7:0) IndexLo 0x1212 */ ++#define fpRelativeOnTargetStabilityThreshold 0x1215 /* (7:0) IndexLo 0x1216 */ ++#define fpDigitalGainFloor 0x1219 /* (7:0) IndexLo 0x121a */ ++#define fpDigitalGainCeiling 0x121d /* (7:0) IndexLo 0x121e */ ++#define fpRelativeIntTimeHysThreshold 0x1221 /* (7:0) IndexLo 0x1222 */ ++#define fpRelativeDigitalGainHysThreshold 0x1225 /* (7:0) IndexLo 0x1226 */ ++#define fpRelativeCompilationProblemThreshold 0x1229 /* (7:0) IndexLo 0x122a */ ++#define fpRoundUpBunchFudge 0x122d /* (7:0) IndexLo 0x122e */ ++#define fpFineClampThreshold 0x1231 /* (7:0) IndexLo 0x1232 */ ++#define fpMaximumManualExposureTime_s 0x1235 /* (7:0) IndexLo 0x1236 */ ++#define fpRelativeStabilityThresholdForAutoFocus 0x1239 /* (7:0) IndexLo 0x123a */ ++#define bLeakShift 0x123c /* (7:0) */ ++ ++#define fpLeakyEnergy 0x1281 /* (7:0) IndexLo 0x1282 */ ++#define fpRelativeStep 0x1285 /* (7:0) IndexLo 0x1286 */ ++ ++#define uwCoarseIntegrationPending_lines 0x1309 /* (7:0) IndexLo 0x130a */ ++#define uwFineIntegrationPending_pixels 0x130d /* (7:0) IndexLo 0x130e */ ++#define fpAnalogGainPending 0x1311 /* (7:0) IndexLo 0x1312 */ ++#define fpDigitalGainPending 0x1315 /* (7:0) IndexLo 0x1316 */ ++#define fpDesiredExposureTime_us 0x1319 /* (7:0) IndexLo 0x131a */ ++#define fpCompiledExposureTime_us 0x131d /* (7:0) IndexLo 0x131e */ ++#define uwCodedAnalogGainPending 0x132b /* (7:0) IndexLo 0x132c */ ++ ++#define bWhiteBalanceMode 0x1480 /* (7:0) */ ++#define bManualRedGain 0x1482 /* (7:0) */ ++#define bManualGreenGain 0x1484 /* (7:0) */ ++#define bManualBlueGain 0x1486 /* (7:0) */ ++#define fpFlashRedGain 0x148b /* (7:0) IndexLo 0x148c */ ++#define fpFlashGreenGain 0x148f /* (7:0) IndexLo 0x1490 */ ++#define fpFlashBlueGain 0x1493 /* (7:0) IndexLo 0x1494 */ ++ ++#define bStatus 0x1500 /* (7:0) */ ++#define fpRedGain 0x1505 /* (7:0) IndexLo 0x1506 */ ++#define fpGreenGain 0x1509 /* (7:0) IndexLo 0x150a */ ++#define fpBlueGain 0x150d /* (7:0) IndexLo 0x150e */ ++ ++#define fpStableTotalStepThreshold 0x1581 /* (7:0) IndexLo 0x1582 */ ++#define fpMinimumRelativeStep 0x1585 /* (7:0) IndexLo 0x1586 */ ++#define fpMaximumRelativeStep 0x1589 /* (7:0) IndexLo 0x158a */ ++/*#define fpStepProportion 0x158d*/ /* (7:0) IndexLo 0x158e */ ++ ++#define fpRedA 0x1601 /* (7:0) IndexLo 0x1602 */ ++#define fpBlueA 0x1605 /* (7:0) IndexLo 0x1606 */ ++#define fpRedB 0x1609 /* (7:0) IndexLo 0x160a */ ++#define fpBlueB 0x160d /* (7:0) IndexLo 0x160e */ ++#define fpMaximumDistanceAllowedFromLocus 0x1611 /* (7:0) IndexLo 0x1612 */ ++#define fEnableConstrainedWhiteBalance 0x1614 /* (7:0) */ ++#define bACCSRCCtrl 0x1616 /* (7:0) */ ++ ++#define fpOutputRedGain 0x1681 /* (7:0) IndexLo 0x1682 */ ++#define fpOutputGreenGain 0x1685 /* (7:0) IndexLo 0x1686 */ ++#define fpOutputBlueGain 0x1689 /* (7:0) IndexLo 0x168a */ ++#define fAreGainsConstrained 0x168c /* (7:0) */ ++ ++#define fpGradientOfLocusAB 0x1701 /* (7:0) IndexLo 0x1702 */ ++#define fpDistanceOfInputPointFromLocusAB 0x1705 /* (7:0) IndexLo 0x1706 */ ++#define fpConstrainedRedPoint 0x1709 /* (7:0) IndexLo 0x170a */ ++#define fpConstrainedBluePoint 0x170d /* (7:0) IndexLo 0x170e */ ++ ++#define bMaxNumberOfFramesToWaitForStability 0x1880 /* (7:0) */ ++ ++#define fWhiteBalanceStable 0x1900 /* (7:0) */ ++#define fExposureStable 0x1902 /* (7:0) */ ++#define fDarkCalStable 0x1904 /* (7:0) */ ++#define fStable 0x1906 /* (7:0) */ ++#define fForcedStablility 0x1908 /* (7:0) */ ++ ++#define fpRedTilt 0x1985 /* (7:0) IndexLo 0x1986 */ ++#define fpGreenTilt 0x1989 /* (7:0) IndexLo 0x198a */ ++#define fpBlueTilt 0x198d /* (7:0) IndexLo 0x198e */ ++#define bBlackCorrectionOffset 0x1990 /* (7:0) */ ++ ++#define uwSensorAnalogGainFloor 0x1a01 /* (7:0) IndexLo 0x1a02 */ ++#define uwSensorAnalogGainCeiling 0x1a05 /* (7:0) IndexLo 0x1a06 */ ++ ++#define bFlashMode 0x1a80 /* (7:0) */ ++#define uwFlashOffLine 0x1a83 /* (7:0) IndexLo 0x1a84 */ ++ ++#define fFlashRecommended 0x1b00 /* (7:0) */ ++#define fFlashGrabComplete 0x1b02 /* (7:0) */ ++ ++#define uwHorizontalOffset 0x1d01 /* (7:0) IndexLo 0x1d02 */ ++#define uwVerticalOffset 0x1d05 /* (7:0) IndexLo 0x1d06 */ ++#define iR2RCoefficient 0x1d08 /* (7:0) Signed */ ++#define iR2GRCoefficient 0x1d0a /* (7:0) Signed */ ++#define iR2GBCoefficient 0x1d0c /* (7:0) Signed */ ++#define iR2BCoefficient 0x1d0e /* (7:0) Signed */ ++#define iR4RCoefficient 0x1d10 /* (7:0) Signed */ ++#define iR4GRCoefficient 0x1d12 /* (7:0) Signed */ ++#define iR4GBCoefficient 0x1d14 /* (7:0) Signed */ ++#define iR4BCoefficient 0x1d16 /* (7:0) Signed */ ++ ++#define ScythefDisableFilter 0x1d80 /* (7:0) */ ++#define JackfDisableFilter 0x1e00 /* (7:0) */ ++ ++#define bAntiAliasFilterSuppress 0x1e80 /* (7:0) */ ++ ++#define ColourMatrixDamperfDisable 0x1f00 /* (7:0) */ ++#define fpLowThreshold 0x1f03 /* (7:0) IndexLo 0x1f04 */ ++#define fpHighThreshold 0x1f07 /* (7:0) IndexLo 0x1f08 */ ++#define fpMinimumOutput 0x1f0b /* (7:0) IndexLo 0x1f0c */ ++ ++#define fpGInR 0x1f81 /* (7:0) IndexLo 0x1f82 */ ++#define fpBInR 0x1f85 /* (7:0) IndexLo 0x1f86 */ ++#define fpRInG 0x1f89 /* (7:0) IndexLo 0x1f8a */ ++#define fpBInG 0x1f8d /* (7:0) IndexLo 0x1f8e */ ++#define fpRInB 0x1f91 /* (7:0) IndexLo 0x1f92 */ ++#define fpGInB 0x1f95 /* (7:0) IndexLo 0x1f96 */ ++ ++#define bUserPeakGain 0x2000 /* (7:0) */ ++#define fDisableGainDamping 0x2002 /* (7:0) */ ++#define fpDamperLowThreshold_Gain 0x2005 /* (7:0) IndexLo 0x2006 */ ++#define fpDamperHighThreshold_Gain 0x2009 /* (7:0) IndexLo 0x200a */ ++#define fpMinimumDamperOutput_Gain 0x200d /* (7:0) IndexLo 0x200e */ ++#define bUserPeakLoThresh 0x2010 /* (7:0) */ ++#define fDisableCoringDamping 0x2012 /* (7:0) */ ++#define bUserPeakHiThresh 0x2014 /* (7:0) */ ++#define fpDamperLowThreshold_Coring 0x2017 /* (7:0) IndexLo 0x2018 */ ++#define fpDamperHighThreshold_Coring 0x201b /* (7:0) IndexLo 0x201c */ ++#define fpMinimumDamperOutput_Coring 0x201f /* (7:0) IndexLo 0x2020 */ ++#define bBlockControl 0x2022 /* (7:0) */ ++ ++#define fGammaManuCtrl0 0x2280 /* (7:0) */ ++#define bRPeakGamma0 0x2282 /* (7:0) */ ++#define bGPeakGamma0 0x2284 /* (7:0) */ ++#define bBPeakGamma0 0x2286 /* (7:0) */ ++#define bRUnPeakGamma0 0x2288 /* (7:0) */ ++#define bGUnPeakGamma0 0x228a /* (7:0) */ ++#define bBUnPeakGamma0 0x228c /* (7:0) */ ++ ++#define fGammaManuCtrl1 0x2300 /* (7:0) */ ++#define bRPeakGamma1 0x2302 /* (7:0) */ ++#define bGPeakGamma1 0x2304 /* (7:0) */ ++#define bBPeakGamma1 0x2306 /* (7:0) */ ++#define bRUnPeakGamma1 0x2308 /* (7:0) */ ++#define bGUnPeakGamma1 0x230a /* (7:0) */ ++#define bBUnPeakGamma1 0x230c /* (7:0) */ ++ ++#define uwLumaExcursion0 0x2381 /* (7:0) IndexLo 0x2382 */ ++#define uwLumaMidpointTimes20 0x2385 /* (7:0) IndexLo 0x2386 */ ++#define uwChromaExcursion0 0x2389 /* (7:0) IndexLo 0x238a */ ++#define uwChromaMidpointTimes20 0x238d /* (7:0) IndexLo 0x238e */ ++ ++#define uwLumaExcursion1 0x2401 /* (7:0) IndexLo 0x2402 */ ++#define uwLumaMidpointTimes21 0x2405 /* (7:0) IndexLo 0x2406 */ ++#define uwChromaExcursion1 0x2409 /* (7:0) IndexLo 0x240a */ ++#define uwChromaMidpointTimes21 0x240d /* (7:0) IndexLo 0x240e */ ++ ++#define FadeToBlackfDisable 0x2480 /* (7:0) */ ++#define fpBlackValue 0x2483 /* (7:0) IndexLo 0x2484 */ ++#define fpDamperLowThreshold 0x2487 /* (7:0) IndexLo 0x2488 */ ++#define fpDamperHighThreshold 0x248b /* (7:0) IndexLo 0x248c */ ++#define fpDamperOutput 0x248f /* (7:0) IndexLo 0x2490 */ ++ ++#define bCodeCheckEn 0x2580 /* (7:0) */ ++#define bBlankFormat 0x2582 /* (7:0) */ ++#define bSyncCodeSetup 0x2584 /* (7:0) */ ++#define bHSyncSetup 0x2586 /* (7:0) */ ++#define bVSyncSetup 0x2588 /* (7:0) */ ++#define bPClkSetup 0x258a /* (7:0) */ ++#define fPclkEn 0x258c /* (7:0) */ ++#define bOpfSpSetup 0x258e /* (7:0) */ ++#define bBlankData_MSB 0x2590 /* (7:0) */ ++#define bBlankData_LSB 0x2592 /* (7:0) */ ++#define bRgbSetup 0x2594 /* (7:0) */ ++#define bYuvSetup 0x2596 /* (7:0) */ ++#define bVsyncRisingCoarseH 0x2598 /* (7:0) */ ++#define bVsyncRisingCoarseL 0x259a /* (7:0) */ ++#define bVsyncRisingFineH 0x259c /* (7:0) */ ++#define bVsyncRisingFineL 0x259e /* (7:0) */ ++#define bVsyncFallingCoarseH 0x25a0 /* (7:0) */ ++#define bVsyncFallingCoarseL 0x25a2 /* (7:0) */ ++#define bVsyncFallingFineH 0x25a4 /* (7:0) */ ++#define bVsyncFallingFineL 0x25a6 /* (7:0) */ ++#define bHsyncRisingH 0x25a8 /* (7:0) */ ++#define bHsyncRisingL 0x25aa /* (7:0) */ ++#define bHsyncFallingH 0x25ac /* (7:0) */ ++#define bHsyncFallingL 0x25ae /* (7:0) */ ++#define bOutputInterface 0x25b0 /* (7:0) */ ++#define bCCPExtraData 0x25b2 /* (7:0) */ ++ ++#define NoRAfDisable 0x2600 /* (7:0) */ ++#define bUsage 0x2602 /* (7:0) */ ++#define bSplit_Kn 0x2604 /* (7:0) */ ++#define bSplit_Nl 0x2606 /* (7:0) */ ++#define bTight_Green 0x2608 /* (7:0) */ ++#define fDisableNoraPromoting 0x260a /* (7:0) */ ++#define DamperLowThreshold 0x260d /* (7:0) IndexLo 0x260e */ ++#define DamperHighThreshold 0x2611 /* (7:0) IndexLo 0x2612 */ ++#define MinimumDamperOutput 0x2615 /* (7:0) IndexLo 0x2616 */ ++ ++ ++ ++ ++#endif /* VS6624_H */ ++ +--- /dev/null ++++ git/drivers/bmi/pims/factory_test/Makefile +@@ -0,0 +1,6 @@ ++# ++# BMI PIMS - Factory Test Module ++# ++ ++obj-$(CONFIG_BUG_FACTORY_TEST) += factory_test.o ++ +--- /dev/null ++++ git/drivers/bmi/pims/factory_test/factory_test.c +@@ -0,0 +1,952 @@ ++/* ++ * factory_test.c ++ * ++ * BIG factory test board device driver ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/* ++ * Include files ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include <../arch/arm/mach-mx3/iomux.h> ++ ++#define BUG_FACTORY_TEST_VERSION "1.0" ++#define BUF_MAX_SIZE 0x20 ++#define FT_ERR -1 ++#define MX31_GPIO_PORT1 0 ++ ++static int major; ++ // IOX I2C transfer structure ++struct iox_i2c_xfer { ++ unsigned char addr; ++ unsigned char offset; ++ unsigned char data; ++} iox_i2c_xfer; ++ ++ // SPI transfer structure ++struct spi_xfer { ++ unsigned char addr; ++ unsigned char data[2]; ++} spi_xfer; ++ ++enum sig_bus { ++ MX31, ++ CPLD ++}; ++ // MX31 signals ++enum msig { ++ CTS0, ++ RTS0, ++ CTS3, ++ RTS3, ++ CAM, ++ VSYNC1, ++ I2S_RXD0, ++ I2S_RXD1, ++ I2S_RXD2, ++ I2S_RXD3 ++}; ++ ++ // CPLD signals ++enum csig { ++ GPIO0, ++ GPIO1, ++ GPIO2, ++ GPIO3, ++ PRES0, ++ PRES1, ++ PRES2, ++ PRES3, ++ CAM_IF, ++ CAM_LOCK_STATUS, ++ LCD ++}; ++ ++ // MX31/CPLD signal structure ++struct mc_signal { ++ enum sig_bus bus; ++ unsigned int signal; ++ unsigned char funct; ++ unsigned int value; ++} mc_signal; ++ ++ // IOCTL commands for Factory Test Module ++#define FT_READ_IOX _IOR('f', 0x1, struct iox_i2c_xfer *) // read IOX ++#define FT_WRITE_IOX _IOR('f', 0x2, struct iox_i2c_xfer *) // write IOX ++#define FT_READ_SPI _IOR('f', 0x3, struct spi_xfer *) // read SPI ++#define FT_WRITE_SPI _IOR('f', 0x4, struct spi_xfer *) // write SPI ++#define FT_SIGNAL _IOR('f', 0x5, struct mc_signal *) // MX31/CPLD signals ++ ++ // private device structure ++struct bug_ft ++{ ++ struct cdev cdev; // character device (4 minor numbers) ++ unsigned int active; // at lease 1 bdev active ++ struct bmi_device *bdev[4]; // BMI device per slot ++ int open_flag[4]; // force single open on each device ++ struct spi_device *spi[4]; // SPI device ++ char rbuf[BUF_MAX_SIZE]; // SPI read buffer ++ char wbuf[BUF_MAX_SIZE]; // SPI write buffer ++}; ++ ++static struct bug_ft bug_ft; // global private data ++ ++/* ++ * SPI function ++ */ ++ ++static int spi_rw(struct spi_device *spi, u8 * buf, size_t len) ++{ ++ struct spi_transfer t = { ++ .tx_buf = (const void *)buf, ++ .rx_buf = buf, ++ .len = len, ++ .cs_change = 0, ++ .delay_usecs = 0, ++ }; ++ struct spi_message m; ++ ++ spi_message_init(&m); ++ ++ spi_message_add_tail(&t, &m); ++ if (spi_sync(spi, &m) != 0 || m.status != 0) ++ return FT_ERR; ++ ++ return m.actual_length; ++} ++ ++/*! ++ * This function allows writing 1 register on a SPI device. ++ * ++ * @param buf pointer on the buffer ++ * @param count size of the buffer ++ * @return This function returns the number of written bytes. ++ */ ++static ssize_t spi_write_reg(struct bug_ft *priv, char *buf, int slot) ++{ ++ int res = 0; ++ ++ memset(priv->wbuf, 0, BUF_MAX_SIZE); ++ priv->wbuf[0] = buf[0]; ++ priv->wbuf[1] = buf[1]; ++ priv->wbuf[2] = buf[2]; ++ priv->wbuf[3] = buf[3]; ++ if (res > 0) { ++ return -EFAULT; ++ } ++ res = spi_rw(priv->spi[slot], priv->wbuf, 1); ++ ++ return res; ++} ++ ++/*! ++ * This function allows reading 1 register from a SPI device. ++ * ++ * @param buf pointer on the buffer ++ * @param off offset in the buffer ++ ++ * @return This function returns the number of read bytes. ++ */ ++static ssize_t spi_read_reg(struct bug_ft *priv, char *buf, int slot) ++{ ++ spi_write_reg(priv, buf, slot); ++ ++ memset(priv->rbuf, 0, BUF_MAX_SIZE); ++ buf[0] = priv->wbuf[3]; ++ buf[1] = priv->wbuf[2]; ++ buf[2] = priv->wbuf[1]; ++ buf[3] = priv->wbuf[0]; ++ ++ return 4; ++} ++ ++/* ++ * BMI set up ++ */ ++ ++ // BMI device ID table ++static struct bmi_device_id bug_ft_tbl[] = ++{ ++ { ++ .match_flags = BMI_DEVICE_ID_MATCH_VENDOR | BMI_DEVICE_ID_MATCH_PRODUCT, ++ .vendor = BMI_VENDOR_BUG_LABS, ++ .product = BMI_PRODUCT_FACTORY_TEST, ++ .revision = BMI_ANY, ++ }, ++ { 0, }, /* terminate list */ ++}; ++MODULE_DEVICE_TABLE(bmi, bug_ft_tbl); ++ ++int bug_ft_probe(struct bmi_device *bdev); ++void bug_ft_remove(struct bmi_device *bdev); ++ ++ // BMI driver structure ++static struct bmi_driver bug_ft_driver = ++{ ++ .name = "bug_ft_control", ++ .id_table = bug_ft_tbl, ++ .probe = bug_ft_probe, ++ .remove = bug_ft_remove, ++}; ++ ++/* ++ * I2C set up ++ * ++ * IOX A on slots 1 & 3 ++ * IOX B on slots 0 & 4 ++ */ ++ ++ // I2C IOX register addresses ++#define IOX0 (0xE8) // I2C port A ++#define IOX1 (0xEA) // I2C port A ++#define IOX2 (0xEC) // I2C port A ++#define IOX3 (0xEE) // I2C port A ++#define IOX4 (0xE8) // I2C port B ++#define IOX5 (0xEA) // I2C port B ++#define IOX6 (0xEC) // I2C port B ++#define IOX7 (0xEE) // I2C port B ++ ++ // I2C IOX register offset addresses ++#define IOX_INPUT0_REG 0x0 ++#define IOX_INPUT1_REG 0x1 ++#define IOX_OUTPUT0_REG 0x2 ++#define IOX_OUTPUT1_REG 0x3 ++#define IOX_POLARITY0_REG 0x4 ++#define IOX_POLARITY1_REG 0x5 ++#define IOX_CONTROL0 0x6 ++#define IOX_CONTROL1 0x7 ++ ++ // read byte from I2C IO expander ++static int ReadByte_IOX(struct i2c_adapter *adap, unsigned char addr, ++ unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ ++ rmsg[0].addr = addr; ++ rmsg[0].flags = 0; /* write */ ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = addr; ++ rmsg[1].flags = I2C_M_RD; /* read */ ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ret = i2c_transfer (adap, rmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "ReadByte_IOX() - i2c_transfer() failed.\n"); ++ ret = FT_ERR; ++ } ++ return ret; ++} ++ ++ // write byte to I2C IO expander ++static int WriteByte_IOX(struct i2c_adapter *adap, unsigned char addr, ++ unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ wmsg[0].addr = addr; ++ wmsg[0].flags = 0; /* write */ ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = addr; ++ wmsg[1].flags = 0; /* write */ ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ ret = i2c_transfer (adap, wmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "WriteByte_IOX() - i2c_transfer() failed.\n"); ++ ret = FT_ERR; ++ } ++ return ret; ++} ++ ++/* ++ * control device operations ++ */ ++ ++// open ++int bug_ft_open(struct inode *inode, struct file *filp) ++{ ++ int slot = MINOR(inode->i_rdev); ++ ++ if (bug_ft.open_flag[slot]) { ++ return - EBUSY; ++ } ++ bug_ft.open_flag[slot] = 1; ++ filp->private_data = &bug_ft; ++ return 0; ++} ++ ++// release ++int bug_ft_release(struct inode *inode, struct file *filp) ++{ ++ int slot = MINOR(inode->i_rdev); ++ ++ bug_ft.open_flag[slot] = 0; ++ return 0; ++} ++ ++/* ++ * ioctl and support functions ++ */ ++ ++ // do_mx31_sig ++int do_mx31_sig(struct mc_signal * mc_signal) ++{ ++ int read_value; ++ ++ switch(mc_signal->signal) { ++ case CTS0: // GPIO2_7 ++ if(mc_signal->funct != 'W') { ++ printk("do_mx31_sig(): CTS0 is a Write-Only signal\n"); ++ return -1; ++ } ++ iomux_config_mux(MX31_PIN_CTS1, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); ++ mxc_set_gpio_direction(MX31_PIN_CTS1, 0); ++ mxc_set_gpio_dataout(MX31_PIN_CTS1, mc_signal->value); ++ break; ++ case RTS0: // GPIO2_6 ++ if(mc_signal->funct != 'R') { ++ printk("do_mx31_sig(): RTS0 is a Read-Only signal\n"); ++ return -1; ++ } ++ mxc_request_iomux(MX31_PIN_RTS1, OUTPUTCONFIG_FUNC, INPUTCONFIG_GPIO); ++ read_value = mxc_get_gpio_datain(MX31_PIN_RTS1); ++ mc_signal->value = read_value; ++ break; ++ case CTS3: // GPIO3_29 ++ if(mc_signal->funct != 'W') { ++ printk("do_mx31_sig(): CTS3 is a Write-Only signal\n"); ++ return -1; ++ } ++ iomux_config_mux(MX31_PIN_ATA_DIOW, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); ++ mxc_set_gpio_direction(MX31_PIN_ATA_DIOW, 0); ++ mxc_set_gpio_dataout(MX31_PIN_ATA_DIOW, mc_signal->value); ++ break; ++ case RTS3: // GPIO3_27 ++ if(mc_signal->funct != 'R') { ++ printk("do_mx31_sig(): RTS3 is a Read-Only signal\n"); ++ return -1; ++ } ++ mxc_request_iomux(MX31_PIN_ATA_CS1, OUTPUTCONFIG_FUNC, INPUTCONFIG_GPIO); ++ read_value = mxc_get_gpio_datain(MX31_PIN_ATA_CS1); ++ mc_signal->value = read_value; ++ break; ++ case CAM: // camera interface -> GPIO ++ if(mc_signal->funct != 'R') { ++ printk("do_mx31_sig(): CAM is a Read-Only signal\n"); ++ return -1; ++ } ++ mxc_request_iomux(MX31_PIN_CSI_D8, OUTPUTCONFIG_FUNC, INPUTCONFIG_GPIO); ++ mxc_request_iomux(MX31_PIN_CSI_D9, OUTPUTCONFIG_FUNC, INPUTCONFIG_GPIO); ++ mxc_request_iomux(MX31_PIN_CSI_D10, OUTPUTCONFIG_FUNC, INPUTCONFIG_GPIO); ++ mxc_request_iomux(MX31_PIN_CSI_D11, OUTPUTCONFIG_FUNC, INPUTCONFIG_GPIO); ++ mxc_request_iomux(MX31_PIN_CSI_D12, OUTPUTCONFIG_FUNC, INPUTCONFIG_GPIO); ++ mxc_request_iomux(MX31_PIN_CSI_D13, OUTPUTCONFIG_FUNC, INPUTCONFIG_GPIO); ++ mxc_request_iomux(MX31_PIN_CSI_D14, OUTPUTCONFIG_FUNC, INPUTCONFIG_GPIO); ++ mxc_request_iomux(MX31_PIN_CSI_D15, OUTPUTCONFIG_FUNC, INPUTCONFIG_GPIO); ++ mxc_request_iomux(MX31_PIN_CSI_HSYNC, OUTPUTCONFIG_FUNC, INPUTCONFIG_GPIO); ++ mxc_request_iomux(MX31_PIN_CSI_VSYNC, OUTPUTCONFIG_FUNC, INPUTCONFIG_GPIO); ++ ++ mc_signal->value = mxc_get_gpio_datain(MX31_PIN_CSI_HSYNC) << 9; ++ mc_signal->value |= mxc_get_gpio_datain(MX31_PIN_CSI_VSYNC) << 8; ++ mc_signal->value |= mxc_get_gpio_datain(MX31_PIN_CSI_D15) << 7; ++ mc_signal->value |= mxc_get_gpio_datain(MX31_PIN_CSI_D14) << 6; ++ mc_signal->value |= mxc_get_gpio_datain(MX31_PIN_CSI_D13) << 5; ++ mc_signal->value |= mxc_get_gpio_datain(MX31_PIN_CSI_D12) << 4; ++ mc_signal->value |= mxc_get_gpio_datain(MX31_PIN_CSI_D11) << 3; ++ mc_signal->value |= mxc_get_gpio_datain(MX31_PIN_CSI_D10) << 2; ++ mc_signal->value |= mxc_get_gpio_datain(MX31_PIN_CSI_D9) << 1; ++ mc_signal->value |= mxc_get_gpio_datain(MX31_PIN_CSI_D8); ++ ++ mxc_request_iomux(MX31_PIN_CSI_D8, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); ++ mxc_request_iomux(MX31_PIN_CSI_D9, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); ++ mxc_request_iomux(MX31_PIN_CSI_D10, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); ++ mxc_request_iomux(MX31_PIN_CSI_D11, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); ++ mxc_request_iomux(MX31_PIN_CSI_D12, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); ++ mxc_request_iomux(MX31_PIN_CSI_D13, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); ++ mxc_request_iomux(MX31_PIN_CSI_D14, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); ++ mxc_request_iomux(MX31_PIN_CSI_D15, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); ++ mxc_request_iomux(MX31_PIN_CSI_HSYNC, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); ++ mxc_request_iomux(MX31_PIN_CSI_VSYNC, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); ++ break; ++ case VSYNC1: // read VSYNC1 state ++ if(mc_signal->funct != 'R') { ++ printk("do_mx31_sig(): VSYNC1 is a Read-Only signal\n"); ++ return -1; ++ } ++ mxc_request_iomux(MX31_PIN_SRST0, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); ++ mc_signal->value = mxc_get_gpio_datain(MX31_PIN_SRST0); ++ mxc_request_iomux(MX31_PIN_SRST0, OUTPUTCONFIG_FUNC, INPUTCONFIG_ALT2); ++ break; ++ case I2S_RXD0: // GPIO1_20 ++ case I2S_RXD2: ++ if(mc_signal->funct != 'R') { ++ printk("do_mx31_sig(): I2S_RXD[02] are Read-Only signals\n"); ++ return -1; ++ } ++ mxc_request_iomux(MX31_PIN_SRXD4, OUTPUTCONFIG_FUNC, INPUTCONFIG_GPIO); ++ read_value = mxc_get_gpio_datain(MX31_PIN_SRXD4); ++ mc_signal->value = read_value; ++ break; ++ case I2S_RXD1: // GPIO1_22 ++ case I2S_RXD3: ++ if(mc_signal->funct != 'R') { ++ printk("do_mx31_sig(): I2S_RXD[13] are Read-Only signals\n"); ++ return -1; ++ } ++ mxc_request_iomux(MX31_PIN_SRXD5, OUTPUTCONFIG_FUNC, INPUTCONFIG_GPIO); ++ read_value = mxc_get_gpio_datain(MX31_PIN_SRXD5); ++ mc_signal->value = read_value; ++ break; ++ default: ++ printk("do_mx31_sig(): unknown signal\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++ // do_cpld_sig ++int do_cpld_sig(struct mc_signal * mc_signal) ++{ ++ int read_value; ++ ++ switch(mc_signal->signal) { ++ case GPIO0: ++ if(mc_signal->funct == 'R') { ++ // set GPIO to input ++ cpld_set_module_gpio_dir(CPLD_M1, 0, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M1, 1, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M1, 2, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M1, 3, CPLD_GPIO_IN); ++ // read GPIO ++ read_value = cpld_read_gpio_data_reg(CPLD_M1); ++ // read interrupt ++ read_value |= cpld_interrupt_status(INT_M1_INT) << 4; ++ mc_signal->value = read_value; ++ } else if(mc_signal->funct == 'H') { ++ // write GPIO ++ cpld_set_module_gpio_data(CPLD_M1, 0, mc_signal->value & 0x1); ++ cpld_set_module_gpio_data(CPLD_M1, 1, (mc_signal->value & 0x2) >> 1); ++ cpld_set_module_gpio_data(CPLD_M1, 2, (mc_signal->value & 0x4) >> 2); ++ cpld_set_module_gpio_data(CPLD_M1, 3, (mc_signal->value & 0x8) >> 3); ++ // set GPIO to output ++ cpld_set_module_gpio_dir(CPLD_M1, 0, CPLD_GPIO_OUT); ++ cpld_set_module_gpio_dir(CPLD_M1, 1, CPLD_GPIO_OUT); ++ cpld_set_module_gpio_dir(CPLD_M1, 2, CPLD_GPIO_OUT); ++ cpld_set_module_gpio_dir(CPLD_M1, 3, CPLD_GPIO_OUT); ++ } else { ++ printk("do_cpld_sig(): Illegal function for CPLD GPIO\n"); ++ return -1; ++ } ++ break; ++ case GPIO1: ++ if(mc_signal->funct == 'R') { ++ // set GPIO to input ++ cpld_set_module_gpio_dir(CPLD_M2, 0, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M2, 1, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M2, 2, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M2, 3, CPLD_GPIO_IN); ++ // read GPIO ++ read_value = cpld_read_gpio_data_reg(CPLD_M2); ++ // read interrupt ++ read_value |= cpld_interrupt_status(INT_M2_INT) << 4; ++ mc_signal->value = read_value; ++ } else if(mc_signal->funct == 'H') { ++ // write GPIO ++ cpld_set_module_gpio_data(CPLD_M2, 0, mc_signal->value & 0x1); ++ cpld_set_module_gpio_data(CPLD_M2, 1, (mc_signal->value & 0x2) >> 1); ++ cpld_set_module_gpio_data(CPLD_M2, 2, (mc_signal->value & 0x4) >> 2); ++ cpld_set_module_gpio_data(CPLD_M2, 3, (mc_signal->value & 0x8) >> 3); ++ // set GPIO to output ++ cpld_set_module_gpio_dir(CPLD_M2, 0, CPLD_GPIO_OUT); ++ cpld_set_module_gpio_dir(CPLD_M2, 1, CPLD_GPIO_OUT); ++ cpld_set_module_gpio_dir(CPLD_M2, 2, CPLD_GPIO_OUT); ++ cpld_set_module_gpio_dir(CPLD_M2, 3, CPLD_GPIO_OUT); ++ } else { ++ printk("do_cpld_sig(): Illegal function for CPLD GPIO\n"); ++ return -1; ++ } ++ break; ++ case GPIO2: ++ if(mc_signal->funct == 'R') { ++ // set GPIO to input ++ cpld_set_module_gpio_dir(CPLD_M3, 0, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M3, 1, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M3, 2, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M3, 3, CPLD_GPIO_IN); ++ // read GPIO ++ read_value = cpld_read_gpio_data_reg(CPLD_M3); ++ // read interrupt ++ read_value |= cpld_interrupt_status(INT_M3_INT) << 4; ++ mc_signal->value = read_value; ++ } else if(mc_signal->funct == 'H') { ++ // write GPIO ++ cpld_set_module_gpio_data(CPLD_M3, 0, mc_signal->value & 0x1); ++ cpld_set_module_gpio_data(CPLD_M3, 1, (mc_signal->value & 0x2) >> 1); ++ cpld_set_module_gpio_data(CPLD_M3, 2, (mc_signal->value & 0x4) >> 2); ++ cpld_set_module_gpio_data(CPLD_M3, 3, (mc_signal->value & 0x8) >> 3); ++ // set GPIO to output ++ cpld_set_module_gpio_dir(CPLD_M3, 0, CPLD_GPIO_OUT); ++ cpld_set_module_gpio_dir(CPLD_M3, 1, CPLD_GPIO_OUT); ++ cpld_set_module_gpio_dir(CPLD_M3, 2, CPLD_GPIO_OUT); ++ cpld_set_module_gpio_dir(CPLD_M3, 3, CPLD_GPIO_OUT); ++ } else { ++ printk("do_cpld_sig(): Illegal function for CPLD GPIO\n"); ++ return -1; ++ } ++ break; ++ case GPIO3: ++ if(mc_signal->funct == 'R') { ++ // set GPIO to input ++ cpld_set_module_gpio_dir(CPLD_M4, 0, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M4, 1, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M4, 2, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M4, 3, CPLD_GPIO_IN); ++ // read GPIO ++ read_value = cpld_read_gpio_data_reg(CPLD_M4); ++ // read interrupt ++ read_value |= cpld_interrupt_status(INT_M4_INT) << 4; ++ mc_signal->value = read_value; ++ } else if(mc_signal->funct == 'H') { ++ // write GPIO ++ cpld_set_module_gpio_data(CPLD_M4, 0, mc_signal->value & 0x1); ++ cpld_set_module_gpio_data(CPLD_M4, 1, (mc_signal->value & 0x2) >> 1); ++ cpld_set_module_gpio_data(CPLD_M4, 2, (mc_signal->value & 0x4) >> 2); ++ cpld_set_module_gpio_data(CPLD_M4, 3, (mc_signal->value & 0x8) >> 3); ++ // set GPIO to output ++ cpld_set_module_gpio_dir(CPLD_M4, 0, CPLD_GPIO_OUT); ++ cpld_set_module_gpio_dir(CPLD_M4, 1, CPLD_GPIO_OUT); ++ cpld_set_module_gpio_dir(CPLD_M4, 2, CPLD_GPIO_OUT); ++ cpld_set_module_gpio_dir(CPLD_M4, 3, CPLD_GPIO_OUT); ++ } else { ++ return -1; ++ } ++ break; ++ case PRES0: ++ if(mc_signal->funct != 'R') { ++ printk("do_cpld_sig(): Illegal function for CPLD PRES signal\n"); ++ return -1; ++ } ++ read_value = (cpld_read_module_present_status(CPLD_M1) >> 2) & 0x1; ++ mc_signal->value = read_value; ++ break; ++ case PRES1: ++ if(mc_signal->funct != 'R') { ++ printk("do_cpld_sig(): Illegal function for CPLD PRES signal\n"); ++ return -1; ++ } ++ read_value = (cpld_read_module_present_status(CPLD_M2) >> 2) & 0x1; ++ mc_signal->value = read_value; ++ break; ++ case PRES2: ++ if(mc_signal->funct != 'R') { ++ printk("do_cpld_sig(): Illegal function for CPLD PRES signal\n"); ++ return -1; ++ } ++ read_value = (cpld_read_module_present_status(CPLD_M3) >> 2) & 0x1; ++ mc_signal->value = read_value; ++ break; ++ case PRES3: ++ if(mc_signal->funct != 'R') { ++ printk("do_cpld_sig(): Illegal function for CPLD PRES signal\n"); ++ return -1; ++ } ++ read_value = (cpld_read_module_present_status(CPLD_M4) >> 2) & 0x1; ++ mc_signal->value = read_value; ++ break; ++ case CAM_IF: ++ if(mc_signal->funct != 'W') { ++ printk("do_cpld_sig(): Illegal function for CPLD CAM_IF signal\n"); ++ return -1; ++ } ++ cpld_sensor_active(CAM_CLK_RISE); ++ break; ++ case CAM_LOCK_STATUS: ++ if(mc_signal->funct != 'R') { ++ printk("do_cpld_sig(): Illegal function for CPLD CAM_LOCK_STATUS signal\n"); ++ return -1; ++ } ++ read_value = (int) __raw_readw(CPLD_BASE_ADDRESS+CPLD_CAM); ++ read_value = cpld_sensor_lock_status(); ++ mc_signal->value = read_value; ++ break; ++ case LCD: ++ if(mc_signal->funct != 'W') { ++ printk("do_cpld_sig(): Illegal function for CPLD LCD signal\n"); ++ return -1; ++ } ++ cpld_lcd_inactive(0); ++ cpld_lcd_inactive(1); ++ cpld_lcd_active(0, 0, LCD_MODE_I80); ++ cpld_lcd_active(1, 0, LCD_MODE_I80); ++ break; ++ default: ++ printk("do_cpld_sig(): unknown signal\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++ // ioctl ++int bug_ft_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, ++ unsigned long arg) ++{ ++ int slot = MINOR(inode->i_rdev); ++ struct bug_ft *bug_ft = (struct bug_ft *) filp->private_data; ++ struct i2c_adapter *adap = &bug_ft->bdev[slot]->adap; ++ unsigned char iox_data[1]; ++ struct iox_i2c_xfer iox_i2c_xfer; ++ struct spi_xfer spi_xfer; ++ struct mc_signal mc_signal; ++ u8 buf[4]; ++ int ret = 0; ++ ++ // error if no ft active. ++ if(bug_ft->active == -1) ++ return -ENODEV; ++ ++ // error if no BMI device ++ if(bug_ft->bdev[slot] == 0) ++ return -ENODEV; ++ ++ // get I2C transfer structure ++ if((cmd == FT_READ_IOX) || (cmd == FT_WRITE_IOX)) ++ if(copy_from_user(&iox_i2c_xfer, (struct iox_i2c_xfer *) arg, sizeof(struct iox_i2c_xfer))) { ++ printk(KERN_INFO "factory_test ioctl(%d): copy_from_user #1 = %d\n", slot, ret); ++ return -EFAULT; ++ } ++ ++ // get SPI transfer structure ++ if((cmd == FT_READ_SPI) || (cmd == FT_WRITE_SPI)) ++ if(copy_from_user(&spi_xfer, (struct spi_xfer *) arg, sizeof(struct spi_xfer))) { ++ printk(KERN_INFO "factory_test ioctl(%d): copy_from_user #1 = %d\n", slot, ret); ++ return -EFAULT; ++ } ++ ++ // get signal structure ++ if(cmd == FT_SIGNAL) ++ if(copy_from_user(&mc_signal, (struct mc_signal *) arg, sizeof(struct mc_signal))) { ++ printk(KERN_INFO "factory_test ioctl(%d): copy_from_user #1 = %d\n", slot, ret); ++ return -EFAULT; ++ } ++ ++ // ioctl's ++ switch (cmd) { ++ // read IOX ++ case FT_READ_IOX: ++ ret = ReadByte_IOX(adap, iox_i2c_xfer.addr, iox_i2c_xfer.offset, iox_data); ++ if(ret == 0) { ++ iox_i2c_xfer.data = *iox_data; ++ if(copy_to_user((struct iox_i2c_xfer *) arg, &iox_i2c_xfer, sizeof(struct iox_i2c_xfer))) ++ ret = -EFAULT; ++ } ++ break; ++ // write IOX ++ case FT_WRITE_IOX: ++ *iox_data = iox_i2c_xfer.data; ++ ret = WriteByte_IOX(adap, iox_i2c_xfer.addr, iox_i2c_xfer.offset, *iox_data); ++ if(ret == 0) { ++ if(copy_to_user((struct iox_i2c_xfer *) arg, &iox_i2c_xfer, sizeof(struct iox_i2c_xfer))) { ++ ret = -EFAULT; ++ } ++ } ++ break; ++ // read SPI ++ case FT_READ_SPI: ++ // READ ++ buf[3] = 0xC0 | ((spi_xfer.addr & 0x3F) >> 1); ++ buf[2] = 0x00 | ((spi_xfer.addr & 0x1) << 7); ++ buf[1] = 0x00; ++ buf[0] = 0x00; ++ ret = spi_read_reg(bug_ft, buf, slot); ++ if(ret == 4) { ++ spi_xfer.data[1] = ((buf[2] & 0x7F) << 1) | ((buf[1] & 0x80) >> 7); ++ spi_xfer.data[0] = ((buf[1] & 0x7F) << 1) | ((buf[0] & 0x80) >> 7); ++ if(copy_to_user((struct spi_xfer *) arg, &spi_xfer, sizeof(struct spi_xfer))) ++ ret = -EFAULT; ++ else ++ ret = 0; ++ } else ++ ret = FT_ERR; ++ break; ++ // write SPI ++ case FT_WRITE_SPI: ++ // EWEN ++ buf[3] = 0x98; ++ buf[2] = 0x00; ++ buf[1] = 0x00; ++ buf[0] = 0x00; ++ ret = spi_write_reg(bug_ft, buf, slot); ++ if(ret != 1) { ++ ret = FT_ERR; ++ break; ++ } ++ // WRITE ++ buf[3] = 0xA0 | ((spi_xfer.addr & 0x3F) >> 1); ++ buf[2] = 0x00 | ((spi_xfer.addr & 0x1) << 7) | (spi_xfer.data[1] >> 1); ++ buf[1] = ((spi_xfer.data[1] & 0x1) << 7) | (spi_xfer.data[0] >> 1); ++ buf[0] = spi_xfer.data[0] << 0x7; ++ ret = spi_write_reg(bug_ft, buf, slot); ++ if(ret == 1) { ++ if(copy_to_user((struct spi_xfer *) arg, &spi_xfer, sizeof(struct spi_xfer))) ++ ret = -EFAULT; ++ else ++ ret = 0; ++ } else ++ ret = FT_ERR; ++ ++ break; ++ case FT_SIGNAL: ++ if(mc_signal.bus == MX31) { ++ ret = do_mx31_sig(&mc_signal); ++ if((mc_signal.funct == 'R') && (ret == 0)) { ++ if(copy_to_user((struct mc_signal *) arg, &mc_signal, sizeof(struct mc_signal))) { ++ ret = -EFAULT; ++ } else { ++ ret = 0; ++ } ++ } ++ } else if(mc_signal.bus == CPLD) { ++ ret = do_cpld_sig(&mc_signal); ++ if((mc_signal.funct == 'R') && (ret == 0)) { ++ if(copy_to_user((struct mc_signal *) arg, &mc_signal, sizeof(struct mc_signal))) { ++ ret = -EFAULT; ++ } else { ++ ret = 0; ++ } ++ } ++ } else { ++ ret = FT_ERR; ++ } ++ break; ++ default: ++ return -ENOTTY; ++ } ++ ++ return ret; ++} ++ ++/* ++ * BMI functions ++ */ ++ ++static const struct file_operations bug_ft_fops = { ++ .owner = THIS_MODULE, ++ .ioctl = bug_ft_ioctl, ++ .open = bug_ft_open, ++ .release = bug_ft_release, ++}; ++ ++int bug_ft_probe(struct bmi_device *bdev) ++{ ++ int slot = bdev->info->slot; ++ struct cdev *cdev_ptr; ++ dev_t dev_id; ++ int ret; ++ unsigned long speed = 1000000; ++ unsigned char mode = SPI_MODE_2 | SPI_CS_HIGH; ++ unsigned char bits_per_word = 32; ++ ++ ++ printk(KERN_INFO "factory_test.c: probe slot %d\n", slot); ++ ++ cdev_ptr = &bug_ft.cdev; ++ cdev_init(cdev_ptr, &bug_ft_fops); ++ ++ dev_id = MKDEV(major, bdev->info->slot); ++ ret = cdev_add(cdev_ptr, dev_id, 1); ++ if(ret) ++ return ret; ++ ++ switch(slot) { ++ case 0: ++ cpld_set_module_gpio_dir(CPLD_M1, 0, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M1, 1, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M1, 2, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M1, 3, CPLD_GPIO_IN); ++ ret = bmi_device_spi_setup(bdev, speed, mode, bits_per_word); ++ if (ret) { ++ printk (KERN_ERR "bug_ft_probe() - bmi_device_spi_setup(0) failed.\n"); ++ return ret; ++ } ++ bug_ft.spi[0] = &bdev->spi; ++ break; ++ case 1: ++ cpld_set_module_gpio_dir(CPLD_M2, 0, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M2, 1, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M2, 2, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M2, 3, CPLD_GPIO_IN); ++ ret = bmi_device_spi_setup(bdev, speed, mode, bits_per_word); ++ if (ret) { ++ printk (KERN_ERR "bug_ft_probe() - bmi_device_spi_setup(2) failed.\n"); ++ return ret; ++ } ++ bug_ft.spi[1] = &bdev->spi; ++ break; ++ case 2: ++ cpld_set_module_gpio_dir(CPLD_M3, 0, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M3, 1, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M3, 2, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M3, 3, CPLD_GPIO_IN); ++ ret = bmi_device_spi_setup(bdev, speed, mode, bits_per_word); ++ if (ret) { ++ printk (KERN_ERR "bug_ft_probe() - bmi_device_spi_setup(3) failed.\n"); ++ return ret; ++ } ++ bug_ft.spi[2] = &bdev->spi; ++ break; ++ case 3: ++ cpld_set_module_gpio_dir(CPLD_M4, 0, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M4, 1, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M4, 2, CPLD_GPIO_IN); ++ cpld_set_module_gpio_dir(CPLD_M4, 3, CPLD_GPIO_IN); ++ ret = bmi_device_spi_setup(bdev, speed, mode, bits_per_word); ++ if (ret) { ++ printk (KERN_ERR "bug_ft_probe() - bmi_device_spi_setup(3) failed.\n"); ++ return ret; ++ } ++ bug_ft.spi[3] = &bdev->spi; ++ break; ++ } ++ if(ret) { ++ cdev_del(cdev_ptr); ++ return ret; ++ } ++ ++ bmi_device_set_drvdata(bdev, &bug_ft); ++ ++ bug_ft.bdev[slot] = bdev; ++ ++ bug_ft.active = 1; ++ ++ return 0; ++} ++ ++void bug_ft_remove(struct bmi_device *bdev) ++{ ++ struct bug_ft *bug_ft = (struct bug_ft*)(bmi_device_get_drvdata (bdev)); ++ int slot = bdev->info->slot; ++ struct cdev *cdev_ptr; ++ dev_t dev_id; ++ ++ switch(slot) { ++ case 0: ++ bmi_device_spi_cleanup(bdev); ++ break; ++ case 1: ++ bmi_device_spi_cleanup(bdev); ++ break; ++ case 2: ++ bmi_device_spi_cleanup(bdev); ++ break; ++ case 3: ++ bmi_device_spi_cleanup(bdev); ++ break; ++ } ++ ++ bug_ft->bdev[slot] = 0; ++ ++ //de-attach driver-specific struct from bmi_device structure ++ bmi_device_set_drvdata(&bdev[slot], 0); ++ ++ if((bug_ft->bdev[0]==0) && (bug_ft->bdev[1]==0) && ++ (bug_ft->bdev[2]==0) && (bug_ft->bdev[3]==0)) { ++ bug_ft->active = -1; ++ cdev_ptr = &bug_ft->cdev; ++ dev_id = MKDEV(major, bdev->info->slot); ++ cdev_del(cdev_ptr); ++ } ++ ++ return; ++} ++ ++/* ++ * Module functions ++ */ ++ ++static __init int bug_ft_init(void) ++{ ++ dev_t dev_id; ++ int retval; ++ ++ // No ft is active. ++ bug_ft.active = -1; ++ ++ // alloc char driver with 4 minor numbers ++ retval = alloc_chrdev_region(&dev_id, 0, 4, "BUG Factory Test Driver"); ++ if (retval) { ++ return -1; ++ } ++ ++ major = MAJOR(dev_id); ++ ++ printk("factory_test.c: BUG FACTORY TEST Driver v%s (major = %d)\n", BUG_FACTORY_TEST_VERSION, major); ++ ++ return bmi_register_driver(&bug_ft_driver); ++} ++ ++static void __exit bug_ft_clean(void) ++{ ++ dev_t dev_id = MKDEV(major, 0); ++ ++ unregister_chrdev_region(dev_id, 4); ++ bmi_unregister_driver(&bug_ft_driver); ++ ++ return; ++} ++ ++module_init(bug_ft_init); ++module_exit(bug_ft_clean); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Peter Giacomini "); ++MODULE_DESCRIPTION("BUG Factory Test board device driver"); ++MODULE_SUPPORTED_DEVICE("bug_ft_control"); ++ +--- /dev/null ++++ git/drivers/bmi/pims/gps/Makefile +@@ -0,0 +1,6 @@ ++# ++# BMI PIMS ++# ++ ++obj-$(CONFIG_BMI_GPS) += bmi_gps.o ++ +--- /dev/null ++++ git/drivers/bmi/pims/gps/bmi_gps.c +@@ -0,0 +1,468 @@ ++/* ++ * bmi_gps.c ++ * ++ * BMI gps device driver ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/* ++ * Include files ++ */ ++ ++ ++//REWORK: Which are not needed ? ++#include ++#include ++#include ++#include ++#include ++#include ++//#include ++#include ++//#include ++#include ++//#include ++ ++//MTW ++#include ++ ++ ++#define BMIGPS_VERSION "1.1" ++ ++ ++// private device structure ++struct bmi_gps ++{ ++ struct bmi_device *bdev; // BMI device ++ struct cdev cdev; ++ struct device *class_dev; ++ int open_flag; // single open flag ++ struct i2c_client *iox; ++}; ++ ++static struct bmi_gps bmi_gps[4]; ++static int major; ++ ++/* ++ * BMI set up ++ */ ++ ++ // BMI device ID table ++static struct bmi_device_id bmi_gps_tbl[] = ++{ ++ { ++ .match_flags = BMI_DEVICE_ID_MATCH_VENDOR | BMI_DEVICE_ID_MATCH_PRODUCT, ++ .vendor = BMI_VENDOR_BUG_LABS, ++ .product = BMI_PRODUCT_GPS_J32, ++ .revision = BMI_ANY, ++ }, ++ { 0, }, /* terminate list */ ++}; ++MODULE_DEVICE_TABLE(bmi, bmi_gps_tbl); ++ ++int bmi_gps_probe(struct bmi_device *bdev); ++void bmi_gps_remove(struct bmi_device *bdev); ++ ++// BMI driver structure ++static struct bmi_driver bmi_gps_driver = ++{ ++ .name = "bmi_gps", ++ .id_table = bmi_gps_tbl, ++ .probe = bmi_gps_probe, ++ .remove = bmi_gps_remove, ++}; ++ ++/* ++ * I2C set up ++ */ ++ ++// I2C Slave Address ++#define BMI_IOX_I2C_ADDRESS 0x71 // 7-bit address ++ ++// I2C IOX register addresses ++#define IOX_INPUT_REG 0x0 ++#define IOX_OUTPUT_REG 0x1 ++#define IOX_POLARITY_REG 0x2 ++#define IOX_CONTROL 0x3 ++ ++static struct i2c_board_info iox_info = { ++ I2C_BOARD_INFO("VH_IOX", BMI_IOX_I2C_ADDRESS), ++}; ++ ++// read byte from I2C IO expander ++ ++static int ReadByte_IOX (struct i2c_client *client, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ ++ ret = i2c_master_send(client, &offset, 1); ++ if (ret == 1) ++ ret = i2c_master_recv(client, data, 1); ++ if (ret < 0) ++ printk (KERN_ERR "ReadByte_IOX() - i2c_transfer() failed...%d\n",ret); ++ return ret; ++} ++ ++// write byte to I2C IO expander ++static int WriteByte_IOX (struct i2c_client *client, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ unsigned char msg[2]; ++ ++ msg[0] = offset; ++ msg[1] = data; ++ ret = i2c_master_send(client, msg, sizeof(msg)); ++ ++ if (ret < 0) ++ printk (KERN_ERR "WriteByte_IOX() - i2c_transfer() failed...%d\n",ret); ++ ++ return ret; ++} ++ ++ ++ ++/* ++ * control device operations ++ */ ++ ++// open ++int cntl_open(struct inode *inode, struct file *file) ++{ ++ struct bmi_gps *gps; ++ ++ gps = container_of(inode->i_cdev, struct bmi_gps, cdev); ++ ++ // Enforce single-open behavior ++ ++ if (gps->open_flag) { ++ return -EBUSY; ++ } ++ gps->open_flag = 1; ++ ++ // Save gps_dev pointer for later. ++ ++ file->private_data = gps; ++ return 0; ++ ++} ++ ++// release ++int cntl_release(struct inode *inode, struct file *file) ++{ ++ struct bmi_gps *gps; ++ ++ gps = (struct bmi_gps *)(file->private_data); ++ gps->open_flag = 0; ++ return 0; ++} ++ ++// ioctl ++int cntl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct i2c_adapter *adap; ++ unsigned char iox_data; ++ ++ unsigned char gpio_mask; ++ struct bmi_gps *gps; ++ int slot; ++ ++ gps = (struct bmi_gps *)(file->private_data); ++ ++ // error if gps not present ++ if(gps->bdev == 0) ++ return -ENODEV; ++ ++ slot = gps->bdev->slot->slotnum; ++ adap = gps->bdev->slot->adap; ++ ++ // ioctl's ++ gpio_mask = bmi_slot_gpio_get(slot); ++ switch (cmd) { ++ case BMI_GPS_RLEDOFF: ++ bmi_slot_gpio_set (slot, (gpio_mask | RED_LED)); // Red LED=OFF ++ break; ++ ++ case BMI_GPS_RLEDON: ++ bmi_slot_gpio_set (slot, (gpio_mask & ~RED_LED)); // Red LED=ON ++ break; ++ ++ case BMI_GPS_GLEDOFF: ++ bmi_slot_gpio_set (slot, (gpio_mask | GREEN_LED)); // Greem LED=OFF ++ break; ++ ++ case BMI_GPS_GLEDON: ++ bmi_slot_gpio_set (slot, (gpio_mask & ~GREEN_LED)); // Greem LED=ON ++ break; ++ ++ case BMI_GPS_SETBOOT: ++ if(ReadByte_IOX (gps->iox, IOX_OUTPUT_REG, &iox_data)) ++ return -ENODEV; ++ iox_data |= 0x08; ++ if(WriteByte_IOX (gps->iox, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ if(ReadByte_IOX (gps->iox, IOX_CONTROL, &iox_data)) // IOX[3]=BOOT=0, IOX[4]=WAKEUP=0 ++ return -ENODEV; ++ iox_data |= 0x08; ++ if(WriteByte_IOX (gps->iox, IOX_CONTROL, iox_data)) // IOX[3]=BOOT=0, IOX[4]=WAKEUP=0 ++ return -ENODEV; ++ break; ++ ++ case BMI_GPS_CLRBOOT: ++ if(ReadByte_IOX (gps->iox, IOX_OUTPUT_REG, &iox_data)) ++ return -ENODEV; ++ iox_data &= ~0x08; ++ if(WriteByte_IOX (gps->iox, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ break; ++ ++ case BMI_GPS_SETWAKE: ++ if(ReadByte_IOX (gps->iox, IOX_OUTPUT_REG, &iox_data)) ++ return -ENODEV; ++ iox_data |= 0x10; ++ if(WriteByte_IOX (gps->iox, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ if(ReadByte_IOX (gps->iox, IOX_CONTROL, &iox_data)) // IOX[3]=BOOT=0, IOX[4]=WAKEUP=0 ++ return -ENODEV; ++ iox_data |= 0x10; ++ if(WriteByte_IOX (gps->iox, IOX_CONTROL, iox_data)) // IOX[3]=BOOT=0, IOX[4]=WAKEUP=0 ++ return -ENODEV; ++ break; ++ ++ case BMI_GPS_CLRWAKE: ++ if(ReadByte_IOX (gps->iox, IOX_OUTPUT_REG, &iox_data)) ++ return -ENODEV; ++ iox_data &= ~0x10; ++ if(WriteByte_IOX (gps->iox, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ break; ++ ++ case BMI_GPS_SETRST: ++ bmi_slot_gpio_set (slot, (gpio_mask & ~GPIO_1)); // RST = 0; ++ ++ break; ++ ++ case BMI_GPS_CLRRST: ++ bmi_slot_gpio_set (slot, (gpio_mask | GPIO_1)); // RST=tristate ++ break; ++ ++ case BMI_GPS_GETSTAT: ++ { ++ int read_data; ++ ++ if(ReadByte_IOX (gps->iox, IOX_INPUT_REG, &iox_data)) ++ return -ENODEV; ++ ++ read_data = iox_data | (bmi_slot_gpio_get(slot) << 8); ++ ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ } ++ break; ++ ++ case BMI_GPS_ACTIVE_ANT : ++ if(ReadByte_IOX (gps->iox, IOX_OUTPUT_REG, &iox_data)) ++ return -ENODEV; ++ iox_data &= ~0x40; ++ iox_data |= 0x80; ++ if(WriteByte_IOX (gps->iox, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ break; ++ ++ case BMI_GPS_PASSIVE_ANT: ++ if(ReadByte_IOX (gps->iox, IOX_OUTPUT_REG, &iox_data)) ++ return -ENODEV; ++ iox_data &= ~0x80; ++ iox_data |= 0x40; ++ if(WriteByte_IOX (gps->iox, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ break; ++ ++ default: ++ return -ENOTTY; ++ } ++ ++ return 0; ++} ++ ++// control file operations ++struct file_operations cntl_fops = { ++ .owner = THIS_MODULE, ++ .ioctl = cntl_ioctl, ++ .open = cntl_open, ++ .release = cntl_release, ++}; ++ ++/* ++ * Module functions ++ */ ++ ++/* ++ * BMI functions ++ */ ++ ++int bmi_gps_probe(struct bmi_device *bdev) ++{ ++ int err; ++ int slot; ++ struct bmi_gps *gps; ++ struct i2c_adapter *adap; ++ struct cdev *cdev; ++ struct class *bmi_class; ++ dev_t dev_id; ++ ++ err = 0; ++ slot = bdev->slot->slotnum; ++ adap = bdev->slot->adap; ++ gps = &bmi_gps[slot]; ++ ++ ++ gps->bdev = 0; ++ gps->open_flag = 0; ++ ++ //Create 1 minor device ++ cdev = &gps->cdev; ++ cdev_init(cdev, &cntl_fops); ++ ++ dev_id = MKDEV(major, slot); ++ err = cdev_add(cdev, dev_id, 1); ++ if (err) { ++ return err; ++ } ++ ++ //Create class device ++ bmi_class = bmi_get_class (); ++ gps->class_dev = device_create(bmi_class, NULL, MKDEV(major, slot), gps, "bmi_gps_control_m%i", slot+1); ++ ++ if (IS_ERR(gps->class_dev)) { ++ printk(KERN_ERR "Unable to create " ++ "class_device for bmi_gps_m%i; errno = %ld\n", ++ slot+1, PTR_ERR(gps->class_dev)); ++ gps->class_dev = NULL; ++ } ++ ++ //bind driver and bmi_device ++ gps->bdev = bdev; ++ bmi_device_set_drvdata(bdev, gps); ++ ++ printk(KERN_INFO "bmi_gps.c: probe slot %d\n", slot); ++ ++ // configure IOX - leave ouputs as inputs unless needed ++ ++ gps->iox = i2c_new_device(bdev->slot->adap, &iox_info); ++ if (gps->iox == NULL) ++ printk(KERN_ERR "IOX NULL...\n"); ++ if(WriteByte_IOX(gps->iox, IOX_OUTPUT_REG, 0x40)) { // ++ return -ENODEV; ++ } ++ if(WriteByte_IOX(gps->iox, IOX_CONTROL, 0x3F)) { // IOX[4:3]=OUT, IOX[7:5,2:0]=IN ++ return -ENODEV; ++ } ++ ++ ++ // Initialize GPIOs (turn LED's on ) ++ ++// bmi_slot_gpio_configure_as_output (int slot, int gpio, int data) ++ ++ bmi_slot_gpio_configure(slot, RED_LED | GREEN_LED | GPIO_1); // Red, Green LEDS and GPIO_1 outputs ++ bmi_slot_gpio_set(slot, 0); ++ ++ //Enable uart transceiver ++ bmi_slot_uart_enable (slot); ++ ++ mdelay(275); ++ ++ // release reset to J32 device ++ bmi_slot_gpio_set ( slot, RED_LED | GREEN_LED | GPIO_1); // reset high, Red, Green LEDS off ++ ++ return 0; ++} ++ ++ ++void bmi_gps_remove(struct bmi_device *bdev) ++{ ++ int slot; ++ struct bmi_gps *gps; ++ struct class *bmi_class; ++ ++ slot = bdev->slot->slotnum; ++ gps = &bmi_gps[slot]; ++ ++ //Disable uart transceiver ++ bmi_slot_uart_disable (slot); ++ bmi_slot_gpio_configure(slot, 0); ++ ++ bmi_class = bmi_get_class (); ++ device_destroy(bmi_class, MKDEV(major, slot)); ++ ++ gps->class_dev = 0; ++ ++ cdev_del (&gps->cdev); ++ ++ //de-attach driver-specific struct from bmi_device structure ++ bmi_device_set_drvdata (bdev, 0); ++ gps->bdev = 0; ++ ++ return; ++} ++ ++ ++ ++ ++ ++static void __exit bmi_gps_cleanup(void) ++{ ++ dev_t dev_id; ++ ++ bmi_unregister_driver (&bmi_gps_driver); ++ ++ dev_id = MKDEV(major, 0); ++ unregister_chrdev_region(dev_id, 4); ++ return; ++} ++ ++ ++ ++ ++static int __init bmi_gps_init(void) ++{ ++ dev_t dev_id; ++ int retval; ++ ++ // alloc char driver with 4 minor numbers ++ ++ retval = alloc_chrdev_region(&dev_id, 0, 4, "BMI GPS Driver"); ++ ++ if (retval) { ++ return -1; ++ } ++ ++ major = MAJOR(dev_id); ++ retval = bmi_register_driver (&bmi_gps_driver); ++ ++ if (retval) { ++ unregister_chrdev_region(dev_id, 4); ++ return -1; ++ } ++ printk("bmi_gps.c: BMI_GPS Driver v%s \n", BMIGPS_VERSION); ++ ++ return 0; ++} ++ ++ ++module_init(bmi_gps_init); ++module_exit(bmi_gps_cleanup); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Peter Giacomini "); ++MODULE_DESCRIPTION("BMI gps device driver"); ++MODULE_SUPPORTED_DEVICE("bmi_gps_control"); ++ +--- /dev/null ++++ git/drivers/bmi/pims/gsm/Makefile +@@ -0,0 +1,6 @@ ++# ++# BMI PIMS ++# ++ ++obj-$(CONFIG_BMI_GSM) += bmi_gsm.o ++ +--- /dev/null ++++ git/drivers/bmi/pims/gsm/bmi_gsm.c +@@ -0,0 +1,301 @@ ++/* ++ * bmi_gsm.c ++ * ++ * BMI GSM device driver ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/* ++ * Include files ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define DEBUG ++#undef DEBUG ++ ++#define BMIGSM_VERSION "1.0" // driver version ++ ++ ++// private device structure ++struct bmi_gsm ++{ ++ struct bmi_device *bdev; // BMI device ++ struct cdev cdev; // control device ++ struct device *class_dev; // control class device ++ int open_flag; ++}; ++ ++static struct bmi_gsm bmi_gsm_priv[4]; // per slot device structure ++static int major; // control device major ++ ++/* ++ * BMI set up ++ */ ++ ++ // BMI device ID table ++static struct bmi_device_id bmi_gsm_tbl[] = ++{ ++ { ++ .match_flags = BMI_DEVICE_ID_MATCH_VENDOR | BMI_DEVICE_ID_MATCH_PRODUCT, ++ .vendor = BMI_VENDOR_BUG_LABS, ++ .product = BMI_PRODUCT_GSM, ++ .revision = BMI_ANY, ++ }, ++ { 0, }, /* terminate list */ ++}; ++ ++MODULE_DEVICE_TABLE(bmi, bmi_gsm_tbl); ++ ++ ++int bmi_gsm_probe(struct bmi_device *bdev); ++void bmi_gsm_remove(struct bmi_device *bdev); ++ ++// BMI driver structure ++static struct bmi_driver bmi_gsm_driver = ++{ ++ .name = "bmi_gsm", ++ .id_table = bmi_gsm_tbl, ++ .probe = bmi_gsm_probe, ++ .remove = bmi_gsm_remove, ++}; ++ ++ ++/* ++ * control device operations ++ */ ++ ++// open ++int cntl_open(struct inode *inode, struct file *file) ++{ ++ struct bmi_gsm *gsmod; ++ ++ gsmod = container_of (inode->i_cdev, struct bmi_gsm, cdev); ++ ++ // Enforce single-open behavior ++ ++ if (gsmod->open_flag) { ++ return -EBUSY; ++ } ++ gsmod->open_flag = 1; ++ ++ // Save gsm_dev pointer for later. ++ ++ file->private_data = gsmod; ++ return 0; ++ ++} ++ ++// release ++int cntl_release(struct inode *inode, struct file *file) ++{ ++ struct bmi_gsm *gsmod; ++ ++ gsmod = (struct bmi_gsm *)(file->private_data); ++ gsmod->open_flag = 0; ++ return 0; ++} ++ ++ ++// ioctl ++int cntl_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct bmi_gsm *gsmod; ++ unsigned char temp = 0; ++ int slot; ++ ++ ++ gsmod = (struct bmi_gsm *)(filp->private_data); ++ ++ if(gsmod->bdev == 0) ++ return -ENODEV; ++ ++ slot = gsmod->bdev->slot->slotnum; ++ ++ // ioctl's ++ temp = bmi_slot_gpio_get(slot); ++ switch (cmd) { ++ case BMI_GSM_RLEDOFF: ++ bmi_slot_gpio_set(slot, temp & (~RED_LED)); // Red LED=OFF ++ break; ++ case BMI_GSM_RLEDON: ++ bmi_slot_gpio_set(slot, temp | RED_LED); // Red LED=ON ++ break; ++ case BMI_GSM_GLEDOFF: ++ bmi_slot_gpio_set(slot, temp & (~GREEN_LED)); // Green LED=OFF ++ break; ++ case BMI_GSM_GLEDON: ++ bmi_slot_gpio_set(slot, temp | GREEN_LED); // Green LED=ON ++ break; ++ } ++ return 0; ++} ++ ++// control file operations ++struct file_operations cntl_fops = { ++ .owner = THIS_MODULE, ++ .ioctl = cntl_ioctl, ++ .open = cntl_open, ++ .release = cntl_release, ++}; ++ ++ ++// Probe ++int bmi_gsm_probe(struct bmi_device *bdev) ++{ ++ int slot; ++ int status; ++ int temp = 0; ++ dev_t dev_id; ++ struct cdev *cdev; ++ struct class *bmi_class; ++ struct bmi_gsm *gsmod; ++ ++ ++ slot = bdev->slot->slotnum; ++ gsmod = &bmi_gsm_priv[slot]; ++ gsmod->bdev = 0; ++ gsmod->open_flag = 0; ++ ++ cdev = &gsmod->cdev; ++ cdev_init(cdev, &cntl_fops); ++ dev_id = MKDEV(major, slot); ++ status = cdev_add(cdev, dev_id, 1); ++ if ( status) ++ return status; ++ ++ bmi_class = bmi_get_class(); ++ gsmod->class_dev = device_create (bmi_class, NULL, MKDEV(major, slot), NULL, "bmi_gsm_ctl_m%i", slot + 1); ++ ++ if (IS_ERR(gsmod->class_dev)) ++ { ++ printk(KERN_ERR "Unable to create class device for bmi_gsm_ctl_m%i...", slot + 1); ++ gsmod->class_dev = NULL; ++ cdev_del(&gsmod->cdev); ++ return -ENODEV; ++ } ++ ++ // configure GPIO ++ ++ // set GPIO direction ++ bmi_slot_gpio_configure (slot, RED_LED | GREEN_LED | GPIO_0); ++ ++ // turn LED's on ++ bmi_slot_gpio_set (slot, ~(RED_LED | GREEN_LED | GPIO_0)); ++ mdelay(500); ++ // turn LED's off ++ bmi_slot_gpio_set (slot, (RED_LED | GREEN_LED)); ++ ++ // Check if SIM is present... ++ // gpio_reg = bmi_read_gpio_data_reg(slot); ++ // turn mini-card on ++ printk(KERN_INFO "Turning Sierra Wireless Card On...\n"); ++ temp = bmi_slot_gpio_get(slot); ++ bmi_slot_gpio_set(slot, temp & (~GPIO_0)); ++ ++ // set up bdev/pbmi_gsm pointers ++ gsmod->bdev = bdev; ++ bmi_device_set_drvdata(bdev, &gsmod); ++ ++ return 0; ++} ++ ++// remove ++void bmi_gsm_remove(struct bmi_device *bdev) ++{ ++ int slot; ++ struct bmi_gsm *gsmod; ++ struct class *bmi_class; ++ ++ slot = bdev->slot->slotnum; ++ ++ gsmod = &bmi_gsm_priv[slot]; ++ ++ bmi_slot_gpio_configure(slot, 0); ++ ++ bmi_class = bmi_get_class (); ++ device_destroy (bmi_class, MKDEV(major, slot)); ++ ++ gsmod->class_dev = 0; ++ ++ cdev_del (&gsmod->cdev); ++ ++ // de-attach driver-specific struct from bmi_device structure ++ bmi_device_set_drvdata (bdev, 0); ++ gsmod->bdev = 0; ++ ++ //de-attach driver-specific struct from bmi_device structure ++ bmi_device_set_drvdata (bdev, NULL); ++ ++ return; ++} ++ ++ ++static __init int bmi_gsm_init(void) ++{ ++ ++ dev_t dev_id; ++ int retval; ++ ++ // alloc char driver with 4 minor numbers ++ retval = alloc_chrdev_region (&dev_id, 0, 4, "BMI GSM Driver"); ++ if (retval) { ++ return -ENODEV; ++ } ++ ++ major = MAJOR(dev_id); ++ retval = bmi_register_driver (&bmi_gsm_driver); ++ if (retval) { ++ unregister_chrdev_region(dev_id, 4); ++ return -ENODEV; ++ } ++ ++ printk("bmi_gsm.c: BMI_GSM Driver v%s \n", BMIGSM_VERSION); ++ ++ return 0; ++} ++ ++static void __exit bmi_gsm_clean(void) ++{ ++ dev_t dev_id; ++ ++ bmi_unregister_driver (&bmi_gsm_driver); ++ ++ dev_id = MKDEV(major, 0); ++ unregister_chrdev_region (dev_id, 4); ++ return; ++} ++ ++module_init(bmi_gsm_init); ++module_exit(bmi_gsm_clean); ++ ++MODULE_AUTHOR("Matt Isaacs "); ++MODULE_DESCRIPTION("BMI gsm device driver"); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ git/drivers/bmi/pims/lcd/Makefile +@@ -0,0 +1,9 @@ ++# ++# BMI PIMS ++# ++ ++obj-$(CONFIG_VIDEO_BMI_LCD) += bmi_lcd_core.o ++bmi_lcd_core-objs := bmi_lcd.o acc.o ++ ++obj-$(CONFIG_VIDEO_BMI_LCD_S320X240) += bmi_s320x240.o ++ +--- /dev/null ++++ git/drivers/bmi/pims/lcd/acc.c +@@ -0,0 +1,114 @@ ++#include "acc.h" ++#include ++#include ++#include ++ ++#define BMI_SLOT_NUM 4 ++ ++static dev_t acc_dev_number; ++ ++static struct file_operations acc_fops = { ++ .owner = THIS_MODULE, ++ .open = acc_open, ++ .read = acc_read, ++ .release = acc_release ++}; ++ ++ ++int acc_open(struct inode *inode, struct file *file) ++{ ++ struct acc_dev * acc; ++ ++ printk(KERN_DEBUG "ACC_OPEN\n"); ++ ++ acc = container_of(inode->i_cdev, struct acc_dev, cdev); ++ ++ file->private_data = acc; ++ ++ return 0; ++} ++ ++int acc_release(struct inode *inode, struct file *file) ++{ ++ printk(KERN_DEBUG "ACC_RELEASE"); ++ ++ return 0; ++} ++ ++int acc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) ++{ ++ struct acc_dev * acc = file->private_data; ++ int result = 0; ++ ++ if(count < 6) { ++ return -EINVAL; ++ } ++ ++ if(wait_event_interruptible(acc->wq, acc->flag != 0)) { ++ return -ERESTARTSYS; ++ } ++ ++ result = copy_to_user(buf, acc->sample, 6); ++ acc->flag = 0; ++ if(result) { ++ return -EFAULT; ++ } ++ ++ return 6; ++} ++ ++int acc_init() ++{ ++ if(alloc_chrdev_region(&acc_dev_number, 0, BMI_SLOT_NUM, "bmi_lcd_acc") < 0) { ++ printk(KERN_DEBUG "Unable to register accelerometer device\n"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++int acc_clean() ++{ ++ unregister_chrdev_region(MAJOR(acc_dev_number), BMI_SLOT_NUM); ++ return 0; ++} ++ ++/* BMI Functions */ ++int acc_probe (struct acc_dev *acc, int slot) ++{ ++ struct class * bmi_class; ++ struct cdev * cdev; ++ int ret; ++ ++ printk(__FUNCTION__); ++ cdev = &acc->cdev; ++ printk(KERN_DEBUG "\nAbout to cdev_init acc=%p cdev=%p\n acc_fops=%p\n", acc, cdev, &acc_fops); ++ cdev_init(cdev, &acc_fops); ++ printk(KERN_DEBUG "After cdev_init\n"); ++ ++ ret = cdev_add(cdev, acc_dev_number + slot, 1); ++ printk(KERN_DEBUG "After cdev_add" ); ++ ++ bmi_class = (struct class *) bmi_get_bmi_class(); ++ printk(KERN_DEBUG "After bmi_get_bmi_class" ); ++ acc->class_dev = device_create(bmi_class, NULL, acc_dev_number + slot, acc, "bmi_lcd_acc_m%d", slot + 1); ++ printk(KERN_DEBUG "After class_device_create" ); ++ ++ init_waitqueue_head(&acc->wq); ++ printk(KERN_DEBUG "After init_waitqueue_head" ); ++ return ret; ++} ++ ++void acc_remove (struct acc_dev *acc, int slot) ++{ ++ struct class *bmi_class; ++ int acc_major = MAJOR(acc_dev_number); ++ ++ bmi_class = (struct class *) bmi_get_bmi_class(); ++ device_destroy (bmi_class, MKDEV(acc_major, slot)); ++ ++ acc->class_dev = 0; ++ ++ cdev_del (&acc->cdev); ++} ++ +--- /dev/null ++++ git/drivers/bmi/pims/lcd/acc.h +@@ -0,0 +1,35 @@ ++#ifndef _ACC_H_ ++#define _ACC_H_ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* Accelerometer device structure */ ++struct acc_dev { ++ struct cdev cdev; ++ u8 sample[6]; ++ u8 flag; ++ struct device * class_dev; ++ wait_queue_head_t wq; ++}; ++ ++ ++int acc_open(struct inode *inode, struct file *file); ++ ++int acc_release(struct inode *inode, struct file *file); ++ ++int acc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos); ++ ++int acc_init(void); ++ ++int acc_clean(void); ++ ++/*BMI Functions */ ++void acc_remove(struct acc_dev *acc, int slot); ++ ++int acc_probe(struct acc_dev *acc, int slot); ++ ++#endif //_ACC_H_ +--- /dev/null ++++ git/drivers/bmi/pims/lcd/bmi_lcd.c +@@ -0,0 +1,1790 @@ ++/* ++ * bmi_lcd.c ++ * ++ * BMI LCD device driver ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/* ++ * Include files ++ */ ++ ++#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 ++ ++#undef ACCELEROMETER ++#define ACCELEROMETER ++ ++#ifdef ACCELEROMETER ++#include "acc.h" ++#endif //ACCELEROMETER ++ ++#define DEBUG ++#undef DEBUG ++ ++#define BMILCD_VERSION "1.2" // driver version ++#define BUF_MAX_SIZE 0x20 // spi buffer size ++#define WORK_DELAY (1) // interrupt work handler delay ++#define DEBOUNCE 10 // touch screen debounce ++#define X_PLATE 400 // touch screen X plate resistance //pjg - This is not the correct value ++#define BMI_SLOT_NUM (4) // number of BMI slots ++#define MAX_STRG (40) // Max string buffer size ++ ++#define VSYNC_DISABLE 0x0 ++#define VSYNC_ENABLE 0x1 ++ ++ // lcd ++struct lcd_interface { ++ char lcd_type[MAX_STRG]; // text description of LCD type ++ u8 suspended; // power management state ++ u8 rotation; // screen rotation ++ u8 disp; // display number (DISP0 or DISP1) ++ u8 addr_mode; // display addressing mode ++ u8 vsync_mode; // VSYNC signal enable (VSYNC_ENABLE | VSYNC_DISABLE) ++ u8 bus_if_type; // bus type (XY | FullWoBE | FullWithBE) ++ ipu_adc_sig_cfg_t adc_sig; // IPU ADC set-up parameters ++ ipu_di_signal_cfg_t di_sig; // IPU DI set-up parameters ++}; ++ ++ ++struct lcd_ctl ++{ ++ int slot; ++ struct cdev cdev; ++ struct device *class_dev; ++}; ++ ++ ++static struct lcd_interface s320x240_lcd_interface = { ++ .lcd_type = "MXCFB_SHARP_320X240", ++ .suspended = 0, ++ .rotation = IPU_ROTATE_NONE, ++ .disp = DISP0, ++ .vsync_mode = VSYNC_DISABLE, ++ .bus_if_type = XY, ++ .adc_sig = { 0, 0, 0, 0, 0, 0, 0, 0, IPU_ADC_BURST_WCS, IPU_ADC_IFC_MODE_SYS80_TYPE2, ++ 16, 0, 0, IPU_ADC_SER_NO_RW }, ++ .di_sig = { 0,0,0,0,0,0,0,0 }, //pjg - reserved for multiple LCD driver ++}; ++ ++extern void s320x240_config(int disp); ++extern void s320x240_disp_off(int disp); ++extern void s320x240_disp_on(int disp); ++ ++ ++struct bmi_lcd; ++ ++struct bmi_lcd_ops { ++ void *(*config) (int disp); // LCD configuration/initialization ++ void *(*reset) (int slot); // LCD reset ++ int *(*suspend) (struct bmi_lcd *blcd); // power management ++ int *(*resume) (struct bmi_lcd *blcd); // power management ++ int *(*disp_on) (int disp); // display on ++ int *(*disp_off) (int disp); // display off ++ int (*activate) (struct bmi_lcd *lcd, int slot); // enable LCD backlight, touchscreen, accelerometer, ... ++ int (*deactivate) (struct bmi_lcd *lcd, int slot); // disable LCD backlight, touchscreen, accelerometer, ... ++}; ++ ++struct bmi_lcd_ops s320x240_bmi_lcd_ops; ++ ++struct bmi_lcd { ++ struct lcd_interface interface; // pointer to this struct is returned by config() ++ struct bmi_lcd_ops lcd_ops; // function pointers ++}; ++ ++static struct bmi_lcd s320x240_bmi_lcd; ++ ++int register_bmi_lcd(struct bmi_lcd *blcd, int slot); ++int unregister_bmi_lcd(struct bmi_lcd *blcd, int slot); ++ ++ // private device structure ++struct pbmi_lcd ++{ ++ unsigned int lcd_cnt; // number of LCD's present ++ unsigned int active; // indication of LCD presence ++ unsigned int activated[BMI_SLOT_NUM]; // indication of LCD presence ++ ++ struct bmi_lcd *blcd[BMI_SLOT_NUM]; // BMI LCD structure - placeholder for multiple display types ++ struct bmi_device *bdev[BMI_SLOT_NUM]; // BMI device per slot ++ unsigned int interrupt[BMI_SLOT_NUM]; // input device interrupt handlers ++ char int_name[MAX_STRG]; // interrupt name ++ ++ struct input_dev *input_dev[BMI_TS_NUM]; // input device (touch screen and accelerometer) ++ struct timer_list timer[BMI_SLOT_NUM]; // touch timer ++ struct lcd_ctl ctl_dev[BMI_SLOT_NUM]; ++ int pen_down[BMI_SLOT_NUM]; ++ int scount[BMI_SLOT_NUM]; ++ ++ struct spi_device *spi[BMI_SLOT_NUM]; // touch screen device interface ++ struct semaphore sem[BMI_SLOT_NUM]; // spi semaphore ++ char rbuf[BMI_SLOT_NUM][BUF_MAX_SIZE]; // spi read buffer ++ char wbuf[BMI_SLOT_NUM][BUF_MAX_SIZE]; // spi write buffer ++ ++#ifdef ACCELEROMETER ++ struct acc_dev acc[BMI_SLOT_NUM]; ++#endif ++}; ++ ++static struct pbmi_lcd pbmi_lcd; // LCD device sructure ++ ++/* ++ * BMI set up ++ */ ++ ++ // BMI device ID table ++static struct bmi_device_id bmi_lcd_tbl[] = ++{ ++ { ++ .match_flags = BMI_DEVICE_ID_MATCH_VENDOR | BMI_DEVICE_ID_MATCH_PRODUCT, ++ .vendor = BMI_VENDOR_BUG_LABS, ++ .product = BMI_PRODUCT_LCD_SHARP_320X240, ++ .revision = BMI_ANY, ++ }, ++ { 0, }, /* terminate list */ ++}; ++ ++MODULE_DEVICE_TABLE(bmi, bmi_lcd_tbl); ++ ++/*printk(KERN_INFO "MDT: 0x%x\n", __mod_bmi_device_table);*/ ++ ++int bmi_lcd_probe(struct bmi_device *bdev); ++void bmi_lcd_remove(struct bmi_device *bdev); ++ ++// BMI driver structure ++static struct bmi_driver bmi_lcd_driver = ++{ ++ .name = "bmi_lcd", ++ .id_table = bmi_lcd_tbl, ++ .probe = bmi_lcd_probe, ++ .remove = bmi_lcd_remove, ++}; ++ ++//Accelerometer driver structure ++ ++ ++/* ++ * I2C set up ++ */ ++ ++ // I2C Slave Address ++#define BMI_IOX_I2C_ADDRESS 0x71 // 7-bit address ++#define BMI_ACC_I2C_ADDRESS 0x17 // 7-bit address ++ ++ // I2C IOX register addresses ++#define IOX_INPUT_REG 0x0 // IOX input data register ++#define IOX_OUTPUT_REG 0x1 // IOX output data register ++#define IOX_POLARITY_REG 0x2 // IOX polarity data register ++#define IOX_CONTROL 0x3 // IOX direction control register ++#define IOX_B1 (0) // bit 0 - backlight control ++#define IOX_A1_A2 (1) // bit 1 - backlight control ++#define IOX_ACC_RST_N (2) // bit 2 - acceleromter reset ++#define IOX_VSYNC_EN_N (3) // bit 3 - VSYNC output buffer enable ++#define IOX_LCD_RST_N (4) // bit 4 - LCD reset ++#define IOX_SERDES_PD_N (5) // bit 5 - SERDES power down ++#define IOX_X_INT (6) // bit 6 - accelerometer interrupt ++#define IOX_Y_INT (7) // bit 7 - accelerometer interrupt ++ ++ // I2C ACC register addresses - OKI ++#define ACC_PAGESEL 0x1E // device ready status ++ // page 0 ++#define ACC_DVRST 0x01 // device reset ++ #define ACC_DVRST_RST 0x3C // device reset ++ #define ACC_DVRST_EN 0xC3 // device enable ++#define ACC_PDWN 0x02 // osc power down ++ #define ACC_PWDN_RST 0x01 // device reset ++ #define ACC_PWDN_EN 0x00 // device enable ++#define ACC_CTRL0 0x03 // control 0 ++ #define ACC_CTRL0_CTSTR 0x40 // control 0 - temp sensor ++ #define ACC_CTRL0_CGSTRNC 0x08 // control 0 - 3-axis/no tilt ++ #define ACC_CTRL0_CGSTRC 0x04 // control 0 - 3-axis/tilt ++ #define ACC_CTRL0_CGAUTO 0x01 // control 0 - auto ++#define ACC_MODE0 0x05 // control 0 ++ #define ACC_MODE0_PDOFF 0x80 // mode 0 - disable auto power down ++ #define ACC_MODE0_RVOFF 0x40 // mode 0 - disable temp compensation ++ #define ACC_MODE0_TMPOFF 0x20 // mode 0 - disable temp measurement ++ #define ACC_MODE0_AGCON 0x10 // mode 0 - enable auto mode pitch and roll ++ #define ACC_MODE0_MAUTO 0x04 // mode 0 - enable auto termination ++ #define ACC_MODE0_GDET00 0x00 // mode 0 - g detection threshold - see ML8953 data sheet ++ #define ACC_MODE0_GDET01 0x01 // mode 0 - g detection threshold - see ML8953 data sheet ++ #define ACC_MODE0_GDET10 0x02 // mode 0 - g detection threshold - see ML8953 data sheet ++#define ACC_MODE1 0x06 // mode 1 ++ #define ACC_MODE1_MOFF 0x20 // mode 1 - disable 3-axis continuous mode ++ #define ACC_MODE1_ZAXIS 0x03 // mode 1 - Z axis ++ #define ACC_MODE1_YAXIS 0x02 // mode 1 - Y axis ++ #define ACC_MODE1_XAXIS 0x01 // mode 1 - X axis ++ #define ACC_MODE1_RAXIS 0x00 // mode 1 - Reference axis ++#define ACC_INTRQ 0x07 // interrupt request (1 = request) ++#define ACC_INTMSK 0x08 // interrupt mask (1 = masked) ++ #define ACC_INT_TREQ 0x20 // interrupt - temperature ++ #define ACC_INT_GREQ 0x08 // interrupt - acceleration/no tilt ++ #define ACC_INT_GCREQ 0x04 // interrupt - acceleration/tilt ++ #define ACC_INT_GAREQ 0x01 // interrupt - automatic ++#define ACC_TMDL 0x09 // timer LSB = (1/6.2 MHz) x 2048 x TMD ++#define ACC_TMDH 0x0A // timer MSB ++#define ACC_CFG 0x0C // configuration ++ #define ACC_CFG_REGMD 0x80 // address auto-increment ++ #define ACC_CFG_SPI3M_3 0x40 // spi mode = 3-wire ++ #define ACC_CFG_SPI3M_4 0x00 // spi mode = 4-wire ++ #define ACC_CFG_SDOCFG_T 0x10 // sdo mode = totem-pole ++ #define ACC_CFG_SDOCFG_OC 0x00 // sdo mode = open-drain ++ #define ACC_CFG_INT1EN_G 0x08 // interrupt 1 mode = g only ++ #define ACC_CFG_INT1EN_ALL 0x00 // interrupt 1 mode = all ++ #define ACC_CFG_INTLVL 0x04 // interrupt level mode ++ #define ACC_CFG_INT1CFG_T 0x02 // interrupt 1 mode = totem-pole ++ #define ACC_CFG_INT1CFG_OC 0x00 // interrupt 1 mode = open-drain ++ #define ACC_CFG_INT0CFG_T 0x01 // interrupt 0 mode = totem-pole ++ #define ACC_CFG_INT0CFG_OC 0x00 // interrupt 0 mode = open-drain ++#define ACC_INTOTM 0x0D // interrupt output conditions ++#define ACC_GAAVE 0x0E // Data averaging - automatic mode ++#define ACC_GNAVE 0x0F // Data averaging - normal mode ++#define ACC_GDTCT0L 0x11 // threshold 0 LSB ++#define ACC_GDTCT0H 0x12 // threshold 0 MSB ++#define ACC_GDTCT1L 0x13 // threshold 1 LSB ++#define ACC_GDTCT1H 0x14 // threshold 1 MSB ++#define ACC_CPURDY 0x15 // device ready status (ready = 0x01) ++ // page 1 ++#define ACC_STATUS 0x01 // measurment status ++ #define ACC_STATUS_ASTS 0x02 // acceleration measurement - automatic modes ++ #define ACC_STATUS_STS 0x01 // acceleration measurement - non-automatic modes ++#define ACC_GAXL 0x02 // g vector ++#define ACC_GAXH 0x03 // g vector ++#define ACC_GAYL 0x04 // g vector ++#define ACC_GAYH 0x05 // g vector ++#define ACC_GAZL 0x06 // g vector ++#define ACC_GAZH 0x07 // g vector ++#define ACC_GASVL 0x08 // g vector ++#define ACC_GASVH 0x09 // g vector ++#define ACC_GNXL 0x0A // g vector ++#define ACC_GNXH 0x0B // g vector ++#define ACC_GNYL 0x0C // g vector ++#define ACC_GNYH 0x0D // g vector ++#define ACC_GNZL 0x0E // g vector ++#define ACC_GNZH 0x0F // g vector ++#define ACC_GNSVL 0x10 // g vector ++#define ACC_GNSVH 0x11 // g vector ++#define ACC_PITCHL 0x12 // pitch ++#define ACC_PITCHH 0x13 // pitch ++#define ACC_ROLLL 0x14 // roll ++#define ACC_ROLLH 0x15 // roll ++#define ACC_TEMPL 0x19 // temperature ++#define ACC_TEMPH 0x1A // temperature ++ ++ // read byte from I2C IO expander ++static int ReadByte_IOX(struct i2c_adapter *adap, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ ++ /* Read Byte with Pointer */ ++ ++ rmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[0].flags = 0; /* write */ ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; /* read */ ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ret = i2c_transfer (adap, rmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "ReadByte_IOX() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++ // write byte to I2C IO expander ++static int WriteByte_IOX(struct i2c_adapter *adap, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ /* Write Byte with Pointer */ ++ ++ wmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[0].flags = 0; /* write */ ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[1].flags = 0; /* write */ ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ ret = i2c_transfer (adap, wmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "WriteByte_IOX() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++ ++#if defined ACCELEROMETER ++ // read byte from I2C acceleromter ++static int ReadByte_ACC(struct i2c_adapter *adap, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ ++ /* Read Byte with Pointer */ ++ ++ rmsg[0].addr = BMI_ACC_I2C_ADDRESS; ++ rmsg[0].flags = 0; /* write */ ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_ACC_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; /* read */ ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ret = i2c_transfer (adap, rmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "ReadByte_ACC() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++ // write byte to I2C accelerometer ++static int WriteByte_ACC(struct i2c_adapter *adap, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ /* Write Byte with Pointer */ ++ ++ wmsg[0].addr = BMI_ACC_I2C_ADDRESS; ++ wmsg[0].flags = 0; /* write */ ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_ACC_I2C_ADDRESS; ++ wmsg[1].flags = 0; /* write */ ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ ret = i2c_transfer (adap, wmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "WriteByte_ACC() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++#endif // ACCELEROMETER ++ ++/* ++ * SPI functions ++ */ ++ ++ // TSC2046 touch screen controller command register bit definitons ++#define SPI_START 0x80 // command start ++#define SPI_AT0 0x00 // read temperature - not supported ++#define SPI_AY 0x10 // read Y ++#define SPI_ABAT 0x20 // read battery - not supported ++#define SPI_AZ1 0x30 // read Z1 ++#define SPI_AZ2 0x40 // read Z2 ++#define SPI_AX 0x50 // read X ++#define SPI_AAUX 0x60 // read AUX - not supported ++#define SPI_AT1 0x70 // read temperature - not supported ++#define SPI_MODE_12 0x00 // 12-bit mode - Preferred ++#define SPI_MODE_8 0x08 // 8-bit mode ++#define SPI_MODE_DFR 0x00 // differential mode - Preferred ++#define SPI_MODE_SER 0x04 // single ended mode ++#define SPI_PD 0x00 // power down - PENIRQ enabled ++#define SPI_ADC 0x01 // ADC enabled ++#define SPI_REF 0x02 // Vref enabled - unused ++#define SPI_REF_ADC 0x03 // Vref & ADC enabled - unused ++ ++ // spi access ++static int spi_rw(struct spi_device *spi, u8 * buf, size_t len) ++{ ++ struct spi_transfer t = { ++ .tx_buf = (const void *)buf, ++ .rx_buf = buf, ++ .len = len, ++ .cs_change = 0, ++ .delay_usecs = 0, ++ }; ++ struct spi_message m; ++ ++ spi_message_init(&m); ++ ++ spi_message_add_tail(&t, &m); ++ if (spi_sync(spi, &m) != 0 || m.status != 0) ++ return -1; ++ ++ return m.actual_length; ++} ++ ++ // spi write register ++static ssize_t spi_lcd_write_reg(struct pbmi_lcd *priv, char *buf, int len, int slot) ++{ ++ int res = 0; ++ ++ down(&priv->sem[slot]); ++ ++ memset(priv->wbuf[slot], 0, BUF_MAX_SIZE); ++ priv->wbuf[slot][0] = buf[0]; ++ priv->wbuf[slot][1] = buf[1]; ++ priv->wbuf[slot][2] = buf[2]; ++ priv->wbuf[slot][3] = buf[3]; ++ res = spi_rw(priv->spi[slot], priv->wbuf[slot], len); ++ if (res != 1) { ++ up(&priv->sem[slot]); ++ return -EFAULT; ++ } ++ ++ up(&priv->sem[slot]); ++ ++ return res; ++} ++ ++ // spi read register ++static ssize_t spi_lcd_read_reg(struct pbmi_lcd *priv, char *buf, int len, int slot) ++{ ++ int res = 0; ++ ++ down(&priv->sem[slot]); ++ ++ memset(priv->wbuf[slot], 0, BUF_MAX_SIZE); ++ priv->wbuf[slot][0] = buf[0]; ++ priv->wbuf[slot][1] = buf[1]; ++ priv->wbuf[slot][2] = buf[2]; ++ priv->wbuf[slot][3] = buf[3]; ++ res = spi_rw(priv->spi[slot], priv->wbuf[slot], len); ++ if (res != 1) { ++ up(&priv->sem[slot]); ++ return -EFAULT; ++ } ++ ++ memset(priv->rbuf[slot], 0, BUF_MAX_SIZE); ++ buf[0] = priv->wbuf[slot][2]; ++ buf[1] = priv->wbuf[slot][1]; ++ ++ up(&priv->sem[slot]); ++ ++ return res; ++} ++ ++ ++// control file operations ++static int lcd_ctl_open (struct inode *, struct file *); ++static int lcd_ctl_release (struct inode *, struct file *); ++static int lcd_ctl_ioctl (struct inode *, struct file *, unsigned int, unsigned long); ++ ++struct file_operations lcd_ctl_fops = { ++ .owner = THIS_MODULE, ++ .ioctl = lcd_ctl_ioctl, ++ .open = lcd_ctl_open, ++ .release = lcd_ctl_release, ++}; ++ ++/* ++ * control device operations ++ */ ++static int lcd_ctl_major; ++ ++int lcd_ctl_init (void) ++{ ++ dev_t dev_id; ++ int retval; ++ ++ // alloc char driver with 4 minor numbers ++ ++ retval = alloc_chrdev_region(&dev_id, 0, 4, "BMI LCD Control Driver"); ++ ++ if (retval) { ++ return -1; ++ } ++ lcd_ctl_major = MAJOR(dev_id); ++ return 0; ++} ++ ++void lcd_ctl_clean (void) ++{ ++ dev_t dev_id; ++ ++ dev_id = MKDEV(lcd_ctl_major, 0); ++ unregister_chrdev_region(dev_id, 4); ++ return; ++} ++ ++int lcd_ctl_probe (struct lcd_ctl *lcd_ctl, int slot) ++{ ++ struct cdev *cdev; ++ dev_t dev_id; ++ int ret; ++ struct class *bmi_class; ++ ++ cdev = &lcd_ctl->cdev; ++ cdev_init (cdev, &lcd_ctl_fops); ++ ++ dev_id = MKDEV (lcd_ctl_major, slot); ++ ret = cdev_add (cdev, dev_id, 1); ++ ++ //Create class device ++ bmi_class = bmi_get_bmi_class (); ++ ++ lcd_ctl->class_dev = device_create (bmi_class, NULL, MKDEV(lcd_ctl_major, slot), lcd_ctl, "bmi_lcd_ctl_m%i", slot+1); ++ ++ if (IS_ERR(lcd_ctl->class_dev)) { ++ printk(KERN_ERR "Unable to create " ++ "class_device for bmi_lcd_ctl_m%i; errno = %ld\n", ++ slot+1, PTR_ERR(lcd_ctl->class_dev)); ++ lcd_ctl->class_dev = NULL; ++ } ++ lcd_ctl->slot = slot; ++ ++ return ret; ++} ++ ++void lcd_ctl_remove (struct lcd_ctl *lcd_ctl, int slot) ++{ ++ struct class *bmi_class; ++ ++ bmi_class = bmi_get_bmi_class (); ++ device_destroy (bmi_class, MKDEV(lcd_ctl_major, slot)); ++ ++ lcd_ctl->class_dev = 0; ++ ++ cdev_del (&lcd_ctl->cdev); ++ return; ++} ++ ++// open ++static int lcd_ctl_open (struct inode *inode, struct file *file) ++{ ++ struct lcd_ctl *lcd_ctl; ++ ++ lcd_ctl = container_of(inode->i_cdev, struct lcd_ctl, cdev); ++ ++ ++ // Save ctl pointer for later. ++ ++ file->private_data = lcd_ctl; ++ return 0; ++} ++ ++// release ++static int lcd_ctl_release (struct inode *inode, struct file *file) ++{ ++ struct lcd_ctl *lcd_ctl; ++ ++ lcd_ctl = container_of(inode->i_cdev, struct lcd_ctl, cdev); ++ return 0; ++} ++ ++// ioctl ++int lcd_ctl_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct lcd_ctl *lcd_ctl; ++ struct i2c_adapter *adap; ++ unsigned char iox_data[1]; ++ int slot; ++ int bl = ((__user arg) & 0x70) >> 4; ++ ++ // error if no lcd active. ++ ++ if(cmd != BMI_LCD_GETSTAT) { ++ // i2c adapter ++ lcd_ctl = container_of(inode->i_cdev, struct lcd_ctl, cdev); ++ slot = lcd_ctl->slot; ++ if (slot < 0) { ++ return -ENODEV; ++ } ++ adap = &pbmi_lcd.bdev[slot]->adap; ++ } ++ ++ // ioctl's ++ switch (cmd) { ++ case BMI_LCD_RLEDOFF: ++ bmi_set_module_gpio_data(slot, 3, 1);// Red LED=OFF ++ break; ++ case BMI_LCD_RLEDON: ++ bmi_set_module_gpio_data(slot, 3, 0);// Red LED=ON ++ break; ++ case BMI_LCD_GLEDOFF: ++ bmi_set_module_gpio_data(slot, 2, 1);// Green LED=OFF ++ break; ++ case BMI_LCD_GLEDON: ++ bmi_set_module_gpio_data(slot, 2, 0);// Green LED=ON ++ break; ++ case BMI_LCD_VSYNC_DIS: // enable VSYNC buffer tristate output ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data |= 0x08; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_VSYNC_EN: // disable VSYNC buffer tristate output ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data &= ~0x08; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_EN: // enable LCD component ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data &= ~0x10; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_DIS: // disable LCD component only ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data |= 0x10; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_SER_EN: // enable Serializer component ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data &= ~0x20; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_SER_DIS: // disable Serializer component only ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data |= 0x20; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_SETRST: // overall module reset ++ bmi_set_module_gpio_data (slot, 1, 0); // RST=0 ++ break; ++ case BMI_LCD_CLRRST: // overall module enable ++ bmi_set_module_gpio_data (slot, 1, 1); // RST=1 ++ break; ++ case BMI_LCD_SET_BL: // set backlight brightness ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data = (*iox_data & 0xFC) | bl; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_GETSTAT: ++ { ++ int *slot = ((int __user *) arg); ++ int read_data; ++ ++ *slot &= 0xF; ++ ++ // error if slot invalid ++ if((*slot < CPLD_M1) || (*slot > CPLD_M4)) ++ return -ENODEV; ++ ++ // error if no lcd in chosen slot ++ if(pbmi_lcd.bdev[*slot] == 0) ++ return -ENODEV; ++ ++ // i2c adapter ++ adap = &pbmi_lcd.bdev[*slot]->adap; ++ ++ if(ReadByte_IOX(adap, IOX_INPUT_REG, iox_data)) ++ return -ENODEV; ++ ++ read_data = *iox_data | (bmi_read_gpio_data_reg(*slot) << 8); ++ ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ } ++ break; ++ case BMI_LCD_ACTIVATE: //pjg fix/test ++ // check for opposite side already active ++ switch(slot) { // opposite side ++ case 0: ++ if(pbmi_lcd.activated[2] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 2 already active)\n", slot); ++ bmi_slot_power_off(0); ++ return -ENODEV; ++ } ++ break; ++ case 1: ++ if(pbmi_lcd.activated[3] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 3 already active)\n", slot); ++ bmi_slot_power_off(1); ++ return -ENODEV; ++ } ++ break; ++ case 2: ++ if(pbmi_lcd.activated[0] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 0 already active)\n", slot); ++ bmi_slot_power_off(2); ++ return -ENODEV; ++ } ++ break; ++ case 3: ++ if(pbmi_lcd.activated[1] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 1 already active)\n", slot); ++ bmi_slot_power_off(3); ++ return -ENODEV; ++ } ++ break; ++ } ++ // activate ++ if((!pbmi_lcd.activated[slot]) && (pbmi_lcd.bdev[slot] != 0)) { ++ bmi_lcd_probe(pbmi_lcd.bdev[slot]); ++ } ++ break; ++ case BMI_LCD_DEACTIVATE: ++ if(pbmi_lcd.activated[slot]) { ++ disable_irq_nosync(pbmi_lcd.interrupt[slot]); ++ pbmi_lcd.activated[slot] = 0; ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data = (*iox_data & 0xF8); ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ bmi_slot_power_off(slot); ++ } ++ break; ++ case BMI_LCD_SUSPEND: ++ printk(KERN_ERR "BMI_LCD_SUSPEND NOT IMPLEMENTED\n"); //pjg ++ break; ++ case BMI_LCD_RESUME: ++ printk(KERN_ERR "BMI_LCD_RESUME NOT IMPLEMENTED\n"); //pjg ++ break; ++ default: ++ return -ENOTTY; ++ } ++ return 0; ++} ++ ++ ++/* ++ * BMI functions ++ */ ++ ++static irqreturn_t module_irq_handler(int irq, void *dummy); ++void bmi_lcd_config(struct bmi_lcd *lcd, int disp); ++ ++ // probe ++int bmi_lcd_probe(struct bmi_device *bdev) ++{ ++#if defined ACCELEROMETER ++ unsigned char acc_data[1]; ++#endif // ACCELEROMETER ++ unsigned char iox_data[1]; ++ int slot = bdev->info->slot; ++ struct i2c_adapter *adap; ++ struct bmi_lcd *lcd; ++ char buf[4]; ++ /*int first_time = 1;*/ ++ ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d\n", slot); ++ ++ // check for opposite side already active ++ switch(slot) { // opposite side ++ case 0: ++ if(pbmi_lcd.activated[2] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 2 already active)\n", slot); ++ bmi_slot_power_off(0); ++ /*bmi_slot_power_off(2);*/ ++ pbmi_lcd.bdev[0] = bdev; ++ /*bdev = pbmi_lcd.bdev[2]; ++ slot = 2; ++ first_time = 0;*/ ++ return 0; ++ } ++ break; ++ case 1: ++ if(pbmi_lcd.activated[3] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 3 already active)\n", slot); ++ bmi_slot_power_off(1); ++ /*bmi_slot_power_off(3);*/ ++ pbmi_lcd.bdev[1] = bdev; ++ /*bdev = pbmi_lcd.bdev[3]; ++ slot = 3; ++ first_time = 0;*/ ++ return 0; ++ } ++ break; ++ case 2: ++ if(pbmi_lcd.activated[0] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 0 already active)\n", slot); ++ bmi_slot_power_off(2); ++ /*bmi_slot_power_off(0);*/ ++ pbmi_lcd.bdev[2] = bdev; ++ /*bdev = pbmi_lcd.bdev[0]; ++ slot = 0; ++ first_time = 0;*/ ++ return 0; ++ } ++ break; ++ case 3: ++ if(pbmi_lcd.activated[1] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 1 already active)\n", slot); ++ bmi_slot_power_off(3); ++ /*bmi_slot_power_off(1);*/ ++ pbmi_lcd.bdev[3] = bdev; ++ /*bdev = pbmi_lcd.bdev[1]; ++ slot = 1; ++ first_time = 0;*/ ++ return 0; ++ } ++ break; ++ } ++ ++ adap = &bdev->adap; ++ bmi_slot_power_on(slot); ++ ++ mdelay(500); ++ ++ if (lcd_ctl_probe(&pbmi_lcd.ctl_dev[slot], slot)) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d control device node error...\n", slot); ++ return -ENODEV; ++ } ++ ++ // configure IOX ++ // [7:6]=interrupts, [5]=SER_PD*, [4]=LCD_RST*, [3]=VSYNC_OE*, [2]=ACC_RST*, [1:0]=backlight ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, 0xFF)) // normal - no accelerometer interrupts ++ return -ENODEV; ++ ++ // normal operation - no accelerometer interrupts ++ if(WriteByte_IOX(adap, IOX_CONTROL, 0x00)) // IOX[7:0]=OUT ++ return -ENODEV; ++ ++ // clear interrupts ++ if(ReadByte_IOX(adap, IOX_INPUT_REG, iox_data)) ++ return -ENODEV; ++ ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d iox data = %x\n", slot, *iox_data); ++ ++#if defined ACCELEROMETER ++ // accelerometer ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d hardware version = 0x%x\n", slot, bdev->epraw.revision_msb); ++ ++ // check for PCB revision >= 1.2 ++ if(bdev->epraw.revision_msb >= 0x12) { ++ ++ // normal IOX operation - accelerometer interrupts ++ if(WriteByte_IOX(adap, IOX_CONTROL, 0xC0)) // IOX[7:6]=IN, IOX[5:0]=OUT ++ return -ENODEV; ++ ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, 0xFB)) // reset OKI accelerometer ++ return -ENODEV; ++ ++ mdelay(2); ++ ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, 0xFF)) // enable OKI accelerometer ++ return -ENODEV; ++ ++ mdelay(2); ++ ++ // write PAGESEL ++ *acc_data = 0x0; ++ if(WriteByte_ACC(adap, ACC_PAGESEL, *acc_data)) ++ return -ENODEV; ++ ++ // read device to verify existance ++ if(ReadByte_ACC(adap, ACC_CPURDY, acc_data)) ++ return -ENODEV; ++ ++ // set TMD = 0x300 (~250 ms) ++ *acc_data = 0x5; ++ if(WriteByte_ACC(adap, ACC_TMDH, *acc_data)) ++ return -ENODEV; ++ ++ *acc_data = 0x0; ++ if(WriteByte_ACC(adap, ACC_TMDL, *acc_data)) ++ return -ENODEV; ++ ++ // set INTOTM ++ *acc_data = 0x00; ++ if(WriteByte_ACC(adap, ACC_INTOTM, *acc_data)) ++ return -ENODEV; ++ ++ // set GxAVE ++ *acc_data = 0x0; ++ if(WriteByte_ACC(adap, ACC_GAAVE, *acc_data)) ++ return -ENODEV; ++ ++ // set GDTCT[01] ++ *acc_data = 0x00; ++ if(WriteByte_ACC(adap, ACC_GDTCT0L, *acc_data)) ++ return -ENODEV; ++ ++ *acc_data = 0x00; ++ if(WriteByte_ACC(adap, ACC_GDTCT0H, *acc_data)) ++ return -ENODEV; ++ ++ *acc_data = 0x00; ++ if(WriteByte_ACC(adap, ACC_GDTCT1L, *acc_data)) ++ return -ENODEV; ++ ++ *acc_data = 0x00; ++ if(WriteByte_ACC(adap, ACC_GDTCT1H, *acc_data)) ++ return -ENODEV; ++ ++ // set MODE0 ++ *acc_data = ACC_MODE0_PDOFF | ACC_MODE0_TMPOFF | ACC_MODE0_AGCON | ACC_MODE0_MAUTO | ACC_MODE0_GDET10; ++ if(WriteByte_ACC(adap, ACC_MODE0, *acc_data)) ++ return -ENODEV; ++ ++ // set CFG ++ *acc_data = ACC_CFG_REGMD | ACC_CFG_INTLVL; ++ if(WriteByte_ACC(adap, ACC_CFG, *acc_data)) ++ return -ENODEV; ++ ++ // set INTMSK ++ *acc_data = 0xFE; ++ if(WriteByte_ACC(adap, ACC_INTMSK, *acc_data)) ++ return -ENODEV; ++ ++ // set CTRL0 ++ *acc_data = ACC_CTRL0_CGAUTO; ++ if(WriteByte_ACC(adap, ACC_CTRL0, *acc_data)) ++ return -ENODEV; ++ ++ // write PAGESEL ++ *acc_data = 0x1; ++ if(WriteByte_ACC(adap, ACC_PAGESEL, *acc_data)) ++ return -ENODEV; ++ ++ acc_probe(&pbmi_lcd.acc[slot], slot); ++ ++ } else { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d hardware version = 0x%x (accelerometer not supported)\n", slot, bdev->epraw.revision_msb); ++ } ++#endif // ACCELEROMETER ++ ++ // reset serial link (master) ++ if((slot == 0) || (slot == 2)) { ++ bmi_lcd_inactive(0); ++ } else { ++ bmi_lcd_inactive(1); ++ } ++ ++ // configure GPIO ++ // turn LED's on ++ bmi_set_module_gpio_data(slot, 3, 0); // Red LED=ON ++ bmi_set_module_gpio_data(slot, 2, 0); // Green LED=ON ++ ++ // assert reset ++ bmi_set_module_gpio_data(slot, 1, 0); // RST=0 ++ ++ // set GPIO direction ++ bmi_set_module_gpio_dir(slot, 3, BMI_GPIO_OUT); ++ bmi_set_module_gpio_dir(slot, 2, BMI_GPIO_OUT); ++ bmi_set_module_gpio_dir(slot, 1, BMI_GPIO_OUT); ++ bmi_set_module_gpio_dir(slot, 0, BMI_GPIO_IN); // real-time pen int state ++ ++ mdelay(200); ++ ++ // turn LED's off ++ bmi_set_module_gpio_data(slot, 3, 1); // Red LED=OFF ++ bmi_set_module_gpio_data(slot, 2, 1); // Green LED=OFF ++ ++ // deassert reset (module) ++ bmi_set_module_gpio_data(slot, 1, 1); // RST=1 ++ ++ mdelay(500); ++ ++ // unreset serial link (master) ++ if((slot == 0) || (slot == 2)) { ++ mdelay(2); ++ bmi_lcd_active(0, 0x0, LCD_MODE_I80); ++ } else { ++ mdelay(2); ++ bmi_lcd_active(1, 0x0, LCD_MODE_I80); ++ } ++ ++ ++ // set up bdev/pbmi_lcd pointers ++ bmi_device_set_drvdata(bdev, &pbmi_lcd); ++ pbmi_lcd.bdev[slot] = bdev; ++ ++ // spi set-up ++ if (bmi_device_spi_setup(bdev, 2000000, SPI_MODE_2, 32)) { ++ printk(KERN_ERR "bmi_lcd.c: Unable to setup spi%d\n", slot); ++ bmi_device_set_drvdata(bdev, NULL); ++ pbmi_lcd.bdev[slot] = NULL; ++ bmi_slot_power_off(slot); ++ return -EFAULT; ++ } ++ ++ bmi_slot_spi_enable(slot); ++ pbmi_lcd.spi[slot] = bmi_device_get_spi(bdev); ++ ++ ++ // check spi access and enable touch screen ++ memset(buf, 0, 4); ++ buf[3] = SPI_START | SPI_PD; ++ if(spi_lcd_write_reg(&pbmi_lcd, buf, 1, slot) != 1) { ++ printk(KERN_WARNING "bmi_lcd.c: Unable set-up spi for bmi_lcd %d\n", slot); ++ bmi_device_set_drvdata(bdev, NULL); ++ pbmi_lcd.bdev[slot] = NULL; ++ pbmi_lcd.spi[slot] = NULL; ++ bmi_device_spi_cleanup(bdev); ++ bmi_slot_spi_disable(slot); ++ bmi_slot_power_off(slot); ++ return -EFAULT; ++ } ++ ++ ++ // complete pbmi_lcd set-up ++ pbmi_lcd.lcd_cnt++; ++ pbmi_lcd.active = 1; ++ pbmi_lcd.activated[slot] = 1; ++ ++ ++ mdelay(100); ++ ++ lcd = pbmi_lcd.blcd[slot]; ++ if((slot == 0) || (slot == 2)) { ++ mdelay(2); ++ bmi_lcd_config(lcd, 0); ++ mdelay(2); ++ } else { ++ mdelay(2); ++ bmi_lcd_config(lcd, 1); ++ mdelay(2); ++ } ++ ++ ++ // request input event interrupt handler ++ pbmi_lcd.interrupt[0] = M1_IRQ; ++ pbmi_lcd.interrupt[1] = M2_IRQ; ++ pbmi_lcd.interrupt[2] = M3_IRQ; ++ pbmi_lcd.interrupt[3] = M4_IRQ; ++ snprintf(pbmi_lcd.int_name, sizeof(pbmi_lcd.int_name), "bmi_lcd%d", slot); ++ if (request_irq(pbmi_lcd.interrupt[slot], &module_irq_handler, 0, pbmi_lcd.int_name, &pbmi_lcd)) { ++ printk( KERN_ERR "bmi_lcd.c: Can't allocate irq %d or find lcd in slot %d\n", pbmi_lcd.interrupt[slot], slot); ++ bmi_device_set_drvdata(bdev, NULL); ++ pbmi_lcd.bdev[slot] = NULL; ++ pbmi_lcd.spi[slot] = NULL; ++ bmi_device_spi_cleanup(bdev); ++ bmi_slot_power_off(slot); ++ return -EBUSY; ++ } ++ ++ // check GPIO status ++ printk(KERN_INFO "bmi_lcd.c: slot %d gpio = %x\n", slot, bmi_read_gpio_data_reg(slot)); ++ printk(KERN_INFO "bmi_lcd.c: LCD count = %d\n", pbmi_lcd.lcd_cnt); ++ ++ return 0; ++} ++ ++extern struct delayed_work bmilcd_work0; ++extern struct delayed_work bmilcd_work1; ++extern struct delayed_work bmilcd_work2; ++extern struct delayed_work bmilcd_work3; ++ ++ // remove ++void bmi_lcd_remove(struct bmi_device *bdev) ++{ ++ int slot = bdev->info->slot; ++ ++ if(pbmi_lcd.activated[slot] == 0) ++ return; ++ ++ switch(slot) { ++ case 0: ++ cancel_delayed_work(&bmilcd_work0); ++ break; ++ case 1: ++ cancel_delayed_work(&bmilcd_work1); ++ break; ++ case 2: ++ cancel_delayed_work(&bmilcd_work2); ++ break; ++ case 3: ++ cancel_delayed_work(&bmilcd_work3); ++ break; ++ } ++ lcd_ctl_remove(&pbmi_lcd.ctl_dev[slot], slot); ++ ++ free_irq(pbmi_lcd.interrupt[slot], &pbmi_lcd); ++ ++ bmi_set_module_gpio_dir (slot, 3, BMI_GPIO_IN); ++ bmi_set_module_gpio_dir (slot, 2, BMI_GPIO_IN); ++ bmi_set_module_gpio_dir (slot, 1, BMI_GPIO_IN); ++ bmi_set_module_gpio_dir (slot, 0, BMI_GPIO_IN); ++ ++ // bmi/spi clean-up ++ bmi_device_spi_cleanup(bdev); ++ pbmi_lcd.spi[slot] = NULL; ++ bmi_slot_spi_disable(slot); ++ ++ //de-attach driver-specific struct from bmi_device structure ++ bmi_device_set_drvdata (bdev, NULL); ++ ++ // deactivate ++ pbmi_lcd.activated[slot] = 0; ++ pbmi_lcd.bdev[slot] = 0; ++ pbmi_lcd.lcd_cnt--; ++ ++ if((pbmi_lcd.activated[0] == 0) && (pbmi_lcd.activated[2] == 0)) { ++ bmi_lcd_inactive(0); // disable serializer ++ } ++ ++ if((pbmi_lcd.activated[1] == 0) && (pbmi_lcd.activated[3] == 0)) { ++ bmi_lcd_inactive(1); // disable serializer ++ } ++ ++ if((pbmi_lcd.activated[0] == 0) && (pbmi_lcd.activated[1] == 0) && ++ (pbmi_lcd.activated[2] == 0) && (pbmi_lcd.activated[3] == 0)) { ++ pbmi_lcd.active = -1; ++ } ++ ++ // enable LCD on opposite side ++ switch(slot) { ++ case 0: ++ if(pbmi_lcd.bdev[2] != 0) ++ bmi_lcd_probe(pbmi_lcd.bdev[2]); ++ break; ++ case 1: ++ if(pbmi_lcd.bdev[3] != 0) ++ bmi_lcd_probe(pbmi_lcd.bdev[3]); ++ break; ++ case 2: ++ if(pbmi_lcd.bdev[0] != 0) ++ bmi_lcd_probe(pbmi_lcd.bdev[0]); ++ break; ++ case 3: ++ if(pbmi_lcd.bdev[1] != 0) ++ bmi_lcd_probe(pbmi_lcd.bdev[1]); ++ break; ++ } ++ ++#ifdef ACCELEROMETER ++ acc_remove(&pbmi_lcd.acc[slot], slot); ++#endif ++ printk(KERN_INFO "bmi_lcd.c: LCD count = %d\n", pbmi_lcd.lcd_cnt); ++ ++ return; ++} ++ ++/* ++ * Input interrupt handler and support routines ++ */ ++ ++static void update_pen_state(void *arg, int slot, int x, int y, int pressure) ++{ ++ struct pbmi_lcd *pbmi_lcd = (struct pbmi_lcd *)arg; ++ int sync = 0; ++ ++ if (pressure) ++ { ++ if((slot == 0) || (slot == 2)) ++ { ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M13], ABS_Y, y); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M13], ABS_X, x); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M13], ABS_PRESSURE, pressure); ++ } ++ else ++ { ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M24], ABS_Y, y); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M24], ABS_X, x); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M24], ABS_PRESSURE, pressure); ++ } ++ ++ if (!pbmi_lcd->pen_down[slot]) ++ { ++ if((slot == 0) || (slot == 2)) ++ { ++ input_report_key(pbmi_lcd->input_dev[BMI_TS_M13], BTN_TOUCH, 1); ++ } ++ else ++ { ++ input_report_key(pbmi_lcd->input_dev[BMI_TS_M24], BTN_TOUCH, 1); ++ } ++ ++ } ++ sync = 1; ++ } ++ else if (pbmi_lcd->pen_down[slot]) ++ { ++ if((slot == 0) || (slot == 2)) ++ { ++ input_report_key(pbmi_lcd->input_dev[BMI_TS_M13], BTN_TOUCH, 0); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M13], ABS_PRESSURE, 0); ++ } ++ else ++ { ++ input_report_key(pbmi_lcd->input_dev[BMI_TS_M24], BTN_TOUCH, 0); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M24], ABS_PRESSURE, 0); ++ } ++ sync = 1; ++ } ++ ++ if (sync) ++ { ++ if((slot == 0) || (slot == 2)) ++ { ++ input_sync(pbmi_lcd->input_dev[BMI_TS_M13]); ++ } ++ else ++ { ++ input_sync(pbmi_lcd->input_dev[BMI_TS_M24]); ++ } ++ } ++ pbmi_lcd->pen_down[slot] = pressure ? 1 : 0; ++ ++} ++ ++ ++void bmilcd_input_work(void *arg, int slot); ++ ++void bmilcd_input_work0(struct work_struct * work) { ++ bmilcd_input_work(&pbmi_lcd, 0); ++} ++ ++void bmilcd_input_work1(struct work_struct * work) { ++ bmilcd_input_work(&pbmi_lcd, 1); ++} ++ ++void bmilcd_input_work2(struct work_struct * work) { ++ bmilcd_input_work(&pbmi_lcd, 2); ++} ++ ++void bmilcd_input_work3(struct work_struct * work) { ++ bmilcd_input_work(&pbmi_lcd, 3); ++} ++ ++DECLARE_DELAYED_WORK(bmilcd_work0, bmilcd_input_work0); ++DECLARE_DELAYED_WORK(bmilcd_work1, bmilcd_input_work1); ++DECLARE_DELAYED_WORK(bmilcd_work2, bmilcd_input_work2); ++DECLARE_DELAYED_WORK(bmilcd_work3, bmilcd_input_work3); ++ ++// work handler ++void bmilcd_input_work(void *arg, int slot) { ++ struct pbmi_lcd *pbmi_lcd = (struct pbmi_lcd *)arg; ++#if defined ACCELEROMETER ++ struct i2c_adapter *adap = &pbmi_lcd->bdev[slot]->adap; ++ unsigned char acc_data[1]; ++ static int pitch = 0; ++ static int roll = 0; ++ static int gx = 0; ++ static int gy = 0; ++ ++#endif // ACCELEROMETER ++ unsigned char buf[4]; ++ int x = 0; ++ int y = 0; ++ int z1 = 0; ++ int z2 = 0; ++ int pressure = 0; ++ int debounce; ++ int penirq; ++ ++#if defined DEBUG ++ printk(KERN_INFO "bmi_lcd.c: bmi_lcd_input work (slot %d)\n", slot); ++#endif ++ ++ if(pbmi_lcd->bdev[slot] == 0) { ++ printk(KERN_INFO "bmi_lcd.c: bmi_lcd_input work called with no bdev active (slot %d)\n", slot); ++ return; ++ } ++ ++#if defined ACCELEROMETER ++ if(pbmi_lcd->bdev[slot]->epraw.revision_msb >= 0x12) { ++ ++ // orientation ++ // read ROLL ++ if(ReadByte_ACC(adap, ACC_ROLLH, acc_data)) ++ goto touch; ++ roll = (0x0000 | *acc_data) << 8; ++ ++ if(ReadByte_ACC(adap, ACC_ROLLL, acc_data)) ++ goto touch; ++ roll = roll | *acc_data; ++ // read PITCH ++ if(ReadByte_ACC(adap, ACC_PITCHH, acc_data)) ++ goto touch; ++ pitch = (0x0000 | *acc_data) << 8; ++ ++ if(ReadByte_ACC(adap, ACC_PITCHL, acc_data)) ++ goto touch; ++ pitch = pitch | *acc_data; ++ ++ ++ ++ ++ if(ReadByte_ACC(adap, ACC_GAZH, acc_data)) ++ goto touch; ++ pbmi_lcd->acc[slot].sample[0] = *acc_data; ++ ++ if(ReadByte_ACC(adap, ACC_GAZL, acc_data)) ++ goto touch; ++ pbmi_lcd->acc[slot].sample[1] = *acc_data; ++ ++ if(ReadByte_ACC(adap, ACC_GAYH, acc_data)) ++ goto touch; ++ pbmi_lcd->acc[slot].sample[2] = *acc_data; ++ gy = *acc_data << 8; ++ ++ if(ReadByte_ACC(adap, ACC_GAYL, acc_data)) ++ goto touch; ++ pbmi_lcd->acc[slot].sample[3] = *acc_data; ++ gy = gy | *acc_data; ++ ++ if(ReadByte_ACC(adap, ACC_GAXH, acc_data)) ++ goto touch; ++ pbmi_lcd->acc[slot].sample[4] = *acc_data; ++ gx = *acc_data << 8; ++ ++ if(ReadByte_ACC(adap, ACC_GAXL, acc_data)) ++ goto touch; ++ pbmi_lcd->acc[slot].sample[5] = *acc_data; ++ gx = gx | *acc_data; ++ ++ //wake up any read's ++ pbmi_lcd->acc[slot].flag = 1; ++ wake_up_interruptible(&pbmi_lcd->acc[slot].wq); ++ ++ // read STATUS ++ if(ReadByte_ACC(adap, ACC_STATUS, acc_data)) ++ goto touch; ++ ++ if((*acc_data & 0x1) == 0) { ++ ++ // write PAGESEL ++ *acc_data = 0x0; ++ if(WriteByte_ACC(adap, ACC_PAGESEL, *acc_data)) ++ goto touch; ++ ++ // read INTRQ ++ if(ReadByte_ACC(adap, ACC_INTRQ, acc_data)) ++ goto touch; ++ } ++ ++ // write PAGESEL ++ *acc_data = 0x1; ++ if(WriteByte_ACC(adap, ACC_PAGESEL, *acc_data)) ++ goto touch; ++ ++ // report orientation ++ // printk(KERN_INFO "bmi_lcd.c: bmi_lcd_input work (slot %d) pitch=0x%x, roll=0x%x, ABS_MISC=0x%x\n", ++ // slot, pitch, roll, pitch << 16 | roll); //pjg - debug ++ ++ input_report_abs(pbmi_lcd->input_dev[slot], ABS_MISC, (pitch << 16) | roll); ++ input_sync(pbmi_lcd->input_dev[slot]); ++ } ++#endif // ACCELEROMETER ++ ++ ++ // read touch screen - X, Y, TOUCH, PRESSURE ++ touch: ++ penirq = bmi_slot_status_irq_state(slot); ++ /*printk(KERN_INFO "bmi_lcd.c: IRQ Status %d (slot %d) %d\n", penirq, slot,msecs_to_jiffies(10));*/ ++ ++ if (pbmi_lcd->activated[slot] && penirq) ++ { ++ ++ for(debounce = 0; debounce < DEBOUNCE; debounce++) ++ { ++ ++ memset(buf, 0, 4); ++ buf[3] = SPI_START | SPI_AY | SPI_MODE_12 | SPI_MODE_DFR | SPI_ADC; ++ spi_lcd_read_reg(pbmi_lcd, buf, 1, slot); ++ y = (((buf[0] << 5) | buf[1] >> 3)) & 0xFFF; ++ ++ memset(buf, 0, 4); ++ buf[3] = SPI_START | SPI_AX | SPI_MODE_12 | SPI_MODE_DFR | SPI_ADC; ++ spi_lcd_read_reg(pbmi_lcd, buf, 1, slot); ++ x = (((buf[0] << 5) | buf[1]) >> 3) & 0xFFF; ++ ++ memset(buf, 0, 4); ++ buf[3] = SPI_START | SPI_AZ1 | SPI_MODE_12 | SPI_MODE_DFR | SPI_ADC; ++ spi_lcd_read_reg(pbmi_lcd, buf, 1, slot); ++ z1 = (((buf[0] << 5) | buf[1]) >> 3) & 0xFFF; ++ ++ memset(buf, 0, 4); ++ buf[3] = SPI_START | SPI_AZ2 | SPI_MODE_12 | SPI_MODE_DFR | SPI_ADC; ++ spi_lcd_read_reg(pbmi_lcd, buf, 1, slot); ++ z2 = (((buf[0] << 5) | buf[1]) >> 3) & 0xFFF; ++ mdelay(1); ++ } ++ ++ if(x && y && z1 && z2) ++ pressure = (X_PLATE * x / 4096) * ((z2 / z1) - 1); ++ ++ x = 4096 - x; ++ y = 4096 - y; ++ ++ if (pressure < 70) ++ { ++ if (pbmi_lcd->scount) ++ update_pen_state(arg, slot, x, y, pressure); ++ else ++ { ++ pbmi_lcd->scount[slot]++; ++ /*update_pen_state(arg, slot, 0, 0, pressure);*/ ++ } ++ } ++ ++ switch(slot) ++ { ++ case BMI_TS_M1: ++ schedule_delayed_work(&bmilcd_work0, WORK_DELAY); ++ break; ++ case BMI_TS_M2: ++ schedule_delayed_work(&bmilcd_work1, WORK_DELAY); ++ break; ++ case BMI_TS_M3: ++ schedule_delayed_work(&bmilcd_work2, WORK_DELAY); ++ break; ++ case BMI_TS_M4: ++ schedule_delayed_work(&bmilcd_work3, WORK_DELAY); ++ break; ++ } ++ /* printk(KERN_INFO "bmi_lcd.c: work scheduled on (slot %d)\n", slot); */ ++ /*buf[3] = SPI_START | SPI_PD; ++ spi_lcd_write_reg(pbmi_lcd, buf, 1, slot);*/ ++ } ++ ++ else ++ { ++ /*printk(KERN_INFO "bmi_lcd.c: Pen up on (slot %d)\n", slot);*/ ++ memset(buf, 0, 4); ++ buf[3] = SPI_START | SPI_PD; ++ spi_lcd_write_reg(pbmi_lcd, buf, 1, slot); ++ update_pen_state(arg,slot, 0, 0, 0); ++ enable_irq(pbmi_lcd->interrupt[slot]); ++ } ++ ++} ++ ++ ++// interrupt handler ++static irqreturn_t module_irq_handler(int irq, void *dummy) ++{ ++ disable_irq_nosync(irq); ++ /*printk(KERN_INFO "bmi_lcd.c: Interupt on (slot %d)\n", irq);*/ ++ switch(irq) ++ { ++ case M1_IRQ: ++ schedule_delayed_work(&bmilcd_work0, WORK_DELAY); ++ pbmi_lcd.scount[BMI_TS_M1] = 0; ++ break; ++ case M2_IRQ: ++ schedule_delayed_work(&bmilcd_work1, WORK_DELAY); ++ pbmi_lcd.scount[BMI_TS_M2] = 0; ++ break; ++ case M3_IRQ: ++ schedule_delayed_work(&bmilcd_work2, WORK_DELAY); ++ pbmi_lcd.scount[BMI_TS_M3] = 0; ++ break; ++ case M4_IRQ: ++ schedule_delayed_work(&bmilcd_work3, WORK_DELAY); ++ pbmi_lcd.scount[BMI_TS_M4] = 0; ++ break; ++ } ++ return IRQ_HANDLED; ++} ++ ++ ++ // BMI LCD fops ++void bmi_lcd_config(struct bmi_lcd *lcd, int disp) ++{ ++ if(pbmi_lcd.active == -1) { ++ return; ++ } ++ ++ if((lcd) && (lcd->lcd_ops.config)) { ++ lcd->lcd_ops.config(disp); ++ } ++} ++ ++void bmi_lcd_reset(struct bmi_lcd *lcd, int slot) ++{ ++ if(pbmi_lcd.active == -1) { ++ return; ++ } ++ ++ if((lcd) && (lcd->lcd_ops.reset)) { ++ lcd->lcd_ops.reset(slot); ++ } ++} ++ ++int register_bmi_lcd(struct bmi_lcd *lcd, int slot) //pjg - placeholder for multiple LCD types ++{ ++ if(!lcd) { ++ return -1; ++ } ++ if((slot < 0) || (slot > 3)) { ++ return -1; ++ } ++ if(pbmi_lcd.blcd[slot]) { ++ return -1; ++ } ++ else { ++ pbmi_lcd.blcd[slot] = lcd; ++ } ++ ++ if(lcd->lcd_ops.activate) { ++ lcd->lcd_ops.activate(lcd, slot); ++ } ++ ++ return 0; ++} ++ ++int unregister_bmi_lcd(struct bmi_lcd *lcd, int slot) //pjg - placeholder for multiple LCD types ++{ ++ if (!lcd) { ++ return -1; ++ } ++ if ((slot < 0) || (slot > 3)) { ++ return -1; ++ } ++ if (pbmi_lcd.blcd[slot] != lcd) { ++ return -1; ++ } ++ else { ++ pbmi_lcd.blcd [slot] = 0; ++ lcd->lcd_ops.deactivate(lcd, slot); ++ } ++ return 0; ++} ++ ++/* ++ * Module functions ++ */ ++ ++char const input_name0[MAX_STRG] = "bmi_lcd_ts0"; ++char const input_name1[MAX_STRG] = "bmi_lcd_ts1"; ++char const input_name2[MAX_STRG] = "bmi_lcd_ts2"; ++char const input_name3[MAX_STRG] = "bmi_lcd_ts3"; ++char const input_name4[MAX_STRG] = "bmi_lcd_ts4"; ++char const input_name5[MAX_STRG] = "bmi_lcd_ts5"; ++char const input_name6[MAX_STRG] = "bmi_lcd_ts6"; ++ ++static __init int bmi_lcd_init(void) ++{ ++ int ts; ++ int rc = 0; ++ ++ // No lcd is active. ++ pbmi_lcd.active = -1; ++ pbmi_lcd.activated[0] = 0; ++ pbmi_lcd.activated[1] = 0; ++ pbmi_lcd.activated[2] = 0; ++ pbmi_lcd.activated[3] = 0; ++ ++ // set up control character device - bmi_lcd_control ++ rc = lcd_ctl_init(); ++ if(rc) { ++ printk(KERN_ERR "bmi_lcd.c: Can't allocate bmi_lcd_control device\n"); ++ return rc; ++ } ++ ++ // Allocate and Register input device. - bmi_lcd_ts[BMI_TS_M1:BMI_TS_M1234] ++ for(ts = BMI_TS_M1; ts < BMI_TS_NUM; ts++) { ++ pbmi_lcd.input_dev[ts] = input_allocate_device(); ++ if(!pbmi_lcd.input_dev[ts]) { ++ printk(KERN_ERR "bmi_lcd_init: Can't allocate input_dev[ts]\n"); ++ return -ENOMEM; ++ } ++ ++ // set up input device ++ switch(ts) { ++ case BMI_TS_M1: ++ pbmi_lcd.input_dev[BMI_TS_M1]->name = input_name0; ++ pbmi_lcd.input_dev[BMI_TS_M1]->phys = input_name0; ++ break; ++ case BMI_TS_M2: ++ pbmi_lcd.input_dev[BMI_TS_M2]->name = input_name1; ++ pbmi_lcd.input_dev[BMI_TS_M2]->phys = input_name1; ++ break; ++ case BMI_TS_M3: ++ pbmi_lcd.input_dev[BMI_TS_M3]->name = input_name2; ++ pbmi_lcd.input_dev[BMI_TS_M3]->phys = input_name2; ++ break; ++ case BMI_TS_M4: ++ pbmi_lcd.input_dev[BMI_TS_M4]->name = input_name3; ++ pbmi_lcd.input_dev[BMI_TS_M4]->phys = input_name3; ++ break; ++ case BMI_TS_M13: ++ pbmi_lcd.input_dev[BMI_TS_M13]->name = input_name4; ++ pbmi_lcd.input_dev[BMI_TS_M13]->phys = input_name4; ++ break; ++ case BMI_TS_M24: ++ pbmi_lcd.input_dev[BMI_TS_M24]->name = input_name5; ++ pbmi_lcd.input_dev[BMI_TS_M24]->phys = input_name5; ++ break; ++ case BMI_TS_M1234: ++ pbmi_lcd.input_dev[BMI_TS_M1234]->name = input_name6; ++ pbmi_lcd.input_dev[BMI_TS_M1234]->phys = input_name6; ++ break; ++ } ++ pbmi_lcd.input_dev[ts]->id.bustype = BUS_BMI; ++ //pbmi_lcd.input_dev[ts]->private = &pbmi_lcd; ++ pbmi_lcd.input_dev[ts]->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY); ++ pbmi_lcd.input_dev[ts]->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS); ++ pbmi_lcd.input_dev[ts]->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH); ++ pbmi_lcd.input_dev[ts]->absbit[BIT_WORD(ABS_X)] |= BIT_MASK(ABS_X); ++ pbmi_lcd.input_dev[ts]->absbit[BIT_WORD(ABS_Y)] |= BIT_MASK(ABS_Y); ++ pbmi_lcd.input_dev[ts]->absbit[BIT_WORD(ABS_PRESSURE)] |= BIT_MASK(ABS_PRESSURE); ++ pbmi_lcd.input_dev[ts]->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); ++ input_set_abs_params(pbmi_lcd.input_dev[ts], ABS_X, BMI_LCD_MIN_XC, BMI_LCD_MAX_XC, 0, 0); ++ input_set_abs_params(pbmi_lcd.input_dev[ts], ABS_Y, BMI_LCD_MIN_YC, BMI_LCD_MAX_YC, 0, 0); ++ input_set_abs_params(pbmi_lcd.input_dev[ts], ABS_PRESSURE, 0, 1024, 0, 0); ++ ++ // register input device ++ if(input_register_device(pbmi_lcd.input_dev[ts])) { ++ int tts; ++ printk(KERN_ERR "bmi_lcd_init() - input_register_device failed.\n"); ++ ++ for(tts = BMI_TS_M1; tts < ts; tts++) ++ input_unregister_device(pbmi_lcd.input_dev[tts]); ++ ++ lcd_ctl_clean(); ++ ++ return -ENODEV; ++ } ++ } ++ ++ pbmi_lcd.lcd_cnt = 0; ++ ++ // hardware specfic set-up ++ s320x240_bmi_lcd.interface = s320x240_lcd_interface, ++ s320x240_bmi_lcd_ops.config = (void(*)) &s320x240_config; ++ s320x240_bmi_lcd_ops.reset = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd_ops.suspend = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd_ops.resume = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd_ops.disp_on = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd_ops.disp_off = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd_ops.activate = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd_ops.deactivate = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd.lcd_ops = s320x240_bmi_lcd_ops; ++ pbmi_lcd.blcd[0] = &s320x240_bmi_lcd; ++ pbmi_lcd.blcd[1] = &s320x240_bmi_lcd; ++ pbmi_lcd.blcd[2] = &s320x240_bmi_lcd; ++ pbmi_lcd.blcd[3] = &s320x240_bmi_lcd; ++ ++ sema_init(&pbmi_lcd.sem[0], 1); ++ sema_init(&pbmi_lcd.sem[1], 1); ++ sema_init(&pbmi_lcd.sem[2], 1); ++ sema_init(&pbmi_lcd.sem[3], 1); ++ ++ ++#ifdef ACCELEROMETER ++ acc_init(); ++#endif ++ /*s320x240_config(0); ++ s320x240_config(1);*/ ++ ++ // register with BMI ++ rc = bmi_register_driver(&bmi_lcd_driver); ++ if(rc) { ++ printk(KERN_ERR "bmi_lcd.c: Can't register bmi_lcd_driver\n"); ++ ++ for(ts = BMI_TS_M1; ts < BMI_TS_NUM; ts++) ++ input_unregister_device(pbmi_lcd.input_dev[ts]); ++ ++ lcd_ctl_clean(); ++ ++ return rc; ++ } ++ ++ printk("bmi_lcd.c: BMI_LCD Driver v%s \n", BMILCD_VERSION); ++ ++ return 0; ++} ++ ++static void __exit bmi_lcd_clean(void) ++{ ++ int ts; ++ ++ // delete timers ++ del_timer(&pbmi_lcd.timer[0]); ++ del_timer(&pbmi_lcd.timer[1]); ++ del_timer(&pbmi_lcd.timer[2]); ++ del_timer(&pbmi_lcd.timer[3]); ++ ++ // remove input devices ++ for(ts = BMI_TS_M1; ts < BMI_TS_NUM; ts++) ++ input_unregister_device(pbmi_lcd.input_dev[ts]); ++ ++ // remove control device ++ lcd_ctl_clean(); ++ ++ // remove bmi driver ++ bmi_unregister_driver(&bmi_lcd_driver); ++ ++#ifdef ACCELEROMETER ++ acc_clean(); ++#endif ++ return; ++} ++ ++module_init(bmi_lcd_init); ++module_exit(bmi_lcd_clean); ++ ++// Exported symbols ++EXPORT_SYMBOL(register_bmi_lcd); ++EXPORT_SYMBOL(unregister_bmi_lcd); ++ ++ ++MODULE_AUTHOR("Peter Giacomini "); ++MODULE_DESCRIPTION("BMI lcd device driver"); ++MODULE_SUPPORTED_DEVICE("bmi_lcd_control"); ++MODULE_SUPPORTED_DEVICE("bmi_lcd_ts"); ++MODULE_SUPPORTED_DEVICE("bmi_lcd_acc"); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ git/drivers/bmi/pims/lcd/bmi_lcd_inf.c +@@ -0,0 +1,1775 @@ ++/* ++ * bmi_lcd.c ++ * ++ * BMI LCD device driver ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/* ++ * Include files ++ */ ++ ++#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 ++ ++#undef ACCELEROMETER ++#define ACCELEROMETER ++ ++#ifdef ACCELEROMETER ++#include "acc.h" ++#endif //ACCELEROMETER ++ ++#define DEBUG ++#undef DEBUG ++ ++#define BMILCD_VERSION "1.2" // driver version ++#define BUF_MAX_SIZE 0x20 // spi buffer size ++#define WORK_DELAY (1) // interrupt work handler delay ++#define DEBOUNCE 10 // touch screen debounce ++#define X_PLATE 400 // touch screen X plate resistance //pjg - This is not the correct value ++#define BMI_SLOT_NUM (4) // number of BMI slots ++#define MAX_STRG (40) // Max string buffer size ++ ++#define VSYNC_DISABLE 0x0 ++#define VSYNC_ENABLE 0x1 ++ ++ // lcd ++struct lcd_interface { ++ char lcd_type[MAX_STRG]; // text description of LCD type ++ u8 suspended; // power management state ++ u8 rotation; // screen rotation ++ u8 disp; // display number (DISP0 or DISP1) ++ u8 addr_mode; // display addressing mode ++ u8 vsync_mode; // VSYNC signal enable (VSYNC_ENABLE | VSYNC_DISABLE) ++ u8 bus_if_type; // bus type (XY | FullWoBE | FullWithBE) ++ ipu_adc_sig_cfg_t adc_sig; // IPU ADC set-up parameters ++ ipu_di_signal_cfg_t di_sig; // IPU DI set-up parameters ++}; ++ ++static struct lcd_interface s320x240_lcd_interface = { ++ .lcd_type = "MXCFB_SHARP_320X240", ++ .suspended = 0, ++ .rotation = IPU_ROTATE_NONE, ++ .disp = DISP0, ++ .vsync_mode = VSYNC_DISABLE, ++ .bus_if_type = XY, ++ .adc_sig = { 0, 0, 0, 0, 0, 0, 0, 0, IPU_ADC_BURST_WCS, IPU_ADC_IFC_MODE_SYS80_TYPE2, ++ 16, 0, 0, IPU_ADC_SER_NO_RW }, ++ .di_sig = { 0,0,0,0,0,0,0,0 }, //pjg - reserved for multiple LCD driver ++}; ++ ++ ++struct bmi_lcd; ++ ++struct bmi_lcd_ops { ++ void *(*config) (int disp); // LCD configuration/initialization ++ void *(*reset) (int slot); // LCD reset ++ int *(*suspend) (struct bmi_lcd *blcd); // power management ++ int *(*resume) (struct bmi_lcd *blcd); // power management ++ int *(*disp_on) (int disp); // display on ++ int *(*disp_off) (int disp); // display off ++ int (*activate) (struct bmi_lcd *lcd, int slot); // enable LCD backlight, touchscreen, accelerometer, ... ++ int (*deactivate) (struct bmi_lcd *lcd, int slot); // disable LCD backlight, touchscreen, accelerometer, ... ++}; ++ ++ ++struct bmi_lcd { ++ struct lcd_interface interface; // pointer to this struct is returned by config() ++ struct bmi_lcd_ops lcd_ops; // function pointers ++}; ++ ++ ++int register_bmi_lcd(struct bmi_lcd *blcd, int slot); ++int unregister_bmi_lcd(struct bmi_lcd *blcd, int slot); ++ ++ // private device structure ++struct pbmi_lcd ++{ ++ int open_flag; // force single open ++ unsigned int lcd_cnt; // number of LCD's present ++ unsigned int active; // indication of LCD presence ++ unsigned int activated[BMI_SLOT_NUM]; // indication of LCD presence ++ ++ struct bmi_lcd *blcd[BMI_SLOT_NUM]; // BMI LCD structure - placeholder for multiple display types ++ struct bmi_device *bdev[BMI_SLOT_NUM]; // BMI device per slot ++ unsigned int interrupt[BMI_SLOT_NUM]; // input device interrupt handlers ++ char int_name[MAX_STRG]; // interrupt name ++ ++ struct input_dev *input_dev[BMI_TS_NUM]; // input device (touch screen and accelerometer) ++ struct timer_list timer[BMI_SLOT_NUM]; // touch timer ++ ++ int pen_down[BMI_SLOT_NUM]; ++ int scount[BMI_SLOT_NUM]; ++ ++ struct spi_device *spi[BMI_SLOT_NUM]; // touch screen device interface ++ struct semaphore sem[BMI_SLOT_NUM]; // spi semaphore ++ char rbuf[BMI_SLOT_NUM][BUF_MAX_SIZE]; // spi read buffer ++ char wbuf[BMI_SLOT_NUM][BUF_MAX_SIZE]; // spi write buffer ++ ++#ifdef ACCELEROMETER ++ struct acc_dev acc[BMI_SLOT_NUM]; ++#endif ++}; ++ ++static struct pbmi_lcd pbmi_lcd; // LCD device sructure ++ ++/* ++ * BMI set up ++ */ ++ ++ // BMI device ID table ++static struct bmi_device_id bmi_lcd_tbl[] = ++{ ++ { ++ .match_flags = BMI_DEVICE_ID_MATCH_VENDOR | BMI_DEVICE_ID_MATCH_PRODUCT, ++ .vendor = BMI_VENDOR_BUG_LABS, ++ .product = BMI_PRODUCT_LCD_SHARP_320X240, ++ .revision = BMI_ANY, ++ }, ++ { 0, }, /* terminate list */ ++}; ++ ++MODULE_DEVICE_TABLE(bmi, bmi_lcd_tbl); ++ ++/*printk(KERN_INFO "MDT: 0x%x\n", __mod_bmi_device_table);*/ ++ ++int bmi_lcd_probe(struct bmi_device *bdev); ++void bmi_lcd_remove(struct bmi_device *bdev); ++ ++// BMI driver structure ++static struct bmi_driver bmi_lcd_driver = ++{ ++ .name = "bmi_lcd", ++ .id_table = bmi_lcd_tbl, ++ .probe = bmi_lcd_probe, ++ .remove = bmi_lcd_remove, ++}; ++ ++//Accelerometer driver structure ++ ++ ++/* ++ * I2C set up ++ */ ++ ++ // I2C Slave Address ++#define BMI_IOX_I2C_ADDRESS 0x71 // 7-bit address ++#define BMI_ACC_I2C_ADDRESS 0x17 // 7-bit address ++ ++ // I2C IOX register addresses ++#define IOX_INPUT_REG 0x0 // IOX input data register ++#define IOX_OUTPUT_REG 0x1 // IOX output data register ++#define IOX_POLARITY_REG 0x2 // IOX polarity data register ++#define IOX_CONTROL 0x3 // IOX direction control register ++#define IOX_B1 (0) // bit 0 - backlight control ++#define IOX_A1_A2 (1) // bit 1 - backlight control ++#define IOX_ACC_RST_N (2) // bit 2 - acceleromter reset ++#define IOX_VSYNC_EN_N (3) // bit 3 - VSYNC output buffer enable ++#define IOX_LCD_RST_N (4) // bit 4 - LCD reset ++#define IOX_SERDES_PD_N (5) // bit 5 - SERDES power down ++#define IOX_X_INT (6) // bit 6 - accelerometer interrupt ++#define IOX_Y_INT (7) // bit 7 - accelerometer interrupt ++ ++ // I2C ACC register addresses - OKI ++#define ACC_PAGESEL 0x1E // device ready status ++ // page 0 ++#define ACC_DVRST 0x01 // device reset ++ #define ACC_DVRST_RST 0x3C // device reset ++ #define ACC_DVRST_EN 0xC3 // device enable ++#define ACC_PDWN 0x02 // osc power down ++ #define ACC_PWDN_RST 0x01 // device reset ++ #define ACC_PWDN_EN 0x00 // device enable ++#define ACC_CTRL0 0x03 // control 0 ++ #define ACC_CTRL0_CTSTR 0x40 // control 0 - temp sensor ++ #define ACC_CTRL0_CGSTRNC 0x08 // control 0 - 3-axis/no tilt ++ #define ACC_CTRL0_CGSTRC 0x04 // control 0 - 3-axis/tilt ++ #define ACC_CTRL0_CGAUTO 0x01 // control 0 - auto ++#define ACC_MODE0 0x05 // control 0 ++ #define ACC_MODE0_PDOFF 0x80 // mode 0 - disable auto power down ++ #define ACC_MODE0_RVOFF 0x40 // mode 0 - disable temp compensation ++ #define ACC_MODE0_TMPOFF 0x20 // mode 0 - disable temp measurement ++ #define ACC_MODE0_AGCON 0x10 // mode 0 - enable auto mode pitch and roll ++ #define ACC_MODE0_MAUTO 0x04 // mode 0 - enable auto termination ++ #define ACC_MODE0_GDET00 0x00 // mode 0 - g detection threshold - see ML8953 data sheet ++ #define ACC_MODE0_GDET01 0x01 // mode 0 - g detection threshold - see ML8953 data sheet ++ #define ACC_MODE0_GDET10 0x02 // mode 0 - g detection threshold - see ML8953 data sheet ++#define ACC_MODE1 0x06 // mode 1 ++ #define ACC_MODE1_MOFF 0x20 // mode 1 - disable 3-axis continuous mode ++ #define ACC_MODE1_ZAXIS 0x03 // mode 1 - Z axis ++ #define ACC_MODE1_YAXIS 0x02 // mode 1 - Y axis ++ #define ACC_MODE1_XAXIS 0x01 // mode 1 - X axis ++ #define ACC_MODE1_RAXIS 0x00 // mode 1 - Reference axis ++#define ACC_INTRQ 0x07 // interrupt request (1 = request) ++#define ACC_INTMSK 0x08 // interrupt mask (1 = masked) ++ #define ACC_INT_TREQ 0x20 // interrupt - temperature ++ #define ACC_INT_GREQ 0x08 // interrupt - acceleration/no tilt ++ #define ACC_INT_GCREQ 0x04 // interrupt - acceleration/tilt ++ #define ACC_INT_GAREQ 0x01 // interrupt - automatic ++#define ACC_TMDL 0x09 // timer LSB = (1/6.2 MHz) x 2048 x TMD ++#define ACC_TMDH 0x0A // timer MSB ++#define ACC_CFG 0x0C // configuration ++ #define ACC_CFG_REGMD 0x80 // address auto-increment ++ #define ACC_CFG_SPI3M_3 0x40 // spi mode = 3-wire ++ #define ACC_CFG_SPI3M_4 0x00 // spi mode = 4-wire ++ #define ACC_CFG_SDOCFG_T 0x10 // sdo mode = totem-pole ++ #define ACC_CFG_SDOCFG_OC 0x00 // sdo mode = open-drain ++ #define ACC_CFG_INT1EN_G 0x08 // interrupt 1 mode = g only ++ #define ACC_CFG_INT1EN_ALL 0x00 // interrupt 1 mode = all ++ #define ACC_CFG_INTLVL 0x04 // interrupt level mode ++ #define ACC_CFG_INT1CFG_T 0x02 // interrupt 1 mode = totem-pole ++ #define ACC_CFG_INT1CFG_OC 0x00 // interrupt 1 mode = open-drain ++ #define ACC_CFG_INT0CFG_T 0x01 // interrupt 0 mode = totem-pole ++ #define ACC_CFG_INT0CFG_OC 0x00 // interrupt 0 mode = open-drain ++#define ACC_INTOTM 0x0D // interrupt output conditions ++#define ACC_GAAVE 0x0E // Data averaging - automatic mode ++#define ACC_GNAVE 0x0F // Data averaging - normal mode ++#define ACC_GDTCT0L 0x11 // threshold 0 LSB ++#define ACC_GDTCT0H 0x12 // threshold 0 MSB ++#define ACC_GDTCT1L 0x13 // threshold 1 LSB ++#define ACC_GDTCT1H 0x14 // threshold 1 MSB ++#define ACC_CPURDY 0x15 // device ready status (ready = 0x01) ++ // page 1 ++#define ACC_STATUS 0x01 // measurment status ++ #define ACC_STATUS_ASTS 0x02 // acceleration measurement - automatic modes ++ #define ACC_STATUS_STS 0x01 // acceleration measurement - non-automatic modes ++#define ACC_GAXL 0x02 // g vector ++#define ACC_GAXH 0x03 // g vector ++#define ACC_GAYL 0x04 // g vector ++#define ACC_GAYH 0x05 // g vector ++#define ACC_GAZL 0x06 // g vector ++#define ACC_GAZH 0x07 // g vector ++#define ACC_GASVL 0x08 // g vector ++#define ACC_GASVH 0x09 // g vector ++#define ACC_GNXL 0x0A // g vector ++#define ACC_GNXH 0x0B // g vector ++#define ACC_GNYL 0x0C // g vector ++#define ACC_GNYH 0x0D // g vector ++#define ACC_GNZL 0x0E // g vector ++#define ACC_GNZH 0x0F // g vector ++#define ACC_GNSVL 0x10 // g vector ++#define ACC_GNSVH 0x11 // g vector ++#define ACC_PITCHL 0x12 // pitch ++#define ACC_PITCHH 0x13 // pitch ++#define ACC_ROLLL 0x14 // roll ++#define ACC_ROLLH 0x15 // roll ++#define ACC_TEMPL 0x19 // temperature ++#define ACC_TEMPH 0x1A // temperature ++ ++ // read byte from I2C IO expander ++static int ReadByte_IOX(struct i2c_adapter *adap, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ int retries = 0; ++ ++ /* Read Byte with Pointer */ ++ ++ rmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[0].flags = 0; /* write */ ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; /* read */ ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ++ while (retries < 5) ++ { ++ ret = i2c_transfer (adap, rmsg, num_msgs); ++ if (ret == 2) ++ break; ++ else ++ retries++; ++ } ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "ReadByte_IOX() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++ // write byte to I2C IO expander ++static int WriteByte_IOX(struct i2c_adapter *adap, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ /* Write Byte with Pointer */ ++ ++ wmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[0].flags = 0; /* write */ ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[1].flags = 0; /* write */ ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ ret = i2c_transfer (adap, wmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "WriteByte_IOX() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++ ++#if defined ACCELEROMETER ++ // read byte from I2C acceleromter ++static int ReadByte_ACC(struct i2c_adapter *adap, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ int retries = 0; ++ ++ /* Read Byte with Pointer */ ++ ++ rmsg[0].addr = BMI_ACC_I2C_ADDRESS; ++ rmsg[0].flags = 0; /* write */ ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_ACC_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; /* read */ ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ++ while (retries < 5) ++ { ++ ret = i2c_transfer (adap, rmsg, num_msgs); ++ if (ret == 2) ++ break; ++ else ++ retries++; ++ mdelay(1); ++ } ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "ReadByte_ACC() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++static int ReadByteLock_ACC(struct pbmi_lcd *priv, unsigned char offset, unsigned char *data, int slot) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ int retries = 0; ++ ++ /* Read Byte with Pointer */ ++ ++ rmsg[0].addr = BMI_ACC_I2C_ADDRESS; ++ rmsg[0].flags = 0; /* write */ ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_ACC_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; /* read */ ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ++ while (retries < 5) ++ { ++ ret = i2c_transfer (adap, rmsg, num_msgs); ++ if (ret == 2) ++ break; ++ else ++ retries++; ++ mdelay(1); ++ } ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "ReadByte_ACC() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++ // write byte to I2C accelerometer ++static int WriteByte_ACC(struct i2c_adapter *adap, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ /* Write Byte with Pointer */ ++ ++ wmsg[0].addr = BMI_ACC_I2C_ADDRESS; ++ wmsg[0].flags = 0; /* write */ ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_ACC_I2C_ADDRESS; ++ wmsg[1].flags = 0; /* write */ ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ ret = i2c_transfer (adap, wmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "WriteByte_ACC() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++#endif // ACCELEROMETER ++ ++/* ++ * SPI functions ++ */ ++ ++ // TSC2046 touch screen controller command register bit definitons ++#define SPI_START 0x80 // command start ++#define SPI_AT0 0x00 // read temperature - not supported ++#define SPI_AY 0x10 // read Y ++#define SPI_ABAT 0x20 // read battery - not supported ++#define SPI_AZ1 0x30 // read Z1 ++#define SPI_AZ2 0x40 // read Z2 ++#define SPI_AX 0x50 // read X ++#define SPI_AAUX 0x60 // read AUX - not supported ++#define SPI_AT1 0x70 // read temperature - not supported ++#define SPI_MODE_12 0x00 // 12-bit mode - Preferred ++#define SPI_MODE_8 0x08 // 8-bit mode ++#define SPI_MODE_DFR 0x00 // differential mode - Preferred ++#define SPI_MODE_SER 0x04 // single ended mode ++#define SPI_PD 0x00 // power down - PENIRQ enabled ++#define SPI_ADC 0x01 // ADC enabled ++#define SPI_REF 0x02 // Vref enabled - unused ++#define SPI_REF_ADC 0x03 // Vref & ADC enabled - unused ++ ++ // spi access ++static int spi_rw(struct spi_device *spi, u8 * buf, size_t len) ++{ ++ struct spi_transfer t = { ++ .tx_buf = (const void *)buf, ++ .rx_buf = buf, ++ .len = len, ++ .cs_change = 0, ++ .delay_usecs = 0, ++ }; ++ struct spi_message m; ++ ++ spi_message_init(&m); ++ ++ spi_message_add_tail(&t, &m); ++ if (spi_sync(spi, &m) != 0 || m.status != 0) ++ return -1; ++ ++ return m.actual_length; ++} ++ ++ // spi write register ++static ssize_t spi_lcd_write_reg(struct pbmi_lcd *priv, char *buf, int len, int slot) ++{ ++ int res = 0; ++ ++ down(&priv->sem[slot]); ++ ++ memset(priv->wbuf[slot], 0, BUF_MAX_SIZE); ++ priv->wbuf[slot][0] = buf[0]; ++ priv->wbuf[slot][1] = buf[1]; ++ priv->wbuf[slot][2] = buf[2]; ++ priv->wbuf[slot][3] = buf[3]; ++ res = spi_rw(priv->spi[slot], priv->wbuf[slot], len); ++ if (res != 1) { ++ up(&priv->sem[slot]); ++ return -EFAULT; ++ } ++ ++ up(&priv->sem[slot]); ++ ++ return res; ++} ++ ++ // spi read register ++static ssize_t spi_lcd_read_reg(struct pbmi_lcd *priv, char *buf, int len, int slot) ++{ ++ int res = 0; ++ ++ down(&priv->sem[slot]); ++ ++ memset(priv->wbuf[slot], 0, BUF_MAX_SIZE); ++ priv->wbuf[slot][0] = buf[0]; ++ priv->wbuf[slot][1] = buf[1]; ++ priv->wbuf[slot][2] = buf[2]; ++ priv->wbuf[slot][3] = buf[3]; ++ res = spi_rw(priv->spi[slot], priv->wbuf[slot], len); ++ if (res != 1) { ++ up(&priv->sem[slot]); ++ return -EFAULT; ++ } ++ ++ memset(priv->rbuf[slot], 0, BUF_MAX_SIZE); ++ buf[0] = priv->wbuf[slot][2]; ++ buf[1] = priv->wbuf[slot][1]; ++ ++ up(&priv->sem[slot]); ++ ++ return res; ++} ++ ++/* ++ * BMI functions ++ */ ++ ++static irqreturn_t module_irq_handler(int irq, void *dummy); ++void bmi_lcd_config(struct bmi_lcd *lcd, int disp); ++ ++ // probe ++int bmi_lcd_probe(struct bmi_device *bdev) ++{ ++#if defined ACCELEROMETER ++ unsigned char acc_data[1]; ++#endif // ACCELEROMETER ++ unsigned char iox_data[1]; ++ int slot = bdev->info->slot; ++ struct i2c_adapter *adap; ++ struct bmi_lcd *lcd; ++ char buf[4]; ++ /*int first_time = 1;*/ ++ ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d\n", slot); ++ ++ // check for opposite side already active ++ switch(slot) { // opposite side ++ case 0: ++ if(pbmi_lcd.activated[2] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 2 already active)\n", slot); ++ bmi_slot_power_off(0); ++ /*bmi_slot_power_off(2);*/ ++ pbmi_lcd.bdev[0] = bdev; ++ /*bdev = pbmi_lcd.bdev[2]; ++ slot = 2; ++ first_time = 0;*/ ++ return 0; ++ } ++ break; ++ case 1: ++ if(pbmi_lcd.activated[3] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 3 already active)\n", slot); ++ bmi_slot_power_off(1); ++ /*bmi_slot_power_off(3);*/ ++ pbmi_lcd.bdev[1] = bdev; ++ /*bdev = pbmi_lcd.bdev[3]; ++ slot = 3; ++ first_time = 0;*/ ++ return 0; ++ } ++ break; ++ case 2: ++ if(pbmi_lcd.activated[0] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 0 already active)\n", slot); ++ bmi_slot_power_off(2); ++ /*bmi_slot_power_off(0);*/ ++ pbmi_lcd.bdev[2] = bdev; ++ /*bdev = pbmi_lcd.bdev[0]; ++ slot = 0; ++ first_time = 0;*/ ++ return 0; ++ } ++ break; ++ case 3: ++ if(pbmi_lcd.activated[1] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 1 already active)\n", slot); ++ bmi_slot_power_off(3); ++ /*bmi_slot_power_off(1);*/ ++ pbmi_lcd.bdev[3] = bdev; ++ /*bdev = pbmi_lcd.bdev[1]; ++ slot = 1; ++ first_time = 0;*/ ++ return 0; ++ } ++ break; ++ } ++ ++ adap = &bdev->adap; ++ bmi_slot_power_on(slot); ++ ++ mdelay(500); ++ ++ // configure IOX ++ // [7:6]=interrupts, [5]=SER_PD*, [4]=LCD_RST*, [3]=VSYNC_OE*, [2]=ACC_RST*, [1:0]=backlight ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, 0xFF)) // normal - no accelerometer interrupts ++ return -ENODEV; ++ ++ // normal operation - no accelerometer interrupts ++ if(WriteByte_IOX(adap, IOX_CONTROL, 0x00)) // IOX[7:0]=OUT ++ return -ENODEV; ++ ++ // clear interrupts ++ if(ReadByte_IOX(adap, IOX_INPUT_REG, iox_data)) ++ return -ENODEV; ++ ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d iox data = %x\n", slot, *iox_data); ++ ++#if defined ACCELEROMETER ++ // accelerometer ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d hardware version = 0x%x\n", slot, bdev->epraw.revision_msb); ++ ++ // check for PCB revision >= 1.2 ++ if(bdev->epraw.revision_msb >= 0x12) { ++ ++ // normal IOX operation - accelerometer interrupts ++ if(WriteByte_IOX(adap, IOX_CONTROL, 0xC0)) // IOX[7:6]=IN, IOX[5:0]=OUT ++ return -ENODEV; ++ ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, 0xFB)) // reset OKI accelerometer ++ return -ENODEV; ++ ++ mdelay(2); ++ ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, 0xFF)) // enable OKI accelerometer ++ return -ENODEV; ++ ++ mdelay(2); ++ ++ // write PAGESEL ++ *acc_data = 0x0; ++ if(WriteByte_ACC(adap, ACC_PAGESEL, *acc_data)) ++ return -ENODEV; ++ ++ // read device to verify existance ++ if(ReadByte_ACC(adap, ACC_CPURDY, acc_data)) ++ return -ENODEV; ++ ++ // set TMD = 0x300 (~250 ms) ++ *acc_data = 0x5; ++ if(WriteByte_ACC(adap, ACC_TMDH, *acc_data)) ++ return -ENODEV; ++ ++ *acc_data = 0x0; ++ if(WriteByte_ACC(adap, ACC_TMDL, *acc_data)) ++ return -ENODEV; ++ ++ // set INTOTM ++ *acc_data = 0x00; ++ if(WriteByte_ACC(adap, ACC_INTOTM, *acc_data)) ++ return -ENODEV; ++ ++ // set GxAVE ++ *acc_data = 0x0; ++ if(WriteByte_ACC(adap, ACC_GAAVE, *acc_data)) ++ return -ENODEV; ++ ++ // set GDTCT[01] ++ *acc_data = 0x00; ++ if(WriteByte_ACC(adap, ACC_GDTCT0L, *acc_data)) ++ return -ENODEV; ++ ++ *acc_data = 0x00; ++ if(WriteByte_ACC(adap, ACC_GDTCT0H, *acc_data)) ++ return -ENODEV; ++ ++ *acc_data = 0x00; ++ if(WriteByte_ACC(adap, ACC_GDTCT1L, *acc_data)) ++ return -ENODEV; ++ ++ *acc_data = 0x00; ++ if(WriteByte_ACC(adap, ACC_GDTCT1H, *acc_data)) ++ return -ENODEV; ++ ++ // set MODE0 ++ *acc_data = ACC_MODE0_PDOFF | ACC_MODE0_TMPOFF | ACC_MODE0_AGCON | ACC_MODE0_MAUTO | ACC_MODE0_GDET10; ++ if(WriteByte_ACC(adap, ACC_MODE0, *acc_data)) ++ return -ENODEV; ++ ++ // set CFG ++ *acc_data = ACC_CFG_REGMD | ACC_CFG_INTLVL; ++ if(WriteByte_ACC(adap, ACC_CFG, *acc_data)) ++ return -ENODEV; ++ ++ // set INTMSK ++ *acc_data = 0xFE; ++ if(WriteByte_ACC(adap, ACC_INTMSK, *acc_data)) ++ return -ENODEV; ++ ++ // set CTRL0 ++ *acc_data = ACC_CTRL0_CGAUTO; ++ if(WriteByte_ACC(adap, ACC_CTRL0, *acc_data)) ++ return -ENODEV; ++ ++ // write PAGESEL ++ *acc_data = 0x1; ++ if(WriteByte_ACC(adap, ACC_PAGESEL, *acc_data)) ++ return -ENODEV; ++ ++ acc_probe(&pbmi_lcd.acc[slot], slot); ++ ++ } else { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d hardware version = 0x%x (accelerometer not supported)\n", slot, bdev->epraw.revision_msb); ++ } ++#endif // ACCELEROMETER ++ ++ // reset serial link (master) ++ if((slot == 0) || (slot == 2)) { ++ bmi_lcd_inactive(0); ++ } else { ++ bmi_lcd_inactive(1); ++ } ++ ++ // configure GPIO ++ // turn LED's on ++ bmi_set_module_gpio_data(slot, 3, 0); // Red LED=ON ++ bmi_set_module_gpio_data(slot, 2, 0); // Green LED=ON ++ ++ // assert reset ++ bmi_set_module_gpio_data(slot, 1, 0); // RST=0 ++ ++ // set GPIO direction ++ bmi_set_module_gpio_dir(slot, 3, BMI_GPIO_OUT); ++ bmi_set_module_gpio_dir(slot, 2, BMI_GPIO_OUT); ++ bmi_set_module_gpio_dir(slot, 1, BMI_GPIO_OUT); ++ bmi_set_module_gpio_dir(slot, 0, BMI_GPIO_IN); // real-time pen int state ++ ++ mdelay(200); ++ ++ // turn LED's off ++ bmi_set_module_gpio_data(slot, 3, 1); // Red LED=OFF ++ bmi_set_module_gpio_data(slot, 2, 1); // Green LED=OFF ++ ++ // deassert reset (module) ++ bmi_set_module_gpio_data(slot, 1, 1); // RST=1 ++ ++ mdelay(500); ++ ++ // unreset serial link (master) ++ if((slot == 0) || (slot == 2)) { ++ mdelay(2); ++ bmi_lcd_active(0, 0x0, LCD_MODE_I80); ++ } else { ++ mdelay(2); ++ bmi_lcd_active(1, 0x0, LCD_MODE_I80); ++ } ++ ++ ++ // set up bdev/pbmi_lcd pointers ++ bmi_device_set_drvdata(bdev, &pbmi_lcd); ++ pbmi_lcd.bdev[slot] = bdev; ++ ++ // spi set-up ++ if (bmi_device_spi_setup(bdev, 2000000, SPI_MODE_2, 32)) { ++ printk(KERN_ERR "bmi_lcd.c: Unable to setup spi%d\n", slot); ++ bmi_device_set_drvdata(bdev, NULL); ++ pbmi_lcd.bdev[slot] = NULL; ++ bmi_slot_power_off(slot); ++ return -EFAULT; ++ } ++ ++ bmi_slot_spi_enable(slot); ++ pbmi_lcd.spi[slot] = bmi_device_get_spi(bdev); ++ ++ ++ // check spi access and enable touch screen ++ memset(buf, 0, 4); ++ buf[3] = SPI_START | SPI_PD; ++ if(spi_lcd_write_reg(&pbmi_lcd, buf, 1, slot) != 1) { ++ printk(KERN_WARNING "bmi_lcd.c: Unable set-up spi for bmi_lcd %d\n", slot); ++ bmi_device_set_drvdata(bdev, NULL); ++ pbmi_lcd.bdev[slot] = NULL; ++ pbmi_lcd.spi[slot] = NULL; ++ bmi_device_spi_cleanup(bdev); ++ bmi_slot_spi_disable(slot); ++ bmi_slot_power_off(slot); ++ return -EFAULT; ++ } ++ ++ ++ // complete pbmi_lcd set-up ++ pbmi_lcd.lcd_cnt++; ++ pbmi_lcd.active = 1; ++ pbmi_lcd.activated[slot] = 1; ++ ++ ++ mdelay(100); ++ ++ lcd = pbmi_lcd.blcd[slot]; ++ if((slot == 0) || (slot == 2)) { ++ mdelay(2); ++ bmi_lcd_config(lcd, 0); ++ mdelay(2); ++ } else { ++ mdelay(2); ++ bmi_lcd_config(lcd, 1); ++ mdelay(2); ++ } ++ ++ ++ // request input event interrupt handler ++ pbmi_lcd.interrupt[0] = M1_IRQ; ++ pbmi_lcd.interrupt[1] = M2_IRQ; ++ pbmi_lcd.interrupt[2] = M3_IRQ; ++ pbmi_lcd.interrupt[3] = M4_IRQ; ++ snprintf(pbmi_lcd.int_name, sizeof(pbmi_lcd.int_name), "bmi_lcd%d", slot); ++ if (request_irq(pbmi_lcd.interrupt[slot], &module_irq_handler, 0, pbmi_lcd.int_name, &pbmi_lcd)) { ++ printk( KERN_ERR "bmi_lcd.c: Can't allocate irq %d or find lcd in slot %d\n", pbmi_lcd.interrupt[slot], slot); ++ bmi_device_set_drvdata(bdev, NULL); ++ pbmi_lcd.bdev[slot] = NULL; ++ pbmi_lcd.spi[slot] = NULL; ++ bmi_device_spi_cleanup(bdev); ++ bmi_slot_power_off(slot); ++ return -EBUSY; ++ } ++ ++ // check GPIO status ++ printk(KERN_INFO "bmi_lcd.c: slot %d gpio = %x\n", slot, bmi_read_gpio_data_reg(slot)); ++ printk(KERN_INFO "bmi_lcd.c: LCD count = %d\n", pbmi_lcd.lcd_cnt); ++ ++ return 0; ++} ++ ++extern struct delayed_work bmilcd_work0; ++extern struct delayed_work bmilcd_work1; ++extern struct delayed_work bmilcd_work2; ++extern struct delayed_work bmilcd_work3; ++ ++ // remove ++void bmi_lcd_remove(struct bmi_device *bdev) ++{ ++ int slot = bdev->info->slot; ++ ++ if(pbmi_lcd.activated[slot] == 0) ++ return; ++ ++ switch(slot) { ++ case 0: ++ cancel_delayed_work(&bmilcd_work0); ++ break; ++ case 1: ++ cancel_delayed_work(&bmilcd_work1); ++ break; ++ case 2: ++ cancel_delayed_work(&bmilcd_work2); ++ break; ++ case 3: ++ cancel_delayed_work(&bmilcd_work3); ++ break; ++ } ++ ++ free_irq(pbmi_lcd.interrupt[slot], &pbmi_lcd); ++ ++ bmi_set_module_gpio_dir (slot, 3, BMI_GPIO_IN); ++ bmi_set_module_gpio_dir (slot, 2, BMI_GPIO_IN); ++ bmi_set_module_gpio_dir (slot, 1, BMI_GPIO_IN); ++ bmi_set_module_gpio_dir (slot, 0, BMI_GPIO_IN); ++ ++ // bmi/spi clean-up ++ bmi_device_spi_cleanup(bdev); ++ pbmi_lcd.spi[slot] = NULL; ++ bmi_slot_spi_disable(slot); ++ ++ //de-attach driver-specific struct from bmi_device structure ++ bmi_device_set_drvdata (&bdev[slot], 0); ++ ++ // deactivate ++ pbmi_lcd.activated[slot] = 0; ++ pbmi_lcd.bdev[slot] = 0; ++ pbmi_lcd.lcd_cnt--; ++ ++ if((pbmi_lcd.activated[0] == 0) && (pbmi_lcd.activated[2] == 0)) { ++ bmi_lcd_inactive(0); // disable serializer ++ } ++ ++ if((pbmi_lcd.activated[1] == 0) && (pbmi_lcd.activated[3] == 0)) { ++ bmi_lcd_inactive(1); // disable serializer ++ } ++ ++ if((pbmi_lcd.activated[0] == 0) && (pbmi_lcd.activated[1] == 0) && ++ (pbmi_lcd.activated[2] == 0) && (pbmi_lcd.activated[3] == 0)) { ++ pbmi_lcd.active = -1; ++ } ++ ++ // enable LCD on opposite side ++ switch(slot) { ++ case 0: ++ if(pbmi_lcd.bdev[2] != 0) ++ bmi_lcd_probe(pbmi_lcd.bdev[2]); ++ break; ++ case 1: ++ if(pbmi_lcd.bdev[3] != 0) ++ bmi_lcd_probe(pbmi_lcd.bdev[3]); ++ break; ++ case 2: ++ if(pbmi_lcd.bdev[0] != 0) ++ bmi_lcd_probe(pbmi_lcd.bdev[0]); ++ break; ++ case 3: ++ if(pbmi_lcd.bdev[1] != 0) ++ bmi_lcd_probe(pbmi_lcd.bdev[1]); ++ break; ++ } ++ ++#ifdef ACCELEROMETER ++ acc_remove(&pbmi_lcd.acc[slot], slot); ++#endif ++ printk(KERN_INFO "bmi_lcd.c: LCD count = %d\n", pbmi_lcd.lcd_cnt); ++ ++ return; ++} ++ ++/* ++ * Input interrupt handler and support routines ++ */ ++ ++static void update_pen_state(void *arg, int slot, int x, int y, int pressure) ++{ ++ struct pbmi_lcd *pbmi_lcd = (struct pbmi_lcd *)arg; ++ int sync = 0; ++ ++ if (pressure) ++ { ++ /*input_report_abs(pbmi_lcd->input_dev[slot], ABS_X, x); ++ input_report_abs(pbmi_lcd->input_dev[slot], ABS_Y, y); ++ input_report_abs(pbmi_lcd->input_dev[slot], ABS_PRESSURE, pressure); ++ ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M1234], ABS_X, x); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M1234], ABS_Y, y); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M1234], ABS_PRESSURE, pressure);*/ ++ ++ if((slot == 0) || (slot == 2)) ++ { ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M13], ABS_Y, y); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M13], ABS_X, x); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M13], ABS_PRESSURE, pressure); ++ } ++ else ++ { ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M24], ABS_Y, y); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M24], ABS_X, x); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M24], ABS_PRESSURE, pressure); ++ } ++ ++ if (!pbmi_lcd->pen_down[slot]) ++ { ++ /*input_report_key(pbmi_lcd->input_dev[slot], BTN_TOUCH, 1); ++ input_report_key(pbmi_lcd->input_dev[BMI_TS_M1234], BTN_TOUCH, 1);*/ ++ if((slot == 0) || (slot == 2)) ++ { ++ input_report_key(pbmi_lcd->input_dev[BMI_TS_M13], BTN_TOUCH, 1); ++ } ++ else ++ { ++ input_report_key(pbmi_lcd->input_dev[BMI_TS_M24], BTN_TOUCH, 1); ++ } ++ ++ } ++ sync = 1; ++ } ++ else if (pbmi_lcd->pen_down[slot]) ++ { ++ /*input_report_key(pbmi_lcd->input_dev[slot], BTN_TOUCH, 0); ++ input_report_abs(pbmi_lcd->input_dev[slot], ABS_PRESSURE, 0); ++ ++ input_report_key(pbmi_lcd->input_dev[BMI_TS_M1234], BTN_TOUCH, 0); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M1234], ABS_PRESSURE, 0); */ ++ ++ if((slot == 0) || (slot == 2)) ++ { ++ input_report_key(pbmi_lcd->input_dev[BMI_TS_M13], BTN_TOUCH, 0); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M13], ABS_PRESSURE, 0); ++ } ++ else ++ { ++ input_report_key(pbmi_lcd->input_dev[BMI_TS_M24], BTN_TOUCH, 0); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M24], ABS_PRESSURE, 0); ++ } ++ sync = 1; ++ } ++ ++ if (sync) ++ { ++ /*input_sync(pbmi_lcd->input_dev[slot]); ++ input_sync(pbmi_lcd->input_dev[BMI_TS_M1234]);*/ ++ if((slot == 0) || (slot == 2)) ++ { ++ input_sync(pbmi_lcd->input_dev[BMI_TS_M13]); ++ } ++ else ++ { ++ input_sync(pbmi_lcd->input_dev[BMI_TS_M24]); ++ } ++ } ++ pbmi_lcd->pen_down[slot] = pressure ? 1 : 0; ++ ++} ++ ++ ++void bmilcd_input_work(void *arg, int slot); ++ ++void bmilcd_input_work0(struct work_struct * work) { ++ bmilcd_input_work(&pbmi_lcd, 0); ++} ++ ++void bmilcd_input_work1(struct work_struct * work) { ++ bmilcd_input_work(&pbmi_lcd, 1); ++} ++ ++void bmilcd_input_work2(struct work_struct * work) { ++ bmilcd_input_work(&pbmi_lcd, 2); ++} ++ ++void bmilcd_input_work3(struct work_struct * work) { ++ bmilcd_input_work(&pbmi_lcd, 3); ++} ++ ++DECLARE_DELAYED_WORK(bmilcd_work0, bmilcd_input_work0); ++DECLARE_DELAYED_WORK(bmilcd_work1, bmilcd_input_work1); ++DECLARE_DELAYED_WORK(bmilcd_work2, bmilcd_input_work2); ++DECLARE_DELAYED_WORK(bmilcd_work3, bmilcd_input_work3); ++ ++// work handler ++void bmilcd_input_work(void *arg, int slot) { ++ struct pbmi_lcd *pbmi_lcd = (struct pbmi_lcd *)arg; ++#if defined ACCELEROMETER ++ struct i2c_adapter *adap = &pbmi_lcd->bdev[slot]->adap; ++ unsigned char acc_data[1]; ++ static int pitch = 0; ++ static int roll = 0; ++ static int gx = 0; ++ static int gy = 0; ++ ++#endif // ACCELEROMETER ++ unsigned char buf[4]; ++ int x = 0; ++ int y = 0; ++ int z1 = 0; ++ int z2 = 0; ++ int pressure = 0; ++ int debounce; ++ int penirq; ++ ++#if defined DEBUG ++ printk(KERN_INFO "bmi_lcd.c: bmi_lcd_input work (slot %d)\n", slot); ++#endif ++ ++ if(pbmi_lcd->bdev[slot] == 0) { ++ printk(KERN_INFO "bmi_lcd.c: bmi_lcd_input work called with no bdev active (slot %d)\n", slot); ++ return; ++ } ++ ++#if defined ACCELEROMETER ++ if(pbmi_lcd->bdev[slot]->epraw.revision_msb >= 0x12) { ++ ++ // orientation ++ // read ROLL ++ if(ReadByte_ACC(adap, ACC_ROLLH, acc_data)) ++ return; ++ roll = (0x0000 | *acc_data) << 8; ++ ++ if(ReadByte_ACC(adap, ACC_ROLLL, acc_data)) ++ return; ++ roll = roll | *acc_data; ++ // read PITCH ++ if(ReadByte_ACC(adap, ACC_PITCHH, acc_data)) ++ return; ++ pitch = (0x0000 | *acc_data) << 8; ++ ++ if(ReadByte_ACC(adap, ACC_PITCHL, acc_data)) ++ return; ++ pitch = pitch | *acc_data; ++ ++ ++ ++ ++ if(ReadByte_ACC(adap, ACC_GAZH, acc_data)) ++ return; ++ pbmi_lcd->acc[slot].sample[0] = *acc_data; ++ ++ if(ReadByte_ACC(adap, ACC_GAZL, acc_data)) ++ return; ++ pbmi_lcd->acc[slot].sample[1] = *acc_data; ++ ++ if(ReadByte_ACC(adap, ACC_GAYH, acc_data)) ++ return; ++ pbmi_lcd->acc[slot].sample[2] = *acc_data; ++ gy = *acc_data << 8; ++ ++ if(ReadByte_ACC(adap, ACC_GAYL, acc_data)) ++ return; ++ pbmi_lcd->acc[slot].sample[3] = *acc_data; ++ gy = gy | *acc_data; ++ ++ if(ReadByte_ACC(adap, ACC_GAXH, acc_data)) ++ return; ++ pbmi_lcd->acc[slot].sample[4] = *acc_data; ++ gx = *acc_data << 8; ++ ++ if(ReadByte_ACC(adap, ACC_GAXL, acc_data)) ++ return; ++ pbmi_lcd->acc[slot].sample[5] = *acc_data; ++ gx = gx | *acc_data; ++ ++ //wake up any read's ++ pbmi_lcd->acc[slot].flag = 1; ++ wake_up_interruptible(&pbmi_lcd->acc[slot].wq); ++ ++ // read STATUS ++ if(ReadByte_ACC(adap, ACC_STATUS, acc_data)) ++ return; ++ ++ if((*acc_data & 0x1) == 0) { ++ ++ // write PAGESEL ++ *acc_data = 0x0; ++ if(WriteByte_ACC(adap, ACC_PAGESEL, *acc_data)) ++ return; ++ ++ // read INTRQ ++ if(ReadByte_ACC(adap, ACC_INTRQ, acc_data)) ++ return; ++ } ++ ++ // write PAGESEL ++ *acc_data = 0x1; ++ if(WriteByte_ACC(adap, ACC_PAGESEL, *acc_data)) ++ return; ++ ++ // report orientation ++ // printk(KERN_INFO "bmi_lcd.c: bmi_lcd_input work (slot %d) pitch=0x%x, roll=0x%x, ABS_MISC=0x%x\n", ++ // slot, pitch, roll, pitch << 16 | roll); //pjg - debug ++ ++ input_report_abs(pbmi_lcd->input_dev[slot], ABS_MISC, (pitch << 16) | roll); ++ input_sync(pbmi_lcd->input_dev[slot]); ++ } ++#endif // ACCELEROMETER ++ ++ ++ // read touch screen - X, Y, TOUCH, PRESSURE ++ ++ penirq = bmi_slot_status_irq_state(slot); ++ /*printk(KERN_INFO "bmi_lcd.c: IRQ Status %d (slot %d) %d\n", penirq, slot,msecs_to_jiffies(10));*/ ++ ++ if (pbmi_lcd->activated[slot] && penirq) ++ { ++ ++ for(debounce = 0; debounce < DEBOUNCE; debounce++) ++ { ++ ++ memset(buf, 0, 4); ++ buf[3] = SPI_START | SPI_AY | SPI_MODE_12 | SPI_MODE_DFR | SPI_ADC; ++ spi_lcd_read_reg(pbmi_lcd, buf, 1, slot); ++ y = (((buf[0] << 5) | buf[1] >> 3)) & 0xFFF; ++ ++ memset(buf, 0, 4); ++ buf[3] = SPI_START | SPI_AX | SPI_MODE_12 | SPI_MODE_DFR | SPI_ADC; ++ spi_lcd_read_reg(pbmi_lcd, buf, 1, slot); ++ x = (((buf[0] << 5) | buf[1]) >> 3) & 0xFFF; ++ ++ memset(buf, 0, 4); ++ buf[3] = SPI_START | SPI_AZ1 | SPI_MODE_12 | SPI_MODE_DFR | SPI_ADC; ++ spi_lcd_read_reg(pbmi_lcd, buf, 1, slot); ++ z1 = (((buf[0] << 5) | buf[1]) >> 3) & 0xFFF; ++ ++ memset(buf, 0, 4); ++ buf[3] = SPI_START | SPI_AZ2 | SPI_MODE_12 | SPI_MODE_DFR | SPI_ADC; ++ spi_lcd_read_reg(pbmi_lcd, buf, 1, slot); ++ z2 = (((buf[0] << 5) | buf[1]) >> 3) & 0xFFF; ++ mdelay(1); ++ } ++ ++ if(x && y && z1 && z2) ++ pressure = (X_PLATE * x / 4096) * ((z2 / z1) - 1); ++ ++ x = 4096 - x; ++ y = 4096 - y; ++ ++ if (pressure < 70) ++ { ++ if (pbmi_lcd->scount) ++ update_pen_state(arg, slot, x, y, pressure); ++ else ++ { ++ pbmi_lcd->scount[slot]++; ++ /*update_pen_state(arg, slot, 0, 0, pressure);*/ ++ } ++ } ++ /* else ++ { ++ update_pen_state(arg, slot, 0, 0, pressure); ++ }*/ ++ ++ switch(slot) ++ { ++ case BMI_TS_M1: ++ schedule_delayed_work(&bmilcd_work0, WORK_DELAY); ++ break; ++ case BMI_TS_M2: ++ schedule_delayed_work(&bmilcd_work1, WORK_DELAY); ++ break; ++ case BMI_TS_M3: ++ schedule_delayed_work(&bmilcd_work2, WORK_DELAY); ++ break; ++ case BMI_TS_M4: ++ schedule_delayed_work(&bmilcd_work3, WORK_DELAY); ++ break; ++ } ++ /* printk(KERN_INFO "bmi_lcd.c: work scheduled on (slot %d)\n", slot); */ ++ /*buf[3] = SPI_START | SPI_PD; ++ spi_lcd_write_reg(pbmi_lcd, buf, 1, slot);*/ ++ } ++ ++ else ++ { ++ /*printk(KERN_INFO "bmi_lcd.c: Pen up on (slot %d)\n", slot);*/ ++ memset(buf, 0, 4); ++ buf[3] = SPI_START | SPI_PD; ++ spi_lcd_write_reg(pbmi_lcd, buf, 1, slot); ++ update_pen_state(arg,slot, 0, 0, 0); ++ enable_irq(pbmi_lcd->interrupt[slot]); ++ } ++ ++} ++ ++ ++// interrupt handler ++static irqreturn_t module_irq_handler(int irq, void *dummy) ++{ ++ disable_irq(irq); ++ /*printk(KERN_INFO "bmi_lcd.c: Interupt on (slot %d)\n", irq);*/ ++ switch(irq) ++ { ++ case M1_IRQ: ++ schedule_delayed_work(&bmilcd_work0, WORK_DELAY); ++ pbmi_lcd.scount[BMI_TS_M1] = 0; ++ break; ++ case M2_IRQ: ++ schedule_delayed_work(&bmilcd_work1, WORK_DELAY); ++ pbmi_lcd.scount[BMI_TS_M2] = 0; ++ break; ++ case M3_IRQ: ++ schedule_delayed_work(&bmilcd_work2, WORK_DELAY); ++ pbmi_lcd.scount[BMI_TS_M3] = 0; ++ break; ++ case M4_IRQ: ++ schedule_delayed_work(&bmilcd_work3, WORK_DELAY); ++ pbmi_lcd.scount[BMI_TS_M4] = 0; ++ break; ++ } ++ return IRQ_HANDLED; ++} ++ ++/* ++ * control device operations ++ */ ++ ++/* ++ * control device operations ++ */ ++ ++// open ++int cntl_open(struct inode *inode, struct file *filp) ++{ ++ if(pbmi_lcd.open_flag) { ++ return - EBUSY; ++ } ++ pbmi_lcd.open_flag = 1; ++ filp->private_data = &pbmi_lcd; ++ return 0; ++} ++ ++// release ++int cntl_release(struct inode *inode, struct file *filp) ++{ ++ pbmi_lcd.open_flag = 0; ++ return 0; ++} ++ ++// ioctl ++int cntl_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct i2c_adapter *adap; ++ unsigned char iox_data[1]; ++ int slot = (__user arg) & 0xF; ++ int bl = ((__user arg) & 0x70) >> 4; ++ ++ // error if no lcd active. ++ if(pbmi_lcd.active == -1) ++ return -ENODEV; ++ ++ if(cmd != BMI_LCD_GETSTAT) { ++ ++ // error if slot invalid ++ if((slot < CPLD_M1) || (slot > CPLD_M4)) ++ return -ENODEV; ++ ++ // error if no lcd in chosen slot ++ if(pbmi_lcd.bdev[slot] == 0) ++ return -ENODEV; ++ ++ // i2c adapter ++ adap = &pbmi_lcd.bdev[slot]->adap; ++ } ++ ++ // ioctl's ++ switch (cmd) { ++ case BMI_LCD_RLEDOFF: ++ bmi_set_module_gpio_data(slot, 3, 1);// Red LED=OFF ++ break; ++ case BMI_LCD_RLEDON: ++ bmi_set_module_gpio_data(slot, 3, 0);// Red LED=ON ++ break; ++ case BMI_LCD_GLEDOFF: ++ bmi_set_module_gpio_data(slot, 2, 1);// Green LED=OFF ++ break; ++ case BMI_LCD_GLEDON: ++ bmi_set_module_gpio_data(slot, 2, 0);// Green LED=ON ++ break; ++ case BMI_LCD_VSYNC_DIS: // enable VSYNC buffer tristate output ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data |= 0x08; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_VSYNC_EN: // disable VSYNC buffer tristate output ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data &= ~0x08; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_EN: // enable LCD component ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data &= ~0x10; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_DIS: // disable LCD component only ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data |= 0x10; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_SER_EN: // enable Serializer component ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data &= ~0x20; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_SER_DIS: // disable Serializer component only ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data |= 0x20; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_SETRST: // overall module reset ++ bmi_set_module_gpio_data (slot, 1, 0); // RST=0 ++ break; ++ case BMI_LCD_CLRRST: // overall module enable ++ bmi_set_module_gpio_data (slot, 1, 1); // RST=1 ++ break; ++ case BMI_LCD_SET_BL: // set backlight brightness ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data = (*iox_data & 0xF8) | bl; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_GETSTAT: ++ { ++ int *slot = ((int __user *) arg); ++ int read_data; ++ ++ *slot &= 0xF; ++ ++ // error if slot invalid ++ if((*slot < CPLD_M1) || (*slot > CPLD_M4)) ++ return -ENODEV; ++ ++ // error if no lcd in chosen slot ++ if(pbmi_lcd.bdev[*slot] == 0) ++ return -ENODEV; ++ ++ // i2c adapter ++ adap = &pbmi_lcd.bdev[*slot]->adap; ++ ++ if(ReadByte_IOX(adap, IOX_INPUT_REG, iox_data)) ++ return -ENODEV; ++ ++ read_data = *iox_data | (bmi_read_gpio_data_reg(*slot) << 8); ++ ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ } ++ break; ++ case BMI_LCD_ACTIVATE: //pjg fix/test ++ // check for opposite side already active ++ switch(slot) { // opposite side ++ case 0: ++ if(pbmi_lcd.activated[2] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 2 already active)\n", slot); ++ bmi_slot_power_off(0); ++ return -ENODEV; ++ } ++ break; ++ case 1: ++ if(pbmi_lcd.activated[3] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 3 already active)\n", slot); ++ bmi_slot_power_off(1); ++ return -ENODEV; ++ } ++ break; ++ case 2: ++ if(pbmi_lcd.activated[0] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 0 already active)\n", slot); ++ bmi_slot_power_off(2); ++ return -ENODEV; ++ } ++ break; ++ case 3: ++ if(pbmi_lcd.activated[1] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 1 already active)\n", slot); ++ bmi_slot_power_off(3); ++ return -ENODEV; ++ } ++ break; ++ } ++ // activate ++ if((!pbmi_lcd.activated[slot]) && (pbmi_lcd.bdev[slot] != 0)) { ++ bmi_lcd_probe(pbmi_lcd.bdev[slot]); ++ } ++ break; ++ case BMI_LCD_DEACTIVATE: ++ if(pbmi_lcd.activated[slot]) { ++ disable_irq_nosync(pbmi_lcd.interrupt[slot]); ++ pbmi_lcd.activated[slot] = 0; ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data = (*iox_data & 0xF8); ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ bmi_slot_power_off(slot); ++ } ++ break; ++ case BMI_LCD_SUSPEND: ++ printk(KERN_ERR "BMI_LCD_SUSPEND NOT IMPLEMENTED\n"); //pjg ++ break; ++ case BMI_LCD_RESUME: ++ printk(KERN_ERR "BMI_LCD_RESUME NOT IMPLEMENTED\n"); //pjg ++ break; ++ default: ++ return -ENOTTY; ++ } ++ return 0; ++} ++ ++ // control file operations ++struct file_operations cntl_fops = { ++ .owner = THIS_MODULE, ++ .ioctl = cntl_ioctl, ++ .open = cntl_open, ++ .release = cntl_release, ++}; ++ ++ // BMI LCD fops ++void bmi_lcd_config(struct bmi_lcd *lcd, int disp) ++{ ++ if(pbmi_lcd.active == -1) { ++ return; ++ } ++ ++ if((lcd) && (lcd->lcd_ops.config)) { ++ lcd->lcd_ops.config(disp); ++ } ++} ++ ++void bmi_lcd_reset(struct bmi_lcd *lcd, int slot) ++{ ++ if(pbmi_lcd.active == -1) { ++ return; ++ } ++ ++ if((lcd) && (lcd->lcd_ops.reset)) { ++ lcd->lcd_ops.reset(slot); ++ } ++} ++ ++int register_bmi_lcd(struct bmi_lcd *lcd, int slot) //pjg - placeholder for multiple LCD types ++{ ++ if(!lcd) { ++ return -1; ++ } ++ if((slot < 0) || (slot > 3)) { ++ return -1; ++ } ++ if(pbmi_lcd.blcd[slot]) { ++ return -1; ++ } ++ else { ++ pbmi_lcd.blcd[slot] = lcd; ++ } ++ ++ if(lcd->lcd_ops.activate) { ++ lcd->lcd_ops.activate(lcd, slot); ++ } ++ ++ return 0; ++} ++ ++int unregister_bmi_lcd(struct bmi_lcd *lcd, int slot) //pjg - placeholder for multiple LCD types ++{ ++ if (!lcd) { ++ return -1; ++ } ++ if ((slot < 0) || (slot > 3)) { ++ return -1; ++ } ++ if (pbmi_lcd.blcd[slot] != lcd) { ++ return -1; ++ } ++ else { ++ pbmi_lcd.blcd [slot] = 0; ++ lcd->lcd_ops.deactivate(lcd, slot); ++ } ++ return 0; ++} ++ ++static struct miscdevice cntl_dev = { ++ MISC_DYNAMIC_MINOR, ++ "bmi_lcd_control", ++ &cntl_fops ++}; ++ ++/* ++ * Module functions ++ */ ++ ++char const input_name0[MAX_STRG] = "bmi_lcd_ts0"; ++char const input_name1[MAX_STRG] = "bmi_lcd_ts1"; ++char const input_name2[MAX_STRG] = "bmi_lcd_ts2"; ++char const input_name3[MAX_STRG] = "bmi_lcd_ts3"; ++char const input_name4[MAX_STRG] = "bmi_lcd_ts4"; ++char const input_name5[MAX_STRG] = "bmi_lcd_ts5"; ++char const input_name6[MAX_STRG] = "bmi_lcd_ts6"; ++ ++static __init int bmi_lcd_init(void) ++{ ++ int ts; ++ int rc = 0; ++ ++ // No lcd is active. ++ pbmi_lcd.active = -1; ++ pbmi_lcd.activated[0] = 0; ++ pbmi_lcd.activated[1] = 0; ++ pbmi_lcd.activated[2] = 0; ++ pbmi_lcd.activated[3] = 0; ++ ++ // set up control character device - bmi_lcd_control ++ rc = misc_register(&cntl_dev); ++ if(rc) { ++ printk(KERN_ERR "bmi_lcd.c: Can't allocate bmi_lcd_control device\n"); ++ return rc; ++ } ++ ++ // Allocate and Register input device. - bmi_lcd_ts[BMI_TS_M1:BMI_TS_M1234] ++ for(ts = BMI_TS_M1; ts < BMI_TS_NUM; ts++) { ++ pbmi_lcd.input_dev[ts] = input_allocate_device(); ++ if(!pbmi_lcd.input_dev[ts]) { ++ printk(KERN_ERR "bmi_lcd_init: Can't allocate input_dev[ts]\n"); ++ return -ENOMEM; ++ } ++ ++ // set up input device ++ switch(ts) { ++ case BMI_TS_M1: ++ pbmi_lcd.input_dev[BMI_TS_M1]->name = input_name0; ++ pbmi_lcd.input_dev[BMI_TS_M1]->phys = input_name0; ++ break; ++ case BMI_TS_M2: ++ pbmi_lcd.input_dev[BMI_TS_M2]->name = input_name1; ++ pbmi_lcd.input_dev[BMI_TS_M2]->phys = input_name1; ++ break; ++ case BMI_TS_M3: ++ pbmi_lcd.input_dev[BMI_TS_M3]->name = input_name2; ++ pbmi_lcd.input_dev[BMI_TS_M3]->phys = input_name2; ++ break; ++ case BMI_TS_M4: ++ pbmi_lcd.input_dev[BMI_TS_M4]->name = input_name3; ++ pbmi_lcd.input_dev[BMI_TS_M4]->phys = input_name3; ++ break; ++ case BMI_TS_M13: ++ pbmi_lcd.input_dev[BMI_TS_M13]->name = input_name4; ++ pbmi_lcd.input_dev[BMI_TS_M13]->phys = input_name4; ++ break; ++ case BMI_TS_M24: ++ pbmi_lcd.input_dev[BMI_TS_M24]->name = input_name5; ++ pbmi_lcd.input_dev[BMI_TS_M24]->phys = input_name5; ++ break; ++ case BMI_TS_M1234: ++ pbmi_lcd.input_dev[BMI_TS_M1234]->name = input_name6; ++ pbmi_lcd.input_dev[BMI_TS_M1234]->phys = input_name6; ++ break; ++ } ++ pbmi_lcd.input_dev[ts]->id.bustype = BUS_BMI; ++ pbmi_lcd.input_dev[ts]->private = &pbmi_lcd; ++ pbmi_lcd.input_dev[ts]->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY); ++ pbmi_lcd.input_dev[ts]->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS); ++ pbmi_lcd.input_dev[ts]->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH); ++ pbmi_lcd.input_dev[ts]->absbit[BIT_WORD(ABS_X)] |= BIT_MASK(ABS_X); ++ pbmi_lcd.input_dev[ts]->absbit[BIT_WORD(ABS_Y)] |= BIT_MASK(ABS_Y); ++ pbmi_lcd.input_dev[ts]->absbit[BIT_WORD(ABS_PRESSURE)] |= BIT_MASK(ABS_PRESSURE); ++ pbmi_lcd.input_dev[ts]->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); ++ input_set_abs_params(pbmi_lcd.input_dev[ts], ABS_X, BMI_LCD_MIN_XC, BMI_LCD_MAX_XC, 0, 0); ++ input_set_abs_params(pbmi_lcd.input_dev[ts], ABS_Y, BMI_LCD_MIN_YC, BMI_LCD_MAX_YC, 0, 0); ++ input_set_abs_params(pbmi_lcd.input_dev[ts], ABS_PRESSURE, 0, 1024, 0, 0); ++ ++ // register input device ++ if(input_register_device(pbmi_lcd.input_dev[ts])) { ++ int tts; ++ printk(KERN_ERR "bmi_lcd_init() - input_register_device failed.\n"); ++ ++ for(tts = BMI_TS_M1; tts < ts; tts++) ++ input_unregister_device(pbmi_lcd.input_dev[tts]); ++ ++ misc_deregister(&cntl_dev); ++ ++ return -ENODEV; ++ } ++ } ++ ++ pbmi_lcd.lcd_cnt = 0; ++ ++ // hardware specfic set-up ++ s320x240_bmi_lcd.interface = s320x240_lcd_interface; ++ s320x240_bmi_lcd_ops.config = (void(*)) &s320x240_config; ++ s320x240_bmi_lcd_ops.reset = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd_ops.suspend = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd_ops.resume = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd_ops.disp_on = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd_ops.disp_off = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd_ops.activate = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd_ops.deactivate = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd.lcd_ops = s320x240_bmi_lcd_ops; ++ pbmi_lcd.blcd[0] = &s320x240_bmi_lcd; ++ pbmi_lcd.blcd[1] = &s320x240_bmi_lcd; ++ pbmi_lcd.blcd[2] = &s320x240_bmi_lcd; ++ pbmi_lcd.blcd[3] = &s320x240_bmi_lcd; ++ ++ sema_init(&pbmi_lcd.sem[0], 1); ++ sema_init(&pbmi_lcd.sem[1], 1); ++ sema_init(&pbmi_lcd.sem[2], 1); ++ sema_init(&pbmi_lcd.sem[3], 1); ++ ++ ++ acc_init(); ++ ++ // register with BMI ++ rc = bmi_register_driver(&bmi_lcd_driver); ++ if(rc) { ++ printk(KERN_ERR "bmi_lcd.c: Can't register bmi_lcd_driver\n"); ++ ++ for(ts = BMI_TS_M1; ts < BMI_TS_NUM; ts++) ++ input_unregister_device(pbmi_lcd.input_dev[ts]); ++ ++ misc_deregister(&cntl_dev); ++ ++ return rc; ++ } ++ ++ printk("bmi_lcd.c: BMI_LCD Driver v%s \n", BMILCD_VERSION); ++ ++ return 0; ++} ++ ++ ++static void __exit bmi_lcd_clean(void) ++{ ++ int ts; ++ ++ // remove input devices ++ for(ts = BMI_TS_M1; ts < BMI_TS_NUM; ts++) ++ input_unregister_device(pbmi_lcd.input_dev[ts]); ++ ++ // remove control device ++ misc_deregister(&cntl_dev); ++ ++ // remove bmi driver ++ bmi_unregister_driver(&bmi_lcd_driver); ++ acc_clean(); ++ return; ++} ++ ++module_init(bmi_lcd_init); ++module_exit(bmi_lcd_clean); ++ ++// Exported symbols ++EXPORT_SYMBOL(register_bmi_lcd); ++EXPORT_SYMBOL(unregister_bmi_lcd); ++ ++ ++MODULE_AUTHOR("Peter Giacomini "); ++MODULE_DESCRIPTION("BMI lcd device driver"); ++MODULE_SUPPORTED_DEVICE("bmi_lcd_control"); ++MODULE_SUPPORTED_DEVICE("bmi_lcd_ts"); ++MODULE_SUPPORTED_DEVICE("bmi_lcd_acc"); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ git/drivers/bmi/pims/lcd/bmi_lcd_mi.c +@@ -0,0 +1,1855 @@ ++/* ++ * bmi_lcd.c ++ * ++ * BMI LCD device driver ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/* ++ * Include files ++ */ ++ ++#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 "acc.h" ++ ++ ++#define DEBUG ++#undef DEBUG ++ ++#define BMILCD_VERSION "1.2" // driver version ++#define BUF_MAX_SIZE 0x20 // spi buffer size ++#define WORK_DELAY (1) // interrupt work handler delay ++#define DEBOUNCE 10 // touch screen debounce ++#define X_PLATE 400 // touch screen X plate resistance //pjg - This is not the correct value ++#define BMI_SLOT_NUM (4) // number of BMI slots ++#define MAX_STRG (40) // Max string buffer size ++ ++#define VSYNC_DISABLE 0x0 ++#define VSYNC_ENABLE 0x1 ++ ++ // lcd ++struct lcd_interface { ++ char lcd_type[MAX_STRG]; // text description of LCD type ++ u8 suspended; // power management state ++ u8 rotation; // screen rotation ++ u8 disp; // display number (DISP0 or DISP1) ++ u8 addr_mode; // display addressing mode ++ u8 vsync_mode; // VSYNC signal enable (VSYNC_ENABLE | VSYNC_DISABLE) ++ u8 bus_if_type; // bus type (XY | FullWoBE | FullWithBE) ++ ipu_adc_sig_cfg_t adc_sig; // IPU ADC set-up parameters ++ ipu_di_signal_cfg_t di_sig; // IPU DI set-up parameters ++}; ++ ++static struct lcd_interface s320x240_lcd_interface = { ++ .lcd_type = "MXCFB_SHARP_320X240", ++ .suspended = 0, ++ .rotation = IPU_ROTATE_NONE, ++ .disp = DISP0, ++ .vsync_mode = VSYNC_DISABLE, ++ .bus_if_type = XY, ++ .adc_sig = { 0, 0, 0, 0, 0, 0, 0, 0, IPU_ADC_BURST_WCS, IPU_ADC_IFC_MODE_SYS80_TYPE2, ++ 16, 0, 0, IPU_ADC_SER_NO_RW }, ++ .di_sig = { 0,0,0,0,0,0,0,0 }, //pjg - reserved for multiple LCD driver ++}; ++ ++extern void s320x240_config(int disp); ++extern void s320x240_disp_off(int disp); ++extern void s320x240_disp_on(int disp); ++ ++ ++struct bmi_lcd; ++ ++struct bmi_lcd_ops { ++ void *(*config) (int disp); // LCD configuration/initialization ++ void *(*reset) (int slot); // LCD reset ++ int *(*suspend) (struct bmi_lcd *blcd); // power management ++ int *(*resume) (struct bmi_lcd *blcd); // power management ++ int *(*disp_on) (int disp); // display on ++ int *(*disp_off) (int disp); // display off ++ int (*activate) (struct bmi_lcd *lcd, int slot); // enable LCD backlight, touchscreen, accelerometer, ... ++ int (*deactivate) (struct bmi_lcd *lcd, int slot); // disable LCD backlight, touchscreen, accelerometer, ... ++}; ++ ++struct bmi_lcd_ops s320x240_bmi_lcd_ops; ++ ++struct bmi_lcd { ++ struct lcd_interface interface; // pointer to this struct is returned by config() ++ struct bmi_lcd_ops lcd_ops; // function pointers ++}; ++ ++static struct bmi_lcd s320x240_bmi_lcd; ++ ++int register_bmi_lcd(struct bmi_lcd *blcd, int slot); ++int unregister_bmi_lcd(struct bmi_lcd *blcd, int slot); ++ ++ // private device structure ++struct pbmi_lcd ++{ ++ int open_flag; // force single open ++ unsigned int lcd_cnt; // number of LCD's present ++ unsigned int active; // indication of LCD presence ++ unsigned int activated[BMI_SLOT_NUM]; // indication of LCD presence ++ ++ struct bmi_lcd *blcd[BMI_SLOT_NUM]; // BMI LCD structure - placeholder for multiple display types ++ struct bmi_device *bdev[BMI_SLOT_NUM]; // BMI device per slot ++ unsigned int interrupt[BMI_SLOT_NUM]; // input device interrupt handlers ++ char int_name[MAX_STRG]; // interrupt name ++ ++ struct input_dev *input_dev[BMI_TS_NUM]; // input device (touch screen and accelerometer) ++ struct timer_list timer[BMI_SLOT_NUM]; // touch timer ++ ++ int pen_down[BMI_SLOT_NUM]; ++ int scount[BMI_SLOT_NUM]; ++ ++ struct semaphore i2c_sem[BMI_SLOT_NUM]; ++ ++ struct spi_device *spi[BMI_SLOT_NUM]; // touch screen device interface ++ struct semaphore sem[BMI_SLOT_NUM]; // spi semaphore ++ char rbuf[BMI_SLOT_NUM][BUF_MAX_SIZE]; // spi read buffer ++ char wbuf[BMI_SLOT_NUM][BUF_MAX_SIZE]; // spi write buffer ++ ++ struct acc_dev acc[BMI_SLOT_NUM]; ++ ++}; ++ ++static struct pbmi_lcd pbmi_lcd; // LCD device sructure ++ ++/* ++ * BMI set up ++ */ ++ ++ // BMI device ID table ++static struct bmi_device_id bmi_lcd_tbl[] = ++{ ++ { ++ .match_flags = BMI_DEVICE_ID_MATCH_VENDOR | BMI_DEVICE_ID_MATCH_PRODUCT, ++ .vendor = BMI_VENDOR_BUG_LABS, ++ .product = BMI_PRODUCT_LCD_SHARP_320X240, ++ .revision = BMI_ANY, ++ }, ++ { 0, }, /* terminate list */ ++}; ++ ++MODULE_DEVICE_TABLE(bmi, bmi_lcd_tbl); ++ ++/*printk(KERN_INFO "MDT: 0x%x\n", __mod_bmi_device_table);*/ ++ ++int bmi_lcd_probe(struct bmi_device *bdev); ++void bmi_lcd_remove(struct bmi_device *bdev); ++ ++// BMI driver structure ++static struct bmi_driver bmi_lcd_driver = ++{ ++ .name = "bmi_lcd", ++ .id_table = bmi_lcd_tbl, ++ .probe = bmi_lcd_probe, ++ .remove = bmi_lcd_remove, ++}; ++ ++//Accelerometer driver structure ++ ++ ++/* ++ * I2C set up ++ */ ++ ++ // I2C Slave Address ++#define BMI_IOX_I2C_ADDRESS 0x71 // 7-bit address ++#define BMI_ACC_I2C_ADDRESS 0x17 // 7-bit address ++ ++ // I2C IOX register addresses ++#define IOX_INPUT_REG 0x0 // IOX input data register ++#define IOX_OUTPUT_REG 0x1 // IOX output data register ++#define IOX_POLARITY_REG 0x2 // IOX polarity data register ++#define IOX_CONTROL 0x3 // IOX direction control register ++#define IOX_B1 (0) // bit 0 - backlight control ++#define IOX_A1_A2 (1) // bit 1 - backlight control ++#define IOX_ACC_RST_N (2) // bit 2 - acceleromter reset ++#define IOX_VSYNC_EN_N (3) // bit 3 - VSYNC output buffer enable ++#define IOX_LCD_RST_N (4) // bit 4 - LCD reset ++#define IOX_SERDES_PD_N (5) // bit 5 - SERDES power down ++#define IOX_X_INT (6) // bit 6 - accelerometer interrupt ++#define IOX_Y_INT (7) // bit 7 - accelerometer interrupt ++ ++ // I2C ACC register addresses - OKI ++#define ACC_PAGESEL 0x1E // device ready status ++ // page 0 ++#define ACC_DVRST 0x01 // device reset ++ #define ACC_DVRST_RST 0x3C // device reset ++ #define ACC_DVRST_EN 0xC3 // device enable ++#define ACC_PDWN 0x02 // osc power down ++ #define ACC_PWDN_RST 0x01 // device reset ++ #define ACC_PWDN_EN 0x00 // device enable ++#define ACC_CTRL0 0x03 // control 0 ++ #define ACC_CTRL0_CTSTR 0x40 // control 0 - temp sensor ++ #define ACC_CTRL0_CGSTRNC 0x08 // control 0 - 3-axis/no tilt ++ #define ACC_CTRL0_CGSTRC 0x04 // control 0 - 3-axis/tilt ++ #define ACC_CTRL0_CGAUTO 0x01 // control 0 - auto ++#define ACC_MODE0 0x05 // control 0 ++ #define ACC_MODE0_PDOFF 0x80 // mode 0 - disable auto power down ++ #define ACC_MODE0_RVOFF 0x40 // mode 0 - disable temp compensation ++ #define ACC_MODE0_TMPOFF 0x20 // mode 0 - disable temp measurement ++ #define ACC_MODE0_AGCON 0x10 // mode 0 - enable auto mode pitch and roll ++ #define ACC_MODE0_MAUTO 0x04 // mode 0 - enable auto termination ++ #define ACC_MODE0_GDET00 0x00 // mode 0 - g detection threshold - see ML8953 data sheet ++ #define ACC_MODE0_GDET01 0x01 // mode 0 - g detection threshold - see ML8953 data sheet ++ #define ACC_MODE0_GDET10 0x02 // mode 0 - g detection threshold - see ML8953 data sheet ++#define ACC_MODE1 0x06 // mode 1 ++ #define ACC_MODE1_MOFF 0x20 // mode 1 - disable 3-axis continuous mode ++ #define ACC_MODE1_ZAXIS 0x03 // mode 1 - Z axis ++ #define ACC_MODE1_YAXIS 0x02 // mode 1 - Y axis ++ #define ACC_MODE1_XAXIS 0x01 // mode 1 - X axis ++ #define ACC_MODE1_RAXIS 0x00 // mode 1 - Reference axis ++#define ACC_INTRQ 0x07 // interrupt request (1 = request) ++#define ACC_INTMSK 0x08 // interrupt mask (1 = masked) ++ #define ACC_INT_TREQ 0x20 // interrupt - temperature ++ #define ACC_INT_GREQ 0x08 // interrupt - acceleration/no tilt ++ #define ACC_INT_GCREQ 0x04 // interrupt - acceleration/tilt ++ #define ACC_INT_GAREQ 0x01 // interrupt - automatic ++#define ACC_TMDL 0x09 // timer LSB = (1/6.2 MHz) x 2048 x TMD ++#define ACC_TMDH 0x0A // timer MSB ++#define ACC_CFG 0x0C // configuration ++ #define ACC_CFG_REGMD 0x80 // address auto-increment ++ #define ACC_CFG_SPI3M_3 0x40 // spi mode = 3-wire ++ #define ACC_CFG_SPI3M_4 0x00 // spi mode = 4-wire ++ #define ACC_CFG_SDOCFG_T 0x10 // sdo mode = totem-pole ++ #define ACC_CFG_SDOCFG_OC 0x00 // sdo mode = open-drain ++ #define ACC_CFG_INT1EN_G 0x08 // interrupt 1 mode = g only ++ #define ACC_CFG_INT1EN_ALL 0x00 // interrupt 1 mode = all ++ #define ACC_CFG_INTLVL 0x04 // interrupt level mode ++ #define ACC_CFG_INT1CFG_T 0x02 // interrupt 1 mode = totem-pole ++ #define ACC_CFG_INT1CFG_OC 0x00 // interrupt 1 mode = open-drain ++ #define ACC_CFG_INT0CFG_T 0x01 // interrupt 0 mode = totem-pole ++ #define ACC_CFG_INT0CFG_OC 0x00 // interrupt 0 mode = open-drain ++#define ACC_INTOTM 0x0D // interrupt output conditions ++#define ACC_GAAVE 0x0E // Data averaging - automatic mode ++#define ACC_GNAVE 0x0F // Data averaging - normal mode ++#define ACC_GDTCT0L 0x11 // threshold 0 LSB ++#define ACC_GDTCT0H 0x12 // threshold 0 MSB ++#define ACC_GDTCT1L 0x13 // threshold 1 LSB ++#define ACC_GDTCT1H 0x14 // threshold 1 MSB ++#define ACC_CPURDY 0x15 // device ready status (ready = 0x01) ++ // page 1 ++#define ACC_STATUS 0x01 // measurment status ++ #define ACC_STATUS_ASTS 0x02 // acceleration measurement - automatic modes ++ #define ACC_STATUS_STS 0x01 // acceleration measurement - non-automatic modes ++#define ACC_GAXL 0x02 // g vector ++#define ACC_GAXH 0x03 // g vector ++#define ACC_GAYL 0x04 // g vector ++#define ACC_GAYH 0x05 // g vector ++#define ACC_GAZL 0x06 // g vector ++#define ACC_GAZH 0x07 // g vector ++#define ACC_GASVL 0x08 // g vector ++#define ACC_GASVH 0x09 // g vector ++#define ACC_GNXL 0x0A // g vector ++#define ACC_GNXH 0x0B // g vector ++#define ACC_GNYL 0x0C // g vector ++#define ACC_GNYH 0x0D // g vector ++#define ACC_GNZL 0x0E // g vector ++#define ACC_GNZH 0x0F // g vector ++#define ACC_GNSVL 0x10 // g vector ++#define ACC_GNSVH 0x11 // g vector ++#define ACC_PITCHL 0x12 // pitch ++#define ACC_PITCHH 0x13 // pitch ++#define ACC_ROLLL 0x14 // roll ++#define ACC_ROLLH 0x15 // roll ++#define ACC_TEMPL 0x19 // temperature ++#define ACC_TEMPH 0x1A // temperature ++ ++ // read byte from I2C IO expander ++static int ReadByte_IOX(struct i2c_adapter *adap, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ ++ /* Read Byte with Pointer */ ++ ++ rmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[0].flags = 0; /* write */ ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; /* read */ ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ++ ret = i2c_transfer (adap, rmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "ReadByte_IOX() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++ ++static int ReadByteLock_IOX(struct pbmi_lcd *priv, unsigned char offset, unsigned char *data, int slot) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ struct i2c_adapter *adap; ++ ++ /* Read Byte with Pointer */ ++ ++ adap = &priv->bdev[slot]->adap; ++ ++ rmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[0].flags = 0; /* write */ ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; /* read */ ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ++ down(&priv->i2c_sem[slot]); ++ ret = i2c_transfer (adap, rmsg, num_msgs); ++ up(&priv->i2c_sem[slot]); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "ReadByte_IOX() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++ ++ // write byte to I2C IO expander ++static int WriteByte_IOX(struct i2c_adapter *adap, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ /* Write Byte with Pointer */ ++ ++ wmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[0].flags = 0; /* write */ ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[1].flags = 0; /* write */ ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ret = i2c_transfer (adap, wmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "WriteByte_IOX() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++ ++static int WriteByteLock_IOX(struct pbmi_lcd *priv, unsigned char offset, unsigned char data, int slot) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ struct i2c_adapter *adap; ++ /* Write Byte with Pointer */ ++ ++ adap = &priv->bdev[slot]->adap; ++ if (adap == NULL) ++ { ++ printk(KERN_INFO "WriteByteLock_IOX adap NULL\n"); ++ return -1; ++ } ++ wmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[0].flags = 0; /* write */ ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[1].flags = 0; /* write */ ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ down(&priv->i2c_sem[slot]); ++ printk(KERN_INFO "WriteByteLock_IOX attempting I2C xfer\n"); ++ ret = i2c_transfer (adap, wmsg, num_msgs); ++ up(&priv->i2c_sem[slot]); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "WriteByteLock_IOX() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++ ++ // read byte from I2C acceleromter ++static int ReadByte_ACC(struct i2c_adapter *adap, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ int retries = 0; ++ ++ /* Read Byte with Pointer */ ++ ++ rmsg[0].addr = BMI_ACC_I2C_ADDRESS; ++ rmsg[0].flags = 0; /* write */ ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_ACC_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; /* read */ ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ++ while (retries < 5) ++ { ++ ret = i2c_transfer (adap, rmsg, num_msgs); ++ if (ret == 2) ++ break; ++ else ++ retries++; ++ mdelay(1); ++ } ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "ReadByte_ACC() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++static int ReadByteLock_ACC(struct pbmi_lcd *priv, unsigned char offset, unsigned char *data, int slot) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ struct i2c_adapter *adap; ++ ++ /* Read Byte with Pointer */ ++ ++ adap = &priv->bdev[slot]->adap; ++ ++ rmsg[0].addr = BMI_ACC_I2C_ADDRESS; ++ rmsg[0].flags = 0; /* write */ ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_ACC_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; /* read */ ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ++ down(&priv->i2c_sem[slot]); ++ ret = i2c_transfer (adap, rmsg, num_msgs); ++ up(&priv->i2c_sem[slot]); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "ReadByteLock_ACC() - i2c_transfer() failed.0x%x\n",-ret); ++ ret = -1; ++ } ++ return ret; ++} ++ ++ // write byte to I2C accelerometer ++static int WriteByte_ACC(struct i2c_adapter *adap, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ /* Write Byte with Pointer */ ++ ++ wmsg[0].addr = BMI_ACC_I2C_ADDRESS; ++ wmsg[0].flags = 0; /* write */ ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_ACC_I2C_ADDRESS; ++ wmsg[1].flags = 0; /* write */ ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ ret = i2c_transfer (adap, wmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "WriteByte_ACC() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++static int WriteByteLock_ACC(struct pbmi_lcd *priv, unsigned char offset, unsigned char data, int slot) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ struct i2c_adapter *adap; ++ /* Write Byte with Pointer */ ++ ++ adap = &priv->bdev[slot]->adap; ++ ++ wmsg[0].addr = BMI_ACC_I2C_ADDRESS; ++ wmsg[0].flags = 0; /* write */ ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_ACC_I2C_ADDRESS; ++ wmsg[1].flags = 0; /* write */ ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ down(&priv->i2c_sem[slot]); ++ ret = i2c_transfer (adap, wmsg, num_msgs); ++ up(&priv->i2c_sem[slot]); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "WriteByteLock_ACC() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++/* ++ * SPI functions ++ */ ++ ++ // TSC2046 touch screen controller command register bit definitons ++#define SPI_START 0x80 // command start ++#define SPI_AT0 0x00 // read temperature - not supported ++#define SPI_AY 0x10 // read Y ++#define SPI_ABAT 0x20 // read battery - not supported ++#define SPI_AZ1 0x30 // read Z1 ++#define SPI_AZ2 0x40 // read Z2 ++#define SPI_AX 0x50 // read X ++#define SPI_AAUX 0x60 // read AUX - not supported ++#define SPI_AT1 0x70 // read temperature - not supported ++#define SPI_MODE_12 0x00 // 12-bit mode - Preferred ++#define SPI_MODE_8 0x08 // 8-bit mode ++#define SPI_MODE_DFR 0x00 // differential mode - Preferred ++#define SPI_MODE_SER 0x04 // single ended mode ++#define SPI_PD 0x00 // power down - PENIRQ enabled ++#define SPI_ADC 0x01 // ADC enabled ++#define SPI_REF 0x02 // Vref enabled - unused ++#define SPI_REF_ADC 0x03 // Vref & ADC enabled - unused ++ ++ // spi access ++static int spi_rw(struct spi_device *spi, u8 * buf, size_t len) ++{ ++ struct spi_transfer t = { ++ .tx_buf = (const void *)buf, ++ .rx_buf = buf, ++ .len = len, ++ .cs_change = 0, ++ .delay_usecs = 0, ++ }; ++ struct spi_message m; ++ ++ spi_message_init(&m); ++ ++ spi_message_add_tail(&t, &m); ++ if (spi_sync(spi, &m) != 0 || m.status != 0) ++ return -1; ++ ++ return m.actual_length; ++} ++ ++ // spi write register ++static ssize_t spi_lcd_write_reg(struct pbmi_lcd *priv, char *buf, int len, int slot) ++{ ++ int res = 0; ++ ++ down(&priv->sem[slot]); ++ ++ memset(priv->wbuf[slot], 0, BUF_MAX_SIZE); ++ priv->wbuf[slot][0] = buf[0]; ++ priv->wbuf[slot][1] = buf[1]; ++ priv->wbuf[slot][2] = buf[2]; ++ priv->wbuf[slot][3] = buf[3]; ++ res = spi_rw(priv->spi[slot], priv->wbuf[slot], len); ++ if (res != 1) { ++ up(&priv->sem[slot]); ++ return -EFAULT; ++ } ++ ++ up(&priv->sem[slot]); ++ ++ return res; ++} ++ ++ // spi read register ++static ssize_t spi_lcd_read_reg(struct pbmi_lcd *priv, char *buf, int len, int slot) ++{ ++ int res = 0; ++ ++ down(&priv->sem[slot]); ++ ++ memset(priv->wbuf[slot], 0, BUF_MAX_SIZE); ++ priv->wbuf[slot][0] = buf[0]; ++ priv->wbuf[slot][1] = buf[1]; ++ priv->wbuf[slot][2] = buf[2]; ++ priv->wbuf[slot][3] = buf[3]; ++ res = spi_rw(priv->spi[slot], priv->wbuf[slot], len); ++ if (res != 1) { ++ up(&priv->sem[slot]); ++ return -EFAULT; ++ } ++ ++ memset(priv->rbuf[slot], 0, BUF_MAX_SIZE); ++ buf[0] = priv->wbuf[slot][2]; ++ buf[1] = priv->wbuf[slot][1]; ++ ++ up(&priv->sem[slot]); ++ ++ return res; ++} ++ ++/* ++ * BMI functions ++ */ ++ ++static irqreturn_t module_irq_handler(int irq, void *dummy); ++void bmi_lcd_config(struct bmi_lcd *lcd, int disp); ++ ++ // probe ++int bmi_lcd_probe(struct bmi_device *bdev) ++{ ++ ++ unsigned char acc_data[1]; ++ unsigned char iox_data[1]; ++ int slot = bdev->info->slot; ++ struct i2c_adapter *adap; ++ struct bmi_lcd *lcd; ++ char buf[4]; ++ ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d\n", slot); ++ ++ // check for opposite side already active ++ switch(slot) { // opposite side ++ case 0: ++ if(pbmi_lcd.activated[2] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 2 already active)\n", slot); ++ bmi_slot_power_off(0); ++ pbmi_lcd.bdev[0] = bdev; ++ return 0; ++ } ++ break; ++ case 1: ++ if(pbmi_lcd.activated[3] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 3 already active)\n", slot); ++ bmi_slot_power_off(1); ++ pbmi_lcd.bdev[1] = bdev; ++ return 0; ++ } ++ break; ++ case 2: ++ if(pbmi_lcd.activated[0] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 0 already active)\n", slot); ++ bmi_slot_power_off(2); ++ pbmi_lcd.bdev[2] = bdev; ++ return 0; ++ } ++ break; ++ case 3: ++ if(pbmi_lcd.activated[1] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 1 already active)\n", slot); ++ bmi_slot_power_off(3); ++ pbmi_lcd.bdev[3] = bdev; ++ return 0; ++ } ++ break; ++ } ++ ++ adap = &bdev->adap; ++ bmi_slot_power_on(slot); ++ ++ // set up bdev/pbmi_lcd pointers ++ bmi_device_set_drvdata(bdev, &pbmi_lcd); ++ pbmi_lcd.bdev[slot] = bdev; ++ ++ printk(KERN_INFO "Adap = 0x%x",adap); ++ ++ printk(KERN_INFO "Lock stuff = 0x%x", &(pbmi_lcd.bdev[slot]->adap)); ++ ++ mdelay(500); ++ ++ // configure IOX ++ // [7:6]=interrupts, [5]=SER_PD*, [4]=LCD_RST*, [3]=VSYNC_OE*, [2]=ACC_RST*, [1:0]=backlight ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, 0xFF)) // normal - no accelerometer interrupts ++ return -ENODEV; ++ if(WriteByteLock_IOX(&pbmi_lcd, IOX_OUTPUT_REG, 0xFF, slot)) // normal - no accelerometer interrupts ++ return -ENODEV; ++ ++ // normal operation - no accelerometer interrupts ++ if(WriteByteLock_IOX(&pbmi_lcd, IOX_CONTROL, 0x00, slot)) // IOX[7:0]=OUT ++ return -ENODEV; ++ ++ // clear interrupts ++ if(ReadByteLock_IOX(&pbmi_lcd, IOX_INPUT_REG, iox_data, slot)) ++ return -ENODEV; ++ ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d iox data = %x\n", slot, *iox_data); ++ ++ ++ // accelerometer ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d hardware version = 0x%x\n", slot, bdev->epraw.revision_msb); ++ ++ // check for PCB revision >= 1.2 ++ if(bdev->epraw.revision_msb >= 0x12) ++ { ++ ++ // normal IOX operation - accelerometer interrupts ++ if(WriteByteLock_IOX(&pbmi_lcd, IOX_CONTROL, 0xC0, slot)) // IOX[7:6]=IN, IOX[5:0]=OUT ++ return -ENODEV; ++ ++ if(WriteByteLock_IOX(&pbmi_lcd, IOX_OUTPUT_REG, 0xFB, slot)) // reset OKI accelerometer ++ return -ENODEV; ++ ++ mdelay(2); ++ ++ if(WriteByteLock_IOX(&pbmi_lcd, IOX_OUTPUT_REG, 0xFF, slot)) // enable OKI accelerometer ++ return -ENODEV; ++ ++ mdelay(2); ++ ++ // write PAGESEL ++ *acc_data = 0x0; ++ if(WriteByteLock_ACC(&pbmi_lcd, ACC_PAGESEL, *acc_data, slot)) ++ return -ENODEV; ++ ++ // read device to verify existance ++ if(ReadByteLock_ACC(&pbmi_lcd, ACC_CPURDY, acc_data, slot)) ++ return -ENODEV; ++ ++ // set TMD = 0x300 (~250 ms) ++ *acc_data = 0x5; ++ if(WriteByteLock_ACC(&pbmi_lcd, ACC_TMDH, *acc_data, slot)) ++ return -ENODEV; ++ ++ *acc_data = 0x0; ++ if(WriteByteLock_ACC(&pbmi_lcd, ACC_TMDL, *acc_data, slot)) ++ return -ENODEV; ++ ++ // set INTOTM ++ *acc_data = 0x00; ++ if(WriteByteLock_ACC(&pbmi_lcd, ACC_INTOTM, *acc_data, slot)) ++ return -ENODEV; ++ ++ // set GxAVE ++ *acc_data = 0x0; ++ if(WriteByteLock_ACC(&pbmi_lcd, ACC_GAAVE, *acc_data, slot)) ++ return -ENODEV; ++ ++ // set GDTCT[01] ++ *acc_data = 0x00; ++ if(WriteByteLock_ACC(&pbmi_lcd, ACC_GDTCT0L, *acc_data, slot)) ++ return -ENODEV; ++ ++ *acc_data = 0x00; ++ if(WriteByteLock_ACC(&pbmi_lcd, ACC_GDTCT0H, *acc_data, slot)) ++ return -ENODEV; ++ ++ *acc_data = 0x00; ++ if(WriteByteLock_ACC(&pbmi_lcd, ACC_GDTCT1L, *acc_data, slot)) ++ return -ENODEV; ++ ++ *acc_data = 0x00; ++ if(WriteByteLock_ACC(&pbmi_lcd, ACC_GDTCT1H, *acc_data, slot)) ++ return -ENODEV; ++ ++ // set MODE0 ++ *acc_data = ACC_MODE0_PDOFF | ACC_MODE0_TMPOFF | ACC_MODE0_AGCON | ACC_MODE0_MAUTO | ACC_MODE0_GDET10; ++ if(WriteByteLock_ACC(&pbmi_lcd, ACC_MODE0, *acc_data, slot)) ++ return -ENODEV; ++ ++ // set CFG ++ *acc_data = ACC_CFG_REGMD | ACC_CFG_INTLVL; ++ if(WriteByteLock_ACC(&pbmi_lcd, ACC_CFG, *acc_data, slot)) ++ return -ENODEV; ++ ++ // set INTMSK ++ *acc_data = 0xFE; ++ if(WriteByteLock_ACC(&pbmi_lcd, ACC_INTMSK, *acc_data, slot)) ++ return -ENODEV; ++ ++ // set CTRL0 ++ *acc_data = ACC_CTRL0_CGAUTO; ++ if(WriteByteLock_ACC(&pbmi_lcd, ACC_CTRL0, *acc_data, slot)) ++ return -ENODEV; ++ ++ // write PAGESEL ++ *acc_data = 0x1; ++ if(WriteByteLock_ACC(&pbmi_lcd, ACC_PAGESEL, *acc_data, slot)) ++ return -ENODEV; ++ ++ acc_probe(&pbmi_lcd.acc[slot], slot); ++ } ++ else ++ { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d hardware version = 0x%x (accelerometer not supported)\n", slot, bdev->epraw.revision_msb); ++ } ++ ++ // reset serial link (master) ++ if((slot == 0) || (slot == 2)) ++ { ++ bmi_lcd_inactive(0); ++ } ++ else ++ { ++ bmi_lcd_inactive(1); ++ } ++ ++ // configure GPIO ++ // turn LED's on ++ bmi_set_module_gpio_data(slot, 3, 0); // Red LED=ON ++ bmi_set_module_gpio_data(slot, 2, 0); // Green LED=ON ++ ++ // assert reset ++ bmi_set_module_gpio_data(slot, 1, 0); // RST=0 ++ ++ // set GPIO direction ++ bmi_set_module_gpio_dir(slot, 3, BMI_GPIO_OUT); ++ bmi_set_module_gpio_dir(slot, 2, BMI_GPIO_OUT); ++ bmi_set_module_gpio_dir(slot, 1, BMI_GPIO_OUT); ++ bmi_set_module_gpio_dir(slot, 0, BMI_GPIO_IN); // real-time pen int state ++ ++ mdelay(200); ++ ++ // turn LED's off ++ bmi_set_module_gpio_data(slot, 3, 1); // Red LED=OFF ++ bmi_set_module_gpio_data(slot, 2, 1); // Green LED=OFF ++ ++ // deassert reset (module) ++ bmi_set_module_gpio_data(slot, 1, 1); // RST=1 ++ ++ mdelay(500); ++ ++ // unreset serial link (master) ++ if((slot == 0) || (slot == 2)) { ++ mdelay(2); ++ bmi_lcd_active(0, 0x0, LCD_MODE_I80); ++ } else { ++ mdelay(2); ++ bmi_lcd_active(1, 0x0, LCD_MODE_I80); ++ } ++ ++ ++ ++ ++ // spi set-up ++ if (bmi_device_spi_setup(bdev, 2000000, SPI_MODE_2, 32)) { ++ printk(KERN_ERR "bmi_lcd.c: Unable to setup spi%d\n", slot); ++ bmi_device_set_drvdata(bdev, NULL); ++ pbmi_lcd.bdev[slot] = NULL; ++ bmi_slot_power_off(slot); ++ return -EFAULT; ++ } ++ ++ bmi_slot_spi_enable(slot); ++ pbmi_lcd.spi[slot] = bmi_device_get_spi(bdev); ++ ++ ++ // check spi access and enable touch screen ++ memset(buf, 0, 4); ++ buf[3] = SPI_START | SPI_PD; ++ if(spi_lcd_write_reg(&pbmi_lcd, buf, 1, slot) != 1) { ++ printk(KERN_WARNING "bmi_lcd.c: Unable set-up spi for bmi_lcd %d\n", slot); ++ bmi_device_set_drvdata(bdev, NULL); ++ pbmi_lcd.bdev[slot] = NULL; ++ pbmi_lcd.spi[slot] = NULL; ++ bmi_device_spi_cleanup(bdev); ++ bmi_slot_spi_disable(slot); ++ bmi_slot_power_off(slot); ++ return -EFAULT; ++ } ++ ++ ++ // complete pbmi_lcd set-up ++ pbmi_lcd.lcd_cnt++; ++ pbmi_lcd.active = 1; ++ pbmi_lcd.activated[slot] = 1; ++ ++ ++ mdelay(100); ++ ++ lcd = pbmi_lcd.blcd[slot]; ++ if((slot == 0) || (slot == 2)) { ++ mdelay(2); ++ bmi_lcd_config(lcd, 0); ++ mdelay(2); ++ } else { ++ mdelay(2); ++ bmi_lcd_config(lcd, 1); ++ mdelay(2); ++ } ++ ++ ++ // request input event interrupt handler ++ pbmi_lcd.interrupt[0] = M1_IRQ; ++ pbmi_lcd.interrupt[1] = M2_IRQ; ++ pbmi_lcd.interrupt[2] = M3_IRQ; ++ pbmi_lcd.interrupt[3] = M4_IRQ; ++ snprintf(pbmi_lcd.int_name, sizeof(pbmi_lcd.int_name), "bmi_lcd%d", slot); ++ if (request_irq(pbmi_lcd.interrupt[slot], &module_irq_handler, 0, pbmi_lcd.int_name, &pbmi_lcd)) ++ { ++ printk( KERN_ERR "bmi_lcd.c: Can't allocate irq %d or find lcd in slot %d\n", pbmi_lcd.interrupt[slot], slot); ++ bmi_device_set_drvdata(bdev, NULL); ++ pbmi_lcd.bdev[slot] = NULL; ++ pbmi_lcd.spi[slot] = NULL; ++ bmi_device_spi_cleanup(bdev); ++ bmi_slot_power_off(slot); ++ return -EBUSY; ++ } ++ ++ // check GPIO status ++ printk(KERN_INFO "bmi_lcd.c: slot %d gpio = %x\n", slot, bmi_read_gpio_data_reg(slot)); ++ printk(KERN_INFO "bmi_lcd.c: LCD count = %d\n", pbmi_lcd.lcd_cnt); ++ ++ return 0; ++} ++ ++extern struct delayed_work bmilcd_work0; ++extern struct delayed_work bmilcd_work1; ++extern struct delayed_work bmilcd_work2; ++extern struct delayed_work bmilcd_work3; ++ ++ // remove ++void bmi_lcd_remove(struct bmi_device *bdev) ++{ ++ int slot = bdev->info->slot; ++ ++ if(pbmi_lcd.activated[slot] == 0) ++ return; ++ ++ switch(slot) { ++ case 0: ++ cancel_delayed_work(&bmilcd_work0); ++ break; ++ case 1: ++ cancel_delayed_work(&bmilcd_work1); ++ break; ++ case 2: ++ cancel_delayed_work(&bmilcd_work2); ++ break; ++ case 3: ++ cancel_delayed_work(&bmilcd_work3); ++ break; ++ } ++ ++ free_irq(pbmi_lcd.interrupt[slot], &pbmi_lcd); ++ ++ bmi_set_module_gpio_dir (slot, 3, BMI_GPIO_IN); ++ bmi_set_module_gpio_dir (slot, 2, BMI_GPIO_IN); ++ bmi_set_module_gpio_dir (slot, 1, BMI_GPIO_IN); ++ bmi_set_module_gpio_dir (slot, 0, BMI_GPIO_IN); ++ ++ // bmi/spi clean-up ++ bmi_device_spi_cleanup(bdev); ++ pbmi_lcd.spi[slot] = NULL; ++ bmi_slot_spi_disable(slot); ++ ++ //de-attach driver-specific struct from bmi_device structure ++ bmi_device_set_drvdata (&bdev[slot], 0); ++ ++ // deactivate ++ pbmi_lcd.activated[slot] = 0; ++ pbmi_lcd.bdev[slot] = 0; ++ pbmi_lcd.lcd_cnt--; ++ ++ if((pbmi_lcd.activated[0] == 0) && (pbmi_lcd.activated[2] == 0)) { ++ bmi_lcd_inactive(0); // disable serializer ++ } ++ ++ if((pbmi_lcd.activated[1] == 0) && (pbmi_lcd.activated[3] == 0)) { ++ bmi_lcd_inactive(1); // disable serializer ++ } ++ ++ if((pbmi_lcd.activated[0] == 0) && (pbmi_lcd.activated[1] == 0) && ++ (pbmi_lcd.activated[2] == 0) && (pbmi_lcd.activated[3] == 0)) { ++ pbmi_lcd.active = -1; ++ } ++ ++ // enable LCD on opposite side ++ switch(slot) { ++ case 0: ++ if(pbmi_lcd.bdev[2] != 0) ++ bmi_lcd_probe(pbmi_lcd.bdev[2]); ++ break; ++ case 1: ++ if(pbmi_lcd.bdev[3] != 0) ++ bmi_lcd_probe(pbmi_lcd.bdev[3]); ++ break; ++ case 2: ++ if(pbmi_lcd.bdev[0] != 0) ++ bmi_lcd_probe(pbmi_lcd.bdev[0]); ++ break; ++ case 3: ++ if(pbmi_lcd.bdev[1] != 0) ++ bmi_lcd_probe(pbmi_lcd.bdev[1]); ++ break; ++ } ++ ++ acc_remove(&pbmi_lcd.acc[slot], slot); ++ printk(KERN_INFO "bmi_lcd.c: LCD count = %d\n", pbmi_lcd.lcd_cnt); ++ ++ return; ++} ++ ++/* ++ * Input interrupt handler and support routines ++ */ ++ ++static void update_pen_state(void *arg, int slot, int x, int y, int pressure) ++{ ++ struct pbmi_lcd *pbmi_lcd = (struct pbmi_lcd *)arg; ++ int sync = 0; ++ ++ if (pressure) ++ { ++ /*input_report_abs(pbmi_lcd->input_dev[slot], ABS_X, x); ++ input_report_abs(pbmi_lcd->input_dev[slot], ABS_Y, y); ++ input_report_abs(pbmi_lcd->input_dev[slot], ABS_PRESSURE, pressure); ++ ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M1234], ABS_X, x); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M1234], ABS_Y, y); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M1234], ABS_PRESSURE, pressure);*/ ++ ++ if((slot == 0) || (slot == 2)) ++ { ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M13], ABS_Y, y); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M13], ABS_X, x); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M13], ABS_PRESSURE, pressure); ++ } ++ else ++ { ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M24], ABS_Y, y); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M24], ABS_X, x); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M24], ABS_PRESSURE, pressure); ++ } ++ ++ if (!pbmi_lcd->pen_down[slot]) ++ { ++ /*input_report_key(pbmi_lcd->input_dev[slot], BTN_TOUCH, 1); ++ input_report_key(pbmi_lcd->input_dev[BMI_TS_M1234], BTN_TOUCH, 1);*/ ++ if((slot == 0) || (slot == 2)) ++ { ++ input_report_key(pbmi_lcd->input_dev[BMI_TS_M13], BTN_TOUCH, 1); ++ } ++ else ++ { ++ input_report_key(pbmi_lcd->input_dev[BMI_TS_M24], BTN_TOUCH, 1); ++ } ++ ++ } ++ sync = 1; ++ } ++ else if (pbmi_lcd->pen_down[slot]) ++ { ++ /*input_report_key(pbmi_lcd->input_dev[slot], BTN_TOUCH, 0); ++ input_report_abs(pbmi_lcd->input_dev[slot], ABS_PRESSURE, 0); ++ ++ input_report_key(pbmi_lcd->input_dev[BMI_TS_M1234], BTN_TOUCH, 0); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M1234], ABS_PRESSURE, 0); */ ++ ++ if((slot == 0) || (slot == 2)) ++ { ++ input_report_key(pbmi_lcd->input_dev[BMI_TS_M13], BTN_TOUCH, 0); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M13], ABS_PRESSURE, 0); ++ } ++ else ++ { ++ input_report_key(pbmi_lcd->input_dev[BMI_TS_M24], BTN_TOUCH, 0); ++ input_report_abs(pbmi_lcd->input_dev[BMI_TS_M24], ABS_PRESSURE, 0); ++ } ++ sync = 1; ++ } ++ ++ if (sync) ++ { ++ /*input_sync(pbmi_lcd->input_dev[slot]); ++ input_sync(pbmi_lcd->input_dev[BMI_TS_M1234]);*/ ++ if((slot == 0) || (slot == 2)) ++ { ++ input_sync(pbmi_lcd->input_dev[BMI_TS_M13]); ++ } ++ else ++ { ++ input_sync(pbmi_lcd->input_dev[BMI_TS_M24]); ++ } ++ } ++ pbmi_lcd->pen_down[slot] = pressure ? 1 : 0; ++ ++} ++ ++ ++void bmilcd_input_work(void *arg, int slot); ++ ++void bmilcd_input_work0(struct work_struct * work) { ++ bmilcd_input_work(&pbmi_lcd, 0); ++} ++ ++void bmilcd_input_work1(struct work_struct * work) { ++ bmilcd_input_work(&pbmi_lcd, 1); ++} ++ ++void bmilcd_input_work2(struct work_struct * work) { ++ bmilcd_input_work(&pbmi_lcd, 2); ++} ++ ++void bmilcd_input_work3(struct work_struct * work) { ++ bmilcd_input_work(&pbmi_lcd, 3); ++} ++ ++DECLARE_DELAYED_WORK(bmilcd_work0, bmilcd_input_work0); ++DECLARE_DELAYED_WORK(bmilcd_work1, bmilcd_input_work1); ++DECLARE_DELAYED_WORK(bmilcd_work2, bmilcd_input_work2); ++DECLARE_DELAYED_WORK(bmilcd_work3, bmilcd_input_work3); ++ ++// work handler ++void bmilcd_input_work(void *arg, int slot) { ++ struct pbmi_lcd *pbmi_lcd = (struct pbmi_lcd *)arg; ++ struct i2c_adapter *adap = &pbmi_lcd->bdev[slot]->adap; ++ unsigned char acc_data[1]; ++ static int pitch = 0; ++ static int roll = 0; ++ static int gx = 0; ++ static int gy = 0; ++ ++ unsigned char iox_data[1]; ++ ++ unsigned char buf[4]; ++ int x = 0; ++ int y = 0; ++ int z1 = 0; ++ int z2 = 0; ++ int pressure = 0; ++ int debounce; ++ int penirq; ++ ++#if defined DEBUG ++ printk(KERN_INFO "bmi_lcd.c: bmi_lcd_input work (slot %d)\n", slot); ++#endif ++ ++ if(pbmi_lcd->bdev[slot] == 0) { ++ printk(KERN_INFO "bmi_lcd.c: bmi_lcd_input work called with no bdev active (slot %d)\n", slot); ++ return; ++ } ++ ++ if(pbmi_lcd->bdev[slot]->epraw.revision_msb >= 0x12) { ++ ++ // orientation ++ // read ROLL ++ printk(KERN_INFO "ACC Work: ROLLH\n"); ++ if(ReadByteLock_ACC(pbmi_lcd, ACC_ROLLH, acc_data, slot)) ++ return; ++ roll = (0x0000 | *acc_data) << 8; ++ printk(KERN_INFO "ACC Work: ROLLL\n"); ++ if(ReadByteLock_ACC(pbmi_lcd, ACC_ROLLL, acc_data, slot)) ++ return; ++ roll = roll | *acc_data; ++ // read PITCH ++ printk(KERN_INFO "ACC Work: PITCHH\n"); ++ if(ReadByteLock_ACC(pbmi_lcd, ACC_PITCHH, acc_data, slot)) ++ return; ++ pitch = (0x0000 | *acc_data) << 8; ++ printk(KERN_INFO "ACC Work: PITCHL\n"); ++ if(ReadByteLock_ACC(pbmi_lcd, ACC_PITCHL, acc_data, slot)) ++ return; ++ pitch = pitch | *acc_data; ++ ++ ++ ++ printk(KERN_INFO "ACC Work: GAZH\n"); ++ if(ReadByteLock_ACC(pbmi_lcd, ACC_GAZH, acc_data, slot)) ++ return; ++ pbmi_lcd->acc[slot].sample[0] = *acc_data; ++ printk(KERN_INFO "ACC Work: GAZL\n"); ++ if(ReadByteLock_ACC(pbmi_lcd, ACC_GAZL, acc_data, slot)) ++ return; ++ pbmi_lcd->acc[slot].sample[1] = *acc_data; ++ printk(KERN_INFO "ACC Work: GAYH\n"); ++ if(ReadByteLock_ACC(pbmi_lcd, ACC_GAYH, acc_data, slot)) ++ return; ++ pbmi_lcd->acc[slot].sample[2] = *acc_data; ++ gy = *acc_data << 8; ++ printk(KERN_INFO "ACC Work: GAYL\n"); ++ if(ReadByteLock_ACC(pbmi_lcd, ACC_GAYL, acc_data, slot)) ++ return; ++ pbmi_lcd->acc[slot].sample[3] = *acc_data; ++ gy = gy | *acc_data; ++ printk(KERN_INFO "ACC Work: GAXH\n"); ++ if(ReadByteLock_ACC(pbmi_lcd, ACC_GAXH, acc_data, slot)) ++ return; ++ pbmi_lcd->acc[slot].sample[4] = *acc_data; ++ gx = *acc_data << 8; ++ printk(KERN_INFO "ACC Work: GAXL\n"); ++ if(ReadByteLock_ACC(pbmi_lcd, ACC_GAXL, acc_data, slot)) ++ return; ++ pbmi_lcd->acc[slot].sample[5] = *acc_data; ++ gx = gx | *acc_data; ++ ++ //wake up any read's ++ pbmi_lcd->acc[slot].flag = 1; ++ wake_up_interruptible(&pbmi_lcd->acc[slot].wq); ++ ++ if(ReadByteLock_IOX(pbmi_lcd, IOX_OUTPUT_REG, iox_data, slot)) ++ return; ++ *iox_data = (*iox_data & 0xF8) | 0x4; ++ if(WriteByteLock_IOX(pbmi_lcd, IOX_OUTPUT_REG, *iox_data, slot)) ++ return; ++ printk(KERN_INFO "ACC Work: IOX\n"); ++ ++ // read STATUS ++ printk(KERN_INFO "ACC Work: STATUS\n"); ++ if(ReadByteLock_ACC(pbmi_lcd, ACC_STATUS, acc_data, slot)) ++ return; ++ ++ if((*acc_data & 0x1) == 0) { ++ ++ // write PAGESEL ++ *acc_data = 0x0; ++ if(WriteByteLock_ACC(pbmi_lcd, ACC_PAGESEL, *acc_data, slot)) ++ return; ++ ++ // read INTRQ ++ printk(KERN_INFO "ACC Work: INTRQ\n"); ++ if(ReadByteLock_ACC(pbmi_lcd, ACC_INTRQ, acc_data, slot)) ++ return; ++ } ++ ++ // write PAGESEL ++ *acc_data = 0x1; ++ if(WriteByteLock_ACC(pbmi_lcd, ACC_PAGESEL, *acc_data, slot)) ++ return; ++ ++ ++ ++ // report orientation ++ // printk(KERN_INFO "bmi_lcd.c: bmi_lcd_input work (slot %d) pitch=0x%x, roll=0x%x, ABS_MISC=0x%x\n", ++ // slot, pitch, roll, pitch << 16 | roll); //pjg - debug ++ ++ input_report_abs(pbmi_lcd->input_dev[slot], ABS_MISC, (pitch << 16) | roll); ++ input_sync(pbmi_lcd->input_dev[slot]); ++ } ++ ++ // read touch screen - X, Y, TOUCH, PRESSURE ++ ++ ++ penirq = bmi_slot_status_irq_state(slot); ++ /*printk(KERN_INFO "bmi_lcd.c: IRQ Status %d (slot %d) %d\n", penirq, slot,msecs_to_jiffies(10));*/ ++ ++ if (pbmi_lcd->activated[slot] && penirq) ++ { ++ ++ for(debounce = 0; debounce < DEBOUNCE; debounce++) ++ { ++ ++ memset(buf, 0, 4); ++ buf[3] = SPI_START | SPI_AY | SPI_MODE_12 | SPI_MODE_DFR | SPI_ADC; ++ spi_lcd_read_reg(pbmi_lcd, buf, 1, slot); ++ y = (((buf[0] << 5) | buf[1] >> 3)) & 0xFFF; ++ ++ memset(buf, 0, 4); ++ buf[3] = SPI_START | SPI_AX | SPI_MODE_12 | SPI_MODE_DFR | SPI_ADC; ++ spi_lcd_read_reg(pbmi_lcd, buf, 1, slot); ++ x = (((buf[0] << 5) | buf[1]) >> 3) & 0xFFF; ++ ++ memset(buf, 0, 4); ++ buf[3] = SPI_START | SPI_AZ1 | SPI_MODE_12 | SPI_MODE_DFR | SPI_ADC; ++ spi_lcd_read_reg(pbmi_lcd, buf, 1, slot); ++ z1 = (((buf[0] << 5) | buf[1]) >> 3) & 0xFFF; ++ ++ memset(buf, 0, 4); ++ buf[3] = SPI_START | SPI_AZ2 | SPI_MODE_12 | SPI_MODE_DFR | SPI_ADC; ++ spi_lcd_read_reg(pbmi_lcd, buf, 1, slot); ++ z2 = (((buf[0] << 5) | buf[1]) >> 3) & 0xFFF; ++ mdelay(1); ++ } ++ ++ if(x && y && z1 && z2) ++ pressure = (X_PLATE * x / 4096) * ((z2 / z1) - 1); ++ ++ x = 4096 - x; ++ y = 4096 - y; ++ ++ if (pressure < 70) ++ { ++ if (pbmi_lcd->scount) ++ update_pen_state(arg, slot, x, y, pressure); ++ else ++ { ++ pbmi_lcd->scount[slot]++; ++ /*update_pen_state(arg, slot, 0, 0, pressure);*/ ++ } ++ } ++ /* else ++ { ++ update_pen_state(arg, slot, 0, 0, pressure); ++ }*/ ++ ++ switch(slot) ++ { ++ case BMI_TS_M1: ++ schedule_delayed_work(&bmilcd_work0, WORK_DELAY); ++ break; ++ case BMI_TS_M2: ++ schedule_delayed_work(&bmilcd_work1, WORK_DELAY); ++ break; ++ case BMI_TS_M3: ++ schedule_delayed_work(&bmilcd_work2, WORK_DELAY); ++ break; ++ case BMI_TS_M4: ++ schedule_delayed_work(&bmilcd_work3, WORK_DELAY); ++ break; ++ } ++ /* printk(KERN_INFO "bmi_lcd.c: work scheduled on (slot %d)\n", slot); */ ++ /*buf[3] = SPI_START | SPI_PD; ++ spi_lcd_write_reg(pbmi_lcd, buf, 1, slot);*/ ++ } ++ ++ else ++ { ++ /*printk(KERN_INFO "bmi_lcd.c: Pen up on (slot %d)\n", slot);*/ ++ memset(buf, 0, 4); ++ buf[3] = SPI_START | SPI_PD; ++ spi_lcd_write_reg(pbmi_lcd, buf, 1, slot); ++ update_pen_state(arg,slot, 0, 0, 0); ++ enable_irq(pbmi_lcd->interrupt[slot]); ++ } ++ ++} ++ ++ ++// interrupt handler ++static irqreturn_t module_irq_handler(int irq, void *dummy) ++{ ++ disable_irq(irq); ++ /*printk(KERN_INFO "bmi_lcd.c: Interupt on (slot %d)\n", irq);*/ ++ switch(irq) ++ { ++ case M1_IRQ: ++ schedule_delayed_work(&bmilcd_work0, WORK_DELAY); ++ pbmi_lcd.scount[BMI_TS_M1] = 0; ++ break; ++ case M2_IRQ: ++ schedule_delayed_work(&bmilcd_work1, WORK_DELAY); ++ pbmi_lcd.scount[BMI_TS_M2] = 0; ++ break; ++ case M3_IRQ: ++ schedule_delayed_work(&bmilcd_work2, WORK_DELAY); ++ pbmi_lcd.scount[BMI_TS_M3] = 0; ++ break; ++ case M4_IRQ: ++ schedule_delayed_work(&bmilcd_work3, WORK_DELAY); ++ pbmi_lcd.scount[BMI_TS_M4] = 0; ++ break; ++ } ++ return IRQ_HANDLED; ++} ++ ++/* ++ * control device operations ++ */ ++ ++/* ++ * control device operations ++ */ ++ ++// open ++int cntl_open(struct inode *inode, struct file *filp) ++{ ++ if(pbmi_lcd.open_flag) { ++ return - EBUSY; ++ } ++ pbmi_lcd.open_flag = 1; ++ filp->private_data = &pbmi_lcd; ++ return 0; ++} ++ ++// release ++int cntl_release(struct inode *inode, struct file *filp) ++{ ++ pbmi_lcd.open_flag = 0; ++ return 0; ++} ++ ++// ioctl ++int cntl_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct i2c_adapter *adap; ++ unsigned char iox_data[1]; ++ int slot = (__user arg) & 0xF; ++ int bl = ((__user arg) & 0x70) >> 4; ++ ++ // error if no lcd active. ++ if(pbmi_lcd.active == -1) ++ return -ENODEV; ++ ++ if(cmd != BMI_LCD_GETSTAT) { ++ ++ // error if slot invalid ++ if((slot < CPLD_M1) || (slot > CPLD_M4)) ++ return -ENODEV; ++ ++ // error if no lcd in chosen slot ++ if(pbmi_lcd.bdev[slot] == 0) ++ return -ENODEV; ++ ++ // i2c adapter ++ adap = &pbmi_lcd.bdev[slot]->adap; ++ } ++ ++ // ioctl's ++ switch (cmd) { ++ case BMI_LCD_RLEDOFF: ++ bmi_set_module_gpio_data(slot, 3, 1);// Red LED=OFF ++ break; ++ case BMI_LCD_RLEDON: ++ bmi_set_module_gpio_data(slot, 3, 0);// Red LED=ON ++ break; ++ case BMI_LCD_GLEDOFF: ++ bmi_set_module_gpio_data(slot, 2, 1);// Green LED=OFF ++ break; ++ case BMI_LCD_GLEDON: ++ bmi_set_module_gpio_data(slot, 2, 0);// Green LED=ON ++ break; ++ case BMI_LCD_VSYNC_DIS: // enable VSYNC buffer tristate output ++ if(ReadByteLock_IOX(&pbmi_lcd, IOX_OUTPUT_REG, iox_data, slot)) ++ return -ENODEV; ++ *iox_data |= 0x08; ++ if(WriteByteLock_IOX(&pbmi_lcd, IOX_OUTPUT_REG, *iox_data, slot)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_VSYNC_EN: // disable VSYNC buffer tristate output ++ if(ReadByteLock_IOX(&pbmi_lcd, IOX_OUTPUT_REG, iox_data, slot)) ++ return -ENODEV; ++ *iox_data &= ~0x08; ++ if(WriteByteLock_IOX(&pbmi_lcd, IOX_OUTPUT_REG, *iox_data, slot)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_EN: // enable LCD component ++ if(ReadByteLock_IOX(&pbmi_lcd, IOX_OUTPUT_REG, iox_data, slot)) ++ return -ENODEV; ++ *iox_data &= ~0x10; ++ if(WriteByteLock_IOX(&pbmi_lcd, IOX_OUTPUT_REG, *iox_data, slot)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_DIS: // disable LCD component only ++ if(ReadByteLock_IOX(&pbmi_lcd, IOX_OUTPUT_REG, iox_data, slot)) ++ return -ENODEV; ++ *iox_data |= 0x10; ++ if(WriteByteLock_IOX(&pbmi_lcd, IOX_OUTPUT_REG, *iox_data, slot)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_SER_EN: // enable Serializer component ++ if(ReadByteLock_IOX(&pbmi_lcd, IOX_OUTPUT_REG, iox_data, slot)) ++ return -ENODEV; ++ *iox_data &= ~0x20; ++ if(WriteByteLock_IOX(&pbmi_lcd, IOX_OUTPUT_REG, *iox_data, slot)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_SER_DIS: // disable Serializer component only ++ if(ReadByteLock_IOX(&pbmi_lcd, IOX_OUTPUT_REG, iox_data, slot)) ++ return -ENODEV; ++ *iox_data |= 0x20; ++ if(WriteByteLock_IOX(&pbmi_lcd, IOX_OUTPUT_REG, *iox_data, slot)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_SETRST: // overall module reset ++ bmi_set_module_gpio_data (slot, 1, 0); // RST=0 ++ break; ++ case BMI_LCD_CLRRST: // overall module enable ++ bmi_set_module_gpio_data (slot, 1, 1); // RST=1 ++ break; ++ case BMI_LCD_SET_BL: // set backlight brightness ++ if(ReadByteLock_IOX(&pbmi_lcd, IOX_OUTPUT_REG, iox_data, slot)) ++ return -ENODEV; ++ *iox_data = (*iox_data & 0xF8) | bl; ++ if(WriteByteLock_IOX(&pbmi_lcd, IOX_OUTPUT_REG, *iox_data, slot)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_GETSTAT: ++ { ++ int *slot = ((int __user *) arg); ++ int read_data; ++ ++ *slot &= 0xF; ++ ++ // error if slot invalid ++ if((*slot < CPLD_M1) || (*slot > CPLD_M4)) ++ return -ENODEV; ++ ++ // error if no lcd in chosen slot ++ if(pbmi_lcd.bdev[*slot] == 0) ++ return -ENODEV; ++ ++ // i2c adapter ++ adap = &pbmi_lcd.bdev[*slot]->adap; ++ ++ if(ReadByteLock_IOX(&pbmi_lcd, IOX_INPUT_REG, iox_data, *slot)) ++ return -ENODEV; ++ ++ read_data = *iox_data | (bmi_read_gpio_data_reg(*slot) << 8); ++ ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ } ++ break; ++ case BMI_LCD_ACTIVATE: //pjg fix/test ++ // check for opposite side already active ++ switch(slot) { // opposite side ++ case 0: ++ if(pbmi_lcd.activated[2] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 2 already active)\n", slot); ++ bmi_slot_power_off(0); ++ return -ENODEV; ++ } ++ break; ++ case 1: ++ if(pbmi_lcd.activated[3] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 3 already active)\n", slot); ++ bmi_slot_power_off(1); ++ return -ENODEV; ++ } ++ break; ++ case 2: ++ if(pbmi_lcd.activated[0] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 0 already active)\n", slot); ++ bmi_slot_power_off(2); ++ return -ENODEV; ++ } ++ break; ++ case 3: ++ if(pbmi_lcd.activated[1] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 1 already active)\n", slot); ++ bmi_slot_power_off(3); ++ return -ENODEV; ++ } ++ break; ++ } ++ // activate ++ if((!pbmi_lcd.activated[slot]) && (pbmi_lcd.bdev[slot] != 0)) { ++ bmi_lcd_probe(pbmi_lcd.bdev[slot]); ++ } ++ break; ++ case BMI_LCD_DEACTIVATE: ++ if(pbmi_lcd.activated[slot]) { ++ disable_irq_nosync(pbmi_lcd.interrupt[slot]); ++ pbmi_lcd.activated[slot] = 0; ++ if(ReadByteLock_IOX(&pbmi_lcd, IOX_OUTPUT_REG, iox_data, slot)) ++ return -ENODEV; ++ *iox_data = (*iox_data & 0xF8); ++ if(WriteByteLock_IOX(&pbmi_lcd, IOX_OUTPUT_REG, *iox_data, slot)) ++ return -ENODEV; ++ bmi_slot_power_off(slot); ++ } ++ break; ++ case BMI_LCD_SUSPEND: ++ printk(KERN_ERR "BMI_LCD_SUSPEND NOT IMPLEMENTED\n"); //pjg ++ break; ++ case BMI_LCD_RESUME: ++ printk(KERN_ERR "BMI_LCD_RESUME NOT IMPLEMENTED\n"); //pjg ++ break; ++ default: ++ return -ENOTTY; ++ } ++ return 0; ++} ++ ++ // control file operations ++struct file_operations cntl_fops = { ++ .owner = THIS_MODULE, ++ .ioctl = cntl_ioctl, ++ .open = cntl_open, ++ .release = cntl_release, ++}; ++ ++ // BMI LCD fops ++void bmi_lcd_config(struct bmi_lcd *lcd, int disp) ++{ ++ if(pbmi_lcd.active == -1) { ++ return; ++ } ++ ++ if((lcd) && (lcd->lcd_ops.config)) { ++ lcd->lcd_ops.config(disp); ++ } ++} ++ ++void bmi_lcd_reset(struct bmi_lcd *lcd, int slot) ++{ ++ if(pbmi_lcd.active == -1) { ++ return; ++ } ++ ++ if((lcd) && (lcd->lcd_ops.reset)) { ++ lcd->lcd_ops.reset(slot); ++ } ++} ++ ++ ++static struct miscdevice cntl_dev = { ++ MISC_DYNAMIC_MINOR, ++ "bmi_lcd_control", ++ &cntl_fops ++}; ++ ++/* ++ * Module functions ++ */ ++ ++char const input_name0[MAX_STRG] = "bmi_lcd_ts0"; ++char const input_name1[MAX_STRG] = "bmi_lcd_ts1"; ++char const input_name2[MAX_STRG] = "bmi_lcd_ts2"; ++char const input_name3[MAX_STRG] = "bmi_lcd_ts3"; ++char const input_name4[MAX_STRG] = "bmi_lcd_ts4"; ++char const input_name5[MAX_STRG] = "bmi_lcd_ts5"; ++char const input_name6[MAX_STRG] = "bmi_lcd_ts6"; ++ ++static __init int bmi_lcd_init(void) ++{ ++ int ts; ++ int rc = 0; ++ ++ // No lcd is active. ++ pbmi_lcd.active = -1; ++ pbmi_lcd.activated[0] = 0; ++ pbmi_lcd.activated[1] = 0; ++ pbmi_lcd.activated[2] = 0; ++ pbmi_lcd.activated[3] = 0; ++ ++ // set up control character device - bmi_lcd_control ++ rc = misc_register(&cntl_dev); ++ if(rc) { ++ printk(KERN_ERR "bmi_lcd.c: Can't allocate bmi_lcd_control device\n"); ++ return rc; ++ } ++ ++ // Allocate and Register input device. - bmi_lcd_ts[BMI_TS_M1:BMI_TS_M1234] ++ for(ts = BMI_TS_M1; ts < BMI_TS_NUM; ts++) { ++ pbmi_lcd.input_dev[ts] = input_allocate_device(); ++ if(!pbmi_lcd.input_dev[ts]) { ++ printk(KERN_ERR "bmi_lcd_init: Can't allocate input_dev[ts]\n"); ++ return -ENOMEM; ++ } ++ ++ // set up input device ++ switch(ts) { ++ case BMI_TS_M1: ++ pbmi_lcd.input_dev[BMI_TS_M1]->name = input_name0; ++ pbmi_lcd.input_dev[BMI_TS_M1]->phys = input_name0; ++ break; ++ case BMI_TS_M2: ++ pbmi_lcd.input_dev[BMI_TS_M2]->name = input_name1; ++ pbmi_lcd.input_dev[BMI_TS_M2]->phys = input_name1; ++ break; ++ case BMI_TS_M3: ++ pbmi_lcd.input_dev[BMI_TS_M3]->name = input_name2; ++ pbmi_lcd.input_dev[BMI_TS_M3]->phys = input_name2; ++ break; ++ case BMI_TS_M4: ++ pbmi_lcd.input_dev[BMI_TS_M4]->name = input_name3; ++ pbmi_lcd.input_dev[BMI_TS_M4]->phys = input_name3; ++ break; ++ case BMI_TS_M13: ++ pbmi_lcd.input_dev[BMI_TS_M13]->name = input_name4; ++ pbmi_lcd.input_dev[BMI_TS_M13]->phys = input_name4; ++ break; ++ case BMI_TS_M24: ++ pbmi_lcd.input_dev[BMI_TS_M24]->name = input_name5; ++ pbmi_lcd.input_dev[BMI_TS_M24]->phys = input_name5; ++ break; ++ case BMI_TS_M1234: ++ pbmi_lcd.input_dev[BMI_TS_M1234]->name = input_name6; ++ pbmi_lcd.input_dev[BMI_TS_M1234]->phys = input_name6; ++ break; ++ } ++ pbmi_lcd.input_dev[ts]->id.bustype = BUS_BMI; ++ pbmi_lcd.input_dev[ts]->private = &pbmi_lcd; ++ pbmi_lcd.input_dev[ts]->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY); ++ pbmi_lcd.input_dev[ts]->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS); ++ pbmi_lcd.input_dev[ts]->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH); ++ pbmi_lcd.input_dev[ts]->absbit[BIT_WORD(ABS_X)] |= BIT_MASK(ABS_X); ++ pbmi_lcd.input_dev[ts]->absbit[BIT_WORD(ABS_Y)] |= BIT_MASK(ABS_Y); ++ pbmi_lcd.input_dev[ts]->absbit[BIT_WORD(ABS_PRESSURE)] |= BIT_MASK(ABS_PRESSURE); ++ pbmi_lcd.input_dev[ts]->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); ++ input_set_abs_params(pbmi_lcd.input_dev[ts], ABS_X, BMI_LCD_MIN_XC, BMI_LCD_MAX_XC, 0, 0); ++ input_set_abs_params(pbmi_lcd.input_dev[ts], ABS_Y, BMI_LCD_MIN_YC, BMI_LCD_MAX_YC, 0, 0); ++ input_set_abs_params(pbmi_lcd.input_dev[ts], ABS_PRESSURE, 0, 1024, 0, 0); ++ ++ // register input device ++ if(input_register_device(pbmi_lcd.input_dev[ts])) { ++ int tts; ++ printk(KERN_ERR "bmi_lcd_init() - input_register_device failed.\n"); ++ ++ for(tts = BMI_TS_M1; tts < ts; tts++) ++ input_unregister_device(pbmi_lcd.input_dev[tts]); ++ ++ misc_deregister(&cntl_dev); ++ ++ return -ENODEV; ++ } ++ } ++ ++ pbmi_lcd.lcd_cnt = 0; ++ ++ // hardware specfic set-up ++ s320x240_bmi_lcd.interface = s320x240_lcd_interface, ++ s320x240_bmi_lcd_ops.config = (void(*)) &s320x240_config; ++ s320x240_bmi_lcd_ops.reset = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd_ops.suspend = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd_ops.resume = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd_ops.disp_on = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd_ops.disp_off = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd_ops.activate = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd_ops.deactivate = NULL; //pjg - placeholder for multiple LCD hardware types ++ s320x240_bmi_lcd.lcd_ops = s320x240_bmi_lcd_ops; ++ pbmi_lcd.blcd[0] = &s320x240_bmi_lcd; ++ pbmi_lcd.blcd[1] = &s320x240_bmi_lcd; ++ pbmi_lcd.blcd[2] = &s320x240_bmi_lcd; ++ pbmi_lcd.blcd[3] = &s320x240_bmi_lcd; ++ ++ sema_init(&pbmi_lcd.sem[0], 1); ++ sema_init(&pbmi_lcd.sem[1], 1); ++ sema_init(&pbmi_lcd.sem[2], 1); ++ sema_init(&pbmi_lcd.sem[3], 1); ++ ++ sema_init(&pbmi_lcd.i2c_sem[0], 1); ++ sema_init(&pbmi_lcd.i2c_sem[1], 1); ++ sema_init(&pbmi_lcd.i2c_sem[2], 1); ++ sema_init(&pbmi_lcd.i2c_sem[3], 1); ++ ++ acc_init(); ++ ++ /*s320x240_config(0); ++ s320x240_config(1);*/ ++ ++ // register with BMI ++ rc = bmi_register_driver(&bmi_lcd_driver); ++ if(rc) { ++ printk(KERN_ERR "bmi_lcd.c: Can't register bmi_lcd_driver\n"); ++ ++ for(ts = BMI_TS_M1; ts < BMI_TS_NUM; ts++) ++ input_unregister_device(pbmi_lcd.input_dev[ts]); ++ ++ misc_deregister(&cntl_dev); ++ ++ return rc; ++ } ++ ++ printk("bmi_lcd.c: BMI_LCD Driver v%s \n", BMILCD_VERSION); ++ ++ return 0; ++} ++ ++static void __exit bmi_lcd_clean(void) ++{ ++ int ts; ++ ++ // delete timers ++ del_timer(&pbmi_lcd.timer[0]); ++ del_timer(&pbmi_lcd.timer[1]); ++ del_timer(&pbmi_lcd.timer[2]); ++ del_timer(&pbmi_lcd.timer[3]); ++ ++ // remove input devices ++ for(ts = BMI_TS_M1; ts < BMI_TS_NUM; ts++) ++ input_unregister_device(pbmi_lcd.input_dev[ts]); ++ ++ // remove control device ++ misc_deregister(&cntl_dev); ++ ++ // remove bmi driver ++ bmi_unregister_driver(&bmi_lcd_driver); ++ ++ acc_clean(); ++ ++ return; ++} ++ ++module_init(bmi_lcd_init); ++module_exit(bmi_lcd_clean); ++ ++ ++MODULE_AUTHOR("Peter Giacomini "); ++MODULE_DESCRIPTION("BMI lcd device driver"); ++MODULE_SUPPORTED_DEVICE("bmi_lcd_control"); ++MODULE_SUPPORTED_DEVICE("bmi_lcd_ts"); ++MODULE_SUPPORTED_DEVICE("bmi_lcd_acc"); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ git/drivers/bmi/pims/lcd/bmi_s320x240.c +@@ -0,0 +1,632 @@ ++#include ++#include ++#include //pjg ++#include ++#include ++#include ++#include "bug_lcd.h" ++ ++// BMI device ID table ++static struct bmi_device_id bmi_vs6624_tbl[] = ++{ ++ { //pjg .match_flags = BMI_DEVICE_ID_MATCH_VENDOR | BMI_DEVICE_ID_MATCH_PRODUCT, ++ .match_flags = BMI_ANY, ++ .vendor = BMI_VENDOR_BUG_LABS, ++ .product = BMI_PRODUCT_CAMERA_VS6624, ++ .revision = BMI_ANY, ++ }, ++ { 0, }, /* terminate list */ ++}; ++MODULE_DEVICE_TABLE(bmi, bmi_vs6624_tbl); ++ ++int bmi_vs6624_probe(struct bmi_device *bdev); ++void bmi_vs6624_remove(struct bmi_device *bdev); ++int bmi_vs6624_suspend(struct bmi_device *bdev); ++int bmi_vs6624_resume(struct bmi_device *bdev); ++ ++// BMI driver structure ++static struct bmi_driver bmi_vs6624_driver = ++{ ++ .name = "bmi_vs6624", ++ .id_table = bmi_vs6624_tbl, ++ .probe = bmi_vs6624_probe, ++ .remove = bmi_vs6624_remove, ++ }; ++ ++ ++struct bmi_vs6624 { ++ struct bmi_device *bdev; ++ struct bmi_cam bcam; ++ unsigned int shutter; // shutter button save state ++ unsigned int zoomin; // zoomin button save state ++ unsigned int zoomout; // zoom out button save state ++ unsigned int flash; // state of camera FLASH ++ int irq; ++ struct input_dev *idev; ++ struct work_struct work; ++ ++}; ++ ++ // I2C Slave Address ++#define BMI_IOX_I2C_ADDRESS 0x71 // 7-bit address ++ ++ // I2C IOX register addresses ++#define IOX_INPUT_REG 0x0 ++#define IOX_OUTPUT_REG 0x1 ++#define IOX_POLARITY_REG 0x2 ++#define IOX_CONTROL 0x3 ++ ++ ++// read byte from I2C IO expander ++ ++static int ReadByte_IOX(struct i2c_adapter *adap, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ ++ /* Read Byte with Pointer */ ++ ++ rmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[0].flags = 0; /* write */ ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; /* read */ ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ret = i2c_transfer (adap, rmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ //Rework: add conditional debug messages here ++ ret = -1; ++ } ++ return ret; ++} ++ ++ ++// write byte to I2C IO expander ++static int WriteByte_IOX(struct i2c_adapter *adap, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ /* Write Byte with Pointer */ ++ ++ ++ wmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[0].flags = 0; /* write */ ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[1].flags = 0; /* write */ ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ ++ ret = i2c_transfer (adap, wmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ //Rework: add conditional debug messages here ++ ++ printk (KERN_ERR "WriteByte_IOX() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++ ++/* ++ * Input interrupt handler and support routines ++ */ ++ ++ ++// work handler ++void bmi_vs6624_buttons_work(void *arg) ++{ ++ struct bmi_vs6624 *bmicam = (struct bmi_vs6624*)arg; ++ struct i2c_adapter *adap = &bmicam->bdev->adap; ++ ++ unsigned char iox_data; ++ unsigned int test_value; ++ int sync_flag = 0; ++ ++ ++ // read IOX data input ++ ReadByte_IOX (adap, IOX_INPUT_REG, &iox_data); ++ ++ // zoom in button ++ test_value = !((iox_data & 0x2) >> 1); ++ if (test_value != bmicam->zoomin) { ++ printk (KERN_ERR "bmi_vs6624buttons_work() - report ZOOMIN\n"); ++ bmicam->zoomin = test_value; ++ input_report_key(bmicam->idev, BN_ZOOMIN, test_value); ++ sync_flag = 1; ++ } ++ ++ ++ // zoom out button ++ test_value = !((iox_data & 0x4) >> 2); ++ if (test_value != bmicam->zoomout) { ++ printk (KERN_ERR "bmi_vs6624_buttons_work() - report ZOOMOUT\n"); ++ bmicam->zoomout = test_value; ++ input_report_key(bmicam->idev, BN_ZOOMOUT, test_value); ++ sync_flag = 1; ++ } ++ ++ // flash button ++ test_value = (iox_data & 0x8) >> 3; ++ if (test_value != bmicam->flash) { ++ printk (KERN_ERR "bmi_vs6624_buttons_work() - report FLASH\n"); ++ bmicam->flash = test_value; ++ input_report_key(bmicam->idev, BN_FLASH, test_value); ++ sync_flag = 1; ++ } ++ ++ ++ if ( sync_flag ) { ++ printk (KERN_ERR "bmi_vs6624_buttons_work() - input_sync()ing..\n"); ++ input_sync(bmicam->idev); ++ } ++ ++ enable_irq(bmicam->irq); ++ ++} ++ ++ ++// interrupt handler ++static irqreturn_t module_irq_handler(int irq, void *dummy) ++{ ++ struct bmi_vs6624 *bmicam = dummy; ++ unsigned int test_value; ++ ++ int slot; ++ ++ ++ disable_irq_nosync(irq); ++ ++ slot = bmicam->bdev->info->slot; ++ ++ ++ // shutter button on GPIO ++ ++ test_value = !(bmi_read_gpio_data_reg (slot) & 0x1); ++ ++ if (!test_value == bmicam->shutter) { ++ bmicam->shutter = test_value; ++ printk (KERN_ERR "module_irq_handler() - report SHUTTER\n"); ++ input_report_key(bmicam->idev, BN_SHUTTER, test_value); ++ input_sync(bmicam->idev); ++ } ++ ++ ++ ++ // other buttons on I2C IOX ++ schedule_work (&bmicam->work); ++ return IRQ_HANDLED; ++} ++ ++/* ++ * control functions ++ */ ++ ++ ++// configure IOX IO and states ++void configure_IOX(struct bmi_vs6624 *cam) ++{ ++ struct i2c_adapter *adap = &cam->bdev->adap; ++ ++ printk (KERN_ERR "configure_IOX() - enter\n"); ++ printk (KERN_ERR "configure_IOX() - cam = %p\n", cam); ++ printk (KERN_ERR "configure_IOX() - cam->bdev = %p\n", cam->bdev); ++ printk (KERN_ERR "configure_IOX() - cam->bdev->adap = %p\n", &cam->bdev->adap); ++ ++ ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, 0x40); // CE=0, F_CHG=1,SYNC=0, TORCH=0 ++ WriteByte_IOX (adap, IOX_CONTROL, 0x0F); // IOX[7:4]=OUT, IOX[3:0]=IN ++} ++ ++// configure GPIO IO and states ++void configure_GPIO(struct bmi_vs6624 *cam) ++{ ++ // set states before turning on outputs ++ ++ int slot = cam->bdev->info->slot; ++ ++ bmi_set_module_gpio_data (slot, 3, 1); // Red LED=OFF ++ bmi_set_module_gpio_data (slot, 2, 1); // Green LED=OFF ++ bmi_set_module_gpio_data (slot, 1, 0); // SER_RST=0 ++ ++ // configure direction ++ bmi_set_module_gpio_data (slot, 3, BMI_GPIO_OUT); ++ bmi_set_module_gpio_data (slot, 2, BMI_GPIO_OUT); ++ bmi_set_module_gpio_data (slot, 1, BMI_GPIO_OUT); ++ bmi_set_module_gpio_data (slot, 0, BMI_GPIO_IN); // SHUTTER ++} ++ ++// deconfigure IOX and GPIO ++void deconfigure_module(struct bmi_vs6624 *cam) ++{ ++ int slot = cam->bdev->info->slot; ++ struct i2c_adapter *adap = &cam->bdev->adap; ++ ++ WriteByte_IOX (adap, IOX_CONTROL, 0xFF); ++ bmi_set_module_gpio_data (slot, 3, BMI_GPIO_IN); ++ bmi_set_module_gpio_data (slot, 2, BMI_GPIO_IN); ++ bmi_set_module_gpio_data (slot, 1, BMI_GPIO_IN); ++} ++ ++ ++// configure serializer on plug-in module ++void configure_serializer(struct bmi_vs6624 *cam) ++{ ++ int slot = cam->bdev->info->slot; ++ ++ bmi_set_module_gpio_data(slot, 1, 1); // SER_RST=1 ++} ++ ++void deconfigure_serializer(struct bmi_vs6624 *cam) ++{ ++ int slot = cam->bdev->info->slot; ++ bmi_set_module_gpio_data(slot, 1, 0); // SER_RST=0 ++} ++ ++void enable_camera(struct bmi_vs6624 *cam) ++{ ++ struct i2c_adapter *adap = &cam->bdev->adap; ++ unsigned char iox_data; ++ ++ printk (KERN_ERR "enable_camera() enter\n"); ++ ++ // The first i2c read seems to mess everything up. ++ ++ ReadByte_IOX(adap, IOX_OUTPUT_REG, &iox_data); ++ printk (KERN_ERR "enable_camera() iox_data = %02X\n", iox_data); ++ ++ WriteByte_IOX(adap, IOX_OUTPUT_REG, iox_data | 0x80); ++ printk (KERN_ERR "enable_camera() exit\n"); ++} ++ ++// disable camera on plug-in module ++void disable_camera(struct bmi_vs6624 *cam) ++{ ++ struct i2c_adapter *adap = &cam->bdev->adap; ++ unsigned char iox_data; ++ ++ printk (KERN_ERR "disable_camera() enter\n"); ++ ++ ReadByte_IOX (adap, IOX_OUTPUT_REG, &iox_data); ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, iox_data & 0x70); ++ ++ printk (KERN_ERR "disable_camera() exit\n"); ++} ++ ++// generate sync ++void generate_camera_sync(struct i2c_adapter *adap) ++{ ++ unsigned char iox_data[0]; ++ ++ printk(KERN_INFO "generate_camera_sync() - enter\n"); ++ ReadByte_IOX (adap, IOX_OUTPUT_REG, iox_data); ++ ++ printk(KERN_INFO "generate_camera_sync() - read = %02X\n", iox_data[0]); ++ printk(KERN_INFO "generate_camera_sync() - write = %02X\n", *iox_data | 0x20); ++ ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, *iox_data | 0x20);// SYNC = 1 ++ ++ printk(KERN_INFO "generate_camera_sync() - write = %02X\n", *iox_data & 0xD0); ++ ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, *iox_data & 0xD0);// SYNC = 0 ++ udelay(20); // 60 MHz * 1024 = ~17 us sync time ++ ++ printk(KERN_INFO "generate_camera_sync() - exit\n"); ++} ++ ++void set_sync(struct i2c_adapter *adap) ++{ ++ unsigned char iox_data[0]; ++ ++ printk(KERN_INFO "set_sync() - enter\n"); ++ ++ ReadByte_IOX (adap, IOX_OUTPUT_REG, iox_data); ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, *iox_data | 0x20);// SYNC = 1 ++ ++ printk(KERN_INFO "set_sync() - exit\n"); ++} ++ ++void clear_sync(struct i2c_adapter *adap) ++{ ++ unsigned char iox_data[0]; ++ ++ printk(KERN_INFO "clear_sync() - enter\n"); ++ ++ ReadByte_IOX (adap, IOX_OUTPUT_REG, iox_data); ++ WriteByte_IOX (adap, IOX_OUTPUT_REG, *iox_data & 0xD0);// SYNC = 0 ++ ++ printk(KERN_INFO "clear_sync() - exit\n"); ++} ++ ++ ++// check serializer lock ++int check_camera_lock(void) ++{ ++ return bmi_sensor_lock_status(); ++} ++ ++void bmi_vs6624_set_color(struct bmi_cam *cam, int bright, int saturation, int red, int green, int blue) ++{ ++ ++ struct i2c_adapter *adap; ++ struct bmi_vs6624 *bmi_vs6624; ++ ++ bmi_vs6624 = container_of(cam, struct bmi_vs6624, bcam); ++ adap = &bmi_vs6624->bdev->adap; ++ ++ vs6624_set_color (adap, bright, saturation, red, green, blue); ++ return; ++ ++} ++ ++void bmi_vs6624_get_color(struct bmi_cam *cam, int *bright, int *saturation, int *red, int *green, int *blue) ++{ ++ struct i2c_adapter *adap; ++ struct bmi_vs6624 *bmi_vs6624; ++ ++ bmi_vs6624 = container_of(cam, struct bmi_vs6624, bcam); ++ adap = &bmi_vs6624->bdev->adap; ++ ++ vs6624_get_color (adap, bright, saturation, red, green, blue); ++ return; ++} ++ ++ ++ ++ ++void bmi_vs6624_set_ae_mode (struct bmi_cam *cam, int ae_mode) ++{ ++ printk (KERN_ERR "bmi_vs6624_set_ae_mode() - NOT IMPLEMENTED.\n"); ++} ++ ++ ++void bmi_vs6624_get_ae_mode (struct bmi_cam *cam, int *ae_mode) ++{ ++ printk (KERN_ERR "bmi_vs6624_set_ae_mode() - NOT IMPLEMENTED.\n"); ++} ++ ++ ++sensor_interface * bmi_vs6624_config (struct bmi_cam *cam, int *frame_rate, int high_quality) ++{ ++ //REWORK: Add code here ++ return 0; ++ ++} ++ ++ ++sensor_interface * bmi_vs6624_reset (struct bmi_cam *cam) ++{ ++ //REWORK: Add code here ++ //REWORK: What is a valid soft reset sequence ? ++ return 0; ++} ++ ++int bmi_vs6624_activate (struct bmi_cam *cam, struct input_dev *idev) ++{ ++ //REWORK: Add code here ++ int rc = 0; ++ int i; ++ struct i2c_adapter *adap; ++ struct bmi_vs6624 *bmi_vs6624; ++ ++ bmi_vs6624 = container_of(cam, struct bmi_vs6624, bcam); ++ ++ ++ //bmi_vs6624 struct fields ++ bmi_vs6624->shutter = 0; ++ bmi_vs6624->zoomin = 0; ++ bmi_vs6624->zoomout = 0; ++ bmi_vs6624->flash = 0; ++ ++ // install button irq_handler ++ if (request_irq(bmi_vs6624->irq, &module_irq_handler, 0, "bmi_cam_button", bmi_vs6624)) { ++ printk( KERN_ERR ++ "bmi_vs6624_activate() Can't allocate irq %d\n", ++ bmi_vs6624->irq ++ ); ++ ++ rc = -EBUSY; ++ goto exit; ++ } ++ ++ //Activate serial link ++ bmi_sensor_active(0); // rising edge clock ++ bmi_sensor_active(1); // rising edge clock ++ configure_serializer (bmi_vs6624); ++ ++ adap = &bmi_vs6624->bdev->adap; ++ set_sync (adap); ++ ++ for (i = 0; i < 10; i++) { ++ ++ msleep(10); ++ ++ if(check_camera_lock()) { ++ printk(KERN_INFO "vs6624.c: camera serializer locked, i = %d\n", i); ++ break; ++ } ++ else { ++ printk(KERN_ERR "vs6624.c: camera serializer did not lock,i = %d\n", i); ++ } ++ ++ } ++ clear_sync (adap); ++ ++ ++exit: ++ return rc; ++} ++int bmi_vs6624_deactivate (struct bmi_cam *cam) ++{ ++ //REWORK: Add code here ++ struct bmi_vs6624 *bmi_vs6624; ++ bmi_vs6624 = container_of(cam, struct bmi_vs6624, bcam); ++ ++ ++ //De-activate serial link ++ deconfigure_serializer (bmi_vs6624); ++ ++ ++ //uninstall button irq_handler ++ ++ free_irq(bmi_vs6624->irq, bmi_vs6624); ++ ++ ++ return 0; ++} ++ ++int bmi_vs6624_probe(struct bmi_device *bdev) ++{ ++ ++ //REWORK: Add code here ++ ++ int slot = bdev->info->slot; ++ ++ ++ // allocate a driver-specific structure ++ ++ struct bmi_vs6624 *bmi_vs6624 = kzalloc(sizeof(struct bmi_vs6624), GFP_KERNEL); ++ if (!bmi_vs6624) { ++ return -1; ++ } ++ ++ // attach bmi_device structure (so we can find it later). ++ ++ bmi_device_set_drvdata(bdev, bmi_vs6624); ++ ++ ++ ++ // initialize bmi_vs6624 struct ++ ++ bmi_vs6624->bdev = bdev; ++ ++ // sensor interface struct fields ++ ++ bmi_vs6624->bcam.interface.clk_mode = 0; // gated ++ bmi_vs6624->bcam.interface.ext_vsync = 1; // external vsync ++ bmi_vs6624->bcam.interface.Vsync_pol = 0; // non-inverted ++ bmi_vs6624->bcam.interface.Hsync_pol = 0; // non-inverted ++ bmi_vs6624->bcam.interface.pixclk_pol = 0; // non-inverted ++ bmi_vs6624->bcam.interface.data_pol = 0; // non-inverted ++ bmi_vs6624->bcam.interface.data_width = 1; // 8-bits ++ bmi_vs6624->bcam.interface.width = 1280-1; // 1280 - SXGA ++ bmi_vs6624->bcam.interface.height = 1024-1; // 1024 - SXGA ++ bmi_vs6624->bcam.interface.pixel_fmt = IPU_PIX_FMT_UYVY; // YUV422 ++ bmi_vs6624->bcam.interface.mclk = 12000000; // frequency/src ++ ++ //bmi_camera_sensor struct fields ++ ++ bmi_vs6624->bcam.sensor.set_color = bmi_vs6624_set_color; ++ bmi_vs6624->bcam.sensor.get_color = bmi_vs6624_get_color; ++ bmi_vs6624->bcam.sensor.set_ae_mode = bmi_vs6624_set_ae_mode; ++ bmi_vs6624->bcam.sensor.get_ae_mode = bmi_vs6624_get_ae_mode; ++ bmi_vs6624->bcam.sensor.config = bmi_vs6624_config; ++ bmi_vs6624->bcam.sensor.reset = bmi_vs6624_reset; ++ ++ //bmi_cam struct fields ++ ++ bmi_vs6624->bcam.activate = bmi_vs6624_activate ; ++ bmi_vs6624->bcam.deactivate = bmi_vs6624_deactivate; ++ ++ //bmi_vs6624 struct fields ++ bmi_vs6624->shutter = 0; ++ bmi_vs6624->zoomin = 0; ++ bmi_vs6624->zoomout = 0; ++ bmi_vs6624->flash = 0; ++ ++ //initialize struct work_struct ++ PREPARE_WORK (&bmi_vs6624->work, bmi_vs6624_buttons_work, bmi_vs6624); ++ ++ ++ //Do one-time hw initialization (e.g. patch) ++ ++ // configure IOX ++ configure_IOX (bmi_vs6624); ++ ++ // configure GPIO ++ configure_GPIO (bmi_vs6624); ++ ++ // chip enable camera ++ enable_camera (bmi_vs6624); ++ ++ vs6624_patch (&bmi_vs6624->bdev->adap); ++ ++ //register with bug_camera ++ ++ //REWORK: check return code ++ register_bug_camera (&bmi_vs6624->bcam, slot); ++ ++ return 0; ++} ++ ++void bmi_vs6624_remove(struct bmi_device *bdev) ++{ ++ //REWORK: Add code here ++ ++ ++ //get our pointer ++ struct bmi_vs6624 *bmi_vs6624 = (struct bmi_vs6624*)(bmi_device_get_drvdata (bdev)); ++ int slot = bdev->info->slot; ++ ++ ++ ++ unregister_bug_camera ( &bmi_vs6624->bcam, slot); ++ ++ //REWORK: Avoid I2c access if camera module is not present. ++ ++ disable_camera (bmi_vs6624); ++ deconfigure_module (bmi_vs6624); ++ ++ ++ //de-attach driver-specific struct from bmi_device structure ++ bmi_device_set_drvdata (bdev, 0); ++ ++ //free driver-specific structure ++ kfree (bmi_vs6624); ++ return; ++} ++ ++ ++static __init int bmi_vs6624_init(void) ++{ ++ ++// REWORK: Add code here. ++ ++// Register with BMI bus. ++ return bmi_register_driver (&bmi_vs6624_driver); ++ ++} ++ ++static void __exit bmi_vs6624_cleanup(void) ++{ ++// REWORK: Add code here. ++ bmi_unregister_driver (&bmi_vs6624_driver); ++ return; ++} ++ ++ ++module_init(bmi_vs6624_init); ++module_exit(bmi_vs6624_cleanup); ++ ++ +--- /dev/null ++++ git/drivers/bmi/pims/lcd/lcd_ctl.c +@@ -0,0 +1,421 @@ ++/* ++ * Copyright 2008 EnCADIS Designs, Inc. All Rights Reserved. ++ * Copyright 2008 Bug-Labs, Inc. All Rights Reserved. ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*----------------------------------------------------------------------------- ++ * ++ * Part of BMI Motion Detector Accelerometer (MDACC) Kernel Module ++ * ++ *----------------------------------------------------------------------------- ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "lcd_ctl.h" ++ ++static int lcd_ctl_open (struct inode *, struct file *); ++static int lcd_ctl_release (struct inode *, struct file *); ++static int lcd_ctl_ioctl (struct inode *, struct file *, unsigned int, unsigned long); ++static int ReadByte_IOX(struct i2c_adapter *, unsigned char, unsigned char *) ++ ++ ++struct file_operations lcd_ctl_fops = { ++ .owner = THIS_MODULE, ++ .ioctl = lcd_ctl_ioctl, ++ .open = lcd_ctl_open, ++ .release = lcd_ctl_release, ++}; ++ ++ ++ // read byte from I2C IO expander ++static int ReadByte_IOX(struct i2c_adapter *adap, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ ++ /* Read Byte with Pointer */ ++ ++ rmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[0].flags = 0; /* write */ ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; /* read */ ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ret = i2c_transfer (adap, rmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "ReadByte_IOX() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++ // write byte to I2C IO expander ++static int WriteByte_IOX(struct i2c_adapter *adap, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ /* Write Byte with Pointer */ ++ ++ wmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[0].flags = 0; /* write */ ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[1].flags = 0; /* write */ ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ ret = i2c_transfer (adap, wmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "WriteByte_IOX() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++ ++static int lcd_ctl_major; ++ ++int lcd_ctl_init (void) ++{ ++ dev_t dev_id; ++ int retval; ++ ++ // alloc char driver with 4 minor numbers ++ ++ retval = alloc_chrdev_region(&dev_id, 0, 4, "BMI LCD Control Driver"); ++ ++ if (retval) { ++ return -1; ++ } ++ lcd_ctl_major = MAJOR(dev_id); ++ return 0; ++} ++ ++void lcd_ctl_clean (void) ++{ ++ dev_t dev_id; ++ ++ dev_id = MKDEV(lcd_ctl_major, 0); ++ unregister_chrdev_region(dev_id, 4); ++ return; ++} ++ ++int lcd_ctl_probe (struct lcd_ctl *lcd_ctl, int slot) ++{ ++ struct cdev *cdev; ++ dev_t dev_id; ++ int ret; ++ struct class *bmi_class; ++ ++ cdev = &lcd_ctl->cdev; ++ cdev_init (cdev, &lcd_ctl_fops); ++ ++ dev_id = MKDEV (lcd_ctl_major, slot); ++ ret = cdev_add (cdev, dev_id, 1); ++ ++ //Create class device ++ bmi_class = bmi_get_bmi_class (); ++ ++ lcd_ctl->class_dev = device_create (bmi_class, NULL, MKDEV(lcd_ctl_major, slot), lcd_ctl, "bmi_lcd_ctl_m%i", slot+1); ++ ++ if (IS_ERR(lcd_ctl->class_dev)) { ++ printk(KERN_ERR "Unable to create " ++ "class_device for bmi_lcd_ctl_m%i; errno = %ld\n", ++ slot+1, PTR_ERR(lcd_ctl->class_dev)); ++ lcd_ctl->class_dev = NULL; ++ } ++ lcd_ctl->slot = slot; ++ ++ return ret; ++} ++ ++void lcd_ctl_remove (struct lcd_ctl *lcd_ctl, int slot) ++{ ++ struct class *bmi_class; ++ ++ bmi_class = bmi_get_bmi_class (); ++ device_destroy (bmi_class, MKDEV(lcd_ctl_major, slot)); ++ ++ lcd_ctl->class_dev = 0; ++ ++ cdev_del (&lcd_ctl->cdev); ++ return; ++} ++ ++ ++static int lcd_ctl_open (struct inode *inode, struct file *file) ++{ ++ struct lcd_ctl *lcd_ctl; ++ ++ lcd_ctl = container_of(inode->i_cdev, struct lcd_ctl, cdev); ++ ++ ++ // Save ctl pointer for later. ++ ++ file->private_data = lcd_ctl; ++ return 0; ++} ++ ++static int lcd_ctl_release (struct inode *inode, struct file *file) ++{ ++ struct lcd_ctl *lcd_ctl; ++ ++ lcd_ctl = container_of(inode->i_cdev, struct lcd_ctl, cdev); ++ return 0; ++} ++ ++ ++/*// ioctl ++int cntl_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct i2c_adapter *adap; ++ unsigned char iox_data[1]; ++ int slot = (__user arg) & 0xF; ++ int bl = ((__user arg) & 0x70) >> 4; ++ ++ // error if no lcd active. ++ if(pbmi_lcd.active == -1) ++ return -ENODEV; ++ ++ if(cmd != BMI_LCD_GETSTAT) { ++ ++ // error if slot invalid ++ if((slot < CPLD_M1) || (slot > CPLD_M4)) ++ return -ENODEV; ++ ++ // error if no lcd in chosen slot ++ if(pbmi_lcd.bdev[slot] == 0) ++ return -ENODEV; ++ ++ // i2c adapter ++ adap = &pbmi_lcd.bdev[slot]->adap; ++ } ++ ++ // ioctl's ++ switch (cmd) { ++ case BMI_LCD_RLEDOFF: ++ bmi_set_module_gpio_data(slot, 3, 1);// Red LED=OFF ++ break; ++ case BMI_LCD_RLEDON: ++ bmi_set_module_gpio_data(slot, 3, 0);// Red LED=ON ++ break; ++ case BMI_LCD_GLEDOFF: ++ bmi_set_module_gpio_data(slot, 2, 1);// Green LED=OFF ++ break; ++ case BMI_LCD_GLEDON: ++ bmi_set_module_gpio_data(slot, 2, 0);// Green LED=ON ++ break; ++ case BMI_LCD_VSYNC_DIS: // enable VSYNC buffer tristate output ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data |= 0x08; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_VSYNC_EN: // disable VSYNC buffer tristate output ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data &= ~0x08; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_EN: // enable LCD component ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data &= ~0x10; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_DIS: // disable LCD component only ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data |= 0x10; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_SER_EN: // enable Serializer component ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data &= ~0x20; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_SER_DIS: // disable Serializer component only ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data |= 0x20; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_SETRST: // overall module reset ++ bmi_set_module_gpio_data (slot, 1, 0); // RST=0 ++ break; ++ case BMI_LCD_CLRRST: // overall module enable ++ bmi_set_module_gpio_data (slot, 1, 1); // RST=1 ++ break; ++ case BMI_LCD_SET_BL: // set backlight brightness ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data = (*iox_data & 0xFC) | bl; ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ break; ++ case BMI_LCD_GETSTAT: ++ { ++ int *slot = ((int __user *) arg); ++ int read_data; ++ ++ *slot &= 0xF; ++ ++ // error if slot invalid ++ if((*slot < CPLD_M1) || (*slot > CPLD_M4)) ++ return -ENODEV; ++ ++ // error if no lcd in chosen slot ++ if(pbmi_lcd.bdev[*slot] == 0) ++ return -ENODEV; ++ ++ // i2c adapter ++ adap = &pbmi_lcd.bdev[*slot]->adap; ++ ++ if(ReadByte_IOX(adap, IOX_INPUT_REG, iox_data)) ++ return -ENODEV; ++ ++ read_data = *iox_data | (bmi_read_gpio_data_reg(*slot) << 8); ++ ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ } ++ break; ++ case BMI_LCD_ACTIVATE: //pjg fix/test ++ // check for opposite side already active ++ switch(slot) { // opposite side ++ case 0: ++ if(pbmi_lcd.activated[2] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 2 already active)\n", slot); ++ bmi_slot_power_off(0); ++ return -ENODEV; ++ } ++ break; ++ case 1: ++ if(pbmi_lcd.activated[3] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 3 already active)\n", slot); ++ bmi_slot_power_off(1); ++ return -ENODEV; ++ } ++ break; ++ case 2: ++ if(pbmi_lcd.activated[0] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 0 already active)\n", slot); ++ bmi_slot_power_off(2); ++ return -ENODEV; ++ } ++ break; ++ case 3: ++ if(pbmi_lcd.activated[1] == 1) { ++ printk(KERN_INFO "bmi_lcd.c: probe slot %d not allowed (slot 1 already active)\n", slot); ++ bmi_slot_power_off(3); ++ return -ENODEV; ++ } ++ break; ++ } ++ // activate ++ if((!pbmi_lcd.activated[slot]) && (pbmi_lcd.bdev[slot] != 0)) { ++ bmi_lcd_probe(pbmi_lcd.bdev[slot]); ++ } ++ break; ++ case BMI_LCD_DEACTIVATE: ++ if(pbmi_lcd.activated[slot]) { ++ disable_irq_nosync(pbmi_lcd.interrupt[slot]); ++ pbmi_lcd.activated[slot] = 0; ++ if(ReadByte_IOX(adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ *iox_data = (*iox_data & 0xF8); ++ if(WriteByte_IOX(adap, IOX_OUTPUT_REG, *iox_data)) ++ return -ENODEV; ++ bmi_slot_power_off(slot); ++ } ++ break; ++ case BMI_LCD_SUSPEND: ++ printk(KERN_ERR "BMI_LCD_SUSPEND NOT IMPLEMENTED\n"); //pjg ++ break; ++ case BMI_LCD_RESUME: ++ printk(KERN_ERR "BMI_LCD_RESUME NOT IMPLEMENTED\n"); //pjg ++ break; ++ default: ++ return -ENOTTY; ++ } ++ return 0; ++} ++*/ ++ ++static int lcd_ctl_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ struct lcd_ctl *lcd_ctl; ++ int slot; ++ ++ lcd_ctl = container_of(inode->i_cdev, struct lcd_ctl, cdev); ++ slot = lcd_ctl->slot; ++ if (slot < 0) { ++ return -ENODEV; ++ } ++ ++ ++ switch (cmd) { ++ ++ case BMI_LCD_RLEDOFF: ++ bmi_slot_gpio_write_bit (slot, 3, 1); //Red LED Off ++ break; ++ ++ case BMI_LCD_RLEDON: ++ bmi_slot_gpio_write_bit (slot, 3, 0); //Red LED On ++ break; ++ ++ case BMI_LCD_GLEDOFF: ++ bmi_slot_gpio_write_bit (slot, 2, 1); //Green LED Off ++ break; ++ ++ case BMI_LCD_GLEDON: ++ bmi_slot_gpio_write_bit (slot, 2, 0); //Green LED On ++ break; ++ ++ default: ++ printk (KERN_ERR "lcd_ctl_ioctl() - error exit\n"); ++ return -ENOTTY; ++ } ++ ++ return 0; ++} ++ +--- /dev/null ++++ git/drivers/bmi/pims/lcd/lcd_ctl.h +@@ -0,0 +1,87 @@ ++/* ++ * Copyright 2008 EnCADIS Designs, Inc. All Rights Reserved. ++ * Copyright 2008 Bug-Labs, Inc. All Rights Reserved. ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*----------------------------------------------------------------------------- ++ * ++ * Part of BMI LCD Kernel Module ++ * ++ *----------------------------------------------------------------------------- ++ */ ++ ++#ifndef LCD_CTL_H ++#define LCD_CTL_H ++ ++#include ++ ++#include ++#include ++ ++#include ++ ++ // IOCTL commands for BMI LCD driver ++#define BMI_LCD_RLEDOFF _IOW(BMI_LCD_IOCTL, 0x1, __u32) // turn off Red LED ++#define BMI_LCD_RLEDON _IOW(BMI_LCD_IOCTL, 0x2, __u32) // turn on Red LED ++#define BMI_LCD_GLEDOFF _IOW(BMI_LCD_IOCTL, 0x3, __u32) // turn off Green LED ++#define BMI_LCD_GLEDON _IOW(BMI_LCD_IOCTL, 0x4, __u32) // turn on Green LED ++#define BMI_LCD_VSYNC_DIS _IOW(BMI_LCD_IOCTL, 0x5, __u32) // Enable VSYNC output buffer ++#define BMI_LCD_VSYNC_EN _IOW(BMI_LCD_IOCTL, 0x6, __u32) // Disable VSYNC output buffer ++#define BMI_LCD_EN _IOW(BMI_LCD_IOCTL, 0x7, __u32) // Enable LCD component ++#define BMI_LCD_DIS _IOW(BMI_LCD_IOCTL, 0x8, __u32) // Disable LCD component ++#define BMI_LCD_SER_EN _IOW(BMI_LCD_IOCTL, 0x9, __u32) // Enable Seriallizer component ++#define BMI_LCD_SER_DIS _IOW(BMI_LCD_IOCTL, 0xa, __u32) // Disable Seriallizer component ++#define BMI_LCD_SETRST _IOW(BMI_LCD_IOCTL, 0xb, __u32) // Disable entire module ++#define BMI_LCD_CLRRST _IOW(BMI_LCD_IOCTL, 0xc, __u32) // Enable entire module ++#define BMI_LCD_SET_BL _IOW(BMI_LCD_IOCTL, 0xd, __u32) // Set IOX backlight bits [2:0] ++#define BMI_LCD_GETSTAT _IOR(BMI_LCD_IOCTL, 0xe, __u32) // Get IOX state ++#define BMI_LCD_ACTIVATE _IOW(BMI_LCD_IOCTL, 0xf, __u32) // Activate SER, TS, ACCEL ++#define BMI_LCD_DEACTIVATE _IOW(BMI_LCD_IOCTL, 0x10, __u32) // Deactivate SER, TS, ACCEL ++#define BMI_LCD_SUSPEND _IOW(BMI_LCD_IOCTL, 0x11, __u32) // Power down module ++#define BMI_LCD_RESUME _IOW(BMI_LCD_IOCTL, 0x12, __u32) // Power up module ++ ++/* ++ * I2C set up ++ */ ++ ++ // I2C Slave Address ++#define BMI_IOX_I2C_ADDRESS 0x71 // 7-bit address ++#define BMI_ACC_I2C_ADDRESS 0x17 // 7-bit address ++ ++ // I2C IOX register addresses ++#define IOX_INPUT_REG 0x0 // IOX input data register ++#define IOX_OUTPUT_REG 0x1 // IOX output data register ++#define IOX_POLARITY_REG 0x2 // IOX polarity data register ++#define IOX_CONTROL 0x3 // IOX direction control register ++#define IOX_B1 (0) // bit 0 - backlight control ++#define IOX_A1_A2 (1) // bit 1 - backlight control ++#define IOX_ACC_RST_N (2) // bit 2 - acceleromter reset ++#define IOX_VSYNC_EN_N (3) // bit 3 - VSYNC output buffer enable ++#define IOX_LCD_RST_N (4) // bit 4 - LCD reset ++#define IOX_SERDES_PD_N (5) // bit 5 - SERDES power down ++#define IOX_X_INT (6) // bit 6 - accelerometer interrupt ++#define IOX_Y_INT (7) // bit 7 - accelerometer interrupt ++ ++struct lcd_ctl ++{ ++ int slot; ++ struct cdev cdev; ++ struct device *class_dev; ++}; ++ ++extern int lcd_ctl_init (void); ++extern void lcd_ctl_clean(void); ++extern int lcd_ctl_probe (struct lcd_ctl *lcd_ctl, int slot); ++extern void lcd_ctl_remove(struct lcd_ctl *lcd_ctl, int slot); ++ ++ ++#endif ++ ++ +--- /dev/null ++++ git/drivers/bmi/pims/mdacc/Kconfig +@@ -0,0 +1,6 @@ ++config BMI_MDACC ++ tristate "BMI Motion Detector/Accelerometer" ++ depends on BMI_PIMS ++ default n ++ ---help--- ++ This is the BMI Motion Detector/Acceleromter driver. +--- /dev/null ++++ git/drivers/bmi/pims/mdacc/Makefile +@@ -0,0 +1,9 @@ ++# ++# BMI PIM: Motion Detector Accelerometer ++# ++ ++bmi_mdacc-objs := mdacc.o avr.o md.o acc.o ctl.o mon.o cque.o ++obj-$(CONFIG_BMI_MDACC) += bmi_mdacc.o ++ ++ ++ +--- /dev/null ++++ git/drivers/bmi/pims/mdacc/acc.c +@@ -0,0 +1,381 @@ ++/* ++ * Copyright 2008 EnCADIS Designs, Inc. All Rights Reserved. ++ * Copyright 2008 Bug-Labs, Inc. All Rights Reserved. ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*----------------------------------------------------------------------------- ++ * ++ * Part of BMI Motion Detector Accelerometer (MDACC) Kernel Module ++ * ++ *----------------------------------------------------------------------------- ++ */ ++ ++#include "acc.h" ++#include "mdacc.h" ++#include "mon.h" ++#include ++#include ++#include ++ ++static int acc_open (struct inode *, struct file *); ++static int acc_release (struct inode *, struct file *); ++static int acc_ioctl (struct inode *, struct file *, unsigned int, unsigned long); ++static ssize_t acc_read (struct file *, char __user *, size_t, loff_t *); ++static unsigned int acc_poll (struct file *, struct poll_table_struct *); ++ ++struct file_operations acc_fops = { ++ .owner = THIS_MODULE, ++ .ioctl = acc_ioctl, ++ .open = acc_open, ++ .release = acc_release, ++ .read = acc_read, ++ .poll = acc_poll, ++}; ++ ++static int acc_major; ++ ++int acc_init (void) ++{ ++ dev_t dev_id; ++ int retval; ++ ++ // alloc char driver with 4 minor numbers ++ ++ retval = alloc_chrdev_region(&dev_id, 0, 4, "BMI MDACC Accelerometer Driver"); ++ ++ if (retval) { ++ return -1; ++ } ++ acc_major = MAJOR(dev_id); ++ return 0; ++} ++ ++void acc_clean(void) ++{ ++ dev_t dev_id; ++ ++ dev_id = MKDEV(acc_major, 0); ++ unregister_chrdev_region(dev_id, 4); ++ return; ++} ++ ++int acc_probe (struct acc *acc, int slot, struct mon *mon) ++{ ++ struct cdev *cdev; ++ dev_t dev_id; ++ int ret; ++ struct class *bmi_class; ++ ++ // initialize cdev ++ ++ cdev = &acc->cdev; ++ cdev_init (cdev, &acc_fops); ++ ++ dev_id = MKDEV (acc_major, slot); ++ ret = cdev_add (cdev, dev_id, 1); ++ ++ //Create class device ++ ++ bmi_class = bmi_get_class (); ++ ++ acc->class_dev = device_create (bmi_class, NULL, MKDEV(acc_major, slot), acc, "bmi_mdacc_acc_m%i", slot+1); ++ ++ if (IS_ERR(acc->class_dev)) { ++ printk(KERN_ERR "Unable to create " ++ "class_device for bmi_mdacc_acc_m%i; errno = %ld\n", ++ slot+1, PTR_ERR(acc->class_dev)); ++ acc->class_dev = NULL; ++ } ++ ++ acc->open_flag = 0; ++ acc->mon = mon; ++ ++ ++ // initialize mdacc_accel_config ++ ++ acc->cfg.read_queue_size = 1; ++ acc->cfg.read_queue_threshold = 1; ++ acc->cfg.delay_mode = 0; ++ acc->cfg.delay = 4000; ++ acc->cfg.delay_resolution = 1; ++ acc->cfg.sensitivity = 0; ++ acc->cfg.run = 0; ++ ++ ++ // initialize cque ++ ++ acc->cque = cque_create (acc->cfg.read_queue_size, acc->cfg.read_queue_threshold); ++ ++ // initialize read_wait_queue ++ ++ init_waitqueue_head (&acc->read_wait_queue); ++ return ret; ++} ++ ++void acc_remove (struct acc *acc, int slot) ++{ ++ struct class *bmi_class; ++ ++ cque_destroy (acc->cque); ++ ++ bmi_class = bmi_get_class (); ++ device_destroy (bmi_class, MKDEV(acc_major, slot)); ++ ++ acc->class_dev = 0; ++ ++ cdev_del (&acc->cdev); ++ ++ ++ return; ++} ++ ++ ++static int acc_open (struct inode *inode, struct file *file) ++{ ++ struct acc *acc; ++ ++ acc = container_of(inode->i_cdev, struct acc, cdev); ++ ++ //Enforce single open behavior ++ if (acc->open_flag) { ++ return -EBUSY; ++ } ++ acc->open_flag = 1; ++ ++ // Save acc_drv pointer for later. ++ file->private_data = acc; ++ return 0; ++} ++ ++static int acc_release (struct inode *inode, struct file *file) ++{ ++ struct acc *acc; ++ ++ acc = container_of(inode->i_cdev, struct acc, cdev); ++ acc->open_flag = 0; ++ ++ //Enforce stop-on-close behavior. ++ if (acc->cfg.run) { ++ acc->cfg.run = 0; ++ mon_stop_accel (acc->mon); ++ } ++ return 0; ++ ++} ++ ++static int check_config (struct mdacc_accel_config *config) ++{ ++ int err = 0; ++ ++ if (!config) { ++ err = 1; ++ goto exit; ++ } ++ ++ if (config->read_queue_size < 1) { ++ err = 1; ++ } ++ if (config->read_queue_threshold > config->read_queue_size) { ++ err = 1; ++ } ++ if (config->delay_mode) { ++ switch (config->delay_resolution) ++ { ++ case 0: ++ err = 1; ++ break; ++ case 1: // 1 => 1 usec ++ if (config->delay < 5000) { ++ err = 1; ++ } ++ break; ++ case 2: ++ if (config->delay < 625) { // 2 => 8 usec ++ err = 1; ++ } ++ break; ++ case 3: ++ if (config->delay < 79) { // 3 => 64 usec ++ err = 1; ++ } ++ break; ++ case 4: ++ if (config->delay < 20) { // 4 => 256 usec ++ err = 1; ++ } ++ break; ++ case 5: ++ if (config->delay < 5) { // 5 => 1024 usec ++ err = 1; ++ } ++ break; ++ default: ++ err = 1; ++ break; ++ } ++ } ++ ++ if (config->sensitivity > 3) { ++ err = 1; ++ } ++ ++exit: ++ return err; ++} ++ ++static int acc_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ int err = 0; ++ struct acc *acc; ++ acc = container_of(inode->i_cdev, struct acc, cdev); ++ ++ switch (cmd) { ++ ++ case BMI_MDACC_ACCELEROMETER_SET_CONFIG: ++ { ++ struct mdacc_accel_config new_cfg; ++ ++ err = copy_from_user ( (void*)&new_cfg, (void*)arg, sizeof (struct mdacc_accel_config) ); ++ if (err) { ++ return -EFAULT; ++ } ++ ++ err = check_config (&new_cfg); ++ if (err) { ++ return -EINVAL; ++ } ++ ++ if (acc->cfg.run) { ++ mon_stop_accel (acc->mon); ++ } ++ ++ // take the mon semaphore ++ down_interruptible (&acc->mon->sem); ++ ++ memcpy ( &acc->cfg, &new_cfg, sizeof (struct mdacc_accel_config) ); ++ cque_destroy (acc->cque); ++ acc->cque = cque_create (acc->cfg.read_queue_size, acc->cfg.read_queue_threshold); ++ ++ // release the mon semaphore ++ up (&acc->mon->sem); ++ ++ mon_set_config_accel( acc->mon, &acc->cfg); ++ ++ } ++ break; ++ ++ case BMI_MDACC_ACCELEROMETER_GET_CONFIG: ++ ++ mon_get_config_accel( acc->mon, &acc->cfg); ++ ++ ++ err = copy_to_user ( (void*)arg, &acc->cfg, sizeof (struct mdacc_accel_config) ); ++ if (err) { ++ return -EFAULT; ++ } ++ break; ++ ++ case BMI_MDACC_ACCELEROMETER_RUN: ++ ++ acc->cfg.run = 1; ++ err = mon_start_accel (acc->mon); ++ if (err){ ++ return -ENODEV; ++ } ++ break; ++ ++ ++ case BMI_MDACC_ACCELEROMETER_STOP: ++ ++ acc->cfg.run = 0; ++ err = mon_stop_accel (acc->mon); ++ if (err){ ++ return -ENODEV; ++ } ++ break; ++ ++ default: ++ printk (KERN_ERR "acc_ioctl() - error exit\n"); ++ return -ENOTTY; ++ } ++ ++ return 0; ++} ++ ++static ssize_t acc_read (struct file *file, char __user *buf, size_t count, loff_t *ppos) ++{ ++// if fd is non-blocking and acc is not enabled, return EAGAIN ++// if fd is non-blocking and acc is enabled, and cque is not ready, return EAGAIN ++// if fd is non-blocking and acc is enabled, and cque is ready, read cque, copy to user, ++ ++// if fd is blocking and acc is not enabled, , return EAGAIN ++// ++ ++// if fs is blocking and acc is enabled, and cque is not ready, sleep until ready. ++// when ready, read cque, copy to user, ++ ++ ++ ++ struct acc *acc = file->private_data; ++ unsigned char temp[6]; ++ int bytes_read; ++ ++ if (count < 6) { ++ return -EINVAL; ++ } ++ ++ if (!acc->cfg.run) { ++ return -EAGAIN; ++ } ++ ++ while (!cque_is_ready_for_read(acc->cque)) { ++ if (file->f_flags & O_NONBLOCK) ++ return -EAGAIN; ++ if (wait_event_interruptible (acc->read_wait_queue, (cque_is_ready_for_read(acc->cque)))) ++ return -ERESTARTSYS; ++ } ++ ++ //loop through 1 sample at a time. ++ ++ bytes_read = 0; ++ ++ while (count >= 6) { ++ ++ if (cque_read (acc->cque, &temp)) ++ break; ++ if (copy_to_user (buf, &temp, 6)) ++ break; ++ bytes_read += 6; ++ buf += 6; ++ count -= 6; ++ } ++ return bytes_read; ++} ++ ++ ++static unsigned int acc_poll (struct file *file, struct poll_table_struct *table) ++{ ++ unsigned int mask = 0; ++ struct acc *acc = file->private_data; ++ ++ poll_wait(file, &acc->read_wait_queue, table); ++ ++ if (cque_is_ready_for_read( acc->cque) ) { ++ mask |= POLLIN | POLLRDNORM; /* readable */ ++ } ++ if (mdacc_check_bdev_acc (acc) ) { ++ mask |= POLLHUP; /* hang-up */ ++ } ++ if (!acc->cfg.run) { ++ mask |= POLLHUP; /* hang-up */ ++ } ++ return mask; ++} ++ +--- /dev/null ++++ git/drivers/bmi/pims/mdacc/acc.h +@@ -0,0 +1,54 @@ ++/* ++ * Copyright 2008 EnCADIS Designs, Inc. All Rights Reserved. ++ * Copyright 2008 Bug-Labs, Inc. All Rights Reserved. ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*----------------------------------------------------------------------------- ++ * ++ * Part of BMI Motion Detector Accelerometer (MDACC) Kernel Module ++ * ++ *----------------------------------------------------------------------------- ++ */ ++ ++#ifndef MDACC_ACC_H ++#define MDACC_ACC_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "cque.h" ++ ++struct mon; ++ ++struct acc ++{ ++ struct cdev cdev; ++ struct device *class_dev; ++ int open_flag; ++ struct mon *mon; ++ struct mdacc_accel_config cfg; ++ struct cque *cque; ++ wait_queue_head_t read_wait_queue; ++}; ++ ++ ++extern int acc_init (void); ++extern void acc_clean(void); ++extern int acc_probe (struct acc *acc, int slot, struct mon *mon); ++extern void acc_remove(struct acc *acc, int slot); ++ ++ ++ ++ ++#endif +--- /dev/null ++++ git/drivers/bmi/pims/mdacc/avr.c +@@ -0,0 +1,511 @@ ++/* ++ * Copyright 2008 EnCADIS Designs, Inc. All Rights Reserved. ++ * Copyright 2008 Bug-Labs, Inc. All Rights Reserved. ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*----------------------------------------------------------------------------- ++ * ++ * Part of BMI Motion Detector Accelerometer (MDACC) Kernel Module ++ * ++ *----------------------------------------------------------------------------- ++ */ ++ ++#include ++#include ++ ++ ++struct avr_regs ++{ ++ unsigned char timer_res; // SPI Register 0 ++ unsigned char timer_msb; // SPI Register 1 ++ unsigned char timer_lsb; // SPI Register 2 ++ unsigned char mode; // SPI Register 3 ++ ++ unsigned char status; // SPI Register 4 ++ ++ unsigned char adc0h; // SPI Register 5 ++ unsigned char adc0l; // SPI Register 6 ++ unsigned char adc1h; // SPI Register 7 ++ unsigned char adc1l; // SPI Register 8 ++ unsigned char adc2h; // SPI Register 9 ++ unsigned char adc2l; // SPI Register 10 ++}; ++ ++ ++ ++/* ++ ++Cmd Bit Definitions ++ ++Cmd bit 7 - R0/W1 ++Cmd bit 6 - Cnt 2 ++Cmd bit 5 - Cnt 1 ++Cmd bit 4 - Cnt 0 ++Cmd bit 3 - Address 3 ++Cmd bit 2 - Address 2 ++Cmd bit 1 - Address 1 ++Cmd bit 0 - Address 0 ++*/ ++ ++ ++ ++#define AVR_CMD_READ_ADC (0x65) ++#define AVR_CMD_READ_STATUS (0x14) ++#define AVR_CMD_READ_STATUS_AND_ADC (0x74) ++#define AVR_CMD_READ_MODE (0x13) ++#define AVR_CMD_READ_TIMER (0x30) ++#define AVR_CMD_READ_TIMER_AND_MODE (0x40) ++#define AVR_CMD_WRITE_MODE (0x93) ++#define AVR_CMD_WRITE_TIMER (0xB0) ++#define AVR_CMD_WRITE_TIMER_AND_MODE (0xC0) ++ ++int avr_read_adc (struct spi_device *spi, struct avr_regs *regs); ++int avr_read_status (struct spi_device *spi, struct avr_regs *regs); ++int avr_read_status_and_adc (struct spi_device *spi, struct avr_regs *regs); ++int avr_read_mode (struct spi_device *spi, struct avr_regs *regs); ++int avr_read_timer (struct spi_device *spi, struct avr_regs *regs); ++int avr_read_timer_and_mode (struct spi_device *spi, struct avr_regs *regs); ++int avr_write_mode (struct spi_device *spi, struct avr_regs *regs); ++int avr_write_timer (struct spi_device *spi, struct avr_regs *regs); ++int avr_write_timer_and_mode (struct spi_device *spi, struct avr_regs *regs); ++ ++ ++int avr_read_adc (struct spi_device *spi, struct avr_regs *regs) ++{ ++ int err; ++ unsigned char cmd; ++ unsigned char sync; ++ unsigned char dont_care; ++ ++ struct spi_transfer x[7]; ++ struct spi_message message; ++ ++ cmd = AVR_CMD_READ_ADC; ++ sync = 0; ++ ++ dont_care = 0; ++ ++ spi_message_init(&message); ++ memset(x, 0, sizeof x); ++ ++ x[0].len = 1; ++ x[0].tx_buf = &cmd; ++ x[0].rx_buf = &sync; ++ x[0].delay_usecs = 400; ++ x[0].bits_per_word = 8; ++ spi_message_add_tail(&x[0], &message); ++ ++ x[1].len = 1; ++ x[1].tx_buf = &dont_care; ++ x[1].rx_buf = ®s->adc0h; ++ x[1].delay_usecs = 400; ++ x[1].bits_per_word = 8; ++ spi_message_add_tail(&x[1], &message); ++ ++ x[2].len = 1; ++ x[2].tx_buf = &dont_care; ++ x[2].rx_buf = ®s->adc0l; ++ x[2].delay_usecs = 400; ++ x[2].bits_per_word = 8; ++ spi_message_add_tail(&x[2], &message); ++ ++ x[3].len = 1; ++ x[3].tx_buf = &dont_care; ++ x[3].rx_buf = ®s->adc1h; ++ x[3].delay_usecs = 400; ++ x[3].bits_per_word = 8; ++ spi_message_add_tail(&x[3], &message); ++ ++ x[4].len = 1; ++ x[4].tx_buf = &dont_care; ++ x[4].rx_buf = ®s->adc1l; ++ x[4].delay_usecs = 400; ++ x[4].bits_per_word = 8; ++ spi_message_add_tail(&x[4], &message); ++ ++ x[5].len = 1; ++ x[5].tx_buf = &dont_care; ++ x[5].rx_buf = ®s->adc2h; ++ x[5].delay_usecs = 400; ++ x[5].bits_per_word = 8; ++ spi_message_add_tail(&x[5], &message); ++ ++ x[6].len = 1; ++ x[6].tx_buf = &dont_care; ++ x[6].rx_buf = ®s->adc2l; ++ x[6].delay_usecs = 400; ++ x[6].bits_per_word = 8; ++ spi_message_add_tail(&x[6], &message); ++ ++ err = spi_sync(spi, &message); ++ ++ return err; ++} ++ ++ ++int avr_read_status (struct spi_device *spi, struct avr_regs *regs) ++{ ++ int err; ++ unsigned char cmd; ++ unsigned char sync; ++ unsigned char dont_care; ++ struct spi_transfer x[2]; ++ struct spi_message message; ++ ++ cmd = AVR_CMD_READ_STATUS; ++ sync = 0; ++ ++ dont_care = 0;; ++ ++ memset(x, 0, sizeof x); ++ spi_message_init(&message); ++ ++ x[0].len = 1; ++ x[0].tx_buf = &cmd; ++ x[0].rx_buf = &sync; ++ x[0].delay_usecs = 400; ++ spi_message_add_tail(&x[0], &message); ++ ++ x[1].len = 1; ++ x[1].tx_buf = &dont_care; ++ x[1].rx_buf = ®s->status; ++ x[1].delay_usecs = 400; ++ spi_message_add_tail(&x[1], &message); ++ ++ err = spi_sync(spi, &message); ++ ++ return err; ++} ++ ++int avr_read_status_and_adc (struct spi_device *spi, struct avr_regs *regs) ++{ ++ int err; ++ unsigned char cmd; ++ unsigned char sync; ++ unsigned char dont_care; ++ struct spi_transfer x[8]; ++ struct spi_message message; ++ ++ cmd = AVR_CMD_READ_STATUS_AND_ADC; ++ sync = 0; ++ dont_care = 0; ++ ++ memset(x, 0, sizeof x); ++ spi_message_init(&message); ++ ++ x[0].len = 1; ++ x[0].tx_buf = &cmd; ++ x[0].rx_buf = &sync; ++ x[0].delay_usecs = 400; ++ spi_message_add_tail(&x[0], &message); ++ ++ x[1].len = 1; ++ x[1].tx_buf = &dont_care; ++ x[1].rx_buf = ®s->status; ++ x[1].delay_usecs = 400; ++ spi_message_add_tail(&x[1], &message); ++ ++ x[2].len = 1; ++ x[2].tx_buf = &dont_care; ++ x[2].rx_buf = ®s->adc0h; ++ x[2].delay_usecs = 400; ++ spi_message_add_tail(&x[2], &message); ++ ++ x[3].len = 1; ++ x[3].tx_buf = &dont_care; ++ x[3].rx_buf = ®s->adc0l; ++ x[3].delay_usecs = 400; ++ spi_message_add_tail(&x[3], &message); ++ ++ x[4].len = 1; ++ x[4].tx_buf = &dont_care; ++ x[4].rx_buf = ®s->adc1h; ++ x[4].delay_usecs = 400; ++ spi_message_add_tail(&x[4], &message); ++ ++ x[5].len = 1; ++ x[5].tx_buf = &dont_care; ++ x[5].rx_buf = ®s->adc1l; ++ x[5].delay_usecs = 400; ++ spi_message_add_tail(&x[5], &message); ++ ++ x[6].len = 1; ++ x[6].tx_buf = &dont_care; ++ x[6].rx_buf = ®s->adc2h; ++ x[6].delay_usecs = 400; ++ spi_message_add_tail(&x[6], &message); ++ ++ x[7].len = 1; ++ x[7].tx_buf = &dont_care; ++ x[7].rx_buf = ®s->adc2l; ++ x[7].delay_usecs = 400; ++ spi_message_add_tail(&x[7], &message); ++ ++ err = spi_sync(spi, &message); ++ ++ return err; ++} ++ ++int avr_read_mode (struct spi_device *spi, struct avr_regs *regs) ++{ ++ int err; ++ unsigned char cmd; ++ unsigned char sync; ++ unsigned char dont_care; ++ ++ struct spi_transfer x[2]; ++ struct spi_message message; ++ ++ ++ cmd = AVR_CMD_READ_MODE; ++ sync = 0; ++ ++ dont_care = 0; ++ memset(x, 0, sizeof x); ++ spi_message_init(&message); ++ ++ x[0].len = 1; ++ x[0].tx_buf = &cmd; ++ x[0].rx_buf = &sync; ++ x[0].delay_usecs = 400; ++ spi_message_add_tail(&x[0], &message); ++ ++ x[1].len = 1; ++ x[1].tx_buf = &dont_care; ++ x[1].rx_buf = ®s->mode; ++ x[1].delay_usecs = 400; ++ spi_message_add_tail(&x[1], &message); ++ ++ err = spi_sync(spi, &message); ++ ++ return err; ++} ++ ++int avr_read_timer (struct spi_device *spi, struct avr_regs *regs) ++{ ++ int err; ++ unsigned char cmd; ++ unsigned char sync; ++ unsigned char dont_care; ++ struct spi_transfer x[4]; ++ struct spi_message message; ++ ++ ++ cmd = AVR_CMD_READ_TIMER; ++ sync = 0; ++ dont_care = 0; ++ ++ memset(x, 0, sizeof x); ++ spi_message_init(&message); ++ ++ x[0].len = 1; ++ x[0].tx_buf = &cmd; ++ x[0].rx_buf = &sync; ++ x[0].delay_usecs = 400; ++ spi_message_add_tail(&x[0], &message); ++ ++ x[1].len = 1; ++ x[1].tx_buf = &dont_care; ++ x[1].rx_buf = ®s->timer_res; ++ x[1].delay_usecs = 400; ++ spi_message_add_tail(&x[1], &message); ++ ++ x[2].len = 1; ++ x[2].tx_buf = &dont_care; ++ x[2].rx_buf = ®s->timer_msb; ++ x[2].delay_usecs = 400; ++ spi_message_add_tail(&x[2], &message); ++ ++ x[3].len = 1; ++ x[3].tx_buf = &dont_care; ++ x[3].rx_buf = ®s->timer_lsb; ++ x[3].delay_usecs = 400; ++ spi_message_add_tail(&x[3], &message); ++ ++ err = spi_sync(spi, &message); ++ ++ return err; ++} ++int avr_read_timer_and_mode (struct spi_device *spi, struct avr_regs *regs) ++{ ++ int err; ++ unsigned char cmd; ++ unsigned char sync; ++ unsigned char dont_care; ++ struct spi_transfer x[5]; ++ struct spi_message message; ++ ++ ++ cmd = AVR_CMD_READ_TIMER_AND_MODE; ++ sync = 0; ++ dont_care = 0; ++ ++ memset(x, 0, sizeof x); ++ spi_message_init(&message); ++ ++ x[0].len = 1; ++ x[0].tx_buf = &cmd; ++ x[0].rx_buf = &sync; ++ x[0].delay_usecs = 400; ++ spi_message_add_tail(&x[0], &message); ++ ++ x[1].len = 1; ++ x[1].tx_buf = &dont_care; ++ x[1].rx_buf = ®s->timer_res; ++ x[1].delay_usecs = 400; ++ spi_message_add_tail(&x[1], &message); ++ ++ x[2].len = 1; ++ x[2].tx_buf = &dont_care; ++ x[2].rx_buf = ®s->timer_msb; ++ x[2].delay_usecs = 400; ++ spi_message_add_tail(&x[2], &message); ++ ++ x[3].len = 1; ++ x[3].tx_buf = &dont_care; ++ x[3].rx_buf = ®s->timer_lsb; ++ x[3].delay_usecs = 400; ++ spi_message_add_tail(&x[3], &message); ++ ++ x[4].len = 1; ++ x[4].tx_buf = &dont_care; ++ x[4].rx_buf = ®s->mode; ++ x[4].delay_usecs = 400; ++ spi_message_add_tail(&x[4], &message); ++ ++ err = spi_sync(spi, &message); ++ ++ return err; ++} ++ ++int avr_write_mode (struct spi_device *spi, struct avr_regs *regs) ++{ ++ int err; ++ unsigned char cmd; ++ unsigned char sync; ++ struct spi_transfer x[2]; ++ struct spi_message message; ++ ++ cmd = AVR_CMD_WRITE_MODE; ++ sync = 0; ++ ++ memset(x, 0, sizeof x); ++ spi_message_init(&message); ++ ++ x[0].len = 1; ++ x[0].tx_buf = &cmd; ++ x[0].rx_buf = &sync; ++ x[0].delay_usecs = 400; ++ spi_message_add_tail(&x[0], &message); ++ ++ x[1].len = 1; ++ x[1].tx_buf = ®s->mode; ++ x[1].rx_buf = 0; ++ x[1].delay_usecs = 400; ++ spi_message_add_tail(&x[1], &message); ++ ++ err = spi_sync(spi, &message); ++ ++ return err; ++} ++ ++int avr_write_timer (struct spi_device *spi, struct avr_regs *regs) ++{ ++ int err; ++ unsigned char cmd; ++ unsigned char sync; ++ struct spi_transfer x[4]; ++ struct spi_message message; ++ ++ cmd = AVR_CMD_WRITE_TIMER; ++ sync = 0; ++ ++ memset(x, 0, sizeof x); ++ spi_message_init(&message); ++ ++ x[0].len = 1; ++ x[0].tx_buf = &cmd; ++ x[0].rx_buf = &sync; ++ x[0].delay_usecs = 400; ++ spi_message_add_tail(&x[0], &message); ++ ++ x[1].len = 1; ++ x[1].tx_buf = ®s->timer_res; ++ x[1].rx_buf = 0; ++ x[1].delay_usecs = 400; ++ spi_message_add_tail(&x[1], &message); ++ ++ x[2].len = 1; ++ x[2].tx_buf = ®s->timer_msb; ++ x[2].rx_buf = 0; ++ x[2].delay_usecs = 400; ++ spi_message_add_tail(&x[2], &message); ++ ++ x[3].len = 1; ++ x[3].tx_buf = ®s->timer_lsb; ++ x[3].rx_buf = 0; ++ x[3].delay_usecs = 400; ++ spi_message_add_tail(&x[3], &message); ++ ++ err = spi_sync(spi, &message); ++ ++ return err; ++} ++ ++int avr_write_timer_and_mode (struct spi_device *spi, struct avr_regs *regs) ++{ ++ int err; ++ unsigned char cmd; ++ unsigned char sync; ++ struct spi_transfer x[5]; ++ struct spi_message message; ++ ++ ++ cmd = AVR_CMD_WRITE_TIMER_AND_MODE; ++ sync = 0; ++ ++ memset(x, 0, sizeof x); ++ spi_message_init(&message); ++ ++ x[0].len = 1; ++ x[0].tx_buf = &cmd; ++ x[0].rx_buf = &sync; ++ x[0].delay_usecs = 400; ++ spi_message_add_tail(&x[0], &message); ++ ++ x[1].len = 1; ++ x[1].tx_buf = ®s->timer_res; ++ x[1].rx_buf = 0; ++ x[1].delay_usecs = 400; ++ spi_message_add_tail(&x[1], &message); ++ ++ x[2].len = 1; ++ x[2].tx_buf = ®s->timer_msb; ++ x[2].rx_buf = 0; ++ x[2].delay_usecs = 400; ++ spi_message_add_tail(&x[2], &message); ++ ++ x[3].len = 1; ++ x[3].tx_buf = ®s->timer_lsb; ++ x[3].rx_buf = 0; ++ x[3].delay_usecs = 400; ++ spi_message_add_tail(&x[3], &message); ++ ++ x[4].len = 1; ++ x[4].tx_buf = ®s->mode; ++ x[4].rx_buf = 0; ++ x[4].delay_usecs = 400; ++ spi_message_add_tail(&x[4], &message); ++ ++ err = spi_sync(spi, &message); ++ ++ return err; ++} ++ +--- /dev/null ++++ git/drivers/bmi/pims/mdacc/avr.h +@@ -0,0 +1,54 @@ ++/* ++ * Copyright 2008 EnCADIS Designs, Inc. All Rights Reserved. ++ * Copyright 2008 Bug-Labs, Inc. All Rights Reserved. ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*----------------------------------------------------------------------------- ++ * ++ * Part of BMI Motion Detector Accelerometer (MDACC) Kernel Module ++ * ++ *----------------------------------------------------------------------------- ++ */ ++#ifndef MDACC_AVR_H ++#define MDACC_AVR_H ++ ++#include ++#include ++ ++struct avr_regs ++{ ++ unsigned char timer_res; // SPI Register 0 ++ unsigned char timer_msb; // SPI Register 1 ++ unsigned char timer_lsb; // SPI Register 2 ++ unsigned char mode; // SPI Register 3 ++ ++ unsigned char status; // SPI Register 4 ++ ++ unsigned char adc0h; // SPI Register 5 ++ unsigned char adc0l; // SPI Register 6 ++ unsigned char adc1h; // SPI Register 7 ++ unsigned char adc1l; // SPI Register 8 ++ unsigned char adc2h; // SPI Register 9 ++ unsigned char adc2l; // SPI Register 10 ++}; ++ ++int avr_read_adc (struct spi_device *spi, struct avr_regs *regs); ++int avr_read_status (struct spi_device *spi, struct avr_regs *regs); ++int avr_read_status_and_adc (struct spi_device *spi, struct avr_regs *regs); ++int avr_read_mode (struct spi_device *spi, struct avr_regs *regs); ++int avr_read_timer (struct spi_device *spi, struct avr_regs *regs); ++int avr_read_timer_and_mode (struct spi_device *spi, struct avr_regs *regs); ++int avr_write_mode (struct spi_device *spi, struct avr_regs *regs); ++int avr_write_timer (struct spi_device *spi, struct avr_regs *regs); ++int avr_write_timer_and_mode (struct spi_device *spi, struct avr_regs *regs); ++ ++#endif ++ ++ +--- /dev/null ++++ git/drivers/bmi/pims/mdacc/cque.c +@@ -0,0 +1,150 @@ ++/* ++ * Copyright 2008 EnCADIS Designs, Inc. All Rights Reserved. ++ * Copyright 2008 Bug-Labs, Inc. All Rights Reserved. ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*----------------------------------------------------------------------------- ++ * ++ * Part of BMI Motion Detector Accelerometer (MDACC) Kernel Module ++ * ++ *----------------------------------------------------------------------------- ++ */ ++ ++#include "cque.h" ++#include ++#include ++ ++struct cque *cque_create (int num_entries, int threshold) ++{ ++ ++ int entry_size; ++ struct cque *cque; ++ void *buf_base; ++ int buf_size; ++ ++ entry_size = 6; ++ cque = 0; ++ buf_size = entry_size * num_entries; ++ if (!buf_size) { ++ return 0; ++ } ++ ++ if (( threshold > num_entries) || ++ ( threshold < 1)) { ++ return 0; ++ } ++ ++ cque = kmalloc (sizeof(cque), GFP_KERNEL); ++ if (!cque) { ++ return 0; ++ } ++ ++ buf_base = kmalloc (buf_size, GFP_KERNEL); ++ if (!buf_base) { ++ kfree (cque); ++ return 0; ++ } ++ ++ cque->entry_size = entry_size; ++ cque->num_entries = num_entries; ++ cque->entry_cnt = 0; ++ cque->threshold = threshold; ++ cque->start = buf_base; ++ cque->end = buf_base + buf_size - entry_size; ++ cque->top = buf_base; ++ cque->bot = buf_base; ++ ++ return cque; ++} ++ ++void cque_destroy (struct cque *cque) ++{ ++ ++ if (cque) { ++ kfree (cque->start); ++ kfree (cque); ++ } ++ return; ++ ++} ++ ++int cque_write (struct cque *cque, void *data) ++{ ++ int size; ++ int err; ++ ++ size = 6; ++ err = 1; ++ if (cque) { ++ //insert ++ ++ memcpy (cque->top, data, size); ++ cque->top += size; ++ if (cque->top > cque->end) { ++ cque->top = cque->start; ++ } ++ ++ ++ if (cque->entry_cnt < cque->num_entries) { ++ cque->entry_cnt++; ++ } ++ else { ++ cque->bot += size; ++ if (cque->bot > cque->end) { ++ cque->bot = cque->start; ++ } ++ } ++ err = 0; ++ } ++ return err; ++ ++} ++ ++int cque_read (struct cque *cque, void *data ) ++{ ++ int size; ++ int err; ++ ++ size = 6; ++ err = 1; ++ if (cque) { ++ ++ if (cque->entry_cnt) { ++ ++ //remove ++ ++ //memcpy (data, cque->bot, size) with swab ; ++ ++ *((short*)(data)) = ntohs (*((short*)(cque->bot))); ++ *((short*)(data+2)) = ntohs (*((short*)(cque->bot+2))); ++ *((short*)(data+4)) = ntohs (*((short*)(cque->bot+4))); ++ cque->bot += size; ++ if (cque->bot > cque->end) { ++ cque->bot = cque->start; ++ } ++ cque->entry_cnt--; ++ err = 0; ++ } ++ } ++ return err; ++} ++ ++int cque_is_ready_for_read (struct cque *cque) ++{ ++ int ready; ++ ++ ready = 0; ++ if ((cque) && (cque->entry_cnt >= cque->threshold)) { ++ ready = 1; ++ } ++ return ready; ++} ++ ++ +--- /dev/null ++++ git/drivers/bmi/pims/mdacc/cque.h +@@ -0,0 +1,42 @@ ++/* ++ * Copyright 2008 EnCADIS Designs, Inc. All Rights Reserved. ++ * Copyright 2008 Bug-Labs, Inc. All Rights Reserved. ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*----------------------------------------------------------------------------- ++ * ++ * Part of BMI Motion Detector Accelerometer (MDACC) Kernel Module ++ * ++ *----------------------------------------------------------------------------- ++ */ ++#ifndef MDACC_CQUE_H ++#define MDACC_CQUE_H ++ ++struct cque ++{ ++ int entry_size; ++ int num_entries; ++ int entry_cnt; ++ int threshold; ++ ++ void *start; ++ void *end; ++ void *top; ++ void *bot; ++}; ++ ++struct cque *cque_create (int num_entries, int threshold); ++void cque_destroy (struct cque *cque); ++ ++int cque_write (struct cque *cque, void *data); ++int cque_read (struct cque *cque, void *data); ++int cque_is_ready_for_read (struct cque *cque); ++ ++#endif +--- /dev/null ++++ git/drivers/bmi/pims/mdacc/ctl.c +@@ -0,0 +1,176 @@ ++/* ++ * Copyright 2008 EnCADIS Designs, Inc. All Rights Reserved. ++ * Copyright 2008 Bug-Labs, Inc. All Rights Reserved. ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*----------------------------------------------------------------------------- ++ * ++ * Part of BMI Motion Detector Accelerometer (MDACC) Kernel Module ++ * ++ *----------------------------------------------------------------------------- ++ */ ++ ++#include "ctl.h" ++#include "mdacc.h" ++#include ++#include ++#include ++#include ++ ++ ++#include ++ ++static int ctl_open (struct inode *, struct file *); ++static int ctl_release (struct inode *, struct file *); ++static int ctl_ioctl (struct inode *, struct file *, unsigned int, unsigned long); ++ ++struct file_operations ctl_fops = { ++ .owner = THIS_MODULE, ++ .ioctl = ctl_ioctl, ++ .open = ctl_open, ++ .release = ctl_release, ++}; ++ ++static int ctl_major; ++ ++int ctl_init (void) ++{ ++ dev_t dev_id; ++ int retval; ++ ++ // alloc char driver with 4 minor numbers ++ ++ retval = alloc_chrdev_region(&dev_id, 0, 4, "BMI MDACC Control Driver"); ++ ++ if (retval) { ++ return -1; ++ } ++ ctl_major = MAJOR(dev_id); ++ return 0; ++} ++ ++void ctl_clean (void) ++{ ++ dev_t dev_id; ++ ++ dev_id = MKDEV(ctl_major, 0); ++ unregister_chrdev_region(dev_id, 4); ++ return; ++} ++ ++int ctl_probe (struct ctl *ctl, int slot) ++{ ++ struct cdev *cdev; ++ dev_t dev_id; ++ int ret; ++ struct class *bmi_class; ++ ++ cdev = &ctl->cdev; ++ cdev_init (cdev, &ctl_fops); ++ ++ dev_id = MKDEV (ctl_major, slot); ++ ret = cdev_add (cdev, dev_id, 1); ++ ++ //Create class device ++ bmi_class = bmi_get_class (); ++ ++ ctl->class_dev = device_create (bmi_class, NULL, MKDEV(ctl_major, slot), ctl, "bmi_mdacc_ctl_m%i", slot+1); ++ ++ if (IS_ERR(ctl->class_dev)) { ++ printk(KERN_ERR "Unable to create " ++ "class_device for bmi_mdacc_ctl_m%i; errno = %ld\n", ++ slot+1, PTR_ERR(ctl->class_dev)); ++ ctl->class_dev = NULL; ++ } ++ ++ return ret; ++} ++ ++void ctl_remove (struct ctl *ctl, int slot) ++{ ++ struct class *bmi_class; ++ ++ bmi_class = bmi_get_class (); ++ device_destroy (bmi_class, MKDEV(ctl_major, slot)); ++ ++ ctl->class_dev = 0; ++ ++ cdev_del (&ctl->cdev); ++ return; ++} ++ ++ ++static int ctl_open (struct inode *inode, struct file *file) ++{ ++ struct ctl *ctl; ++ ++ ctl = container_of(inode->i_cdev, struct ctl, cdev); ++ ++ ++ // Save ctl pointer for later. ++ ++ file->private_data = ctl; ++ return 0; ++} ++ ++static int ctl_release (struct inode *inode, struct file *file) ++{ ++ struct ctl *ctl; ++ ++ ctl = container_of(inode->i_cdev, struct ctl, cdev); ++ return 0; ++} ++ ++static int ctl_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ struct ctl *ctl; ++ int slot; ++ unsigned char tmp = 0; ++ ++ ctl = container_of(inode->i_cdev, struct ctl, cdev); ++ slot = mdacc_get_slot_ctl (ctl); ++ if (slot < 0) { ++ return -ENODEV; ++ } ++ ++ switch (cmd) { ++ ++ case BMI_MDACC_CTL_RED_LED_OFF: ++ tmp = bmi_slot_gpio_get(slot); ++ bmi_slot_gpio_set (slot, tmp | RED_LED); ++ //bmi_slot_gpio_write_bit (slot, 3, 1); //Red LED Off ++ break; ++ ++ case BMI_MDACC_CTL_RED_LED_ON: ++ tmp = bmi_slot_gpio_get(slot); ++ bmi_slot_gpio_set (slot, tmp & ~RED_LED); ++ //bmi_slot_gpio_write_bit (slot, 3, 0); //Red LED On ++ break; ++ ++ case BMI_MDACC_CTL_GREEN_LED_OFF: ++ tmp = bmi_slot_gpio_get(slot); ++ bmi_slot_gpio_set (slot, tmp | GREEN_LED); ++ //bmi_slot_gpio_write_bit (slot, 2, 1); //Green LED Off ++ break; ++ ++ case BMI_MDACC_CTL_GREEN_LED_ON: ++ tmp = bmi_slot_gpio_get(slot); ++ bmi_slot_gpio_set (slot, tmp & ~GREEN_LED); ++ //bmi_slot_gpio_write_bit (slot, 2, 0); //Green LED On ++ break; ++ ++ default: ++ printk (KERN_ERR "ctl_ioctl() - error exit\n"); ++ return -ENOTTY; ++ } ++ ++ return 0; ++} ++ +--- /dev/null ++++ git/drivers/bmi/pims/mdacc/ctl.h +@@ -0,0 +1,43 @@ ++/* ++ * Copyright 2008 EnCADIS Designs, Inc. All Rights Reserved. ++ * Copyright 2008 Bug-Labs, Inc. All Rights Reserved. ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*----------------------------------------------------------------------------- ++ * ++ * Part of BMI Motion Detector Accelerometer (MDACC) Kernel Module ++ * ++ *----------------------------------------------------------------------------- ++ */ ++ ++#ifndef MDACC_CTL_H ++#define MDACC_CTL_H ++ ++#include ++ ++#include ++#include ++ ++ ++struct ctl ++{ ++ struct cdev cdev; ++ struct device *class_dev; ++}; ++ ++extern int ctl_init (void); ++extern void ctl_clean(void); ++extern int ctl_probe (struct ctl *ctl, int slot); ++extern void ctl_remove(struct ctl *ctl, int slot); ++ ++ ++#endif ++ ++ +--- /dev/null ++++ git/drivers/bmi/pims/mdacc/md.c +@@ -0,0 +1,333 @@ ++/* ++ * Copyright 2008 EnCADIS Designs, Inc. All Rights Reserved. ++ * Copyright 2008 Bug-Labs, Inc. All Rights Reserved. ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*----------------------------------------------------------------------------- ++ * ++ * Part of BMI Motion Detector Accelerometer (MDACC) Kernel Module ++ * ++ *----------------------------------------------------------------------------- ++ */ ++ ++#include "md.h" ++#include "mdacc.h" ++#include "mon.h" ++#include ++#include ++#include ++ ++static int md_open (struct inode *, struct file *); ++static int md_release (struct inode *, struct file *); ++static int md_ioctl (struct inode *, struct file *, unsigned int, unsigned long); ++static ssize_t md_read (struct file *, char __user *, size_t, loff_t *); ++static unsigned int md_poll (struct file *, struct poll_table_struct *); ++ ++struct file_operations md_fops = { ++ .owner = THIS_MODULE, ++ .ioctl = md_ioctl, ++ .open = md_open, ++ .release = md_release, ++ .read = md_read, ++ .poll = md_poll, ++}; ++ ++static int md_major; ++ ++#define BMI_MOTION_DETECT_MASK (BMI_MOTION_DETECT_STATUS | \ ++ BMI_MOTION_DETECT_LATCHED_STATUS | \ ++ BMI_MOTION_DETECT_DELTA | \ ++ BMI_MOTION_DETECT_ENABLED) ++ ++ ++ ++void md_update (struct md *md, char data) ++{ ++ ++ unsigned char old_delta; ++ unsigned char new_delta; ++ unsigned char merge_bits; ++ unsigned char new_bits; ++ ++ ++ // Delta and Latched Status Bit Handling. ++ ++ // MOTION_STATUS Bit 3 ++ // LATCHED_STATUS Bit 2 ++ // DELTA Bit 1 ++ // ENABLED Bit 0 ++ ++ ++ // Handle bits individually ++ ++ old_delta = md->status & 0x02; ++ new_delta = data & 0x02; ++ ++ if (!new_delta) { ++ //preserve old latch bit, update delta bit ++ merge_bits = (md->status & 0x06) | (data & 0x02); ++ } ++ else { ++ //update latch bit and delta bit ++ merge_bits = (md->status & 0x06) | (data & 0x06); ++ } ++ new_bits = data & 0x09; ++ md->status = merge_bits | new_bits; ++ ++ if (!old_delta && new_delta) { ++ md->ready = 1; ++ //wake up anyone sleeping on our read wait queue ++ wake_up_interruptible (&md->read_wait_queue); ++ ++ } ++ return; ++} ++ ++ ++void md_clear_status (struct md *md) ++{ ++ ++ md->status &= ~(BMI_MOTION_DETECT_LATCHED_STATUS | ++ BMI_MOTION_DETECT_DELTA); ++ ++ md->ready = 0; ++ return; ++ ++} ++ ++ ++int md_init (void) ++{ ++ dev_t dev_id; ++ int retval; ++ ++ // alloc char driver with 4 minor numbers ++ ++ retval = alloc_chrdev_region(&dev_id, 0, 4, "BMI MDACC Motion Detector Driver"); ++ ++ if (retval) { ++ return -1; ++ } ++ md_major = MAJOR(dev_id); ++ return 0; ++} ++ ++void md_clean (void) ++{ ++ dev_t dev_id; ++ ++ dev_id = MKDEV(md_major, 0); ++ unregister_chrdev_region(dev_id, 4); ++ return; ++} ++ ++int md_probe (struct md *md, int slot, struct mon *mon) ++{ ++ struct cdev *cdev; ++ dev_t dev_id; ++ int ret; ++ struct class *bmi_class; ++ ++ md->removed = 0; ++ ++ cdev = &md->cdev; ++ cdev_init (cdev, &md_fops); ++ ++ dev_id = MKDEV (md_major, slot); ++ ret = cdev_add (cdev, dev_id, 1); ++ ++ //Create class device ++ bmi_class = bmi_get_class (); ++ ++ md->class_dev = device_create (bmi_class, NULL, MKDEV(md_major, slot), md, "bmi_mdacc_mot_m%i", slot+1); ++ ++ if (IS_ERR(md->class_dev)) { ++ printk(KERN_ERR "Unable to create " ++ "class_device for bmi_mdacc_mot_m%i; errno = %ld\n", ++ slot+1, PTR_ERR(md->class_dev)); ++ md->class_dev = NULL; ++ } ++ ++ md->open_flag = 0; ++ md->enabled = 0; ++ md->status = 0; ++ init_waitqueue_head (&md->read_wait_queue); ++ md->mon = mon; ++ return ret; ++} ++ ++void md_remove (struct md *md, int slot ) ++{ ++ struct class *bmi_class; ++ ++ md->removed = 1; ++ md->ready = -1; ++ wake_up_interruptible (&md->read_wait_queue); ++ ++ cdev_del (&md->cdev); ++ bmi_class = bmi_get_class (); ++ device_destroy (bmi_class, MKDEV(md_major, slot)); ++ md->class_dev = 0; ++ return; ++} ++ ++ ++static int md_open (struct inode *inode, struct file *file) ++{ ++ struct md *md; ++ ++ md = container_of(inode->i_cdev, struct md, cdev); ++ ++ //Enforce single open behavior ++ if (md->open_flag) { ++ return -EBUSY; ++ } ++ md->open_flag = 1; ++ ++ // Save md_drv pointer for later. ++ file->private_data = md; ++ return 0; ++} ++ ++static int md_release (struct inode *inode, struct file *file) ++{ ++ struct md *md; ++ ++ md = container_of(inode->i_cdev, struct md, cdev); ++ md->open_flag = 0; ++ ++ //Enforce stop-on-close behavior. ++ if (md->enabled) { ++ mon_stop_motion (md->mon); ++ } ++ return 0; ++} ++ ++static int md_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ int err = 0; ++ struct md *md; ++ md = container_of(inode->i_cdev, struct md, cdev); ++ ++ switch (cmd) { ++ ++ case BMI_MDACC_MOTION_DETECTOR_GET_STATUS: ++ ++ err = mon_status_request (md->mon); ++ if (err){ ++ return -ENODEV; ++ } ++ ++ //copy to user ++ err = copy_to_user((void*)(arg), &md->status, sizeof(md->status)); ++ md_clear_status (md); ++ if (err) { ++ return -EFAULT; ++ } ++ break; ++ ++ ++ case BMI_MDACC_MOTION_DETECTOR_RUN: ++ ++ err = mon_start_motion (md->mon); ++ ++ if (err){ ++ return -ENODEV; ++ } ++ mon_status_request (md->mon); ++ md->enabled = 1; ++ break; ++ ++ ++ case BMI_MDACC_MOTION_DETECTOR_STOP: ++ ++ err = mon_stop_motion (md->mon); ++ if (err){ ++ return -ENODEV; ++ } ++ ++ break; ++ ++ default: ++ printk (KERN_ERR "md_ioctl() - error exit\n"); ++ return -ENOTTY; ++ } ++ return 0; ++} ++ ++static ssize_t md_read (struct file *file, char __user *buf, size_t count, loff_t *ppos) ++{ ++ ++// ++// if fd is non-blocking and md is not enabled, return EWOULDBLOCK ++// if fd is non-blocking and md is enabled, and md is not ready, return EWOULDBLOCK ++// if fd is non-blocking and md is enabled, and md is ready, copy md->status to user, md_clear_status(), ++ ++// if fd is blocking and md is not enabled, avr_read_status, ++// md_update, copy md->status to user, md_clear_status() ++ ++// if fs is blocking and md is enabled, and md is not ready, sleep until ready. ++// when ready, copy md->status to user, md_clear_status() ++ ++ ++ int err; ++ struct md *md = file->private_data; ++ ++ ++ if (!md->enabled) { ++ return -EAGAIN; ++ } ++ ++ if (file->f_flags & O_NONBLOCK) { ++ return -EAGAIN; ++ } ++ ++ while (!md->ready) { ++ ++ if (file->f_flags & O_NONBLOCK) ++ return -EAGAIN; ++ if (wait_event_interruptible (md->read_wait_queue, (md->ready))) ++ return -ERESTARTSYS; ++ ++ if(md->removed) { ++ return -1; ++ } ++ } ++ ++ err = copy_to_user (buf, &md->status, 1); ++ md_clear_status (md); ++ if (err) { ++ return -EFAULT; ++ } ++ return 1; ++} ++ ++static unsigned int md_poll (struct file *file, struct poll_table_struct *table) ++{ ++ unsigned int mask = 0; ++ struct md *md = file->private_data; ++ ++ poll_wait(file, &md->read_wait_queue, table); ++ ++ if (md->ready) { ++ mask |= POLLIN | POLLRDNORM; /* readable */ ++ } ++ ++ if (mdacc_check_bdev_md (md) ) { ++ mask |= POLLHUP; /* hang-up */ ++ } ++ ++ if (!md->enabled) { ++ mask |= POLLHUP; /* hang-up */ ++ } ++ return mask; ++} ++ ++ +--- /dev/null ++++ git/drivers/bmi/pims/mdacc/md.h +@@ -0,0 +1,60 @@ ++/* ++ * Copyright 2008 EnCADIS Designs, Inc. All Rights Reserved. ++ * Copyright 2008 Bug-Labs, Inc. All Rights Reserved. ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*----------------------------------------------------------------------------- ++ * ++ * Part of BMI Motion Detector Accelerometer (MDACC) Kernel Module ++ * ++ *----------------------------------------------------------------------------- ++ */ ++ ++#ifndef MDACC_MD_H ++#define MDACC_MD_H ++ ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++ ++#include ++ ++struct mon; ++ ++struct md ++{ ++ struct cdev cdev; ++ struct device *class_dev; ++ int open_flag; ++ int enabled; ++ unsigned char status; ++ int ready; ++ wait_queue_head_t read_wait_queue; ++ struct mon *mon; ++ u8 removed; ++}; ++ ++ ++extern int md_init (void); ++extern void md_clean(void); ++extern int md_probe (struct md *md, int slot, struct mon *mon); ++extern void md_remove(struct md *md, int slot); ++ ++ ++void md_update ( struct md *md, char data); ++void md_clear_status (struct md *md ); ++ ++ ++#endif +--- /dev/null ++++ git/drivers/bmi/pims/mdacc/mdacc.c +@@ -0,0 +1,333 @@ ++/* ++ * Copyright 2008 EnCADIS Designs, Inc. All Rights Reserved. ++ * Copyright 2008 Bug-Labs, Inc. All Rights Reserved. ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*----------------------------------------------------------------------------- ++ * ++ * BMI Motion Detector Accelerometer (MDACC) Kernel Module ++ * ++ * This kernel module contains the device drivers for the Bug MDACC Plug-In ++ * Module. Refer to include/linux/bmi/bmi_mdacc.h for user-level device driver ++ * programming information. ++ *------------------------------------------------------------------------------ ++ */ ++ ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++ ++#include ++ ++#define BMI_MDACC_VERSION "1.0" // driver version ++ ++ ++#include "md.h" ++#include "acc.h" ++#include "ctl.h" ++#include "mon.h" ++#include "avr.h" ++#include "cque.h" ++#include "mdacc.h" ++ ++ ++// private device structure ++struct pim ++{ ++ struct bmi_device *bdev; ++ struct ctl ctl; ++ struct md md; ++ struct acc acc; ++ struct mon mon; ++ char *name; ++}; ++ ++static struct pim bug_mdacc_pim[4]; ++ ++// BMI device ID table ++static struct bmi_device_id bmi_mdacc_tbl[] = ++{ ++ { ++ .match_flags = BMI_DEVICE_ID_MATCH_VENDOR | BMI_DEVICE_ID_MATCH_PRODUCT, ++ .vendor = BMI_VENDOR_BUG_LABS, ++ .product = BMI_PRODUCT_MOT_ACCEL, ++ .revision = BMI_ANY, ++ }, ++ { 0, }, /* terminate list */ ++}; ++MODULE_DEVICE_TABLE(bmi, bmi_mdacc_tbl); ++ ++int bmi_mdacc_probe(struct bmi_device *bdev); ++void bmi_mdacc_remove(struct bmi_device *bdev); ++ ++// BMI driver structure ++static struct bmi_driver bmi_mdacc_driver = ++{ ++ .name = "bmi_mdacc", ++ .id_table = bmi_mdacc_tbl, ++ .probe = bmi_mdacc_probe, ++ .remove = bmi_mdacc_remove, ++}; ++ ++ ++// Support functions ++ ++int mdacc_get_slot_mon (struct mon *mon) ++{ ++ struct pim *pim; ++ int slot; ++ ++ pim = container_of(mon, struct pim, mon); ++ ++ if (pim->bdev == 0) { ++ slot = -1; ++ } ++ else { ++ slot = pim->bdev->slot->slotnum; ++ } ++ return slot; ++} ++ ++int mdacc_get_slot_ctl (struct ctl *ctl) ++{ ++ struct pim *pim; ++ int slot; ++ ++ pim = container_of(ctl, struct pim, ctl); ++ ++ if (pim->bdev == 0) { ++ slot = -1; ++ } ++ else { ++ slot = pim->bdev->slot->slotnum; ++ } ++ return slot; ++} ++ ++ ++struct spi_device* mdacc_get_spi_mon (struct mon *mon) ++{ ++ struct pim *pim; ++ struct spi_device *spi = 0; ++ ++ /* ++ pim = container_of(mon, struct pim, mon); ++ ++ if (pim->bdev) { ++ spi = pim->bdev->slot->slotnum; ++ } ++ */ ++ return spi; ++} ++ ++struct bmi_device* mdacc_get_bdev_mon (struct mon *mon) ++{ ++ struct pim *pim; ++ ++ pim = container_of(mon, struct pim, mon); ++ return pim->bdev; ++} ++ ++int mdacc_check_bdev_md (struct md *md) ++{ ++ int err; ++ struct pim *pim; ++ ++ err = 0; ++ pim = container_of(md, struct pim, md); ++ if (!pim->bdev) { ++ err = 1; ++ } ++ return err; ++} ++ ++int mdacc_check_bdev_acc (struct acc *acc) ++{ ++ int err; ++ struct pim *pim; ++ ++ err = 0; ++ pim = container_of(acc, struct pim, acc); ++ if (!pim->bdev) { ++ err = 1;; ++ } ++ return err; ++} ++ ++// BMI Functions ++ ++int bmi_mdacc_probe(struct bmi_device *bdev) ++{ ++ int slot; ++ struct pim *pim; ++ int irq; ++ unsigned char tmp = 0; ++ ++ // Module GPIO use: ++ // 0 1 ++ // GPIO 3 Red LED On Off ++ // GPIO 2 Green LED On Off ++ // GPIO 1 AVR Reset Reset Normal Operation ++ // GPIO 0 Accel. Sleep Mode Sleep Normal Operation ++ ++ slot = bdev->slot->slotnum; ++ pim = &bug_mdacc_pim[slot]; ++ ++ bmi_device_set_drvdata(bdev, pim); ++ pim->bdev = bdev; ++ ++ ++ // Setup GPIOs for this slot ++ ++ bmi_slot_gpio_configure(slot, RED_LED | GREEN_LED | GPIO_1 | GPIO_0); //Red LED: On ++ bmi_slot_gpio_set(slot, GPIO_0); ++ ++ bmi_slot_spi_enable(slot); ++ ++ //AVR Reset Active time ++ mdelay(1); ++ ++ ++ //Take AVR out of reset ++ bmi_slot_gpio_set(slot, GPIO_1 | GPIO_0); ++ ++ //AVR Reset Recovery time ++ ++ mdelay (100); ++ ++ ++ switch (slot) { ++ case 0: ++ pim->name = "mdacc_m1"; ++ break; ++ case 1: ++ pim->name = "mdacc_m2"; ++ break; ++ case 2: ++ pim->name = "mdacc_m3"; ++ break; ++ case 3: ++ pim->name = "mdacc_m4"; ++ break; ++ } ++ ++ irq = bdev->slot->status_irq; ++ ++ if (mon_probe (&pim->mon, pim->name, irq, &pim->md, &pim->acc) ) { ++ printk (KERN_ERR "bmi_mdacc_probe() - mon_probe() failed.\n"); ++ goto exit1; ++ } ++ if (md_probe (&pim->md, slot, &pim->mon) ) { ++ printk (KERN_ERR "bmi_mdacc_probe() - md_probe() failed.\n"); ++ goto exit2; ++ } ++ if (acc_probe (&pim->acc, slot, &pim->mon) ) { ++ printk (KERN_ERR "bmi_mdacc_probe() - acc_probe() failed.\n"); ++ goto exit3; ++ } ++ if (ctl_probe (&pim->ctl, slot) ) { ++ printk (KERN_ERR "bmi_mdacc_probe() - ctl_probe() failed.\n"); ++ goto exit4; ++ } ++ ++ tmp = bmi_slot_gpio_get(slot); ++ bmi_slot_gpio_set (slot, tmp | RED_LED); //Red + Green LEDs Off ++ return 0; ++ ++exit4: ++ acc_remove (&pim->acc, slot); ++exit3: ++ md_remove (&pim->md, slot); ++exit2: ++ mon_remove (&pim->mon); ++ ++exit1: ++ bmi_slot_spi_disable(slot); ++ bmi_device_set_drvdata (bdev, 0); ++ pim->bdev = 0; ++ // bmi_slot_gpio_write_bit (slot, 2, 1); //Green LED Off ++ tmp = bmi_slot_gpio_get(slot); ++ bmi_slot_gpio_set (slot, tmp | GREEN_LED); ++ return -1; ++} ++ ++void bmi_mdacc_remove(struct bmi_device *bdev) ++{ ++ int slot; ++ struct pim *pim; ++ ++ slot = bdev->slot->slotnum; ++ pim = &bug_mdacc_pim[slot]; ++ ++ ctl_remove (&pim->ctl, slot); ++ acc_remove (&pim->acc, slot); ++ md_remove (&pim->md, slot); ++ mon_remove (&pim->mon); ++ ++ bmi_slot_spi_disable(slot); ++ ++ bmi_device_set_drvdata (bdev, 0); ++#if 0 ++ pim->bdev = 0; ++#endif ++ ++ return; ++} ++ ++ ++ ++static __init int bmi_mdacc_init(void) ++{ ++ int rc = 0; ++ ++ acc_init(); ++ md_init(); ++ ctl_init(); ++ ++// Register with BMI bus. ++ rc = bmi_register_driver(&bmi_mdacc_driver); ++ if(rc) { ++ printk(KERN_ERR "bmi_mdacc_init() - bmi_register_driver failed\n"); ++ return rc; ++ } ++ ++ printk("BMI MDACC Driver v%s \n", BMI_MDACC_VERSION); ++ return 0; ++} ++ ++static void __exit bmi_mdacc_clean(void) ++{ ++// Unregister with BMI bus. ++ bmi_unregister_driver(&bmi_mdacc_driver); ++ ++ ctl_clean(); ++ md_clean(); ++ acc_clean(); ++ return; ++} ++ ++module_init(bmi_mdacc_init); ++module_exit(bmi_mdacc_clean); ++ ++MODULE_AUTHOR("EnCADIS Design, Inc."); ++MODULE_DESCRIPTION("BMI Motion Detector/Accelerometer Driver"); ++MODULE_LICENSE("GPL"); ++ ++ ++ ++ ++ ++ ++ +--- /dev/null ++++ git/drivers/bmi/pims/mdacc/mdacc.h +@@ -0,0 +1,43 @@ ++/* ++ * Copyright 2008 EnCADIS Designs, Inc. All Rights Reserved. ++ * Copyright 2008 Bug-Labs, Inc. All Rights Reserved. ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*----------------------------------------------------------------------------- ++ * ++ * Part of BMI Motion Detector Accelerometer (MDACC) Kernel Module ++ * ++ *----------------------------------------------------------------------------- ++ */ ++ ++#ifndef MDACC_H ++#define MDACC_H ++ ++struct acc; ++struct ctl; ++struct md; ++struct mon; ++struct spi_device; ++struct bmi_device; ++ ++extern int mdacc_get_slot_mon (struct mon *mon); ++extern int mdacc_get_slot_ctl (struct ctl *ctl); ++ ++extern struct bmi_device* mdacc_get_bdev_mon (struct mon *mon); ++extern struct spi_device* mdacc_get_spi_mon (struct mon *mon); ++ ++int mdacc_check_bdev_md (struct md *md); ++int mdacc_check_bdev_acc (struct acc *acc); ++ ++struct mon *mdacc_get_mon_md(struct md *md); ++struct mon *mdacc_get_mon_acc(struct acc *acc); ++ ++#endif ++ +--- /dev/null ++++ git/drivers/bmi/pims/mdacc/mon.c +@@ -0,0 +1,474 @@ ++/* ++ * Copyright 2008 EnCADIS Designs, Inc. All Rights Reserved. ++ * Copyright 2008 Bug-Labs, Inc. All Rights Reserved. ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*----------------------------------------------------------------------------- ++ * ++ * Part of BMI Motion Detector Accelerometer (MDACC) Kernel Module ++ * ++ *----------------------------------------------------------------------------- ++ */ ++ ++#include "mon.h" ++#include "mdacc.h" ++#include ++ ++#include ++ ++#define work_to_mon(w) container_of(w, struct mon, work_item) ++ ++enum ++{ ++ MON_STATE_IDLE, ++ MON_STATE_MOTION_ONLY, ++ MON_STATE_ACC_ONLY, ++ MON_STATE_MOTION_AND_ACC ++}; ++ ++enum ++{ ++ MON_ACTION_START_ACC, ++ MON_ACTION_START_MOTION, ++ MON_ACTION_STOP_ACC, ++ MON_ACTION_STOP_MOTION ++}; ++ ++ ++ ++ ++/* ++ Spi Mode Register ++ -------------------------------- ++ Timer Enable Bit 4 ++ ADC Poll Enable Bit 3 ++ Motion Detect Enable Bit 2 ++ GSEL1:0 Bits 1:0 ++ ++ ++ SPI Status Register ++ ------------------------------------ ++ Not used Bit 7 ++ Timer Enabled Bit 6 ++ Adc Complete Bit 5 ++ Adc Enabled Bit 4 ++ Motion Detect Status Bit 3 ++ Motion Detect Latched Status Bit 2 ++ Motion Detect Delta Bit 1 ++ Motion Detect Enabled Bit 0 ++ ++ ++ ++*/ ++ ++static void mon_change_state (struct mon* mon, int action) ++{ ++ switch (mon->state) { ++ ++ case MON_STATE_IDLE: ++ ++ switch (action) { ++ ++ case MON_ACTION_START_MOTION: ++ mon->state = MON_STATE_MOTION_ONLY; ++ break; ++ ++ case MON_ACTION_START_ACC: ++ mon->state = MON_STATE_ACC_ONLY; ++ break; ++ } ++ break; ++ ++ case MON_STATE_MOTION_ONLY: ++ ++ switch (action) { ++ ++ case MON_ACTION_STOP_MOTION: ++ mon->state = MON_STATE_IDLE; ++ break; ++ ++ case MON_ACTION_START_ACC: ++ mon->state = MON_STATE_MOTION_AND_ACC; ++ break; ++ } ++ break; ++ ++ case MON_STATE_ACC_ONLY: ++ ++ switch (action) { ++ ++ case MON_ACTION_STOP_ACC: ++ mon->state = MON_STATE_IDLE; ++ break; ++ ++ case MON_ACTION_START_MOTION: ++ mon->state = MON_STATE_MOTION_AND_ACC; ++ break; ++ } ++ break; ++ ++ case MON_STATE_MOTION_AND_ACC: ++ ++ switch (action) { ++ ++ case MON_ACTION_STOP_ACC: ++ mon->state = MON_STATE_MOTION_ONLY; ++ break; ++ ++ case MON_ACTION_STOP_MOTION: ++ mon->state = MON_STATE_ACC_ONLY; ++ break; ++ } ++ break; ++ } ++ return; ++} ++ ++int mon_start_motion (struct mon *mon) ++{ ++ int err = 0; ++ struct spi_device *spi; ++ ++ spi = mon->spi; ++ if (spi) { ++ if (down_interruptible (&mon->sem)) ++ return -ERESTARTSYS; ++ mon->regs.mode |= 0x04; ++ avr_write_mode (spi, &mon->regs); ++ mon_change_state (mon, MON_ACTION_START_MOTION); ++ up (&mon->sem); ++ } ++ else { ++ printk (KERN_ERR "mon_start_motion() - FAIL - spi is 0.\n"); ++ err = 1; ++ } ++ return err ; ++} ++ ++int mon_stop_motion (struct mon *mon) ++{ ++ int err = 0; ++ struct spi_device *spi; ++ ++ spi = mon->spi; ++ if (spi) { ++ if (down_interruptible (&mon->sem)) ++ return -ERESTARTSYS; ++ mon->regs.mode &= ~(0x04); ++ avr_write_mode (spi, &mon->regs); ++ mon_change_state (mon, MON_ACTION_STOP_MOTION); ++ up (&mon->sem); ++ } ++ else { ++ printk (KERN_ERR "mon_stop_motion() - FAIL - spi is 0.\n"); ++ err = 1; ++ } ++ return err ; ++} ++ ++ ++int mon_set_config_accel (struct mon *mon, struct mdacc_accel_config *cfg) ++{ ++ int err = 0; ++ unsigned char tmp; ++ struct spi_device *spi; ++ ++ spi = mon->spi; ++ if (cfg && spi) { ++ if (down_interruptible (&mon->sem)) ++ return -ERESTARTSYS; ++ if (cfg->delay_mode) { ++ ++ mon->regs.timer_res = cfg->delay_resolution; ++ mon->regs.timer_msb = cfg->delay >> 8; ++ mon->regs.timer_lsb = cfg->delay; ++ mon->regs.mode |= 0x10; ++ } ++ else { ++ mon->regs.mode &= ~0x10; ++ } ++ ++ if (cfg->run) { ++ mon->regs.mode |= 0x08; ++ mon_change_state (mon, MON_ACTION_START_ACC); ++ } ++ else { ++ mon->regs.mode &= ~0x08; ++ mon_change_state (mon, MON_ACTION_STOP_ACC); ++ ++ } ++ ++ tmp = mon->regs.mode & 0xFC; ++ tmp |= cfg->sensitivity & 0x03; ++ mon->regs.mode = tmp; ++ ++ if (cfg->delay_mode) { ++ avr_write_timer_and_mode (spi, &mon->regs); ++ } ++ else { ++ avr_write_mode (spi, &mon->regs); ++ } ++ up (&mon->sem); ++ } ++ else { ++ printk (KERN_ERR "mon_set_config_accel() - FAIL - null pointer.\n"); ++ err = 1; ++ } ++ return err ; ++} ++ ++int mon_get_config_accel (struct mon *mon, struct mdacc_accel_config *cfg) ++{ ++ int err = 0; ++ struct spi_device *spi; ++ ++ spi = mon->spi; ++ if (cfg && spi) { ++ if (down_interruptible (&mon->sem)) ++ return -ERESTARTSYS; ++ ++ avr_read_timer_and_mode (spi, &mon->regs); ++ ++ ++ if (mon->regs.mode & 0x10) { ++ cfg->delay_mode = 1; ++ cfg->delay_resolution = mon->regs.timer_res; ++ cfg->delay = mon->regs.timer_msb << 8 | mon->regs.timer_lsb; ++ } ++ else { ++ cfg->delay_mode = 0; ++ cfg->delay_resolution = 1; ++ cfg->delay = 5000; ++ } ++ ++ if (mon->regs.mode & 0x08) { ++ cfg->run = 1; ++ } ++ else { ++ cfg->run = 0; ++ } ++ cfg->sensitivity = mon->regs.mode & 0x03; ++ up (&mon->sem); ++ } ++ else { ++ printk (KERN_ERR "mon_get_config_accel() - FAIL - null pointer.\n"); ++ err = 1; ++ } ++ return err ; ++} ++ ++int mon_start_accel (struct mon *mon) ++{ ++ int err = 0; ++ struct spi_device *spi; ++ ++ spi = mon->spi; ++ if (spi) { ++ if (down_interruptible (&mon->sem)) ++ return -ERESTARTSYS; ++ mon->regs.mode |= 0x08; ++ avr_write_mode (spi, &mon->regs); ++ mon_change_state (mon, MON_ACTION_START_ACC); ++ up (&mon->sem); ++ } ++ else { ++ printk (KERN_ERR "mon_start_accel() - FAIL - spi is 0.\n"); ++ err = 1; ++ } ++ return err ; ++} ++ ++ ++int mon_stop_accel (struct mon *mon) ++{ ++ int err = 0; ++ ++ struct spi_device *spi; ++ ++ spi = mon->spi; ++ if (spi) { ++ if (down_interruptible (&mon->sem)) ++ return -ERESTARTSYS; ++ ++ mon->regs.mode &= ~0x08; ++ avr_write_mode (spi, &mon->regs); ++ mon_change_state (mon, MON_ACTION_STOP_ACC); ++ up (&mon->sem); ++ } ++ else { ++ printk (KERN_ERR "mon_stop_accel() - FAIL - spi is 0.\n"); ++ err = 1; ++ } ++ return err ; ++} ++ ++ ++int mon_status_request (struct mon* mon) ++{ ++ struct spi_device *spi; ++ int err = 0; ++ ++ ++ spi = mon->spi; ++ ++ if (!spi) { ++ printk (KERN_ERR "mon_status_request() - FAIL - spi is 0.\n"); ++ err = 1; ++ } ++ else { ++ ++ if (down_interruptible (&mon->sem)) ++ return -ERESTARTSYS; ++ //Read the avr status register ++ ++ switch (mon->state) { ++ ++ ++ case MON_STATE_IDLE: ++ ++ avr_read_status (spi, &mon->regs); ++ ++ //update md status ++ md_update (mon->md, mon->regs.status); ++ break; ++ ++ case MON_STATE_MOTION_ONLY: ++ ++ avr_read_status (spi, &mon->regs); ++ ++ //update md status ++ md_update (mon->md, mon->regs.status); ++ break; ++ ++ ++ case MON_STATE_ACC_ONLY: ++ ++ avr_read_status_and_adc (spi, &mon->regs); ++ ++ cque_write (mon->acc->cque, &mon->regs.adc0h); ++ if (cque_is_ready_for_read (mon->acc->cque) ) { ++ wake_up_interruptible (&mon->acc->read_wait_queue); ++ } ++ break; ++ ++ case MON_STATE_MOTION_AND_ACC: ++ ++ avr_read_status (spi, &mon->regs); ++ ++ //update md status ++ md_update (mon->md, mon->regs.status); ++ ++ // adc complete status ? ++ if (mon->regs.status & 0x20) { ++ avr_read_adc (spi, &mon->regs); ++ cque_write (mon->acc->cque, &mon->regs.adc0h); ++ if (cque_is_ready_for_read (mon->acc->cque) ) { ++ wake_up_interruptible (&mon->acc->read_wait_queue); ++ } ++ } ++ ++ break; ++ ++ default: ++ printk (KERN_ERR "mon_work_handler() - invalid state.\n"); ++ ++ } ++ up (&mon->sem); ++ } ++ return err; ++} ++ ++// work handler ++static void mon_work_handler (struct work_struct * work) ++{ ++ ++ struct mon *mon = work_to_mon(work); ++ ++ if ( !mon_status_request(mon) ) { ++ enable_irq (mon->irq); ++ } ++ return; ++} ++ ++// interrupt handler ++static irqreturn_t mon_irq_handler(int irq, void *dummy) ++{ ++ struct mon *mon = dummy; ++ ++ disable_irq_nosync(irq); ++ schedule_work (&mon->work_item); ++ return IRQ_HANDLED; ++} ++ ++int mon_probe (struct mon *mon, const char *name, int irq, struct md *md, struct acc *acc) ++{ ++ int err; ++ struct bmi_device *bdev; ++ unsigned long speed; ++ ++ unsigned char mode; ++ unsigned char bits_per_word; ++ ++ err = 1; ++ if (mon) { ++ bdev = mdacc_get_bdev_mon (mon); ++ speed = 250000; ++// speed = 125000; ++ mode = 1; ++ bits_per_word = 8; ++ ++ strcpy(mon->mon_spi_info.modalias, "bug_mdacc_spi"); ++ mon->mon_spi_info.max_speed_hz = speed; ++ mon->mon_spi_info.bus_num = bdev->slot->spi_bus_num; ++ mon->mon_spi_info.chip_select = bdev->slot->spi_cs; ++ mon->mon_spi_info.mode = mode; ++ mon->spi = spi_new_device(spi_busnum_to_master(mon->mon_spi_info.bus_num), &mon->mon_spi_info) ; ++ if (!mon->spi) { ++ printk (KERN_ERR "mon_probe() - bmi_device_spi_setup() failed.\n"); ++ goto exit; ++ } ++ ++ mon->irq = irq; ++ mon->md = md; ++ mon->acc = acc; ++ init_MUTEX (&mon->sem); ++ mon->state = MON_STATE_IDLE; ++ memset (&mon->regs, 0, sizeof (struct avr_regs) ); ++ ++ mon->workqueue = create_singlethread_workqueue (name); ++ if (!mon->workqueue) { ++ printk (KERN_ERR "mon_probe() - create_singlethread_workqueue() failed.\n"); ++ goto exit; ++ } ++ INIT_WORK(&mon->work_item, mon_work_handler); ++ ++ if (request_irq(irq, &mon_irq_handler, 0, name, mon)) { ++ printk (KERN_ERR "mon_probe() - request_irq (irq = %d) failed.\n", irq); ++ destroy_workqueue( mon->workqueue ); ++ goto exit; ++ } ++ err = 0; ++ } ++exit: ++ return err; ++} ++ ++ ++void mon_remove (struct mon *mon) ++{ ++ if (mon) { ++ free_irq(mon->irq, mon); ++ destroy_workqueue( mon->workqueue ); ++ spi_unregister_device(mon->spi); ++ } ++ return; ++} ++ ++ +--- /dev/null ++++ git/drivers/bmi/pims/mdacc/mon.h +@@ -0,0 +1,61 @@ ++/* ++ * Copyright 2008 EnCADIS Designs, Inc. All Rights Reserved. ++ * Copyright 2008 Bug-Labs, Inc. All Rights Reserved. ++ * ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*----------------------------------------------------------------------------- ++ * ++ * Part of BMI Motion Detector Accelerometer (MDACC) Kernel Module ++ * ++ *----------------------------------------------------------------------------- ++ */ ++ ++#ifndef MDACC_MON_H ++#define MDACC_MON_H ++ ++#include "avr.h" ++#include "md.h" ++#include "acc.h" ++ ++#include ++ ++struct mon ++{ ++ int irq; ++ struct md *md; ++ struct acc *acc; ++ struct spi_device *spi; ++ struct spi_board_info mon_spi_info; ++ struct semaphore sem; ++ int state; ++ struct avr_regs regs; ++ struct workqueue_struct *workqueue; ++ struct work_struct work_item; ++}; ++ ++struct md; ++struct acc; ++ ++int mon_probe (struct mon *mon, const char *name, int irq, struct md *md, struct acc *acc); ++void mon_remove (struct mon *mon); ++ ++int mon_start_motion (struct mon *mon); ++int mon_stop_motion (struct mon *mon); ++ ++int mon_set_config_accel (struct mon *mon, struct mdacc_accel_config *cfg); ++int mon_get_config_accel (struct mon *mon, struct mdacc_accel_config *cfg); ++int mon_start_accel (struct mon *mon); ++int mon_stop_accel (struct mon *mon); ++ ++int mon_status_request (struct mon *mon); ++ ++ ++#endif ++ +--- /dev/null ++++ git/drivers/bmi/pims/projector/Makefile +@@ -0,0 +1,7 @@ ++# ++# BMI PIMS ++# ++ ++obj-$(CONFIG_VIDEO_BMI_PROJECTOR) += bmi_projector_core.o ++bmi_projector_core-objs := bmi_projector.o ch7024.o ++ +--- /dev/null ++++ git/drivers/bmi/pims/projector/bmi_projector.c +@@ -0,0 +1,674 @@ ++/* ++ * bmi_projector.c ++ * ++ * BMI PROJECTOR device driver ++ * ++ * Derived from: bmi_lcd.c ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/* ++ * Include files ++ */ ++ ++#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 "ch7024.h" ++ ++#define DEBUG_PROJECTOR ++#undef DEBUG_PROJECTOR ++ ++#define BMIPROJECTOR_VERSION "1.0" // driver version ++#define BMI_SLOT_NUM (4) // number of BMI slots ++#define MAX_STRG (40) // Max string buffer size ++#define VSYNC_DISABLE 0x0 ++#define VSYNC_ENABLE 0x1 ++#define PROJ_DEF_MODE 0x09 // Projector default mode of operation ++ ++ // projector ++struct projector_interface { ++ char projector_type[MAX_STRG]; // text description of PROJECTOR type ++ u8 suspended; // power management state ++ u8 rotation; // screen rotation ++ u8 disp; // display number (DISP0 or DISP1) ++ u8 addr_mode; // display addressing mode ++ u8 vsync_mode; // VSYNC signal enable (VSYNC_ENABLE | VSYNC_DISABLE) ++ u8 bus_if_type; // bus type (XY | FullWoBE | FullWithBE) ++ ipu_adc_sig_cfg_t adc_sig; // IPU ADC set-up parameters ++ ipu_di_signal_cfg_t di_sig; // IPU DI set-up parameters ++}; ++ ++static struct projector_interface projector_interface = { ++ .projector_type = "MXCFB_PROJECTOR", ++ .suspended = 0, ++ .rotation = IPU_ROTATE_NONE, ++ .disp = DISP0, ++ .vsync_mode = VSYNC_DISABLE, ++ .bus_if_type = XY, ++ .adc_sig = { 0, 0, 0, 0, 0, 0, 0, 0, IPU_ADC_BURST_WCS, IPU_ADC_IFC_MODE_SYS80_TYPE2, ++ 16, 0, 0, IPU_ADC_SER_NO_RW }, ++ .di_sig = { 0,0,0,0,0,0,0,0 }, //pjg - reserved for multiple Projector driver ++}; ++ ++extern void projector_config(int disp); ++extern int projector_disp_on(int disp); ++extern int projector_disp_regset(int disp, unsigned short reg, unsigned short val); ++ ++struct bmi_projector; ++static int disp_mode_reg = 0x09; // Bit 3 of GPIO control register should always be maintained high ++//static int proj_mode = 0x1; // Bit 3 of GPIO control register should always be maintained high ++ ++struct bmi_projector_ops { ++ void *(*config) (int disp); // Projector configuration/initialization ++ void *(*reset) (int slot); // Projector reset ++ int *(*suspend) (struct bmi_projector *bprojector); // power management ++ int *(*resume) (struct bmi_projector *bprojector); // power management ++ int *(*disp_on) (int disp); // display on ++ int *(*disp_off) (int disp); // display off ++ int (*activate) (struct bmi_projector *projector, int slot); // enable Projector ++ int (*deactivate) (struct bmi_projector *projector, int slot); // disable Projector ++}; ++ ++struct bmi_projector_ops bmi_projector_ops; ++ ++struct bmi_projector { ++ struct projector_interface interface; // pointer to this struct is returned by config() ++ struct bmi_projector_ops projector_ops; // function pointers ++}; ++ ++static struct bmi_projector bmi_projector; ++ ++int register_bmi_projector(struct bmi_projector *bprojector, int slot); ++int unregister_bmi_projector(struct bmi_projector *bprojector, int slot); ++ ++ // private device structure ++struct pbmi_projector ++{ ++ int open_flag; // force single open ++ unsigned int projector_cnt; // number of Projector's present ++ unsigned int active; // indication of Projector's presence ++ unsigned int activated[BMI_SLOT_NUM]; // indication of Projector's presence ++ int proj_mode[BMI_SLOT_NUM]; // Indicate the state of projector on the slot ++ //int disp_mode_reg[BMI_SLOT_NUM]; ++ ++ struct bmi_projector *bprojector[BMI_SLOT_NUM]; // BMI Projector structure - placeholder for multiple display types ++ struct bmi_device *bdev[BMI_SLOT_NUM]; // BMI device per slot ++ unsigned int interrupt[BMI_SLOT_NUM]; // input device interrupt handlers ++ char int_name[MAX_STRG]; // interrupt name ++}; ++ ++static struct pbmi_projector pbmi_projector; // Projector device sructure ++ ++/* ++ * BMI set up ++ */ ++ ++ // BMI device ID table ++static struct bmi_device_id bmi_projector_tbl[] = ++{ ++ { ++ .match_flags = BMI_DEVICE_ID_MATCH_VENDOR | BMI_DEVICE_ID_MATCH_PRODUCT, ++ .vendor = BMI_VENDOR_BUG_LABS, ++ .product = BMI_PRODUCT_PROJECTOR, ++ .revision = BMI_ANY, ++ }, ++ { 0, }, /* terminate list */ ++}; ++ ++MODULE_DEVICE_TABLE(bmi, bmi_projector_tbl); ++ ++int bmi_projector_probe(struct bmi_device *bdev); ++void bmi_projector_remove(struct bmi_device *bdev); ++ ++// BMI driver structure ++static struct bmi_driver bmi_projector_driver = ++{ ++ .name = "bmi_projector", ++ .id_table = bmi_projector_tbl, ++ .probe = bmi_projector_probe, ++ .remove = bmi_projector_remove, ++}; ++ ++void bmi_projector_config(struct bmi_projector *projector, int disp); ++ ++ // probe ++int bmi_projector_probe(struct bmi_device *bdev) ++{ ++ int slot = bdev->info->slot; ++ struct i2c_adapter *adap; ++ struct bmi_projector *projector; ++ /*int first_time = 1;*/ ++ ++ printk(KERN_INFO "bmi_projector.c: probe slot %d\n", slot); ++ ++ // check for opposite side already active ++ switch(slot) { // opposite side ++ case 0: ++ if(pbmi_projector.activated[2] == 1) { ++ printk(KERN_INFO "bmi_projector.c: probe slot %d not allowed (slot 2 already active)\n", slot); ++ bmi_slot_power_off(0); ++ pbmi_projector.bdev[0] = bdev; ++ return 0; ++ } ++ break; ++ case 1: ++ if(pbmi_projector.activated[3] == 1) { ++ printk(KERN_INFO "bmi_projector.c: probe slot %d not allowed (slot 3 already active)\n", slot); ++ bmi_slot_power_off(1); ++ pbmi_projector.bdev[1] = bdev; ++ return 0; ++ } ++ break; ++ case 2: ++ if(pbmi_projector.activated[0] == 1) { ++ printk(KERN_INFO "bmi_projector.c: probe slot %d not allowed (slot 0 already active)\n", slot); ++ bmi_slot_power_off(2); ++ pbmi_projector.bdev[2] = bdev; ++ return 0; ++ } ++ break; ++ case 3: ++ if(pbmi_projector.activated[1] == 1) { ++ printk(KERN_INFO "bmi_projector.c: probe slot %d not allowed (slot 1 already active)\n", slot); ++ bmi_slot_power_off(3); ++ pbmi_projector.bdev[3] = bdev; ++ return 0; ++ } ++ break; ++ } ++ ++ adap = &bdev->adap; ++ ++// bmi_slot_power_on(slot); ++ ++ mdelay(500); ++ ++ if (!ch7024_detect (adap)) ++ { ++ /* setup for NTSC */ ++ ch7024_setup (adap, PROJOUT_FMT_NTSC); ++#ifdef DEBUG_PROJECTOR ++ printk ("\nFound encoder on slot %d \n", slot); ++#endif ++ ch7024_enable (adap); ++ } ++ else ++ { ++ printk ("\nError! Failed to detect encoder chip\n"); ++ return 0; ++ } ++ ++ // reset serial link (master) ++ if((slot == 0) || (slot == 2)) { ++ bmi_lcd_inactive(0); // We are using Same CPLD pins for projector ++ } else { ++ bmi_lcd_inactive(1); ++ } ++ ++ // FPGA PROG_0 - Active low signal ++ bmi_set_module_gpio_data(slot, 0, 0); ++ bmi_set_module_gpio_dir(slot, 0, BMI_GPIO_OUT); ++ ++ /* Reset the FPGA */ ++ bmi_set_module_gpio_data(slot, 1, 1); ++ bmi_set_module_gpio_dir(slot, 0, BMI_GPIO_OUT); ++ mdelay(100); ++ bmi_set_module_gpio_data(slot, 1, 0); ++ ++ // unreset serial link (master) ++ if((slot == 0) || (slot == 2)) { ++ mdelay(2); ++ bmi_lcd_active(0, 0x0, LCD_MODE_I80); ++ } else { ++ mdelay(2); ++ bmi_lcd_active(1, 0x0, LCD_MODE_I80); ++ } ++ ++ ++ // set up bdev/pbmi_projector pointers ++ bmi_device_set_drvdata(bdev, &pbmi_projector); ++ pbmi_projector.bdev[slot] = bdev; ++ ++ // complete pbmi_projector set-up ++ pbmi_projector.projector_cnt++; ++ pbmi_projector.active = 1; ++ pbmi_projector.activated[slot] = 1; ++ pbmi_projector.proj_mode[slot] = 1; ++ ++ mdelay(100); ++ ++ projector = pbmi_projector.bprojector[slot]; ++ if((slot == 0) || (slot == 2)) { ++ mdelay(2); ++ bmi_projector_config(projector, 0); ++ mdelay(2); ++ } else { ++ mdelay(2); ++ bmi_projector_config(projector, 1); ++ mdelay(2); ++ } ++ ++ // Turn on Projctor ++ disp_mode_reg = PROJ_DEF_MODE; ++ projector_disp_regset((slot & 0x1), 0x1, disp_mode_reg); ++ // check GPIO status ++ printk(KERN_INFO "bmi_projector.c: slot %d gpio = %x\n", slot, bmi_read_gpio_data_reg(slot)); ++ printk(KERN_INFO "bmi_projector.c: Projector count = %d\n", pbmi_projector.projector_cnt); ++ ++ return 0; ++} ++ ++ // remove ++void bmi_projector_remove(struct bmi_device *bdev) ++{ ++ int slot = bdev->info->slot; ++ ++ if(pbmi_projector.activated[slot] == 0) ++ return; ++ ++ bmi_set_module_gpio_dir (slot, 3, BMI_GPIO_IN); ++ bmi_set_module_gpio_dir (slot, 2, BMI_GPIO_IN); ++ bmi_set_module_gpio_dir (slot, 1, BMI_GPIO_IN); ++ bmi_set_module_gpio_dir (slot, 0, BMI_GPIO_IN); ++ ++ //de-attach driver-specific struct from bmi_device structure ++ bmi_device_set_drvdata (bdev, NULL); ++ ++ // deactivate ++ pbmi_projector.activated[slot] = 0; ++ pbmi_projector.bdev[slot] = 0; ++ pbmi_projector.projector_cnt--; ++ ++ if((pbmi_projector.activated[0] == 0) && (pbmi_projector.activated[2] == 0)) { ++ bmi_lcd_inactive(0); // disable serializer ++ } ++ ++ if((pbmi_projector.activated[1] == 0) && (pbmi_projector.activated[3] == 0)) { ++ bmi_lcd_inactive(1); // disable serializer ++ } ++ ++ if((pbmi_projector.activated[0] == 0) && (pbmi_projector.activated[1] == 0) && ++ (pbmi_projector.activated[2] == 0) && (pbmi_projector.activated[3] == 0)) { ++ pbmi_projector.active = -1; ++ } ++ ++ // enable Projector on opposite side ++ switch(slot) { ++ case 0: ++ if(pbmi_projector.bdev[2] != 0) ++ bmi_projector_probe(pbmi_projector.bdev[2]); ++ break; ++ case 1: ++ if(pbmi_projector.bdev[3] != 0) ++ bmi_projector_probe(pbmi_projector.bdev[3]); ++ break; ++ case 2: ++ if(pbmi_projector.bdev[0] != 0) ++ bmi_projector_probe(pbmi_projector.bdev[0]); ++ break; ++ case 3: ++ if(pbmi_projector.bdev[1] != 0) ++ bmi_projector_probe(pbmi_projector.bdev[1]); ++ break; ++ } ++ ++ printk(KERN_INFO "bmi_projector.c: projector count = %d\n", pbmi_projector.projector_cnt); ++ ++ return; ++} ++ ++/* ++ * control device operations ++ */ ++ ++/* ++ * control device operations ++ */ ++ ++// open ++int cntl_open(struct inode *inode, struct file *filp) ++{ ++ if(pbmi_projector.open_flag) { ++ return - EBUSY; ++ } ++ pbmi_projector.open_flag = 1; ++ filp->private_data = &pbmi_projector; ++ return 0; ++} ++ ++// release ++int cntl_release(struct inode *inode, struct file *filp) ++{ ++ pbmi_projector.open_flag = 0; ++ return 0; ++} ++ ++// ioctl ++int cntl_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct i2c_adapter *adap; ++ int slot = (__user arg) & 0xF; ++ int disp = 0; ++ int ret = 0; ++ ++ // error if no projector active. ++ if(pbmi_projector.active == -1) ++ return -ENODEV; ++ ++ // error if slot invalid ++ if((slot < CPLD_M1) || (slot > CPLD_M4)) ++ return -ENODEV; ++ ++ disp = slot & 0x1; // disp=0 for Slot 0 and 2, disp=1 for 1 and 3 ++#ifdef DEBUG_PROJECTOR ++ printk (KERN_INFO "Slot No is:%d\n", slot); ++ printk (KERN_INFO "Disp No is:%d\n", disp); ++#endif ++ ++ // error if no projector in chosen slot ++ if(pbmi_projector.bdev[slot] == 0) ++ return -ENODEV; ++ ++ // i2c adapter ++ adap = &pbmi_projector.bdev[slot]->adap; ++ ++ if( (cmd != BMI_PROJECTOR_ON) && (pbmi_projector.proj_mode[slot]/*proj_mode*/ == 0) ) ++ { ++ printk(KERN_ERR "Project is in OFF state !!!\n"); ++ return -EINVAL; ++ } ++ ++ // ioctl's ++ switch (cmd) { ++ case BMI_PROJECTOR_ON: ++ { ++ printk(KERN_INFO "BMI_PROJECTOR turning on\n"); ++ disp_mode_reg &= ~(0x3); ++ disp_mode_reg |= 0x1; ++ ch7024_enable(adap); ++ projector_disp_regset(disp, 0x1, disp_mode_reg); ++ mdelay(100); ++ projector_disp_regset(disp, 0x0, 0x1); ++ //proj_mode = 0x1; ++ pbmi_projector.proj_mode[slot] = 0x1; ++ } ++ break; ++ ++ case BMI_PROJECTOR_MODE: ++ { ++ int mode = ((__user arg) & 0xF0) >> 4; ++ printk(KERN_INFO "BMI_PROJECTOR setting mode to 0x%x \n",mode); ++ ++ disp_mode_reg &= ~(0x3); ++ switch(mode) ++ { ++ case PROJECTOR_ECONOMY_MODE: ++ disp_mode_reg |= 0x2; //Economy mode ++ break; ++ case PROJECTOR_BRIGHT_MODE: ++ disp_mode_reg |= 0x1; ++ break; ++ default: ++ printk(KERN_ERR "Invalid Mode\n"); ++ return -EINVAL; ++ } ++ ++ projector_disp_regset(disp, 0x1, disp_mode_reg); ++ } ++ break; ++ ++ case BMI_PROJECTOR_OFF: ++ { ++ disp_mode_reg &= ~(0x3); ++ disp_mode_reg |= 0x3; ++ ch7024_disable(adap); ++#ifdef DEBUG_PROJECTOR ++ printk (KERN_INFO "Mode reg value is:0x%X\n", disp_mode_reg); ++#endif ++ projector_disp_regset(disp, 0x1, disp_mode_reg); ++ //proj_mode = 0x0; ++ pbmi_projector.proj_mode[slot] = 0x0; ++ } ++ break; ++ ++ case BMI_PROJECTOR_BATTERY: ++ { ++ printk(KERN_INFO "BMI_PROJECTOR Staring Battery Charger for BUG\n"); ++ ch7024_disable(adap); ++ projector_disp_regset(disp, 0x1, 0xF); ++ //proj_mode = 0x0; ++ pbmi_projector.proj_mode[slot] = 0x0; ++ } ++ ++ break; ++ case BMI_PROJECTOR_HUE: ++ { ++ int val = ((__user arg) >> 8) & 0xff; ++ printk(KERN_INFO "BMI_PROJECTOR setting Hue to 0x%x\n",val); ++ ret = ch7024_set_hue(adap, val); ++ } ++ break; ++ case BMI_PROJECTOR_SATURATION: ++ { ++ int val = ((__user arg) >> 8) & 0xff; ++ printk(KERN_INFO "BMI_PROJECTOR setting Saturation to 0x%x\n",val); ++ ret = ch7024_set_sat(adap, val); ++ } ++ break; ++ case BMI_PROJECTOR_CONTRAST: ++ { ++ int val = ((__user arg) >> 8) & 0xff; ++ printk(KERN_INFO "BMI_PROJECTOR setting Contrast to 0x%x\n",val); ++ ret = ch7024_set_cont(adap, val); ++ } ++ break; ++ case BMI_PROJECTOR_BRIGHTNESS: ++ { ++ int val = ((__user arg) >> 8) & 0xff; ++ printk(KERN_INFO "BMI_PROJECTOR setting Brightness to 0x%x\n",val); ++ ret = ch7024_set_bright(adap, val); ++ } ++ break; ++ case BMI_PROJECTOR_SHARPNESS: ++ { ++ int val = ((__user arg) >> 8) & 0xff; ++ printk(KERN_INFO "BMI_PROJECTOR setting Sharpness to 0x%x\n",val); ++ ret = ch7024_set_sharp(adap, val); ++ } ++ break; ++ default: ++ return -ENOTTY; ++ } ++ return ret; ++} ++ ++ // control file operations ++struct file_operations cntl_fops = { ++ .owner = THIS_MODULE, ++ .ioctl = cntl_ioctl, ++ .open = cntl_open, ++ .release = cntl_release, ++}; ++ ++ // BMI Projector fops ++void bmi_projector_config(struct bmi_projector *projector, int disp) ++{ ++ if(pbmi_projector.active == -1) { ++ return; ++ } ++ ++ if((projector) && (projector->projector_ops.config)) { ++ projector->projector_ops.config(disp); ++ } ++} ++ ++void bmi_projector_reset(struct bmi_projector *projector, int slot) ++{ ++ if(pbmi_projector.active == -1) { ++ return; ++ } ++ ++ if((projector) && (projector->projector_ops.reset)) { ++ projector->projector_ops.reset(slot); ++ } ++} ++ ++int register_bmi_projector(struct bmi_projector *projector, int slot) //pjg - placeholder for multiple Projector types ++{ ++ if(!projector) { ++ return -1; ++ } ++ if((slot < 0) || (slot > 3)) { ++ return -1; ++ } ++ if(pbmi_projector.bprojector[slot]) { ++ return -1; ++ } ++ else { ++ pbmi_projector.bprojector[slot] = projector; ++ } ++ ++ if(projector->projector_ops.activate) { ++ projector->projector_ops.activate(projector, slot); ++ } ++ ++ return 0; ++} ++ ++int unregister_bmi_projector(struct bmi_projector *projector, int slot) //pjg - placeholder for multiple projector types ++{ ++ if (!projector) { ++ return -1; ++ } ++ if ((slot < 0) || (slot > 3)) { ++ return -1; ++ } ++ if (pbmi_projector.bprojector[slot] != projector) { ++ return -1; ++ } ++ else { ++ pbmi_projector.bprojector [slot] = 0; ++ projector->projector_ops.deactivate(projector, slot); ++ } ++ return 0; ++} ++ ++static struct miscdevice cntl_dev = { ++ MISC_DYNAMIC_MINOR, ++ "bmi_projector", ++ &cntl_fops ++}; ++ ++static __init int bmi_projector_init(void) ++{ ++ int rc = 0; ++ ++ // No projector is active. ++ pbmi_projector.active = -1; ++ pbmi_projector.activated[0] = 0; ++ pbmi_projector.activated[1] = 0; ++ pbmi_projector.activated[2] = 0; ++ pbmi_projector.activated[3] = 0; ++ pbmi_projector.proj_mode[0] = 0; ++ pbmi_projector.proj_mode[1] = 0; ++ pbmi_projector.proj_mode[2] = 0; ++ pbmi_projector.proj_mode[3] = 0; ++ ++ // set up control character device - bmi_projector_control ++ rc = misc_register(&cntl_dev); ++ if(rc) { ++ printk(KERN_ERR "bmi_projector.c: Can't allocate bmi_projector_control device\n"); ++ return rc; ++ } ++ ++ pbmi_projector.projector_cnt = 0; ++ ++ // hardware specfic set-up ++ bmi_projector.interface = projector_interface, ++ bmi_projector_ops.config = (void(*)) &projector_config; ++ bmi_projector_ops.reset = NULL; //pjg - placeholder for multiple projector hardware types ++ bmi_projector_ops.suspend = NULL; //pjg - placeholder for multiple projector hardware types ++ bmi_projector_ops.resume = NULL; //pjg - placeholder for multiple projector hardware types ++ bmi_projector_ops.disp_on = NULL; //pjg - placeholder for multiple projector hardware types ++ bmi_projector_ops.disp_off = NULL; //pjg - placeholder for multiple projector hardware types ++ bmi_projector_ops.activate = NULL; //pjg - placeholder for multiple Projector hardware types ++ bmi_projector_ops.deactivate = NULL; //pjg - placeholder for multiple Projector hardware types ++ bmi_projector.projector_ops = bmi_projector_ops; ++ pbmi_projector.bprojector[0] = &bmi_projector; ++ pbmi_projector.bprojector[1] = &bmi_projector; ++ pbmi_projector.bprojector[2] = &bmi_projector; ++ pbmi_projector.bprojector[3] = &bmi_projector; ++ ++ // register with BMI ++ rc = bmi_register_driver(&bmi_projector_driver); ++ if(rc) { ++ printk(KERN_ERR "bmi_projector.c: Can't register bmi_projector_driver\n"); ++ ++ misc_deregister(&cntl_dev); ++ ++ return rc; ++ } ++ ++ printk("bmi_projector.c: BMI_Projector Driver v%s \n", BMIPROJECTOR_VERSION); ++ ++ return 0; ++} ++ ++static void __exit bmi_projector_clean(void) ++{ ++ ++ // remove control device ++ misc_deregister(&cntl_dev); ++ ++ // remove bmi driver ++ bmi_unregister_driver(&bmi_projector_driver); ++ ++ return; ++} ++ ++module_init(bmi_projector_init); ++module_exit(bmi_projector_clean); ++ ++// Exported symbols ++EXPORT_SYMBOL(register_bmi_projector); ++EXPORT_SYMBOL(unregister_bmi_projector); ++ ++ ++MODULE_AUTHOR("Suresh Rao"); ++MODULE_DESCRIPTION("BMI projector device driver"); ++MODULE_SUPPORTED_DEVICE("bmi_projector_control"); ++MODULE_LICENSE("GPL"); ++ +--- /dev/null ++++ git/drivers/bmi/pims/projector/ch7024.c +@@ -0,0 +1,476 @@ ++/* ++ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++ /*! ++ * @file ch7024.c ++ * @brief Driver for CH7024 TV encoder ++ * ++ * @ingroup Framebuffer ++ */ ++//#define DEBUG ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "ch7024.h" ++ ++#define DEBUG_CH7024 ++ ++static int ch7024_found = 0; ++static struct i2c_adapter *ch7024_adap = NULL; ++ ++static int i2c_ch7024_client_xfer( char *reg, int reg_len, char *buf, int num, ++ int tran_flag) ++{ ++ struct i2c_msg msg[2]; ++ int ret; ++ if ((ch7024_adap == NULL)) ++ { ++ printk (KERN_ERR "ch7024_adap is NULL\n"); ++ return -1; ++ } ++ msg[0].addr = CH7024_I2C_ADDR; ++ msg[0].len = reg_len; ++ msg[0].buf = reg; ++ msg[0].flags = tran_flag; ++ msg[0].flags &= ~I2C_M_RD; ++ ++ msg[1].addr = CH7024_I2C_ADDR; ++ msg[1].len = num; ++ msg[1].buf = buf; ++ ++ msg[1].flags = tran_flag; ++ if (tran_flag & I2C_M_RD) { ++ msg[1].flags |= I2C_M_RD; ++ } else { ++ msg[1].flags &= ~I2C_M_RD; ++ } ++ ++ ret = i2c_transfer(ch7024_adap, msg, 2); ++ return ret; ++} ++ ++static int bug_i2c_ch7024_polling_read(char *reg, int reg_len, char *buf, int num) ++{ ++ return i2c_ch7024_client_xfer(reg, reg_len, buf, num,I2C_M_RD); ++} ++ ++static int bug_i2c_ch7024_polling_write(char *reg, int reg_len, char *buf, ++ int num) ++{ ++ return i2c_ch7024_client_xfer(reg, reg_len, buf, num, 0); ++ ++} ++ ++static int ch7024_read_reg(u32 reg, u32 * word, u32 len) ++{ ++ int i; ++ u8 *wp = (u8 *) word; ++ ++ *word = 0; ++ ++ for (i = 0; i < len; i++) { ++ int ret = bug_i2c_ch7024_polling_read((char *)®, 1, wp, 1); ++ if (ret < 0) ++ return ret; ++ wp++; ++ reg++; ++ } ++ return 0; ++} ++ ++static int ch7024_write_reg(u32 reg, u32 word, u32 len) ++{ ++ return bug_i2c_ch7024_polling_write((char *)®, 1, (u8 *) & word, len); ++} ++ ++/** ++ * PAL B/D/G/H/K/I clock and timting structures ++ */ ++static struct ch7024_clock ch7024_clk_pal = { ++ .A = 0x0, ++ .P = 0x36b00, ++ .N = 0x41eb00, ++ .T = 0x3f, ++ .PLLN1 = 0x0, ++ .PLLN2 = 0x1b, ++ .PLLN3 = 0x12, ++}; ++ ++static struct ch7024_input_timing ch7024_timing_pal = { ++ .HTI = 950, ++ .VTI = 560, ++ .HAI = 640, ++ .VAI = 480, ++ .HW = 60, ++ .HO = 250, ++ .VW = 40, ++ .VO = 40, ++ .VOS = CH7024_VOS_PAL_BDGHKI, ++}; ++ ++/** ++ * NTSC_M clock and timting structures ++ * TODO: change values to work well. ++ */ ++static struct ch7024_clock ch7024_clk_ntsc = { ++ .A = 0x0, ++ .P = 0x2ac90, ++ .N = 0x36fc90, ++ .T = 0x3f, ++ .PLLN1 = 0x0, ++ .PLLN2 = 0x1b, ++ .PLLN3 = 0x12, ++}; ++ ++static struct ch7024_input_timing ch7024_timing_ntsc = { ++ .HTI = 801, ++ .VTI = 554, ++ .HAI = 640, ++ .VAI = 480, ++ .HW = 60, ++ .HO = 101, ++ .VW = 20, ++ .VO = 54, ++ .VOS = CH7024_VOS_NTSC_M, ++}; ++ ++/** ++ * ch7024_setup ++ * initial the CH7024 chipset by setting register ++ * @param: ++ * vos: output video format ++ * @return: ++ * 0 successful ++ * otherwise failed ++ */ ++int ch7024_setup(struct i2c_adapter *adap,int vos) ++{ ++ struct ch7024_input_timing *ch_timing; ++ struct ch7024_clock *ch_clk; ++#ifdef DEBUG_CH7024 ++ int i, val; ++#endif ++ ch7024_adap = adap; ++#if 0 ++ if (!ch7024_found) { ++ printk(KERN_ERR "CH7024: no such device to setup!\n"); ++ return -ENODEV; ++ } ++#endif ++ /* select output video format */ ++ if (vos == PROJOUT_FMT_PAL) { ++ ch_timing = &ch7024_timing_pal; ++ ch_clk = &ch7024_clk_pal; ++ pr_debug("CH7024: change to PAL video\n"); ++ } else if (vos == PROJOUT_FMT_NTSC) { ++ ch_timing = &ch7024_timing_ntsc; ++ ch_clk = &ch7024_clk_ntsc; ++ pr_debug("CH7024: change to NTSC video\n"); ++ } else if (vos == PROJOUT_FMT_QVGA) { ++ ch_timing = &ch7024_timing_ntsc; ++ ch_clk = &ch7024_clk_ntsc; ++ pr_debug("CH7024: change to NTSC video\n"); ++ } ++ else { ++ ++ pr_debug("CH7024: no such video format.\n"); ++ return -EINVAL; ++ } ++ printk("Resetting Chrontel Card\n"); ++ ch7024_write_reg(CH7024_POWER, 0x0C, 1); /* power on, disable DAC */ ++ ch7024_write_reg(CH7024_RESET, 0x00, 1); /* Reset */ ++ ch7024_write_reg(CH7024_RESET, 0x03, 1); /* Reset */ ++ mdelay(10); ++ ++ ch7024_write_reg(CH7024_POWER, 0x0C, 1); /* power on, disable DAC */ ++ ch7024_write_reg(CH7024_XTAL, CH7024_XTAL_13MHZ, 1); /* 13MHz cystal */ ++ ch7024_write_reg(CH7024_SYNC, 0x0D, 1); /* Master mode, and TTL */ ++ ch7024_write_reg(CH7024_IDF1, 0x00, 1); ++ ch7024_write_reg(CH7024_TVFILTER1, 0x00, 1); /* set XCH=0 */ ++ ++ /* set input clock and divider */ ++ /* set PLL */ ++ ch7024_write_reg(CH7024_PLL1, ch_clk->PLLN1, 1); ++ ch7024_write_reg(CH7024_PLL2, ch_clk->PLLN2, 1); ++ ch7024_write_reg(CH7024_PLL3, ch_clk->PLLN3, 1); ++ ++ /* set A register */ ++ ch7024_write_reg(CH7024_PCLK_A1, 0x00, 1); ++ ch7024_write_reg(CH7024_PCLK_A2, 0x00, 1); ++ ch7024_write_reg(CH7024_PCLK_A3, 0x00, 1); ++ ch7024_write_reg(CH7024_PCLK_A4, 0x00, 1); ++ /* set P register */ ++ ch7024_write_reg(CH7024_CLK_P1, (ch_clk->P >> 16) & 0xFF, 1); ++ ch7024_write_reg(CH7024_CLK_P2, (ch_clk->P >> 8) & 0xFF, 1); ++ ch7024_write_reg(CH7024_CLK_P3, ch_clk->P & 0xFF, 1); ++ /* set N register */ ++ ch7024_write_reg(CH7024_CLK_N1, (ch_clk->N >> 16) & 0xFF, 1); ++ ch7024_write_reg(CH7024_CLK_N2, (ch_clk->N >> 8) & 0xFF, 1); ++ ch7024_write_reg(CH7024_CLK_N3, ch_clk->N & 0xFF, 1); ++ /* set T register */ ++ ch7024_write_reg(CH7024_CLK_T, ch_clk->T & 0xFF, 1); ++ ++ /* set sub-carrier frequency generation method */ ++ ch7024_write_reg(CH7024_ACIV, 0x10, 1); /* ACIV = 1, automatical SCF */ ++ /* TV out pattern and DAC switch */ ++ ch7024_write_reg(CH7024_OUT_FMT, (0x10 | ch_timing->VOS) & 0xFF, 1); ++ ++if (vos != PROJOUT_FMT_QVGA) ++{ ++ ++ /* input settings */ ++ ch7024_write_reg(CH7024_IDF2, 0x033, 1); ++ /* HAI/HTI VAI */ ++ ch7024_write_reg(CH7024_IN_TIMING1, ((ch_timing->HTI >> 5) & 0x38) | ++ ((ch_timing->HAI >> 8) & 0x07), 1); ++ ch7024_write_reg(CH7024_IN_TIMING2, ch_timing->HAI & 0xFF, 1); ++ ch7024_write_reg(CH7024_IN_TIMING8, ch_timing->VAI & 0xFF, 1); ++ /* HTI VTI */ ++ ch7024_write_reg(CH7024_IN_TIMING3, ch_timing->HTI & 0xFF, 1); ++ ch7024_write_reg(CH7024_IN_TIMING9, ch_timing->VTI & 0xFF, 1); ++ /* HW/HO(h) VW */ ++ ch7024_write_reg(CH7024_IN_TIMING4, ((ch_timing->HW >> 5) & 0x18) | ++ ((ch_timing->HO >> 8) & 0x7), 1); ++ ch7024_write_reg(CH7024_IN_TIMING6, ch_timing->HW & 0xFF, 1); ++ ch7024_write_reg(CH7024_IN_TIMING11, ch_timing->VW & 0x3F, 1); ++ /* HO(l) VO/VAI/VTI */ ++ ch7024_write_reg(CH7024_IN_TIMING5, ch_timing->HO & 0xFF, 1); ++ ch7024_write_reg(CH7024_IN_TIMING7, ((ch_timing->VO >> 4) & 0x30) | ++ ((ch_timing->VTI >> 6) & 0x0C) | ++ ((ch_timing->VAI >> 8) & 0x03), 1); ++ ch7024_write_reg(CH7024_IN_TIMING10, ch_timing->VO & 0xFF, 1); ++ ++} ++ /* adjust the brightness */ ++ ch7024_write_reg(CH7024_TVBRI, 0x90, 1); ++ ++ ch7024_write_reg(CH7024_OUT_TIMING1, 0x4, 1); ++ ch7024_write_reg(CH7024_OUT_TIMING2, 0xe0, 1); ++ ++ if (vos == PROJOUT_FMT_PAL) { ++ ch7024_write_reg(CH7024_V_POS1, 0x03, 1); ++ ch7024_write_reg(CH7024_V_POS2, 0x7d, 1); ++ } else { ++ ch7024_write_reg(CH7024_V_POS1, 0x02, 1); ++ ch7024_write_reg(CH7024_V_POS2, 0x7b, 1); ++ } ++ ++ /* Set up the sub carrier frequency */ ++ if (vos == PROJOUT_FMT_PAL) { ++ } ++ else { ++ /* We have crystal of 13MHz */ ++ ch7024_write_reg(CH7024_SC_FREQ4, 0x7E, 1); ++ ch7024_write_reg(CH7024_SC_FREQ3, 0xEA, 1); ++ ch7024_write_reg(CH7024_SC_FREQ2, 0x33, 1); ++ ch7024_write_reg(CH7024_SC_FREQ1, 0x02, 1); ++ ++ } ++ ++#ifdef DEBUG_CH7024 ++ for (i = 0; i < CH7024_SC_FREQ4; i++) { ++ ++ ch7024_read_reg(i, &val, 1); ++ pr_debug("CH7024, reg[0x%x] = %x\n", i, val); ++ } ++#endif ++ return 0; ++} ++ ++/** ++ * ch7024_enable ++ * Enable the ch7024 Power to begin TV encoder ++ */ ++void ch7024_enable(struct i2c_adapter *adap) ++{ ++ ch7024_adap = adap; ++ if (ch7024_found) { ++ ch7024_write_reg(CH7024_POWER, 0x00, 1); ++ printk("CH7024 power on.\n"); ++ } ++} ++ ++/** ++ * ch7024_disable ++ * Disable the ch7024 Power to stop TV encoder ++ */ ++void ch7024_disable(struct i2c_adapter *adap) ++{ ++ ch7024_adap = adap; ++ if (ch7024_found) { ++ ch7024_write_reg(CH7024_POWER, 0x0D, 1); ++ printk("CH7024 power off.\n"); ++ } ++} ++ ++int ch7024_dump (struct i2c_adapter *adap) ++ { ++ int i; ++ u32 data; ++ ch7024_adap = adap; ++ for (i =0; i <= CH7024_SC_FREQ4; i++) ++ { ++ ch7024_read_reg(i, &data, 1); ++ printk ("Offset :0%X Value :0%X\n", i, data); ++ } ++ ch7024_read_reg(0x62, &data, 1); ++ printk ("Offset :0x62 Value :0%X\n", data); ++ ch7024_read_reg(0x63, &data, 1); ++ printk ("Offset :0x63 Value :0%X\n", data); ++ ch7024_read_reg(0x7E, &data, 1); ++ printk ("Offset :0x7E Value :0%X\n", data); ++ return 0; ++ } ++EXPORT_SYMBOL(ch7024_dump); ++ ++int encoder_read_reg (struct i2c_adapter *adap, u32 offset, u32 *data) ++ { ++ int ret; ++ ch7024_adap = adap; ++ ret = ch7024_read_reg(offset, data, 1); ++ if (ret < 0) ++ { ++ printk ("Encoder read register failed at offset 0x%X\n", offset); ++ return ret; ++ } ++ return 0; ++ ++ } ++EXPORT_SYMBOL(encoder_read_reg); ++ ++int encoder_write_reg (struct i2c_adapter *adap, u32 offset, u32 data) ++ { ++ int ret; ++ ch7024_adap = adap; ++ ret = ch7024_write_reg(offset, data, 1); ++ if (ret < 0) ++ { ++ printk ("Encoder write2 register failed at offset 0x%X\n", offset); ++ return ret; ++ } ++ return 0; ++ ++ } ++EXPORT_SYMBOL(encoder_write_reg); ++ ++int ch7024_detect (struct i2c_adapter *adap) ++{ ++ int ret; ++ u32 id; ++ ch7024_adap = adap; ++ /*TODO client detection */ ++ ret = ch7024_read_reg(CH7024_DEVID, &id, 1); ++ if (ret < 0 || id != CH7024_DEVICE_ID) { ++ printk(KERN_ERR ++ "ch7024: TV encoder not present: %d, read ret %d\n", id, ++ ret); ++ return -1; ++ } ++ printk(KERN_ERR "ch7024: TV encoder present: %x, read ret %x\n", id, ++ ret); ++ ch7024_found = 1; ++ return 0; ++ ++} ++EXPORT_SYMBOL(ch7024_detect); ++ ++int ch7024_set_bright (struct i2c_adapter *adap,u32 val) ++{ ++ ch7024_adap = adap; ++ if (val & ~0xFF) { ++ printk ("Brighness value is out of range[0-255] %d\n", val); ++ return -1; ++ } else { ++ ch7024_write_reg(CH7024_TVBRI, val, 1); ++ } ++ return 0; ++} ++EXPORT_SYMBOL(ch7024_set_bright); ++ ++int ch7024_set_cont (struct i2c_adapter *adap,u32 val) ++{ ++ ch7024_adap = adap; ++ if (val & ~0x7F) { ++ printk ("Contrast value is out of range[0-127] %d\n", val); ++ return -1; ++ } else { ++ ch7024_write_reg(CH7024_TVCTA, val, 1); ++ } ++ return 0; ++} ++EXPORT_SYMBOL(ch7024_set_cont); ++ ++int ch7024_set_hue (struct i2c_adapter *adap,u32 val) ++{ ++ ch7024_adap = adap; ++ if (val & ~0x7F) { ++ printk ("Hue value is out of range[0-127] %d\n", val); ++ return -1; ++ } else { ++ ch7024_write_reg(CH7024_TVHUE, val, 1); ++ } ++ return 0; ++} ++EXPORT_SYMBOL(ch7024_set_hue); ++ ++int ch7024_set_sharp (struct i2c_adapter *adap,u32 val) ++{ ++ ch7024_adap = adap; ++ if (val & ~0x07) { ++ printk ("Sharpness value is out of range[0-8] %d\n", val); ++ return -1; ++ } else { ++ ch7024_write_reg(CH7024_TVSHARP, val, 1); ++ } ++ return 0; ++} ++EXPORT_SYMBOL(ch7024_set_sharp); ++ ++int ch7024_set_sat (struct i2c_adapter *adap,u32 val) ++{ ++ ch7024_adap = adap; ++ if (val & ~0x7F) { ++ printk ("Saturation value is out of range[0-127] %d\n", val); ++ return -1; ++ } else { ++ ch7024_write_reg(CH7024_TVSAT, val, 1); ++ } ++ return 0; ++} ++EXPORT_SYMBOL(ch7024_set_sat); ++ ++void ch7024_set_attr (struct i2c_adapter *adap,struct ch7024_attr *attributes) ++{ ++ if (!attributes) ++ return; ++ ch7024_set_bright (adap, attributes->brghtness & 0xFF); ++ ch7024_set_cont (adap, attributes->contrast & 0xFF); ++ ch7024_set_hue (adap, attributes->hue & 0xFF); ++ ch7024_set_sharp (adap, attributes->sharpness & 0xFF); ++ ch7024_set_sat (adap,attributes->saturation & 0xFF); ++ return; ++} ++ ++EXPORT_SYMBOL(ch7024_set_attr); ++ ++ ++EXPORT_SYMBOL(ch7024_setup); ++EXPORT_SYMBOL(ch7024_enable); ++EXPORT_SYMBOL(ch7024_disable); ++ ++ ++ +--- /dev/null ++++ git/drivers/bmi/pims/projector/ch7024.h +@@ -0,0 +1,166 @@ ++/* ++ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*! ++ * @file ch7024.h ++ * @brief Driver for CH7024 TV encoder ++ * ++ * @ingroup Framebuffer ++ */ ++#ifndef _CH7024_H_ ++#define _CH7024_H_ ++ ++#ifdef __KERNEL__ ++ ++ ++/* I2C bus id and device address of CH7024 chip */ ++ ++#define CH7024_I2C_ADDR 0x76 /* 7bits I2C address */ ++ ++/*! ++ * CH7024 registers ++ */ ++#define CH7024_DEVID 0x00 ++#define CH7024_REVID 0x01 ++#define CH7024_PG 0x02 ++ ++#define CH7024_RESET 0x03 ++#define CH7024_POWER 0x04 ++#define CH7024_TVHUE 0x05 ++#define CH7024_TVSAT 0x06 ++#define CH7024_TVCTA 0x07 ++#define CH7024_TVBRI 0x08 ++#define CH7024_TVSHARP 0x09 ++#define CH7024_OUT_FMT 0x0A ++#define CH7024_XTAL 0x0B ++#define CH7024_IDF1 0x0C ++#define CH7024_IDF2 0x0D ++#define CH7024_SYNC 0x0E ++#define CH7024_TVFILTER1 0x0F ++#define CH7024_TVFILTER2 0x10 ++#define CH7024_IN_TIMING1 0x11 ++#define CH7024_IN_TIMING2 0x12 ++#define CH7024_IN_TIMING3 0x13 ++#define CH7024_IN_TIMING4 0x14 ++#define CH7024_IN_TIMING5 0x15 ++#define CH7024_IN_TIMING6 0x16 ++#define CH7024_IN_TIMING7 0x17 ++#define CH7024_IN_TIMING8 0x18 ++#define CH7024_IN_TIMING9 0x19 ++#define CH7024_IN_TIMING10 0x1A ++#define CH7024_IN_TIMING11 0x1B ++#define CH7024_ACIV 0x1C ++#define CH7024_OUT_TIMING1 0x1E ++#define CH7024_OUT_TIMING2 0x1F ++#define CH7024_V_POS1 0x20 ++#define CH7024_V_POS2 0x21 ++#define CH7024_H_POS1 0x22 ++#define CH7024_H_POS2 0x23 ++#define CH7024_PCLK_A1 0x24 ++#define CH7024_PCLK_A2 0x25 ++#define CH7024_PCLK_A3 0x26 ++#define CH7024_PCLK_A4 0x27 ++#define CH7024_CLK_P1 0x28 ++#define CH7024_CLK_P2 0x29 ++#define CH7024_CLK_P3 0x2A ++#define CH7024_CLK_N1 0x2B ++#define CH7024_CLK_N2 0x2C ++#define CH7024_CLK_N3 0x2D ++#define CH7024_CLK_T 0x2E ++#define CH7024_PLL1 0x2F ++#define CH7024_PLL2 0x30 ++#define CH7024_PLL3 0x31 ++#define CH7024_SC_FREQ1 0x34 ++#define CH7024_SC_FREQ2 0x35 ++#define CH7024_SC_FREQ3 0x36 ++#define CH7024_SC_FREQ4 0x37 ++#define CH7024_DATA_IO 0x63 ++ ++/*! ++ * CH7024 register values ++ */ ++/* video output formats */ ++#define CH7024_VOS_NTSC_M 0x0 ++#define CH7024_VOS_NTSC_J 0x1 ++#define CH7024_VOS_NTSC_443 0x2 ++#define CH7024_VOS_PAL_BDGHKI 0x3 ++#define CH7024_VOS_PAL_M 0x4 ++#define CH7024_VOS_PAL_N 0x5 ++#define CH7024_VOS_PAL_NC 0x6 ++#define CH7024_VOS_PAL_60 0x7 ++/* crystal predefined */ ++#define CH7024_XTAL_13MHZ 0x4 ++#define CH7024_XTAL_26MHZ 0xB ++#define CH7024_XTAL_27MHZ 0xC ++ ++/* chip ID */ ++#define CH7024_DEVICE_ID 0x45 ++ ++/* clock source define */ ++#define CLK_HIGH 0 ++#define CLK_LOW 1 ++ ++/* CH7024 presets structs */ ++struct ch7024_clock { ++ u32 A; ++ u32 P; ++ u32 N; ++ u32 T; ++ u8 PLLN1; ++ u8 PLLN2; ++ u8 PLLN3; ++}; ++ ++struct ch7024_input_timing { ++ u32 HTI; ++ u32 VTI; ++ u32 HAI; ++ u32 VAI; ++ u32 HW; ++ u32 HO; ++ u32 VW; ++ u32 VO; ++ u32 VOS; ++}; ++ ++struct ch7024_attr{ ++ u32 brghtness; ++ u32 sharpness; ++ u32 hue; ++ u32 contrast; ++ u32 saturation; ++}; ++ ++/* function declare, used by bmi projector module */ ++int ch7024_setup (struct i2c_adapter *adap,int vos); ++void ch7024_enable (struct i2c_adapter *adap); ++void ch7024_disable (struct i2c_adapter *adap); ++int ch7024_detect (struct i2c_adapter *adap); ++void ch7024_set_attr (struct i2c_adapter *adap, struct ch7024_attr *attributes); ++int ch7024_set_sat (struct i2c_adapter *adap, u32 val); ++int ch7024_set_sharp (struct i2c_adapter *adap, u32 val); ++int ch7024_set_hue (struct i2c_adapter *adap, u32 val); ++int ch7024_set_cont (struct i2c_adapter *adap, u32 val); ++int ch7024_set_bright (struct i2c_adapter *adap, u32 val); ++int ch7024_dump (struct i2c_adapter *adap); ++int encoder_read_reg (struct i2c_adapter *adap, u32 offset, u32 *data); ++int encoder_write_reg (struct i2c_adapter *adap, u32 offset, u32 data); ++ ++#endif /* __KERNEL__ */ ++ ++/* output video format */ ++#define PROJOUT_FMT_PAL 0x01 ++#define PROJOUT_FMT_NTSC 0x02 ++#define PROJOUT_FMT_QVGA 0x03 ++ ++#endif /* _CH7024_H_ */ +--- /dev/null ++++ git/drivers/bmi/pims/sensor/Makefile +@@ -0,0 +1,6 @@ ++# ++# BMI PIMS ++# ++ ++obj-$(CONFIG_BMI_SENSOR) += bmi_sensor.o ++ +--- /dev/null ++++ git/drivers/bmi/pims/sensor/bmi_sensor.c +@@ -0,0 +1,4321 @@ ++/* ++ * bmi_sensor.c ++ * ++ * BMI sensor device driver ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/* ++ * Include files ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++#define BMISENSOR_VERSION "1.0" ++ ++#define work_to_sensor(w) container_of(w, struct bmi_sensor, work_item) ++#define dev_to_bmi_device(d) container_of(d, struct bmi_device, dev) ++ ++/* ++ * Global variables ++ */ ++ ++static ushort factory_test = 0; ++static int eeprom_init = 0; ++static ushort xdac_init = 0; ++static ushort ydac_init = 0; ++static ushort zdac_init = 0; ++static ushort fcc_test = 0; ++ ++// private device structure ++struct bmi_sensor ++{ ++ struct semaphore sem; // bmi_sensor mutex ++ struct bmi_device *bdev; // BMI device ++ struct cdev cdev; // control device ++ struct device *class_dev; // control class device ++ struct sensor_eeprom_raw eeprom; // eeprom contents ++ char int_name[20]; // interrupt name ++ struct workqueue_struct *workqueue; // interrupt work queue ++ struct work_struct work_item; // interrupt work structure ++ char work_name[20]; // workqueue name ++ wait_queue_head_t pl_wait_queue; // Proximity/Light interrupt wait queue ++ unsigned char pl_int_en; // Proximity/Light interrupts are enabled ++ unsigned char pl_int_fl; // Proximity/Light interrupt occurred ++ wait_queue_head_t temp_wait_queue; // Temperature interrupt wait queue ++ unsigned char temp_int_en; // Temperature interrupts are enabled ++ unsigned char temp_int_fl; // Temperature interrupt occurred ++ wait_queue_head_t mot_wait_queue; // Motion interrupt wait queue ++ unsigned char mot_int_en; // Motion interrupts are enabled ++ unsigned char mot_int_fl; // Motion interrupt occurred ++ unsigned int mot_state; // previous motion detector state ++ wait_queue_head_t acc_wait1_queue; // Accelerometer interrupt wait queue ++ unsigned char acc_int1_en; // Accelerometer interrupts are enabled ++ unsigned char acc_int1_fl; // Accelerometer interrupt occurred ++ wait_queue_head_t acc_wait2_queue; // Accelerometer interrupt wait queue ++ unsigned char acc_int2_en; // Accelerometer interrupts are enabled ++ unsigned char acc_int2_fl; // Accelerometer interrupt occurred ++ wait_queue_head_t usb_wait_queue; // USB interrupt wait queue ++ unsigned char usb_int_en; // USB interrupts are enabled ++ unsigned char usb_int_fl; // USB interrupt occurred ++ wait_queue_head_t dcomp_wait_queue; // Digital compass interrupt wait queue ++ unsigned char dcomp_int_en; // Digital compass interrupts are enabled ++ unsigned char dcomp_int_fl; // Digital compass interrupt occurred ++ unsigned int aprox_duration; // Analog Proximity LED burst duration (ms) ++ struct timer_list aprox_timer; // Analog Proximity LED burst timer ++ wait_queue_head_t aprox_wait_queue; // Analog Proximity timer wait queue ++ unsigned char aprox_int_en; // Analog Proximity timer are enabled ++ unsigned char aprox_int_fl; // Analog Proximity timer occurred ++ wait_queue_head_t dlight_wait_queue; // Digital Light interrupt wait queue ++ unsigned char dlight_int_en; // Digital Light interrupts are enabled ++ unsigned char dlight_int_fl; // Digital Light interrupt occurred ++ unsigned int comp_xsf; // Compass calibration ++ unsigned int comp_ysf; // Compass calibration ++ unsigned int comp_zsf; // Compass calibration ++ unsigned int comp_xoff; // Compass calibration ++ unsigned int comp_yoff; // Compass calibration ++ unsigned int comp_zoff; // Compass calibration ++}; ++ ++static struct bmi_sensor bmi_sensor[4]; // per slot device structure ++static int major; // control device major ++ ++/* ++ * BMI set up ++ */ ++ ++// BMI device ID table ++static struct bmi_device_id bmi_sensor_tbl[] = ++{ ++ { ++ .match_flags = BMI_DEVICE_ID_MATCH_VENDOR | BMI_DEVICE_ID_MATCH_PRODUCT, ++ .vendor = BMI_VENDOR_BUG_LABS, ++ .product = BMI_PRODUCT_SENSOR, ++ .revision = BMI_ANY, ++ }, ++ { 0, }, /* terminate list */ ++}; ++MODULE_DEVICE_TABLE(bmi, bmi_sensor_tbl); ++ ++int bmi_sensor_probe(struct bmi_device *bdev); ++void bmi_sensor_remove(struct bmi_device *bdev); ++ ++// BMI driver structure ++static struct bmi_driver bmi_sensor_driver = ++{ ++ .name = "bmi_sensor", ++ .id_table = bmi_sensor_tbl, ++ .probe = bmi_sensor_probe, ++ .remove = bmi_sensor_remove, ++}; ++ ++/* ++ * I2C set up ++ */ ++ ++// IOX ++// write byte to I2C IO expander ++static int WriteByte_IOX(struct i2c_adapter *adap, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ // Write Byte with Pointer ++ wmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[0].flags = 0; // write ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[1].flags = 0; // write ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ ret = i2c_transfer(adap, wmsg, num_msgs); ++ ++ if(ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk(KERN_ERR "WriteByte_IOX() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++// read byte from I2C IO expander ++static int ReadByte_IOX(struct i2c_adapter *adap, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ ++ // Read Byte with Pointer ++ rmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[0].flags = 0; // write ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; // read ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ret = i2c_transfer(adap, rmsg, num_msgs); ++ ++ if(ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk(KERN_ERR "ReadByte_IOX() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++// ADC ++// write byte to ADC ++static int WriteByte_ADC(struct i2c_adapter *adap, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[1]; ++ int num_msgs; ++ ++ wmsg[0].addr = BMI_ADC_I2C_ADDRESS; ++ wmsg[0].flags = 0; // write ++ wmsg[0].len = 1; ++ wmsg[0].buf = &data; ++ ++ num_msgs = 1; ++ ++ ret = i2c_transfer(adap, wmsg, num_msgs); ++ ++ if(ret == 1) { ++ ret = 0; ++ } ++ else { ++ printk(KERN_ERR "WriteByte_ADC() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++// read data from ADC ++static int ReadByte_ADC(struct i2c_adapter *adap, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[1]; ++ int num_msgs; ++ ++ rmsg[0].addr = BMI_ADC_I2C_ADDRESS; ++ rmsg[0].flags = I2C_M_RD; // read ++ rmsg[0].len = 2; ++ rmsg[0].buf = data; ++ ++ num_msgs = 1; ++ ret = i2c_transfer(adap, rmsg, num_msgs); ++ ++ if(ret == 1) { ++ ret = 0; ++ } ++ else { ++ printk(KERN_ERR "ReadByte_ADC() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++// Proximity/Light and Digital Light (same I2c address and format) ++// write byte to I2C PL ++static int WriteByte_PL(struct i2c_adapter *adap, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ // Write Byte with Pointer ++ wmsg[0].addr = BMI_PL_I2C_ADDRESS; ++ wmsg[0].flags = 0; // write ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_PL_I2C_ADDRESS; ++ wmsg[1].flags = 0; // write ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ ret = i2c_transfer(adap, wmsg, num_msgs); ++ ++ if(ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk(KERN_ERR "WriteByte_PL() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++// read byte from I2C PL ++static int ReadByte_PL(struct i2c_adapter *adap, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ ++ // Read Byte with Pointer ++ rmsg[0].addr = BMI_PL_I2C_ADDRESS; ++ rmsg[0].flags = 0; // write ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_PL_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; // read ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ret = i2c_transfer(adap, rmsg, num_msgs); ++ ++ if(ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk(KERN_ERR "ReadByte_PL() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++// write byte to I2C PL SYNC ++static int WriteByte_PL_SYNC(struct i2c_adapter *adap) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[1]; ++ int num_msgs; ++ unsigned char offset = SENSOR_PL_EXT_SYNC; ++ ++ // Write Byte with Pointer ++ wmsg[0].addr = BMI_PL_I2C_ADDRESS; ++ wmsg[0].flags = 0; // write ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ num_msgs = 1; ++ ++ ret = i2c_transfer(adap, wmsg, num_msgs); ++ ++ if(ret == 1) { ++ ret = 0; ++ } ++ else { ++ printk(KERN_ERR "WriteByte_PL_SYNC() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++// write byte to I2C DL Interrupt Clear ++static int WriteByte_DL_IC(struct i2c_adapter *adap) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[1]; ++ int num_msgs; ++ unsigned char offset = SENSOR_DL_INT_CLR; ++ ++ // Write Byte with Pointer ++ wmsg[0].addr = BMI_DLIGHT_I2C_ADDRESS; ++ wmsg[0].flags = 0; // write ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ num_msgs = 1; ++ ++ ret = i2c_transfer(adap, wmsg, num_msgs); ++ ++ if(ret == 1) { ++ ret = 0; ++ } ++ else { ++ printk(KERN_ERR "WriteByte_DL_IC() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++// Temperature ++// write byte to Temperature sensor ++static int WriteByte_TEMP(struct i2c_adapter *adap, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ // Write Byte with Pointer ++ wmsg[0].addr = BMI_TEMP_I2C_ADDRESS; ++ wmsg[0].flags = 0; // write ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_TEMP_I2C_ADDRESS; ++ wmsg[1].flags = 0; // write ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ ret = i2c_transfer(adap, wmsg, num_msgs); ++ ++ if(ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk(KERN_ERR "WriteByte_TEMP() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++// read byte from Temperature sensor ++static int ReadByte_TEMP(struct i2c_adapter *adap, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ ++ // Read Byte with Pointer ++ rmsg[0].addr = BMI_TEMP_I2C_ADDRESS; ++ rmsg[0].flags = 0; // write ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_TEMP_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; // read ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ret = i2c_transfer(adap, rmsg, num_msgs); ++ ++ if(ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk(KERN_ERR "ReadByte_TEMP() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++// Accelerometer ++// write byte to I2C Accelerometer ++static int WriteByte_ACC(struct i2c_adapter *adap, struct sensor_acc_rw *acc_rw) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ // Write Byte with Pointer ++ wmsg[0].addr = BMI_ACCEL_I2C_ADDRESS; ++ wmsg[0].flags = 0; // write ++ wmsg[0].len = 1; ++ wmsg[0].buf = &acc_rw->address; ++ ++ wmsg[1].addr = BMI_ACCEL_I2C_ADDRESS; ++ wmsg[1].flags = 0; // write ++ wmsg[1].len = 1; ++ wmsg[1].buf = acc_rw->data; ++ ++ num_msgs = 2; ++ ++ ret = i2c_transfer(adap, wmsg, num_msgs); ++ ++ if(ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk(KERN_ERR "WriteByte_ACC() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++// read byte(s) from Acceleromter ++static int ReadByte_ACC(struct i2c_adapter *adap, struct sensor_acc_rw *acc_rw) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ ++ // Read Byte with Pointer ++ rmsg[0].addr = BMI_ACCEL_I2C_ADDRESS; ++ rmsg[0].flags = 0; // write ++ rmsg[0].len = 1; ++ rmsg[0].buf = &acc_rw->address; ++ ++ rmsg[1].addr = BMI_ACCEL_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; // read ++ rmsg[1].len = acc_rw->count; ++ rmsg[1].buf = acc_rw->data; ++ ++ num_msgs = 2; ++ ret = i2c_transfer(adap, rmsg, num_msgs); ++ ++ if(ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk(KERN_ERR "ReadByte_ACC() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++// digital compass ++// write byte to digital compass ++static int WriteByte_DCOMP(struct i2c_adapter *adap, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ // Write Byte with Pointer ++ wmsg[0].addr = BMI_DCOMP_I2C_ADDRESS; ++ wmsg[0].flags = 0; // write ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_DCOMP_I2C_ADDRESS; ++ wmsg[1].flags = 0; // write ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ ret = i2c_transfer(adap, wmsg, num_msgs); ++ ++ if(ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk(KERN_ERR "WriteByte_DCOMP() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++// read byte from digital compass ++static int ReadByte_DCOMP(struct i2c_adapter *adap, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ ++ // Read Byte with Pointer ++ rmsg[0].addr = BMI_DCOMP_I2C_ADDRESS; ++ rmsg[0].flags = 0; // write ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_DCOMP_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; // read ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ret = i2c_transfer(adap, rmsg, num_msgs); ++ ++ if(ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk(KERN_ERR "ReadByte_DCOMP() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++// EEPROM ++// write byte to I2C EEPROM ++static int WriteByte_EE(struct i2c_adapter *adap, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ // Write Byte with Pointer ++ wmsg[0].addr = BMI_MEE_I2C_ADDRESS; ++ wmsg[0].flags = 0; // write ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_MEE_I2C_ADDRESS; ++ wmsg[1].flags = 0; // write ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ ret = i2c_transfer(adap, wmsg, num_msgs); ++ ++ if(ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk(KERN_ERR "WriteByte_EE() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++// read byte from I2C EEPROM ++static int ReadByte_EE(struct i2c_adapter *adap, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ ++ // Read Byte with Pointer ++ rmsg[0].addr = BMI_MEE_I2C_ADDRESS; ++ rmsg[0].flags = 0; // write ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_MEE_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; // read ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ret = i2c_transfer(adap, rmsg, num_msgs); ++ ++ if(ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk(KERN_ERR "ReadByte_EE() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++/* ++ * control device operations ++ */ ++ ++// open ++int cntl_open(struct inode *inode, struct file *file) ++{ ++ struct bmi_sensor *sensor; ++ ++ sensor = container_of(inode->i_cdev, struct bmi_sensor, cdev); ++ file->private_data = sensor; ++ return 0; ++ ++} ++ ++// release ++int cntl_release(struct inode *inode, struct file *file) ++{ ++ return 0; ++} ++ ++// analog proximity timer function ++void aptimer(unsigned long arg) ++{ ++ struct bmi_sensor *sensor = (struct bmi_sensor *) arg; ++ int ret; ++ ++ del_timer (&sensor->aprox_timer); ++ ++ // wake sleepers ++ ret = down_interruptible(&sensor->sem); ++ sensor->aprox_int_en = 0; ++ sensor->aprox_int_fl = 1; ++ up(&sensor->sem); ++ wake_up_all(&sensor->aprox_wait_queue); ++} ++ ++// ioctl ++int cntl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct i2c_adapter *adap; ++ unsigned char iox_data; ++ struct bmi_sensor *sensor = (struct bmi_sensor *)(file->private_data); ++ int slot; ++ int ret = 0; ++ ++ // error if sensor not present ++ if(sensor->bdev == 0) ++ return -ENODEV; ++ ++ slot = bmi_device_get_slot(sensor->bdev); ++ adap = bmi_device_get_i2c_adapter(sensor->bdev); ++ ++ // ioctl's ++ switch(cmd) { ++ ++ case BMI_SENSOR_RLEDOFF: ++ bmi_slot_gpio_write_bit(slot, SENSOR_GPIO_RED_LED, SENSOR_GPIO_LED_OFF); // Red LED=OFF ++ break; ++ ++ case BMI_SENSOR_RLEDON: ++ bmi_slot_gpio_write_bit(slot, SENSOR_GPIO_RED_LED, SENSOR_GPIO_LED_ON); // Red LED=ON ++ break; ++ ++ case BMI_SENSOR_GLEDOFF: ++ bmi_slot_gpio_write_bit(slot, SENSOR_GPIO_GREEN_LED, SENSOR_GPIO_LED_OFF); // Green LED=OFF ++ break; ++ ++ case BMI_SENSOR_GLEDON: ++ bmi_slot_gpio_write_bit(slot, SENSOR_GPIO_GREEN_LED, SENSOR_GPIO_LED_ON); // Green LED=ON ++ break; ++ ++ case BMI_SENSOR_GETSTAT: ++ { ++ int read_data; ++ ++ if(ReadByte_IOX(adap, IOX_INPUT0_REG, &iox_data)) ++ return -ENODEV; ++ read_data = iox_data; ++ ++ if(ReadByte_IOX(adap, IOX_INPUT1_REG, &iox_data)) ++ return -ENODEV; ++ read_data |= (iox_data << 8) | (bmi_read_gpio_data_reg(slot) << 16); ++ ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ } ++ break; ++ ++ case BMI_SENSOR_ADCWR: ++ { ++ unsigned char adc_data; ++ ++ if(sensor->eeprom.adc_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ adc_data = (unsigned char) (arg & 0xFF); ++ if(WriteByte_ADC(adap, adc_data)) ++ return -ENODEV; ++ } ++ break; ++ ++ case BMI_SENSOR_ADCRD: ++ { ++ unsigned char adc_data[2]; ++ int read_data; ++ ++ if(sensor->eeprom.adc_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if(ReadByte_ADC(adap, adc_data)) ++ return -ENODEV; ++ read_data = ((adc_data[0] & SENSOR_ADC_DATA_MSB) << 8) | adc_data[1]; ++ ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ } ++ break; ++ ++ case BMI_SENSOR_HUMRD: ++ { ++ unsigned char adc_data[2]; ++ int read_data; ++ ++ if(sensor->eeprom.humidity_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_HUMIDITY | SENSOR_ADC_PD_OFF)) ++ return -ENODEV; ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) ++ return -ENODEV; ++ read_data = ((adc_data[0] & SENSOR_ADC_DATA_MSB) << 8) | adc_data[1]; ++ ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ } ++ break; ++ ++ case BMI_SENSOR_ACOMPRST: ++ { ++ if(sensor->eeprom.acompass_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if(ReadByte_IOX(adap, IOX_INPUT0_REG, &iox_data)) ++ return -ENODEV; ++ ++ iox_data &= ~(0x1 << SENSOR_IOX_COMP_RS_N); ++ if(WriteByte_IOX(adap, IOX_OUTPUT0_REG, iox_data)) ++ return -ENODEV; ++ ++ mdelay(5); ++ ++ iox_data |= (0x1 << SENSOR_IOX_COMP_RS_N); ++ if(WriteByte_IOX(adap, IOX_OUTPUT0_REG, iox_data)) ++ return -ENODEV; ++ } ++ break; ++ ++ case BMI_SENSOR_ACOMPXRD: ++ { ++ unsigned char adc_data[2]; ++ int read_data; ++ ++ if(sensor->eeprom.acompass_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_ACOMPASS_X | SENSOR_ADC_PD_OFF)) ++ return -ENODEV; ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) ++ return -ENODEV; ++ read_data = ((adc_data[0] & SENSOR_ADC_DATA_MSB) << 8) | adc_data[1]; ++ ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ } ++ break; ++ ++ case BMI_SENSOR_ACOMPYRD: ++ { ++ unsigned char adc_data[2]; ++ int read_data; ++ ++ if(sensor->eeprom.acompass_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_ACOMPASS_Y | SENSOR_ADC_PD_OFF)) ++ return -ENODEV; ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) ++ return -ENODEV; ++ read_data = ((adc_data[0] & SENSOR_ADC_DATA_MSB) << 8) | adc_data[1]; ++ ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ } ++ break; ++ ++ case BMI_SENSOR_ACOMPZRD: ++ { ++ unsigned char adc_data[2]; ++ int read_data; ++ ++ if(sensor->eeprom.acompass_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_ACOMPASS_Z | SENSOR_ADC_PD_OFF)) ++ return -ENODEV; ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) ++ return -ENODEV; ++ read_data = ((adc_data[0] & SENSOR_ADC_DATA_MSB) << 8) | adc_data[1]; ++ ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ } ++ break; ++ ++ case BMI_SENSOR_PLWR: ++ { ++ struct sensor_pl_rw *pl = NULL; ++ unsigned char pl_data; ++ ++ if(sensor->eeprom.light_proximity_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if ((pl = kmalloc(sizeof(struct sensor_pl_rw), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ if (copy_from_user(pl, (struct sensor_pl_rw *) arg, sizeof(struct sensor_pl_rw))) { ++ kfree(pl); ++ return -EFAULT; ++ } ++ ++ pl_data = pl->cmd1; ++ if(WriteByte_PL(adap, SENSOR_PL_CMD1, pl_data)) { ++ kfree(pl); ++ return -ENODEV; ++ } ++ ++ pl_data = pl->cmd2; ++ if(WriteByte_PL(adap, SENSOR_PL_CMD2, pl_data)) { ++ kfree(pl); ++ return -ENODEV; ++ } ++ ++ pl_data = pl->int_lt_lsb; ++ if(WriteByte_PL(adap, SENSOR_PL_INT_LT_LSB, pl_data)) { ++ kfree(pl); ++ return -ENODEV; ++ } ++ ++ pl_data = pl->int_lt_msb; ++ if(WriteByte_PL(adap, SENSOR_PL_INT_LT_MSB, pl_data)) { ++ kfree(pl); ++ return -ENODEV; ++ } ++ ++ pl_data = pl->int_ht_lsb; ++ if(WriteByte_PL(adap, SENSOR_PL_INT_HT_LSB, pl_data)) { ++ kfree(pl); ++ return -ENODEV; ++ } ++ ++ pl_data = pl->int_ht_msb; ++ if(WriteByte_PL(adap, SENSOR_PL_INT_HT_MSB, pl_data)) { ++ kfree(pl); ++ return -ENODEV; ++ } ++ ++ kfree(pl); ++ } ++ break; ++ ++ case BMI_SENSOR_PLRD: ++ { ++ struct sensor_pl_rw *pl = NULL; ++ unsigned char pl_data; ++ ++ if(sensor->eeprom.light_proximity_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if ((pl = kmalloc(sizeof(struct sensor_pl_rw), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ ++ if(ReadByte_PL(adap, SENSOR_PL_CMD1, &pl_data)) { ++ kfree(pl); ++ return -ENODEV; ++ } ++ pl->cmd1 = pl_data; ++ ++ if(ReadByte_PL(adap, SENSOR_PL_DATA_MSB, &pl_data)) { ++ kfree(pl); ++ return -ENODEV; ++ } ++ pl->dm = pl_data; ++ ++ if(ReadByte_PL(adap, SENSOR_PL_DATA_LSB, &pl_data)) { ++ kfree(pl); ++ return -ENODEV; ++ } ++ pl->dl = pl_data; ++ ++ if(copy_to_user((struct sensor_pl_rw *) arg, pl, sizeof(struct sensor_pl_rw))) { ++ kfree(pl); ++ return -EFAULT; ++ } ++ ++ kfree(pl); ++ } ++ break; ++ ++ case BMI_SENSOR_PL_SYNC: ++ { ++ if(sensor->eeprom.light_proximity_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if(WriteByte_PL_SYNC(adap)) ++ return -ENODEV; ++ } ++ break; ++ ++ case BMI_SENSOR_PL_IWAIT: ++ { ++ struct sensor_pl_rw *pl = NULL; ++ unsigned char pl_data; ++ ++ if(sensor->eeprom.light_proximity_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if ((pl = kmalloc(sizeof(struct sensor_pl_rw), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ if (copy_from_user(pl, (struct sensor_pl_rw *) arg, sizeof(struct sensor_pl_rw))) { ++ kfree(pl); ++ return -EFAULT; ++ } ++ ++ pl_data = pl->cmd1; ++ if(WriteByte_PL(adap, SENSOR_PL_CMD1, pl_data)) { ++ kfree(pl); ++ return -ENODEV; ++ } ++ ++ pl_data = pl->cmd2; ++ if(WriteByte_PL(adap, SENSOR_PL_CMD2, pl_data)) { ++ kfree(pl); ++ return -ENODEV; ++ } ++ ++ pl_data = pl->int_lt_lsb; ++ if(WriteByte_PL(adap, SENSOR_PL_INT_LT_LSB, pl_data)) { ++ kfree(pl); ++ return -ENODEV; ++ } ++ ++ pl_data = pl->int_lt_msb; ++ if(WriteByte_PL(adap, SENSOR_PL_INT_LT_MSB, pl_data)) { ++ kfree(pl); ++ return -ENODEV; ++ } ++ ++ pl_data = pl->int_ht_lsb; ++ if(WriteByte_PL(adap, SENSOR_PL_INT_HT_LSB, pl_data)) { ++ kfree(pl); ++ return -ENODEV; ++ } ++ ++ pl_data = pl->int_ht_msb; ++ if(WriteByte_PL(adap, SENSOR_PL_INT_HT_MSB, pl_data)) { ++ kfree(pl); ++ return -ENODEV; ++ } ++ ++ ret = down_interruptible(&sensor->sem); ++ sensor->pl_int_en = 1; ++ sensor->pl_int_fl = 0; ++ up(&sensor->sem); ++ ret = wait_event_interruptible(sensor->pl_wait_queue, (sensor->pl_int_fl == 1)); ++ if(ret) ++ return ret; ++ ++ if(ReadByte_PL(adap, SENSOR_PL_CMD1, &pl_data)) { ++ kfree(pl); ++ return -ENODEV; ++ } ++ pl->cmd1 = pl_data; ++ ++ if(ReadByte_PL(adap, SENSOR_PL_DATA_MSB, &pl_data)) { ++ kfree(pl); ++ return -ENODEV; ++ } ++ pl->dm = pl_data; ++ ++ if(ReadByte_PL(adap, SENSOR_PL_DATA_LSB, &pl_data)) { ++ kfree(pl); ++ return -ENODEV; ++ } ++ pl->dl = pl_data; ++ ++ if(copy_to_user((struct sensor_pl_rw *) arg, pl, sizeof(struct sensor_pl_rw))) { ++ kfree(pl); ++ return -EFAULT; ++ } ++ ++ kfree(pl); ++ } ++ break; ++ ++ case BMI_SENSOR_SNDARD: ++ { ++ unsigned char adc_data[2]; ++ int read_data; ++ ++ if(sensor->eeprom.sound_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_SOUND_AVG | SENSOR_ADC_PD_OFF)) ++ return -ENODEV; ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) ++ return -ENODEV; ++ read_data = ((adc_data[0] & SENSOR_ADC_DATA_MSB) << 8) | adc_data[1]; ++ ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ } ++ break; ++ ++ case BMI_SENSOR_SNDPRD: ++ case BMI_SENSOR_SNDIRD: ++ { ++ unsigned char adc_data[2]; ++ int read_data; ++ ++ if(sensor->eeprom.sound_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ // read peak ++ if(WriteByte_ADC(adap, SENSOR_ADC_SOUND_PEAK | SENSOR_ADC_PD_OFF)) ++ return -ENODEV; ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) ++ return -ENODEV; ++ read_data = ((adc_data[0] & SENSOR_ADC_DATA_MSB) << 8) | adc_data[1]; ++ ++ // clear peak ++ if(ReadByte_IOX(adap, IOX_INPUT1_REG, &iox_data)) ++ return -ENODEV; ++ ++ iox_data &= ~(0x1 << SENSOR_IOX_S_PK_CLR_N); ++ if(WriteByte_IOX(adap, IOX_OUTPUT1_REG, iox_data)) ++ return -ENODEV; ++ ++ mdelay(1); ++ ++ iox_data |= (0x1 << SENSOR_IOX_S_PK_CLR_N); ++ if(WriteByte_IOX(adap, IOX_OUTPUT1_REG, iox_data)) ++ return -ENODEV; ++ ++ if(cmd == BMI_SENSOR_SNDPRD) { ++ // return data ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ } else { ++ ++ // read peak ++ if(WriteByte_ADC(adap, SENSOR_ADC_SOUND_PEAK | SENSOR_ADC_PD_OFF)) ++ return -ENODEV; ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) ++ return -ENODEV; ++ read_data = ((adc_data[0] & SENSOR_ADC_DATA_MSB) << 8) | adc_data[1]; ++ ++ // return data ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ } ++ ++ } ++ break; ++ ++ case BMI_SENSOR_TEMPWR: ++ { ++ struct sensor_temp_rw *temp = NULL; ++ unsigned char temp_addr; ++ unsigned char temp_data; ++ ++ if(sensor->eeprom.temperature_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if ((temp = kmalloc(sizeof(struct sensor_temp_rw), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ if (copy_from_user(temp, (struct sensor_temp_rw *) arg, sizeof(struct sensor_temp_rw))) { ++ kfree(temp); ++ return -EFAULT; ++ } ++ ++ temp_addr = temp->address; ++ temp_data = temp->d1; ++ if(WriteByte_TEMP(adap, temp_addr, temp_data)) { ++ kfree(temp); ++ return -ENODEV; ++ } ++ ++ kfree(temp); ++ } ++ break; ++ ++ case BMI_SENSOR_TEMPRD: ++ { ++ struct sensor_temp_rw *temp = NULL; ++ unsigned char temp_addr; ++ unsigned char temp_data; ++ ++ if(sensor->eeprom.temperature_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if ((temp = kmalloc(sizeof(struct sensor_temp_rw), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ if (copy_from_user(temp, (struct sensor_temp_rw *) arg, sizeof(struct sensor_temp_rw))) { ++ kfree(temp); ++ return -EFAULT; ++ } ++ ++ temp_addr = temp->address; ++ if(ReadByte_TEMP(adap, temp_addr, &temp_data)) { ++ kfree(temp); ++ return -ENODEV; ++ } ++ ++ temp->d1 = temp_data; ++ if(copy_to_user((struct sensor_temp_rw *) arg, temp, sizeof(struct sensor_temp_rw))) { ++ kfree(temp); ++ return -EFAULT; ++ } ++ ++ kfree(temp); ++ } ++ break; ++ ++ case BMI_SENSOR_TEMPRD_SL: ++ { ++ unsigned int read_data; ++ unsigned char temp_datam; ++ unsigned char temp_datal; ++ ++ if(sensor->eeprom.temperature_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_LOC_MSB, &temp_datam)) { ++ return -ENODEV; ++ } ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_LOC_LSB, &temp_datal)) { ++ return -ENODEV; ++ } ++ ++ read_data = (temp_datam << 8) | temp_datal; ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ ++ } ++ break; ++ ++ case BMI_SENSOR_TEMPRD_SR: ++ { ++ unsigned int read_data; ++ unsigned char temp_datam; ++ unsigned char temp_datal; ++ ++ if(sensor->eeprom.temperature_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_REM_MSB, &temp_datam)) { ++ return -ENODEV; ++ } ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_REM_LSB, &temp_datal)) { ++ return -ENODEV; ++ } ++ ++ read_data = (temp_datam << 8) | temp_datal; ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ ++ } ++ break; ++ ++ case BMI_SENSOR_TEMPRD_UR: ++ { ++ unsigned int read_data; ++ unsigned char temp_datam; ++ unsigned char temp_datal; ++ ++ if(sensor->eeprom.temperature_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_UREM_MSB, &temp_datam)) { ++ return -ENODEV; ++ } ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_UREM_LSB, &temp_datal)) { ++ return -ENODEV; ++ } ++ ++ read_data = (temp_datam << 8) | temp_datal; ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ ++ } ++ break; ++ ++ case BMI_SENSOR_TEMP_IWAIT: ++ { ++ if(sensor->eeprom.temperature_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ ret = down_interruptible(&sensor->sem); ++ sensor->temp_int_en = 1; ++ sensor->temp_int_fl = 0; ++ up(&sensor->sem); ++ ret = wait_event_interruptible(sensor->temp_wait_queue, (sensor->temp_int_fl == 1)); ++ if(ret) ++ return ret; ++ } ++ break; ++ ++ case BMI_SENSOR_MOTRD: ++ { ++ unsigned int read_data; ++ ++ if(sensor->eeprom.motion_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ read_data = bmi_slot_gpio_read_bit(slot, SENSOR_GPIO_MOT_DET); ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ ++ } ++ break; ++ ++ case BMI_SENSOR_MOT_IWAIT: ++ { ++ unsigned int read_data; ++ ++ if(sensor->eeprom.motion_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ ret = down_interruptible(&sensor->sem); ++ sensor->mot_int_en = 1; ++ sensor->mot_int_fl = 0; ++ up(&sensor->sem); ++ ret = wait_event_interruptible(sensor->mot_wait_queue, (sensor->mot_int_fl == 1)); ++ if(ret) ++ return ret; ++ ++ read_data = bmi_slot_gpio_read_bit(slot, SENSOR_GPIO_MOT_DET); ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ ++ } ++ break; ++ ++ case BMI_SENSOR_ACCWR: ++ { ++ struct sensor_acc_rw *acc = NULL; ++ ++ if((sensor->eeprom.accel_present != SENSOR_DEVICE_PRESENT) ++ && (sensor->eeprom.acc302_present != SENSOR_DEVICE_PRESENT)) ++ return -ENODEV; ++ ++ if ((acc = kmalloc(sizeof(struct sensor_acc_rw), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ if (copy_from_user(acc, (struct sensor_acc_rw *) arg, sizeof(struct sensor_acc_rw))) { ++ kfree(acc); ++ return -EFAULT; ++ } ++ ++ if(WriteByte_ACC(adap, acc)) { ++ kfree(acc); ++ return -ENODEV; ++ } ++ ++ kfree(acc); ++ } ++ break; ++ ++ case BMI_SENSOR_ACCRD: ++ { ++ struct sensor_acc_rw *acc = NULL; ++ ++ if((sensor->eeprom.accel_present != SENSOR_DEVICE_PRESENT) ++ && (sensor->eeprom.acc302_present != SENSOR_DEVICE_PRESENT)) ++ return -ENODEV; ++ ++ if ((acc = kmalloc(sizeof(struct sensor_acc_rw), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ if (copy_from_user(acc, (struct sensor_acc_rw *) arg, sizeof(struct sensor_acc_rw))) { ++ kfree(acc); ++ return -EFAULT; ++ } ++ ++ if(ReadByte_ACC(adap, acc)) { ++ kfree(acc); ++ return -ENODEV; ++ } ++ ++ if(copy_to_user((struct sensor_acc_rw *) arg, acc, sizeof(struct sensor_acc_rw))) { ++ kfree(acc); ++ return -EFAULT; ++ } ++ ++ kfree(acc); ++ } ++ break; ++ ++ case BMI_SENSOR_ACCXRD: ++ { ++ struct sensor_acc_rw *acc = NULL; ++ unsigned int read_data; ++ ++ if(sensor->eeprom.accel_present == SENSOR_DEVICE_PRESENT) { ++ ++ if ((acc = kmalloc(sizeof(struct sensor_acc_rw), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ ++ acc->address = SENSOR_ACC_DX0; ++ acc->count = 2; ++ ++ if(ReadByte_ACC(adap, acc)) { ++ kfree(acc); ++ return -ENODEV; ++ } ++ ++ read_data = (acc->data[1] << 8) | acc->data[0]; ++ if(put_user(read_data, (int __user *) arg)) { ++ kfree(acc); ++ return -EFAULT; ++ } ++ } else if(sensor->eeprom.acc302_present == SENSOR_DEVICE_PRESENT) { ++ if ((acc = kmalloc(sizeof(struct sensor_acc_rw), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ ++ acc->address = SENSOR_A3_OUTX; ++ acc->count = 1; ++ ++ if(ReadByte_ACC(adap, acc)) { ++ kfree(acc); ++ return -ENODEV; ++ } ++ ++ read_data = acc->data[0]; ++ if(put_user(read_data, (int __user *) arg)) { ++ kfree(acc); ++ return -EFAULT; ++ } ++ } else { ++ return -ENODEV; ++ } ++ ++ kfree(acc); ++ } ++ break; ++ ++ case BMI_SENSOR_ACCYRD: ++ { ++ struct sensor_acc_rw *acc = NULL; ++ unsigned int read_data; ++ ++ if(sensor->eeprom.accel_present != SENSOR_DEVICE_PRESENT) { ++ if ((acc = kmalloc(sizeof(struct sensor_acc_rw), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ ++ acc->address = SENSOR_ACC_DY0; ++ acc->count = 2; ++ ++ if(ReadByte_ACC(adap, acc)) { ++ kfree(acc); ++ return -ENODEV; ++ } ++ ++ read_data = (acc->data[1] << 8) | acc->data[0]; ++ if(put_user(read_data, (int __user *) arg)) { ++ kfree(acc); ++ return -EFAULT; ++ } ++ } else if(sensor->eeprom.acc302_present == SENSOR_DEVICE_PRESENT) { ++ if ((acc = kmalloc(sizeof(struct sensor_acc_rw), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ ++ acc->address = SENSOR_A3_OUTY; ++ acc->count = 1; ++ ++ if(ReadByte_ACC(adap, acc)) { ++ kfree(acc); ++ return -ENODEV; ++ } ++ ++ read_data = acc->data[0]; ++ if(put_user(read_data, (int __user *) arg)) { ++ kfree(acc); ++ return -EFAULT; ++ } ++ } else { ++ return -ENODEV; ++ } ++ ++ kfree(acc); ++ } ++ break; ++ ++ case BMI_SENSOR_ACCZRD: ++ { ++ struct sensor_acc_rw *acc = NULL; ++ unsigned int read_data; ++ ++ if(sensor->eeprom.accel_present != SENSOR_DEVICE_PRESENT) { ++ if ((acc = kmalloc(sizeof(struct sensor_acc_rw), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ ++ acc->address = SENSOR_ACC_DZ0; ++ acc->count = 2; ++ ++ if(ReadByte_ACC(adap, acc)) { ++ kfree(acc); ++ return -ENODEV; ++ } ++ ++ read_data = (acc->data[1] << 8) | acc->data[0]; ++ if(put_user(read_data, (int __user *) arg)) { ++ kfree(acc); ++ return -EFAULT; ++ } ++ } else if(sensor->eeprom.acc302_present == SENSOR_DEVICE_PRESENT) { ++ if ((acc = kmalloc(sizeof(struct sensor_acc_rw), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ ++ acc->address = SENSOR_A3_OUTZ; ++ acc->count = 1; ++ ++ if(ReadByte_ACC(adap, acc)) { ++ kfree(acc); ++ return -ENODEV; ++ } ++ ++ read_data = acc->data[0]; ++ if(put_user(read_data, (int __user *) arg)) { ++ kfree(acc); ++ return -EFAULT; ++ } ++ } else { ++ return -ENODEV; ++ } ++ ++ kfree(acc); ++ } ++ break; ++ ++ case BMI_SENSOR_ACC_I1WAIT: ++ { ++ if((sensor->eeprom.accel_present != SENSOR_DEVICE_PRESENT) ++ && (sensor->eeprom.acc302_present != SENSOR_DEVICE_PRESENT)) ++ return -ENODEV; ++ ++ ret = down_interruptible(&sensor->sem); ++ sensor->acc_int1_en = 1; ++ sensor->acc_int1_fl = 0; ++ up(&sensor->sem); ++ ret = wait_event_interruptible(sensor->acc_wait1_queue, (sensor->acc_int1_fl == 1)); ++ if(ret) ++ return ret; ++ } ++ break; ++ ++ case BMI_SENSOR_ACC_I2WAIT: ++ { ++ if((sensor->eeprom.accel_present != SENSOR_DEVICE_PRESENT) ++ && (sensor->eeprom.acc302_present != SENSOR_DEVICE_PRESENT)) ++ return -ENODEV; ++ ++ ret = down_interruptible(&sensor->sem); ++ sensor->acc_int2_en = 1; ++ sensor->acc_int2_fl = 0; ++ up(&sensor->sem); ++ ret = wait_event_interruptible(sensor->acc_wait2_queue, (sensor->acc_int2_fl == 1)); ++ if(ret) ++ return ret; ++ } ++ break; ++ ++ case BMI_SENSOR_EEWR: ++ { ++ struct sensor_rw *ee = NULL; ++ unsigned char ee_addr; ++ unsigned char ee_data; ++ ++ if ((ee = kmalloc(sizeof(struct sensor_rw), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ if (copy_from_user(ee, (struct sensor_rw *) arg, sizeof(struct sensor_rw))) { ++ kfree(ee); ++ return -EFAULT; ++ } ++ ++ ee_addr = ee->address; ++ ee_data = ee->data; ++ if(WriteByte_EE(adap, ee_addr, ee_data)) { ++ kfree(ee); ++ return -ENODEV; ++ } ++ ++ kfree(ee); ++ } ++ break; ++ ++ case BMI_SENSOR_EERD: ++ { ++ struct sensor_rw *ee = NULL; ++ unsigned char ee_addr; ++ unsigned char ee_data; ++ ++ if ((ee = kmalloc(sizeof(struct sensor_rw), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ if (copy_from_user(ee, (struct sensor_rw *) arg, sizeof(struct sensor_rw))) { ++ kfree(ee); ++ return -EFAULT; ++ } ++ ++ ee_addr = ee->address; ++ if(ReadByte_EE(adap, ee_addr, &ee_data)) { ++ kfree(ee); ++ return -ENODEV; ++ } ++ ++ ee->data = ee_data; ++ if(copy_to_user((struct sensor_rw *) arg, ee, sizeof(struct sensor_rw))) { ++ kfree(ee); ++ return -EFAULT; ++ } ++ ++ kfree(ee); ++ } ++ break; ++ ++ case BMI_SENSOR_MOT_IE: ++ { ++ if(sensor->eeprom.motion_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if(ReadByte_IOX(adap, IOX_OUTPUT0_REG, &iox_data)) ++ return -ENODEV; ++ ++ if(arg == BMI_SENSOR_ON) ++ iox_data |= (0x1 << SENSOR_IOX_MOT_EN); ++ else ++ iox_data &= ~(0x1 << SENSOR_IOX_MOT_EN); ++ ++ if(WriteByte_IOX(adap, IOX_OUTPUT0_REG, iox_data)) ++ return -ENODEV; ++ } ++ break; ++ ++ case BMI_SENSOR_USB_IWAIT: ++ { ++ ret = down_interruptible(&sensor->sem); ++ sensor->usb_int_en = 1; ++ sensor->usb_int_fl = 0; ++ up(&sensor->sem); ++ ret = wait_event_interruptible(sensor->usb_wait_queue, (sensor->usb_int_fl == 1)); ++ if(ret) ++ return ret; ++ } ++ break; ++ ++ case BMI_SENSOR_USB_PWR_EN: ++ { ++ if(ReadByte_IOX(adap, IOX_OUTPUT0_REG, &iox_data)) ++ return -ENODEV; ++ ++ if(arg == BMI_SENSOR_ON) ++ iox_data |= (0x1 << SENSOR_IOX_USB_EN); ++ else ++ iox_data &= ~(0x1 << SENSOR_IOX_USB_EN); ++ ++ if(WriteByte_IOX(adap, IOX_OUTPUT0_REG, iox_data)) ++ return -ENODEV; ++ } ++ break; ++ ++ case BMI_SENSOR_HUM_PWR_EN: ++ { ++ if(ReadByte_IOX(adap, IOX_OUTPUT0_REG, &iox_data)) ++ return -ENODEV; ++ ++ if(arg == BMI_SENSOR_ON) ++ iox_data |= (0x1 << SENSOR_IOX_HUM_EN); ++ else ++ iox_data &= ~(0x1 << SENSOR_IOX_HUM_EN); ++ ++ if(WriteByte_IOX(adap, IOX_OUTPUT0_REG, iox_data)) ++ return -ENODEV; ++ } ++ break; ++ ++ case BMI_SENSOR_DCOM_RST: ++ { ++ if(ReadByte_IOX(adap, IOX_OUTPUT0_REG, &iox_data)) ++ return -ENODEV; ++ ++ if(arg == BMI_SENSOR_ON) ++ iox_data |= (0x1 << SENSOR_IOX_COMP_RS_N); ++ else ++ iox_data &= ~(0x1 << SENSOR_IOX_COMP_RS_N); ++ ++ if(WriteByte_IOX(adap, IOX_OUTPUT0_REG, iox_data)) ++ return -ENODEV; ++ ++ } ++ break; ++ ++ case BMI_SENSOR_COM_GCAL: ++ { ++ struct sensor_comp_cal *cal = NULL; ++ unsigned char ee_datam; ++ unsigned char ee_datal; ++ ++ if ((cal = kmalloc(sizeof(struct sensor_comp_cal), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ ++ if(ReadByte_EE(adap, 0x0, &ee_datam)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ if(ReadByte_EE(adap, 0x1, &ee_datal)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ cal->xsf = (ee_datam << 8) | ee_datal; ++ ++ if(ReadByte_EE(adap, 0x2, &ee_datam)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ if(ReadByte_EE(adap, 0x3, &ee_datal)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ cal->ysf = (ee_datam << 8) | ee_datal; ++ ++ if(ReadByte_EE(adap, 0x4, &ee_datam)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ if(ReadByte_EE(adap, 0x5, &ee_datal)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ cal->zsf = (ee_datam << 8) | ee_datal; ++ ++ if(ReadByte_EE(adap, 0x6, &ee_datam)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ if(ReadByte_EE(adap, 0x7, &ee_datal)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ cal->xoff = (ee_datam << 8) | ee_datal; ++ ++ if(ReadByte_EE(adap, 0x8, &ee_datam)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ if(ReadByte_EE(adap, 0x9, &ee_datal)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ cal->yoff = (ee_datam << 8) | ee_datal; ++ ++ if(ReadByte_EE(adap, 0xA, &ee_datam)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ if(ReadByte_EE(adap, 0xB, &ee_datal)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ cal->zoff = (ee_datam << 8) | ee_datal; ++ ++ if(copy_to_user((struct sensor_comp_cal *) arg, cal, sizeof(struct sensor_comp_cal))) { ++ kfree(cal); ++ return -EFAULT; ++ } ++ ++ kfree(cal); ++ } ++ break; ++ ++ case BMI_SENSOR_COM_SCAL: ++ { ++ struct sensor_comp_cal *cal = NULL; ++ unsigned char ee_datam; ++ unsigned char ee_datal; ++ ++ if ((cal = kmalloc(sizeof(struct sensor_comp_cal), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ if (copy_from_user(cal, (struct sensor_comp_cal *) arg, sizeof(struct sensor_comp_cal))) { ++ kfree(cal); ++ return -EFAULT; ++ } ++ ++ sensor->comp_xsf = cal->xsf; ++ sensor->comp_ysf = cal->ysf; ++ sensor->comp_zsf = cal->zsf; ++ sensor->comp_xoff = cal->xoff; ++ sensor->comp_xoff = cal->xoff; ++ sensor->comp_zoff = cal->zoff; ++ ++ ee_datam = (unsigned char) ((cal->xsf >> 8) & 0xff); ++ ee_datal = (unsigned char) (cal->xsf & 0xff); ++ ++ if(WriteByte_EE(adap, 0x0, ee_datam)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ if(WriteByte_EE(adap, 0x1, ee_datal)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ ee_datam = (unsigned char) ((cal->ysf >> 8) & 0xff); ++ ee_datal = (unsigned char) (cal->ysf & 0xff); ++ ++ if(WriteByte_EE(adap, 0x2, ee_datam)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ if(WriteByte_EE(adap, 0x3, ee_datal)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ ee_datam = (unsigned char) ((cal->zsf >> 8) & 0xff); ++ ee_datal = (unsigned char) (cal->zsf & 0xff); ++ ++ if(WriteByte_EE(adap, 0x4, ee_datam)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ if(WriteByte_EE(adap, 0x5, ee_datal)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ ee_datam = (unsigned char) ((cal->xoff >> 8) & 0xff); ++ ee_datal = (unsigned char) (cal->xoff & 0xff); ++ ++ if(WriteByte_EE(adap, 0x6, ee_datam)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ if(WriteByte_EE(adap, 0x7, ee_datal)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ ee_datam = (unsigned char) ((cal->yoff >> 8) & 0xff); ++ ee_datal = (unsigned char) (cal->yoff & 0xff); ++ ++ if(WriteByte_EE(adap, 0x8, ee_datam)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ if(WriteByte_EE(adap, 0x9, ee_datal)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ ee_datam = (unsigned char) ((cal->zoff >> 8) & 0xff); ++ ee_datal = (unsigned char) (cal->zoff & 0xff); ++ ++ if(WriteByte_EE(adap, 0xA, ee_datam)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ if(WriteByte_EE(adap, 0xB, ee_datal)) { ++ kfree(cal); ++ return -ENODEV; ++ } ++ ++ kfree(cal); ++ } ++ break; ++ ++ case BMI_SENSOR_DCWR: ++ { ++ struct sensor_rw *dc = NULL; ++ unsigned char dc_addr; ++ unsigned char dc_data; ++ ++ if(sensor->eeprom.dcompass_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if ((dc = kmalloc(sizeof(struct sensor_rw), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ if (copy_from_user(dc, (struct sensor_rw *) arg, sizeof(struct sensor_rw))) { ++ kfree(dc); ++ return -EFAULT; ++ } ++ ++ dc_addr = dc->address; ++ dc_data = dc->data; ++ if(WriteByte_DCOMP(adap, dc_addr, dc_data)) { ++ kfree(dc); ++ return -ENODEV; ++ } ++ ++ kfree(dc); ++ } ++ break; ++ ++ case BMI_SENSOR_DCRD: ++ { ++ struct sensor_rw *dc = NULL; ++ unsigned char dc_addr; ++ unsigned char dc_data; ++ ++ if(sensor->eeprom.dcompass_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if ((dc = kmalloc(sizeof(struct sensor_rw), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ if (copy_from_user(dc, (struct sensor_rw *) arg, sizeof(struct sensor_rw))) { ++ kfree(dc); ++ return -EFAULT; ++ } ++ ++ dc_addr = dc->address; ++ if(ReadByte_DCOMP(adap, dc_addr, &dc_data)) { ++ kfree(dc); ++ return -ENODEV; ++ } ++ ++ dc->data = dc_data; ++ if(copy_to_user((struct sensor_rw *) arg, dc, sizeof(struct sensor_rw))) { ++ kfree(dc); ++ return -EFAULT; ++ } ++ ++ kfree(dc); ++ } ++ break; ++ ++ case BMI_SENSOR_DC_GDAC: ++ { ++ struct sensor_comp_dac *dac = NULL; ++ ++ if(sensor->eeprom.dcompass_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if ((dac = kmalloc(sizeof(struct sensor_comp_dac), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ ++ dac->xdac = sensor->eeprom.xdac; ++ dac->ydac = sensor->eeprom.ydac; ++ dac->zdac = sensor->eeprom.zdac; ++ ++ if(copy_to_user((struct sensor_comp_dac *) arg, dac, sizeof(struct sensor_comp_dac))) { ++ kfree(dac); ++ return -EFAULT; ++ } ++ ++ kfree(dac); ++ } ++ break; ++ ++ case BMI_SENSOR_DC_SDAC: ++ { ++ struct sensor_comp_dac *dac = NULL; ++ ++ if(sensor->eeprom.dcompass_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if ((dac = kmalloc(sizeof(struct sensor_comp_dac), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ if (copy_from_user(dac, (struct sensor_comp_dac *) arg, sizeof(struct sensor_comp_dac))) { ++ kfree(dac); ++ return -EFAULT; ++ } ++ ++ sensor->eeprom.xdac = dac->xdac; ++ sensor->eeprom.ydac = dac->ydac; ++ sensor->eeprom.zdac = dac->zdac; ++ ++ if(WriteByte_EE(adap, SENSOR_EE_XDAC, dac->xdac & 0xFF)) { ++ kfree(dac); ++ return -ENODEV; ++ } ++ mdelay(5); ++ ++ if(WriteByte_EE(adap, SENSOR_EE_YDAC, dac->ydac & 0xFF)) { ++ kfree(dac); ++ return -ENODEV; ++ } ++ mdelay(5); ++ ++ if(WriteByte_EE(adap, SENSOR_EE_ZDAC, dac->zdac & 0xFF)) { ++ kfree(dac); ++ return -ENODEV; ++ } ++ mdelay(5); ++ ++ kfree(dac); ++ } ++ break; ++ ++ case BMI_SENSOR_DC_IWAIT: ++ { ++ if(sensor->eeprom.dcompass_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ ret = down_interruptible(&sensor->sem); ++ sensor->dcomp_int_en = 1; ++ sensor->dcomp_int_fl = 0; ++ up(&sensor->sem); ++ ret = wait_event_interruptible(sensor->dcomp_wait_queue, (sensor->dcomp_int_fl == 1)); ++ if(ret) ++ return ret; ++ } ++ break; ++ ++ case BMI_SENSOR_APROX_DUR: ++ { ++ if(sensor->eeprom.aproximity_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if(arg < 2) ++ sensor->aprox_duration = HZ/50; ++ else if(arg > 100) ++ sensor->aprox_duration = HZ/10; ++ else ++ sensor->aprox_duration = (HZ/100) * arg; ++ } ++ break; ++ ++ case BMI_SENSOR_APROXRD: ++ { ++ unsigned char aprox_data[2]; ++ int read_data; ++ ++ if(sensor->eeprom.aproximity_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ // start burst to LED ++ if(ReadByte_IOX(adap, IOX_INPUT1_REG, &iox_data)) ++ return -ENODEV; ++ iox_data |= (0x1 << SENSOR_IOX_PROX_RST_N); ++ if(WriteByte_IOX(adap, IOX_OUTPUT1_REG, iox_data)) ++ return -ENODEV; ++ ++ // set up timer ++ sensor->aprox_timer.expires = jiffies + sensor->aprox_duration; ++ add_timer (&sensor->aprox_timer); ++ ++ // wait for timer ++ ret = down_interruptible(&sensor->sem); ++ sensor->aprox_int_en = 1; ++ sensor->aprox_int_fl = 0; ++ up(&sensor->sem); ++ ret = wait_event_interruptible(sensor->aprox_wait_queue, (sensor->aprox_int_fl == 1)); ++ if(ret) ++ return ret; ++ ++ if(ReadByte_IOX(adap, IOX_INPUT1_REG, &iox_data)) ++ return -ENODEV; ++ ++ // digital output ++ read_data = (iox_data & (0x1 << SENSOR_IOX_PROX_OUT)) << 14; ++ ++ // read ADC - analog output ++ if(WriteByte_ADC(adap, SENSOR_ADC_APROXIMITY | SENSOR_ADC_PD_OFF)) ++ return -ENODEV; ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, aprox_data)) ++ return -ENODEV; ++ read_data |= (aprox_data[0] << 8) | aprox_data[1]; ++ ++ // stop burst to LED ++ iox_data &= ~(0x1 << SENSOR_IOX_PROX_RST_N); ++ if(WriteByte_IOX(adap, IOX_OUTPUT1_REG, iox_data)) ++ return -ENODEV; ++ ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ } ++ break; ++ ++ case BMI_SENSOR_ALIGHTRD: ++ { ++ unsigned char adc_data[2]; ++ int read_data; ++ ++ if(sensor->eeprom.alight_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_LIGHT | SENSOR_ADC_PD_OFF)) ++ return -ENODEV; ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) ++ return -ENODEV; ++ read_data = ((adc_data[0] & SENSOR_ADC_DATA_MSB) << 8) | adc_data[1]; ++ ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ } ++ break; ++ ++ case BMI_SENSOR_DLIGHTWR: ++ { ++ struct sensor_dl_rw *dl = NULL; ++ unsigned char dl_data; ++ ++ if(sensor->eeprom.dlight_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if ((dl = kmalloc(sizeof(struct sensor_dl_rw), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ if (copy_from_user(dl, (struct sensor_dl_rw *) arg, sizeof(struct sensor_dl_rw))) { ++ kfree(dl); ++ return -EFAULT; ++ } ++ ++ dl_data = dl->cmd; ++ if(WriteByte_PL(adap, SENSOR_DL_CMD, dl_data)) { ++ kfree(dl); ++ return -ENODEV; ++ } ++ ++ dl_data = dl->control; ++ if(WriteByte_PL(adap, SENSOR_DL_CONT, dl_data)) { ++ kfree(dl); ++ return -ENODEV; ++ } ++ ++ dl_data = dl->int_thi; ++ if(WriteByte_PL(adap, SENSOR_DL_INT_THI, dl_data)) { ++ kfree(dl); ++ return -ENODEV; ++ } ++ ++ dl_data = dl->int_tlo; ++ if(WriteByte_PL(adap, SENSOR_DL_INT_TLO, dl_data)) { ++ kfree(dl); ++ return -ENODEV; ++ } ++ ++ kfree(dl); ++ } ++ break; ++ ++ case BMI_SENSOR_DLIGHTRD: ++ { ++ unsigned char dl_data; ++ unsigned int read_data; ++ ++ if(sensor->eeprom.dlight_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ // read sensor data ++ if(ReadByte_PL(adap, SENSOR_DL_SENSOR_MSB, &dl_data)) { ++ return -ENODEV; ++ } ++ read_data = ((unsigned int) (dl_data)) << 8; ++ ++ if(ReadByte_PL(adap, SENSOR_DL_SENSOR_LSB, &dl_data)) { ++ return -ENODEV; ++ } ++ read_data |= dl_data; ++ ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ } ++ break; ++ ++ case BMI_SENSOR_DLIGHT_IC: ++ { ++ if(sensor->eeprom.dlight_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if(WriteByte_DL_IC(adap)) ++ return -ENODEV; ++ } ++ break; ++ ++ case BMI_SENSOR_DLIGHT_IWAIT: ++ { ++ struct sensor_dl_rw *dl = NULL; ++ unsigned char dl_data; ++ unsigned int read_data; ++ ++ if(sensor->eeprom.dlight_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ // write all register ++ if ((dl = kmalloc(sizeof(struct sensor_dl_rw), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ if (copy_from_user(dl, (struct sensor_dl_rw *) arg, sizeof(struct sensor_dl_rw))) { ++ kfree(dl); ++ return -EFAULT; ++ } ++ ++ dl_data = dl->cmd; ++ if(WriteByte_PL(adap, SENSOR_DL_CMD, dl_data)) { ++ kfree(dl); ++ return -ENODEV; ++ } ++ ++ dl_data = dl->control; ++ if(WriteByte_PL(adap, SENSOR_DL_CONT, dl_data)) { ++ kfree(dl); ++ return -ENODEV; ++ } ++ ++ dl_data = dl->int_thi; ++ if(WriteByte_PL(adap, SENSOR_DL_INT_THI, dl_data)) { ++ kfree(dl); ++ return -ENODEV; ++ } ++ ++ dl_data = dl->int_tlo; ++ if(WriteByte_PL(adap, SENSOR_DL_INT_TLO, dl_data)) { ++ kfree(dl); ++ return -ENODEV; ++ } ++ ++ // enable interrupt ++ ret = down_interruptible(&sensor->sem); ++ sensor->dlight_int_en = 1; ++ sensor->dlight_int_fl = 0; ++ up(&sensor->sem); ++ // wait on interrupt ++ ret = wait_event_interruptible(sensor->dlight_wait_queue, (sensor->dlight_int_fl == 1)); ++ if(ret) ++ return ret; ++ ++ // read sensor data ++ if(ReadByte_PL(adap, SENSOR_DL_SENSOR_MSB, &dl_data)) { ++ return -ENODEV; ++ } ++ read_data = ((unsigned int) (dl_data)) << 8; ++ ++ if(ReadByte_PL(adap, SENSOR_DL_SENSOR_LSB, &dl_data)) { ++ return -ENODEV; ++ } ++ read_data |= dl_data; ++ dl->sensor_data = read_data; ++ ++ if(copy_to_user((struct sensor_dl_rw *) arg, dl, sizeof(struct sensor_dl_rw))) { ++ kfree(dl); ++ return -EFAULT; ++ } ++ ++ kfree(dl); ++ } ++ break; ++ ++ case BMI_SENSOR_MIC_EN: ++ { ++ if(sensor->eeprom.sound_present != SENSOR_DEVICE_PRESENT) ++ return -ENODEV; ++ ++ if(ReadByte_IOX(adap, IOX_OUTPUT1_REG, &iox_data)) ++ return -ENODEV; ++ ++ if(arg == BMI_SENSOR_ON) ++ iox_data |= (0x1 << SENSOR_IOX_MIC_EN); ++ else ++ iox_data &= ~(0x1 << SENSOR_IOX_MIC_EN); ++ ++ if(WriteByte_IOX(adap, IOX_OUTPUT1_REG, iox_data)) ++ return -ENODEV; ++ } ++ break; ++ ++ default: ++ return -ENOTTY; ++ } ++ ++ return 0; ++} ++ ++// control file operations ++struct file_operations cntl_fops = { ++ .owner = THIS_MODULE, ++ .ioctl = cntl_ioctl, ++ .open = cntl_open, ++ .release = cntl_release, ++}; ++ ++/* ++ * PIM functions ++ */ ++ ++// interrupt handler ++static void sensor_work_handler(struct work_struct * work) ++{ ++ struct bmi_sensor *sensor = work_to_sensor(work); ++ struct i2c_adapter *adap = bmi_device_get_i2c_adapter(sensor->bdev); ++ int slot = bmi_device_get_slot(sensor->bdev); ++ unsigned char iox0; ++ unsigned char iox1; ++ unsigned char i2c_dummy; ++ struct sensor_acc_rw acc_rw; ++ ++ if(ReadByte_IOX(adap, IOX_INPUT0_REG, &iox0)) { ++ printk(KERN_ERR "bmi_sensor.c: sensor_work_handler - IOX0 error\n"); ++ return; ++ } ++ ++ if(ReadByte_IOX(adap, IOX_INPUT1_REG, &iox1)) { ++ printk(KERN_ERR "bmi_sensor.c: sensor_work_handler - IOX1 error\n"); ++ return; ++ } ++ ++ if(sensor->eeprom.light_proximity_present == SENSOR_DEVICE_PRESENT) { ++ if(sensor->pl_int_en) { ++ if((iox1 & (0x1 << SENSOR_IOX_PL_INT)) == 0) { ++ sensor->pl_int_en = 0; ++ sensor->pl_int_fl = 1; ++ // clear interrupts ++ if(ReadByte_PL(adap, SENSOR_PL_CMD1, &i2c_dummy)) { ++ printk(KERN_ERR "bmi_sensor.c: PL read error\n"); ++ } ++ wake_up_all(&sensor->pl_wait_queue); ++ } ++ } ++ } ++ ++ if(sensor->eeprom.temperature_present == SENSOR_DEVICE_PRESENT) { ++ if(sensor->temp_int_en) { ++ if((iox1 & (0x1 << SENSOR_IOX_TEMP_INT)) == 0) { ++ sensor->temp_int_en = 0; ++ sensor->temp_int_fl = 1; ++ // disable interrupts ++ if(WriteByte_TEMP(adap, SENSOR_TEMP_CONF1_WR, SENSOR_TEMP_CONF1_STOP)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP write error\n"); ++ } ++ wake_up_all(&sensor->temp_wait_queue); ++ } ++ } ++ } ++ ++ if(sensor->eeprom.motion_present == SENSOR_DEVICE_PRESENT) { ++ if(sensor->mot_int_en) { ++ if(sensor->mot_state != bmi_slot_gpio_read_bit(slot, SENSOR_GPIO_MOT_DET)) { ++ sensor->mot_state = bmi_slot_gpio_read_bit(slot, SENSOR_GPIO_MOT_DET); ++ sensor->mot_int_en = 0; ++ sensor->mot_int_fl = 1; ++ wake_up_all(&sensor->mot_wait_queue); ++ } ++ } ++ } ++ ++ if((sensor->eeprom.accel_present == SENSOR_DEVICE_PRESENT) ++ || (sensor->eeprom.acc302_present == SENSOR_DEVICE_PRESENT)) { ++ if(sensor->acc_int1_en) { ++ if((iox0 & (0x1 << SENSOR_IOX_ACC_INT1)) == 0) { ++ sensor->acc_int1_en = 0; ++ sensor->acc_int1_fl = 1; ++ wake_up_all(&sensor->acc_wait1_queue); ++ } ++ } ++ ++ if(sensor->acc_int2_en) { ++ if((iox0 & (0x1 << SENSOR_IOX_ACC_INT2)) == 0) { ++ sensor->acc_int2_en = 0; ++ sensor->acc_int2_fl = 1; ++ wake_up_all(&sensor->acc_wait2_queue); ++ } ++ } ++ ++ if(sensor->eeprom.accel_present == SENSOR_DEVICE_PRESENT) { ++ // clear interrupts ++ acc_rw.address = SENSOR_ACC_IS; ++ acc_rw.count = 1; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC_IS read error\n"); ++ } ++ ++ acc_rw.address = SENSOR_ACC_DX0; ++ acc_rw.count = 2; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC read (DX0) error\n"); ++ } ++ ++ acc_rw.address = SENSOR_ACC_DY0; ++ acc_rw.count = 2; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC read (DY0) error\n"); ++ } ++ ++ acc_rw.address = SENSOR_ACC_DZ0; ++ acc_rw.count = 2; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC read (DZ0) error\n"); ++ } ++ } else { // LIS302DL ++ // clear interrupts ++ if(sensor->acc_int1_en) { ++ if((iox0 & (0x1 << SENSOR_IOX_ACC_INT1)) == 0) { ++ acc_rw.address = SENSOR_A3_SRC1; ++ acc_rw.count = 1; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: A3_SRC1 read error\n"); ++ } ++ } ++ } ++ ++ if(sensor->acc_int2_en) { ++ if((iox0 & (0x1 << SENSOR_IOX_ACC_INT2)) == 0) { ++ acc_rw.address = SENSOR_A3_SRC2; ++ acc_rw.count = 1; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: A3_SRC2 read error\n"); ++ } ++ } ++ } ++ ++ acc_rw.address = SENSOR_A3_STAT; ++ acc_rw.count = 1; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: A3_STAT read error\n"); ++ } ++ ++ acc_rw.address = SENSOR_A3_OUTX; ++ acc_rw.count = 1; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: A3 read (OUTX) error\n"); ++ } ++ ++ acc_rw.address = SENSOR_A3_OUTY; ++ acc_rw.count = 1; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: A3 read (OUTY) error\n"); ++ } ++ ++ acc_rw.address = SENSOR_A3_OUTZ; ++ acc_rw.count = 1; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: A3 read (OUTZ) error\n"); ++ } ++ } ++ } ++ ++ if(sensor->eeprom.dcompass_present == SENSOR_DEVICE_PRESENT) { ++ if(sensor->dcomp_int_en) { ++ if((iox1 & (0x1 << SENSOR_IOX_DCOMP_INT)) != 0) { ++ sensor->dcomp_int_en = 0; ++ sensor->dcomp_int_fl = 1; ++ // clear interrupts ++ if(ReadByte_DCOMP(adap, SENSOR_DCOMP_TMPS, &i2c_dummy)) { ++ printk(KERN_ERR "bmi_sensor.c: TMPS error\n"); ++ } ++ ++ wake_up_all(&sensor->dcomp_wait_queue); ++ } ++ } ++ } ++ ++ if(sensor->eeprom.dlight_present == SENSOR_DEVICE_PRESENT) { ++ if(sensor->dlight_int_en) { ++ if((iox1 & (0x1 << SENSOR_IOX_PL_INT)) == 0) { ++ sensor->dlight_int_en = 0; ++ sensor->dlight_int_fl = 1; ++ // clear interrupts ++ if(ReadByte_PL(adap, SENSOR_DL_CONT, &i2c_dummy)) { ++ printk(KERN_ERR "bmi_sensor.c: DL read error\n"); ++ } ++ i2c_dummy &= ~(SENSOR_DL_CONT_INT); ++ if(WriteByte_PL(adap, SENSOR_DL_CONT, i2c_dummy)) { ++ printk(KERN_ERR "bmi_sensor.c: DL write error\n"); ++ } ++ if(WriteByte_DL_IC(adap)) { ++ printk(KERN_ERR "bmi_sensor.c: DL interrupt clear error\n"); ++ } ++ wake_up_all(&sensor->pl_wait_queue); ++ } ++ } ++ } ++ ++ ++ if((iox0 & (0x1 << SENSOR_IOX_USB_FL_N)) == 0) { ++ sensor->usb_int_en = 0; ++ sensor->usb_int_fl = 1; ++ // disable USB power ++ if(ReadByte_IOX(adap, IOX_INPUT0_REG, &i2c_dummy)) // clear IOX interrupts ++ printk(KERN_ERR "bmi_sensor.c: USB IOX read error\n"); ++ wake_up_all(&sensor->usb_wait_queue); ++ } ++ ++ return; ++} ++ ++static irqreturn_t module_irq_handler(int irq, void *dummy) ++{ ++ struct bmi_sensor *sensor = (struct bmi_sensor *) dummy; ++ ++ schedule_work (&sensor->work_item); ++ return IRQ_HANDLED; ++} ++ ++/* ++ * BMI functions ++ */ ++ ++/*------------------------------------- ++ * ++ * bmi device sysfs attributes ++ * ++ *------------------------------------- ++ */ ++ ++static ssize_t show_humidity(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct bmi_device *bdev = dev_to_bmi_device(dev); ++ struct i2c_adapter *adap = bmi_device_get_i2c_adapter(bdev); ++ unsigned char adc_data[2]; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_HUMIDITY)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC write error\n"); ++ } ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read error\n"); ++ } ++ ++ return sprintf(buf, "0x%x\n", (adc_data[0] << 8) | adc_data[1]); ++} ++static DEVICE_ATTR(humidity, S_IRUGO, show_humidity, NULL); ++ ++static ssize_t show_acompass(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct bmi_device *bdev = dev_to_bmi_device(dev); ++ struct i2c_adapter *adap = bmi_device_get_i2c_adapter(bdev); ++ unsigned char adc_data[2]; ++ unsigned int compass_x; ++ unsigned int compass_y; ++ unsigned int compass_z; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_ACOMPASS_X)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC write error\n"); ++ } ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read error\n"); ++ } ++ compass_x = (adc_data[0] << 8) | adc_data[1]; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_ACOMPASS_Y)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC write error\n"); ++ } ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read error\n"); ++ } ++ compass_y = (adc_data[0] << 8) | adc_data[1]; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_ACOMPASS_Z)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC write error\n"); ++ } ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read error\n"); ++ } ++ compass_z = (adc_data[0] << 8) | adc_data[1]; ++ ++ return sprintf(buf, "X=0x%x\nY=0x%x\nZ=0x%x\n", ++ compass_x, compass_y, compass_z); ++} ++static DEVICE_ATTR(acompass, S_IRUGO, show_acompass, NULL); ++ ++static ssize_t show_dcompass(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct bmi_device *bdev = dev_to_bmi_device(dev); ++ struct i2c_adapter *adap = bmi_device_get_i2c_adapter(bdev); ++ unsigned char compass_i; ++ unsigned char compass_t; ++ unsigned char compass_x; ++ unsigned char compass_y; ++ unsigned char compass_z; ++ ++ if(WriteByte_DCOMP(adap, SENSOR_DCOMP_MS1, SENSOR_DCOMP_MS1_SENSOR)) { ++ printk(KERN_ERR "bmi_sensor.c: DCOMP MS1 write error\n"); ++ } ++ ++ mdelay(20); ++ ++ if(ReadByte_DCOMP(adap, SENSOR_DCOMP_ST, &compass_i)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read error\n"); ++ } ++ if((compass_i & SENSOR_DCOMP_ST_INT) == 0) { ++ printk(KERN_ERR "bmi_sensor.c: DCOMP interrupt error\n"); ++ } ++ ++ if(ReadByte_DCOMP(adap, SENSOR_DCOMP_TMPS, &compass_t)) { ++ printk(KERN_ERR "bmi_sensor.c: TMPS error\n"); ++ } ++ ++ if(ReadByte_DCOMP(adap, SENSOR_DCOMP_H1X, &compass_x)) { ++ printk(KERN_ERR "bmi_sensor.c: H1X error\n"); ++ } ++ ++ if(ReadByte_DCOMP(adap, SENSOR_DCOMP_H1Y, &compass_y)) { ++ printk(KERN_ERR "bmi_sensor.c: H1Y error\n"); ++ } ++ ++ if(ReadByte_DCOMP(adap, SENSOR_DCOMP_H1Z, &compass_z)) { ++ printk(KERN_ERR "bmi_sensor.c: H1Z error\n"); ++ } ++ ++ return sprintf(buf, "T=0x%x\nX=0x%x\nY=0x%x\nZ=0x%x\n", ++ compass_t, compass_x, compass_y, compass_z); ++} ++static DEVICE_ATTR(dcompass, S_IRUGO, show_dcompass, NULL); ++ ++static ssize_t show_als(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct bmi_device *bdev = dev_to_bmi_device(dev); ++ struct i2c_adapter *adap = bmi_device_get_i2c_adapter(bdev); ++ unsigned char pl_data[2]; ++ ++ if(WriteByte_PL(adap, SENSOR_PL_CMD1, SENSOR_PL_CMD1_ALS_1X)) { ++ printk(KERN_ERR "bmi_sensor.c: PL write error\n"); ++ } ++ ++ mdelay(20); ++ ++ if(ReadByte_PL(adap, SENSOR_PL_DATA_MSB, &pl_data[0])) { ++ printk(KERN_ERR "bmi_sensor.c: PL read error\n"); ++ } ++ ++ if(ReadByte_PL(adap, SENSOR_PL_DATA_LSB, &pl_data[1])) { ++ printk(KERN_ERR "bmi_sensor.c: PL read error\n"); ++ } ++ ++ return sprintf(buf, "0x%x\n", (pl_data[0] << 8) | pl_data[1]); ++} ++static DEVICE_ATTR(als, S_IRUGO, show_als, NULL); ++ ++static ssize_t show_ir(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct bmi_device *bdev = dev_to_bmi_device(dev); ++ struct i2c_adapter *adap = bmi_device_get_i2c_adapter(bdev); ++ unsigned char pl_data[2]; ++ ++ if(WriteByte_PL(adap, SENSOR_PL_CMD1, SENSOR_PL_CMD1_IR_1X)) { ++ printk(KERN_ERR "bmi_sensor.c: PL write error\n"); ++ } ++ ++ mdelay(20); ++ ++ if(ReadByte_PL(adap, SENSOR_PL_DATA_MSB, &pl_data[0])) { ++ printk(KERN_ERR "bmi_sensor.c: PL read error\n"); ++ } ++ ++ if(ReadByte_PL(adap, SENSOR_PL_DATA_LSB, &pl_data[1])) { ++ printk(KERN_ERR "bmi_sensor.c: PL read error\n"); ++ } ++ ++ return sprintf(buf, "0x%x\n", (pl_data[0] << 8) | pl_data[1]); ++} ++static DEVICE_ATTR(ir, S_IRUGO, show_ir, NULL); ++ ++static ssize_t show_proximity(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct bmi_device *bdev = dev_to_bmi_device(dev); ++ struct i2c_adapter *adap = bmi_device_get_i2c_adapter(bdev); ++ unsigned char pl_data[2]; ++ ++ if(WriteByte_PL(adap, SENSOR_PL_CMD1, SENSOR_PL_CMD1_PROX_1X)) { ++ printk(KERN_ERR "bmi_sensor.c: PL write error\n"); ++ } ++ ++ mdelay(20); ++ ++ if(ReadByte_PL(adap, SENSOR_PL_DATA_MSB, &pl_data[0])) { ++ printk(KERN_ERR "bmi_sensor.c: PL read error\n"); ++ } ++ ++ if(ReadByte_PL(adap, SENSOR_PL_DATA_LSB, &pl_data[1])) { ++ printk(KERN_ERR "bmi_sensor.c: PL read error\n"); ++ } ++ ++ return sprintf(buf, "0x%x\n", (pl_data[0] << 8) | pl_data[1]); ++} ++static DEVICE_ATTR(proximity, S_IRUGO, show_proximity, NULL); ++ ++static ssize_t show_snda(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct bmi_device *bdev = dev_to_bmi_device(dev); ++ struct i2c_adapter *adap = bmi_device_get_i2c_adapter(bdev); ++ unsigned char adc_data[2]; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_SOUND_AVG)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC write error\n"); ++ } ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read error\n"); ++ } ++ ++ return sprintf(buf, "0x%x\n", (adc_data[0] << 8) | adc_data[1]); ++} ++static DEVICE_ATTR(sound_avg, S_IRUGO, show_snda, NULL); ++ ++static ssize_t show_sndp(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct bmi_device *bdev = dev_to_bmi_device(dev); ++ struct i2c_adapter *adap = bmi_device_get_i2c_adapter(bdev); ++ unsigned char adc_data[2]; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_SOUND_PEAK)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC write error\n"); ++ } ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read error\n"); ++ } ++ ++ return sprintf(buf, "0x%x\n", (adc_data[0] << 8) | adc_data[1]); ++} ++static DEVICE_ATTR(sound_peak, S_IRUGO, show_sndp, NULL); ++ ++static ssize_t show_temp_l(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct bmi_device *bdev = dev_to_bmi_device(dev); ++ struct i2c_adapter *adap = bmi_device_get_i2c_adapter(bdev); ++ unsigned char temp_datam; ++ unsigned char temp_datal; ++ ++ if(WriteByte_TEMP(adap, SENSOR_TEMP_CONF1_WR, SENSOR_TEMP_CONF1_STOP)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP write (CONF1) error\n"); ++ } ++ ++ if(WriteByte_TEMP(adap, SENSOR_TEMP_ONE_SHOT, 0x0)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP write (CONF1) error\n"); ++ } ++ ++ mdelay(400); ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_LOC_MSB, &temp_datam)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP read (LOCAL MSB) error\n"); ++ } ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_LOC_LSB, &temp_datal)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP read (LOCAL LSB) error\n"); ++ } ++ ++ return sprintf(buf, "0x%x\n", (temp_datam << 8) | temp_datal); ++} ++static DEVICE_ATTR(temp_local, S_IRUGO, show_temp_l, NULL); ++ ++static ssize_t show_temp_sr(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct bmi_device *bdev = dev_to_bmi_device(dev); ++ struct i2c_adapter *adap = bmi_device_get_i2c_adapter(bdev); ++ unsigned char temp_datam; ++ unsigned char temp_datal; ++ ++ if(WriteByte_TEMP(adap, SENSOR_TEMP_CONF1_WR, SENSOR_TEMP_CONF1_STOP)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP write (CONF1) error\n"); ++ } ++ ++ if(WriteByte_TEMP(adap, SENSOR_TEMP_ONE_SHOT, 0x0)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP write (CONF1) error\n"); ++ } ++ ++ mdelay(400); ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_REM_MSB, &temp_datam)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP read (REM MSB) error\n"); ++ } ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_REM_LSB, &temp_datal)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP read (REM LSB) error\n"); ++ } ++ ++ return sprintf(buf, "0x%x\n", (temp_datam << 8) | temp_datal); ++} ++static DEVICE_ATTR(temp_sremote, S_IRUGO, show_temp_sr, NULL); ++ ++static ssize_t show_temp_ur(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct bmi_device *bdev = dev_to_bmi_device(dev); ++ struct i2c_adapter *adap = bmi_device_get_i2c_adapter(bdev); ++ unsigned char temp_datam; ++ unsigned char temp_datal; ++ ++ if(WriteByte_TEMP(adap, SENSOR_TEMP_CONF1_WR, SENSOR_TEMP_CONF1_STOP)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP write (CONF1) error\n"); ++ } ++ ++ if(WriteByte_TEMP(adap, SENSOR_TEMP_ONE_SHOT, 0x0)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP write (CONF1) error\n"); ++ } ++ ++ mdelay(400); ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_UREM_MSB, &temp_datam)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP read (UREM MSB) error\n"); ++ } ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_UREM_LSB, &temp_datal)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP read (UREM LSB) error\n"); ++ } ++ ++ return sprintf(buf, "0x%x\n", (temp_datam << 8) | temp_datal); ++} ++static DEVICE_ATTR(temp_uremote, S_IRUGO, show_temp_ur, NULL); ++ ++static ssize_t show_motion(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct bmi_device *bdev = dev_to_bmi_device(dev); ++ int slot = bmi_device_get_slot(bdev); ++ ++ return sprintf(buf, "0x%x\n", bmi_slot_gpio_read_bit(slot, SENSOR_GPIO_MOT_DET)); ++} ++static DEVICE_ATTR(motion, S_IRUGO, show_motion, NULL); ++ ++static ssize_t show_accel(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct bmi_device *bdev = dev_to_bmi_device(dev); ++ int slot = bmi_device_get_slot(bdev); ++ struct i2c_adapter *adap = bmi_device_get_i2c_adapter(bdev); ++ struct sensor_acc_rw acc_rw; ++ int x; ++ int y; ++ int z; ++ ++ if(bmi_sensor[slot].eeprom.accel_present != SENSOR_DEVICE_PRESENT) { ++ acc_rw.address = SENSOR_ACC_DX0; ++ acc_rw.count = 2; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC read (DX0) error\n"); ++ } ++ x = (acc_rw.data[0] << 8) | acc_rw.data[1]; ++ ++ acc_rw.address = SENSOR_ACC_DY0; ++ acc_rw.count = 2; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC read (DY0) error\n"); ++ } ++ y = (acc_rw.data[0] << 8) | acc_rw.data[1]; ++ ++ acc_rw.address = SENSOR_ACC_DZ0; ++ acc_rw.count = 2; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC read (DZ0) error\n"); ++ } ++ z = (acc_rw.data[0] << 8) | acc_rw.data[1]; ++ } else { ++ acc_rw.address = SENSOR_A3_OUTX; ++ acc_rw.count = 1; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC read (OUTX) error\n"); ++ } ++ x = acc_rw.data[0]; ++ ++ acc_rw.address = SENSOR_A3_OUTY; ++ acc_rw.count = 1; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC read (OUTY) error\n"); ++ } ++ y = acc_rw.data[0]; ++ ++ acc_rw.address = SENSOR_A3_OUTZ; ++ acc_rw.count = 1; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC read (OUTZ) error\n"); ++ } ++ z = acc_rw.data[0]; ++ } ++ return sprintf(buf, "X=0x%x\nY=0x%x\nZ=0x%x\n", x, y, z); ++} ++static DEVICE_ATTR(accel, S_IRUGO, show_accel, NULL); ++ ++static ssize_t show_aprox(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct bmi_device *bdev = dev_to_bmi_device(dev); ++ int slot = bmi_device_get_slot(bdev); ++ struct bmi_sensor *sensor = &bmi_sensor[slot]; ++ struct i2c_adapter *adap = bmi_device_get_i2c_adapter(bdev); ++ unsigned int read_data; ++ unsigned char iox_data; ++ unsigned char aprox_data; ++ int ret; ++ ++ // start burst to LED ++ if(ReadByte_IOX(adap, IOX_INPUT1_REG, &iox_data)) ++ printk(KERN_ERR "bmi_sensor.c: IOX read error\n"); ++ iox_data |= (0x1 << SENSOR_IOX_PROX_RST_N); ++ if(WriteByte_IOX(adap, IOX_OUTPUT1_REG, iox_data)) ++ printk(KERN_ERR "bmi_sensor.c: IOX write error\n"); ++ ++ // set up timer ++ sensor->aprox_timer.expires = jiffies + sensor->aprox_duration; ++ add_timer (&sensor->aprox_timer); ++ ++ // wait for timer ++ ret = down_interruptible(&sensor->sem); ++ sensor->aprox_int_en = 1; ++ sensor->aprox_int_fl = 0; ++ up(&sensor->sem); ++ wait_event_interruptible(sensor->aprox_wait_queue, (sensor->aprox_int_fl == 1)); ++ ++ // stop burst to LED ++ if(ReadByte_IOX(adap, IOX_INPUT1_REG, &iox_data)) ++ printk(KERN_ERR "bmi_sensor.c: IOX read error\n"); ++ iox_data &= ~(0x1 << SENSOR_IOX_PROX_RST_N); ++ if(WriteByte_IOX(adap, IOX_OUTPUT1_REG, iox_data)) ++ printk(KERN_ERR "bmi_sensor.c: IOX write error\n"); ++ ++ // digital output ++ read_data = (iox_data & (0x1 << SENSOR_IOX_PROX_OUT)) << 14; ++ ++ // read ADC - analog output ++ if(WriteByte_ADC(adap, SENSOR_ADC_APROXIMITY | SENSOR_ADC_PD_OFF)) ++ printk(KERN_ERR "bmi_sensor.c: IOX write error\n"); ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, &aprox_data)) ++ printk(KERN_ERR "bmi_sensor.c: IOX read error\n"); ++ read_data |= aprox_data; ++ ++ return sprintf(buf, "Analog Proxiimity = 0x%x\n", read_data); ++} ++static DEVICE_ATTR(aprox, S_IRUGO, show_aprox, NULL); ++ ++static ssize_t show_alight(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct bmi_device *bdev = dev_to_bmi_device(dev); ++ struct i2c_adapter *adap = bmi_device_get_i2c_adapter(bdev); ++ unsigned char adc_data[2]; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_LIGHT)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC write error\n"); ++ } ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read error\n"); ++ } ++ ++ return sprintf(buf, "0x%x\n", (adc_data[0] << 8) | adc_data[1]); ++} ++static DEVICE_ATTR(alight, S_IRUGO, show_alight, NULL); ++ ++static ssize_t show_dlight(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct bmi_device *bdev = dev_to_bmi_device(dev); ++ struct i2c_adapter *adap = bmi_device_get_i2c_adapter(bdev); ++ unsigned char dl_data[2]; ++ ++ if(ReadByte_PL(adap, SENSOR_DL_SENSOR_MSB, &dl_data[0])) { ++ printk(KERN_ERR "bmi_sensor.c: DL read error\n"); ++ } ++ ++ if(ReadByte_PL(adap, SENSOR_DL_SENSOR_LSB, &dl_data[1])) { ++ printk(KERN_ERR "bmi_sensor.c: DL read error\n"); ++ } ++ ++ return sprintf(buf, "0x%x\n", (dl_data[0] << 8) | dl_data[1]); ++} ++static DEVICE_ATTR(dlight, S_IRUGO, show_dlight, NULL); ++ ++ ++// read calibration/equipage EEPROM ++int read_eeprom(struct i2c_adapter *adap, struct sensor_eeprom_raw *eeprom) ++{ ++ unsigned char ee_data; ++ ++ if(ReadByte_EE(adap, 0x0, &ee_data)) ++ return -ENODEV; ++ eeprom->xsf_msb = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x1, &ee_data)) ++ return -ENODEV; ++ eeprom->xsf_lsb = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x2, &ee_data)) ++ return -ENODEV; ++ eeprom->ysf_msb = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x3, &ee_data)) ++ return -ENODEV; ++ eeprom->ysf_lsb = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x4, &ee_data)) ++ return -ENODEV; ++ eeprom->zsf_msb = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x5, &ee_data)) ++ return -ENODEV; ++ eeprom->zsf_lsb = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x6, &ee_data)) ++ return -ENODEV; ++ eeprom->xoff_msb = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x7, &ee_data)) ++ return -ENODEV; ++ eeprom->xoff_lsb = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x8, &ee_data)) ++ return -ENODEV; ++ eeprom->yoff_msb = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x9, &ee_data)) ++ return -ENODEV; ++ eeprom->zoff_lsb = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0xA, &ee_data)) ++ return -ENODEV; ++ eeprom->zoff_msb = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0xB, &ee_data)) ++ return -ENODEV; ++ eeprom->yoff_lsb = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0xC, &ee_data)) ++ return -ENODEV; ++ eeprom->xdac = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0xD, &ee_data)) ++ return -ENODEV; ++ eeprom->ydac = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0xE, &ee_data)) ++ return -ENODEV; ++ eeprom->zdac = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0xF, &ee_data)) ++ return -ENODEV; ++ eeprom->adc_present = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x10, &ee_data)) ++ return -ENODEV; ++ eeprom->humidity_present = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x11, &ee_data)) ++ return -ENODEV; ++ eeprom->acompass_present = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x12, &ee_data)) ++ return -ENODEV; ++ eeprom->light_proximity_present = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x13, &ee_data)) ++ return -ENODEV; ++ eeprom->sound_present = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x14, &ee_data)) ++ return -ENODEV; ++ eeprom->temperature_present = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x15, &ee_data)) ++ return -ENODEV; ++ eeprom->motion_present = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x16, &ee_data)) ++ return -ENODEV; ++ eeprom->accel_present = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x17, &ee_data)) ++ return -ENODEV; ++ eeprom->dcompass_present = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x18, &ee_data)) ++ return -ENODEV; ++ eeprom->aproximity_present = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x19, &ee_data)) ++ return -ENODEV; ++ eeprom->alight_present = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x1A, &ee_data)) ++ return -ENODEV; ++ eeprom->dlight_present = (__u8) ee_data; ++ ++ if(ReadByte_EE(adap, 0x1B, &ee_data)) ++ return -ENODEV; ++ eeprom->acc302_present = (__u8) ee_data; ++ ++ return 0; ++} ++ ++// probe - insert PIM ++int bmi_sensor_probe(struct bmi_device *bdev) ++{ ++ int err = 0; ++ int slot = bmi_device_get_slot(bdev); ++ struct bmi_sensor *sensor = &bmi_sensor[slot]; ++ struct i2c_adapter *adap = bmi_device_get_i2c_adapter(bdev); ++ struct cdev *cdev; ++ struct class *bmi_class; ++ dev_t dev_id; ++ int irq; ++ unsigned char iox_data; ++ ++ sensor->bdev = 0; ++ ++ // Create 1 minor device ++ cdev = &sensor->cdev; ++ cdev_init(cdev, &cntl_fops); ++ ++ dev_id = MKDEV(major, slot); ++ err = cdev_add(cdev, dev_id, 1); ++ if(err) { ++ return err; ++ } ++ ++ // Create class device ++ bmi_class = bmi_get_bmi_class(); ++ sensor->class_dev = device_create(bmi_class, NULL, ++ MKDEV(major, slot), NULL, ++ "bmi_sensor_cntl_m%i", slot+1); ++ ++ if(IS_ERR(sensor->class_dev)) { ++ printk(KERN_ERR "Unable to create " ++ "class_device for bmi_sensor_cntl_m%i; errno = %ld\n", ++ slot+1, PTR_ERR(sensor->class_dev)); ++ goto error; ++ } ++ ++ // bind driver and bmi_device ++ sensor->bdev = bdev; ++ bmi_device_set_drvdata(bdev, sensor); ++ ++ printk(KERN_INFO "bmi_sensor.c: probe slot %d\n", slot); ++ ++ // configure IOX ++ if(factory_test || fcc_test) { ++ if(WriteByte_IOX(adap, IOX_OUTPUT0_REG, 0x98)) { // USB/HUM on, MOT_INT off, COMPASS RST High ++ printk(KERN_ERR "bmi_sensor.c: IOX error in slot %d\n", slot); ++ goto error; ++ } ++ ++ if(WriteByte_IOX(adap, IOX_OUTPUT1_REG, 0x08)) { // Speaker Peak Clear, all other outputs low ++ printk(KERN_ERR "bmi_sensor.c: IOX error in slot %d\n", slot); ++ goto error; ++ } ++ } else { ++ if(WriteByte_IOX(adap, IOX_OUTPUT0_REG, 0x80)) { // USB/HUM/MOT_INT off, COMPASS RST High ++ printk(KERN_ERR "bmi_sensor.c: IOX error in slot %d\n", slot); ++ goto error; ++ } ++ ++ if(WriteByte_IOX(adap, IOX_OUTPUT1_REG, 0x0A)) { // Speaker Peak Clear/analog proximity enable high, all other outputs low ++ printk(KERN_ERR "bmi_sensor.c: IOX error in slot %d\n", slot); ++ goto error; ++ } ++ } ++ ++ if(WriteByte_IOX(adap, IOX_CONTROL0_REG, 0x27)) { // IOX[5,2:0]=IN, IOX[7:6,4:3]=OUT ++ printk(KERN_ERR "bmi_sensor.c: IOX error in slot %d\n", slot); ++ goto error; ++ } ++ ++ if(WriteByte_IOX(adap, IOX_CONTROL1_REG, 0xb4)) { // IOX[7,5:4,2]=IN, IOX[6,3,1:0]=OUT ++ printk(KERN_ERR "bmi_sensor.c: IOX error in slot %d\n", slot); ++ goto error; ++ } ++ ++ // Initialize GPIOs (turn LED's on) ++ bmi_slot_gpio_configure_as_output(slot, SENSOR_GPIO_RED_LED, SENSOR_GPIO_LED_ON); // Red LED=ON ++ bmi_slot_gpio_configure_as_output(slot, SENSOR_GPIO_GREEN_LED, SENSOR_GPIO_LED_ON); // Green LED=ON ++ bmi_slot_gpio_configure_as_input(slot, SENSOR_GPIO_PDOUT); // proximity real-time state ++ bmi_slot_gpio_configure_as_input(slot, SENSOR_GPIO_MOT_DET); // motion real-time state ++ ++ mdelay(200); ++ ++ // turn LED's off ++ bmi_slot_gpio_write_bit(slot, SENSOR_GPIO_RED_LED, SENSOR_GPIO_LED_OFF); // Red LED=OFF ++ bmi_slot_gpio_write_bit(slot, SENSOR_GPIO_GREEN_LED, SENSOR_GPIO_LED_OFF); // Green LED=OFF ++ ++ // bmi_sensor initialization ++ init_MUTEX(&sensor->sem); ++ sprintf(sensor->work_name, "sensor_m%d", slot + 1); ++ init_waitqueue_head(&sensor->pl_wait_queue); ++ sensor->pl_int_en = 0; ++ sensor->pl_int_fl = 0; ++ init_waitqueue_head(&sensor->temp_wait_queue); ++ sensor->temp_int_en = 0; ++ sensor->temp_int_fl = 0; ++ init_waitqueue_head(&sensor->mot_wait_queue); ++ sensor->mot_int_en = 0; ++ sensor->mot_int_fl = 0; ++ sensor->mot_state = bmi_slot_gpio_read_bit(slot, SENSOR_GPIO_MOT_DET); // initial motion detector state ++ init_waitqueue_head(&sensor->acc_wait1_queue); ++ sensor->acc_int1_en = 0; ++ sensor->acc_int1_fl = 0; ++ init_waitqueue_head(&sensor->acc_wait2_queue); ++ sensor->acc_int2_en = 0; ++ sensor->acc_int2_fl = 0; ++ init_waitqueue_head(&sensor->usb_wait_queue); ++ sensor->usb_int_en = 0; ++ sensor->usb_int_fl = 0; ++ init_waitqueue_head(&sensor->dcomp_wait_queue); ++ sensor->dcomp_int_en = 0; ++ sensor->dcomp_int_fl = 0; ++ sensor->aprox_duration = 200; ++ init_timer(&sensor->aprox_timer); ++ sensor->aprox_timer.data = (unsigned long) &bmi_sensor[slot]; ++ sensor->aprox_timer.function = aptimer; ++ init_waitqueue_head(&sensor->aprox_wait_queue); ++ sensor->aprox_int_en = 0; ++ sensor->aprox_int_fl = 0; ++ ++ sensor->workqueue = create_singlethread_workqueue(sensor->work_name); ++ if (!sensor->workqueue) { ++ printk(KERN_ERR "bmi_sensor.c: Can't create_singlethread_workqueue() in slot %d\n", ++ slot); ++ goto error; ++ } ++ INIT_WORK(&sensor->work_item, sensor_work_handler); ++ ++ // initialize EEPROM for presence ++ if(factory_test && eeprom_init) { ++ unsigned char addr = SENSOR_PRESENT_START; ++ ++ // presence ++ while(addr <= SENSOR_PRESENT_END) { ++ if(eeprom_init & 0x1) { ++ WriteByte_EE(adap, addr++, SENSOR_DEVICE_PRESENT); ++ } else { ++ WriteByte_EE(adap, addr++, SENSOR_DEVICE_NOT_PRESENT); ++ } ++ eeprom_init = eeprom_init >> 1; ++ mdelay(5); ++ } ++ } ++ ++ if(factory_test && xdac_init) { ++ WriteByte_EE(adap, SENSOR_EE_XDAC, xdac_init & 0xFF); ++ mdelay(5); ++ } ++ ++ if(factory_test && ydac_init) { ++ WriteByte_EE(adap, SENSOR_EE_YDAC, ydac_init & 0xFF); ++ mdelay(5); ++ } ++ ++ if(factory_test && zdac_init) { ++ WriteByte_EE(adap, SENSOR_EE_ZDAC, zdac_init & 0xFF); ++ mdelay(5); ++ } ++ ++ // read EEPROM for calibration/presence ++ if(read_eeprom(adap, &sensor->eeprom)) { ++ printk(KERN_ERR "bmi_sensor.c: Can't read calibration EEPROM in slot %d\n", ++ slot); ++ goto error; ++ } ++ ++ sensor->comp_xsf = (sensor->eeprom.xsf_msb << 8) | sensor->eeprom.xsf_lsb; ++ sensor->comp_ysf = (sensor->eeprom.ysf_msb << 8) | sensor->eeprom.ysf_lsb; ++ sensor->comp_zsf = (sensor->eeprom.zsf_msb << 8) | sensor->eeprom.zsf_lsb; ++ sensor->comp_xoff = (sensor->eeprom.xoff_msb << 8) | sensor->eeprom.xoff_lsb; ++ sensor->comp_yoff = (sensor->eeprom.yoff_msb << 8) | sensor->eeprom.yoff_lsb; ++ sensor->comp_zoff = (sensor->eeprom.zoff_msb << 8) | sensor->eeprom.zoff_lsb; ++ ++ if(sensor->eeprom.adc_present == SENSOR_DEVICE_PRESENT) { ++ unsigned char adc_data[2]; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_CH0)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC write error\n"); ++ goto error; ++ } ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read error\n"); ++ goto error; ++ } ++ ++ if((adc_data[0] & 0xF0) != 0x0) { ++ printk(KERN_ERR "bmi_sensor.c: ADC compare error\n"); ++ goto error; ++ } ++ ++ if(factory_test == 1) { ++ printk(KERN_INFO "bmi_sensor.c: ADC present in slot %d\n", slot); ++ } ++ } ++ ++ if(sensor->eeprom.humidity_present == SENSOR_DEVICE_PRESENT) { ++ unsigned char adc_data[2]; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_HUMIDITY)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC write (Humidity) error\n"); ++ goto error; ++ } ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read (Humidity) error\n"); ++ goto error; ++ } ++ ++ printk(KERN_INFO "bmi_sensor.c: initial Humidity = %d\n", ++ (adc_data[0] << 8) | adc_data[1]); ++ ++ if(device_create_file(&sensor->bdev->dev, &dev_attr_humidity)) { ++ printk (KERN_ERR ++ "bmi_sensor.c (%d): attr (humidity) failed.\n", ++ slot); ++ goto sysfs_err1; ++ } ++ ++ if(factory_test == 1) { ++ printk(KERN_INFO "bmi_sensor.c: HUMIDITY Sensor present in slot %d\n", slot); ++ } ++ } ++ ++ if(sensor->eeprom.acompass_present == SENSOR_DEVICE_PRESENT) { ++ unsigned char adc_data[2]; ++ unsigned int compass_x; ++ unsigned int compass_y; ++ unsigned int compass_z; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_ACOMPASS_X)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC write error\n"); ++ goto sysfs_err1; ++ ++ } ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read error\n"); ++ device_remove_file(&sensor->bdev->dev, &dev_attr_humidity); ++ goto sysfs_err1; ++ } ++ compass_x = (adc_data[0] << 8) | adc_data[1]; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_ACOMPASS_Y)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC write error\n"); ++ goto sysfs_err1; ++ } ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read error\n"); ++ goto sysfs_err1; ++ } ++ compass_y = (adc_data[0] << 8) | adc_data[1]; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_ACOMPASS_Z)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC write error\n"); ++ goto sysfs_err1; ++ } ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read error\n"); ++ goto sysfs_err1; ++ } ++ compass_z = (adc_data[0] << 8) | adc_data[1]; ++ ++ printk(KERN_INFO "bmi_sensor.c: initial COMPASS (X,Y,Z) = %d,%d,%d\n", ++ compass_x, compass_y, compass_z); ++ ++ if(device_create_file(&sensor->bdev->dev, &dev_attr_acompass)) { ++ printk (KERN_ERR ++ "bmi_sensor.c (%d): attr (acompass) failed.\n", ++ slot); ++ goto sysfs_err1; ++ } ++ ++ if(factory_test == 1) { ++ printk(KERN_INFO "bmi_sensor.c: ACOMPASS Sensor present in slot %d\n", slot); ++ } ++ } ++ ++ if(sensor->eeprom.dcompass_present == SENSOR_DEVICE_PRESENT) { ++ unsigned char hxga; ++ unsigned char hyga; ++ unsigned char hzga; ++ unsigned char compass_i; ++ unsigned char compass_t; ++ unsigned char compass_x; ++ unsigned char compass_y; ++ unsigned char compass_z; ++ ++ if(WriteByte_DCOMP(adap, SENSOR_DCOMP_MS1, SENSOR_DCOMP_MS1_EEPROM)) { ++ printk(KERN_ERR "bmi_sensor.c: DCOMP_MS1 write error\n"); ++ goto sysfs_err2; ++ } ++ ++ if(ReadByte_DCOMP(adap, SENSOR_DCOMP_EE_EHXGA, &hxga)) { ++ printk(KERN_ERR "bmi_sensor.c: EE_EHXGA read error\n"); ++ goto sysfs_err2; ++ } ++ ++ if(ReadByte_DCOMP(adap, SENSOR_DCOMP_EE_EHYGA, &hyga)) { ++ printk(KERN_ERR "bmi_sensor.c: EE_EHYGA read error\n"); ++ goto sysfs_err2; ++ } ++ ++ if(ReadByte_DCOMP(adap, SENSOR_DCOMP_EE_EHZGA, &hzga)) { ++ printk(KERN_ERR "bmi_sensor.c: EE_EHZGA read error\n"); ++ goto sysfs_err2; ++ } ++ ++ if(WriteByte_DCOMP(adap, SENSOR_DCOMP_MS1, SENSOR_DCOMP_MS1_PD)) { ++ printk(KERN_ERR "bmi_sensor.c: DCOMP_MS1 write error\n"); ++ goto sysfs_err2; ++ } ++ ++ if(WriteByte_DCOMP(adap, SENSOR_DCOMP_HXGA, hxga)) { ++ printk(KERN_ERR "bmi_sensor.c: DCOMP_HXGA write error\n"); ++ goto sysfs_err2; ++ } ++ ++ if(WriteByte_DCOMP(adap, SENSOR_DCOMP_HYGA, hyga)) { ++ printk(KERN_ERR "bmi_sensor.c: DCOMP_HYGA write error\n"); ++ goto sysfs_err2; ++ } ++ ++ if(WriteByte_DCOMP(adap, SENSOR_DCOMP_HZGA, hzga)) { ++ printk(KERN_ERR "bmi_sensor.c: DCOMP_HZGA write error\n"); ++ goto sysfs_err2; ++ } ++ ++ if(WriteByte_DCOMP(adap, SENSOR_DCOMP_HXDA, sensor->eeprom.xdac)) { ++ printk(KERN_ERR "bmi_sensor.c: DCOMP_HXDA write error\n"); ++ goto sysfs_err2; ++ ++ } ++ ++ if(WriteByte_DCOMP(adap, SENSOR_DCOMP_HYDA, sensor->eeprom.ydac)) { ++ printk(KERN_ERR "bmi_sensor.c: DCOMP_HYDA write error\n"); ++ goto sysfs_err2; ++ ++ } ++ ++ if(WriteByte_DCOMP(adap, SENSOR_DCOMP_HZDA, sensor->eeprom.zdac)) { ++ printk(KERN_ERR "bmi_sensor.c: DCOMP_HZDA write error\n"); ++ goto sysfs_err2; ++ ++ } ++ ++ if(WriteByte_DCOMP(adap, SENSOR_DCOMP_MS1, SENSOR_DCOMP_MS1_SENSOR)) { ++ printk(KERN_ERR "bmi_sensor.c: DCOMP_MS1 write error\n"); ++ goto sysfs_err2; ++ ++ } ++ ++ mdelay(20); ++ ++ if(ReadByte_DCOMP(adap, SENSOR_DCOMP_ST, &compass_i)) { ++ printk(KERN_ERR "bmi_sensor.c: DCOMP_ST read error\n"); ++ goto sysfs_err2; ++ } ++ ++ if((compass_i & SENSOR_DCOMP_ST_INT) == 0) { ++ printk(KERN_ERR "bmi_sensor.c: DCOMP interrupt error\n"); ++ goto sysfs_err2; ++ } ++ ++ if(ReadByte_DCOMP(adap, SENSOR_DCOMP_TMPS, &compass_t)) { ++ printk(KERN_ERR "bmi_sensor.c: DCOMP_TMPS error\n"); ++ goto sysfs_err2; ++ } ++ ++ if(ReadByte_DCOMP(adap, SENSOR_DCOMP_H1X, &compass_x)) { ++ printk(KERN_ERR "bmi_sensor.c: DCOMP_H1X error\n"); ++ goto sysfs_err2; ++ } ++ ++ if(ReadByte_DCOMP(adap, SENSOR_DCOMP_H1Y, &compass_y)) { ++ printk(KERN_ERR "bmi_sensor.c: DCOMP_H1Y error\n"); ++ goto sysfs_err2; ++ } ++ ++ if(ReadByte_DCOMP(adap, SENSOR_DCOMP_H1Z, &compass_z)) { ++ printk(KERN_ERR "bmi_sensor.c: DCOMP_H1Z error\n"); ++ goto sysfs_err2; ++ } ++ ++ printk(KERN_INFO "bmi_sensor.c: initial COMPASS (T,X,Y,Z) = 0x%x,0x%x,0x%x,0x%x\n", ++ compass_t, compass_x, compass_y, compass_z); ++ ++ if(device_create_file(&sensor->bdev->dev, &dev_attr_dcompass)) { ++ printk (KERN_ERR ++ "bmi_sensor.c (%d): attr (dcompass) failed.\n", ++ slot); ++ goto sysfs_err2; ++ } ++ ++ if(factory_test == 1) { ++ printk(KERN_INFO "bmi_sensor.c: DCOMPASS Sensor present in slot %d\n", slot); ++ } ++ } ++ ++ if(sensor->eeprom.light_proximity_present == SENSOR_DEVICE_PRESENT) { ++ unsigned char pl_data[2]; ++ ++ if(WriteByte_PL(adap, SENSOR_PL_CMD1, SENSOR_PL_CMD1_ALS_1X)) { ++ printk(KERN_ERR "bmi_sensor.c: PL write (ALS) error\n"); ++ goto sysfs_err3; ++ } ++ ++ if(ReadByte_PL(adap, SENSOR_PL_DATA_MSB, &pl_data[0])) { ++ printk(KERN_ERR "bmi_sensor.c: PL read (ALS) error\n"); ++ goto sysfs_err3; ++ } ++ ++ if(ReadByte_PL(adap, SENSOR_PL_DATA_MSB, &pl_data[1])) { ++ printk(KERN_ERR "bmi_sensor.c: PL read (ALS) error\n"); ++ goto sysfs_err3; ++ } ++ printk(KERN_INFO "bmi_sensor.c: initial PL ALS = %d\n", ++ (pl_data[0] << 8) | pl_data[1]); ++ ++ if(device_create_file(&sensor->bdev->dev, &dev_attr_als)) { ++ printk (KERN_ERR ++ "bmi_sensor.c (%d): attr (ALS) failed.\n", ++ slot); ++ goto sysfs_err3; ++ } ++ ++ if(WriteByte_PL(adap, SENSOR_PL_CMD1, SENSOR_PL_CMD1_IR_1X)) { ++ printk(KERN_ERR "bmi_sensor.c: PL write (IR) error\n"); ++ goto sysfs_err4; ++ } ++ ++ mdelay(20); ++ ++ if(ReadByte_PL(adap, SENSOR_PL_DATA_MSB, &pl_data[0])) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read (IR) error\n"); ++ goto sysfs_err4; ++ } ++ ++ if(ReadByte_PL(adap, SENSOR_PL_DATA_MSB, &pl_data[1])) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read (IR) error\n"); ++ goto sysfs_err4; ++ } ++ printk(KERN_INFO "bmi_sensor.c: initial IR = %d\n", ++ (pl_data[0] << 8) | pl_data[1]); ++ ++ if(device_create_file(&sensor->bdev->dev, &dev_attr_ir)) { ++ printk (KERN_ERR ++ "bmi_sensor.c (%d): attr (IR) failed.\n", ++ slot); ++ goto sysfs_err4; ++ } ++ ++ if(WriteByte_PL(adap, SENSOR_PL_CMD1, SENSOR_PL_CMD1_PROX_1X)) { ++ printk(KERN_ERR "bmi_sensor.c: PL write (Proximity) error\n"); ++ goto sysfs_err5; ++ } ++ ++ mdelay(20); ++ ++ if(ReadByte_PL(adap, SENSOR_PL_DATA_MSB, &pl_data[0])) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read (Proximity) error\n"); ++ goto sysfs_err5; ++ } ++ ++ if(ReadByte_PL(adap, SENSOR_PL_DATA_MSB, &pl_data[1])) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read (Proximity) error\n"); ++ goto sysfs_err5; ++ } ++ printk(KERN_INFO "bmi_sensor.c: initial Proximity = %d\n", ++ (pl_data[0] << 8) | pl_data[1]); ++ ++ if(device_create_file(&sensor->bdev->dev, &dev_attr_proximity)) { ++ printk (KERN_ERR ++ "bmi_sensor.c (%d): attr (Proximity) failed.\n", ++ slot); ++ goto sysfs_err5; ++ } ++ ++ if(factory_test == 1) { ++ printk(KERN_INFO "bmi_sensor.c: Combined LIGHT/PROXIMITY Sensor present in slot %d\n", slot); ++ } ++ } ++ ++ if(sensor->eeprom.sound_present == SENSOR_DEVICE_PRESENT) { ++ unsigned char adc_data[2]; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_SOUND_AVG)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC write (Sound Average) error\n"); ++ goto sysfs_err6; ++ } ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read (Sound Average) error\n"); ++ goto sysfs_err6; ++ } ++ ++ printk(KERN_INFO "bmi_sensor.c: initial Sound Average = %d\n", ++ (adc_data[0] << 8) | adc_data[1]); ++ ++ if(device_create_file(&sensor->bdev->dev, &dev_attr_sound_avg)) { ++ printk (KERN_ERR ++ "bmi_sensor.c (%d): attr (Sound Average) failed.\n", ++ slot); ++ goto sysfs_err6; ++ } ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_SOUND_PEAK)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC write (Sound Peak) error\n"); ++ goto sysfs_err7; ++ } ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read (Sound Peak) error\n"); ++ goto sysfs_err7; ++ } ++ ++ printk(KERN_INFO "bmi_sensor.c: initial Sound Peak = %d\n", ++ (adc_data[0] << 8) | adc_data[1]); ++ ++ if(device_create_file(&sensor->bdev->dev, &dev_attr_sound_peak)) { ++ printk (KERN_ERR ++ "bmi_sensor.c (%d): attr (Sound Peak) failed.\n", ++ slot); ++ goto sysfs_err7; ++ } ++ ++ if(factory_test == 1) { ++ printk(KERN_INFO "bmi_sensor.c: SOUND PRESSURE Sensor present in slot %d\n", slot); ++ } ++ } ++ ++ if(sensor->eeprom.temperature_present == SENSOR_DEVICE_PRESENT) { ++ unsigned char temp_datam; ++ unsigned char temp_datal; ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_MAN_ID, &temp_datam)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP read (Manufacturer ID) error\n"); ++ goto sysfs_err8; ++ } ++ ++ if(temp_datam != SENSOR_TEMP_MAN_ID_DATA) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP MAN ID error (read=0x%x, expected=0x%x\n", ++ temp_datam, SENSOR_TEMP_MAN_ID_DATA); ++ goto sysfs_err8; ++ } ++ ++ printk(KERN_INFO "bmi_sensor.c: TEMP Manufacturer ID = 0x%x\n", temp_datam); ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_REV_ID, &temp_datam)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP read (Revision ID) error\n"); ++ goto sysfs_err8; ++ } ++ ++ if(temp_datam != SENSOR_TEMP_REV_ID_DATA) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP REV ID error (read=0x%x, expected=0x%x\n", ++ temp_datam, SENSOR_TEMP_REV_ID_DATA); ++ goto sysfs_err8; ++ } ++ ++ printk(KERN_INFO "bmi_sensor.c: TEMP Revision ID = 0x%x\n", temp_datam); ++ ++ if(WriteByte_TEMP(adap, SENSOR_TEMP_CONF2, 0x0)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP write (CONF2) error\n"); ++ goto sysfs_err8; ++ } ++ ++ if(WriteByte_TEMP(adap, SENSOR_TEMP_CONF1_WR, SENSOR_TEMP_CONF1_STOP)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP write (CONF1) error\n"); ++ goto sysfs_err8; ++ } ++ ++ if(WriteByte_TEMP(adap, SENSOR_TEMP_CONV_WR, SENSOR_TEMP_CONV_P364)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP write (CONF1) error\n"); ++ goto sysfs_err8; ++ } ++ ++ if(WriteByte_TEMP(adap, SENSOR_TEMP_ONE_SHOT, 0x0)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP write (CONF1) error\n"); ++ goto sysfs_err8; ++ } ++ ++ mdelay(400); ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_LOC_MSB, &temp_datam)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP read (LOCAL MSB) error\n"); ++ goto sysfs_err8; ++ } ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_LOC_LSB, &temp_datal)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP read (LOCAL LSB) error\n"); ++ goto sysfs_err8; ++ } ++ ++ printk(KERN_INFO "bmi_sensor.c: initial Local temperature = 0x%x\n", ++ (temp_datam << 8) | temp_datal); ++ ++ if(device_create_file(&sensor->bdev->dev, &dev_attr_temp_local)) { ++ printk (KERN_ERR ++ "bmi_sensor.c (%d): attr (TEMP local) failed.\n", ++ slot); ++ goto sysfs_err8; ++ } ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_REM_MSB, &temp_datam)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP read (REM MSB) error\n"); ++ goto sysfs_err9; ++ } ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_REM_LSB, &temp_datal)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP read (REM LSB) error\n"); ++ goto sysfs_err9; ++ } ++ ++ printk(KERN_INFO "bmi_sensor.c: initial Remote temperature = 0x%x\n", ++ (temp_datam << 8) | temp_datal); ++ ++ if(device_create_file(&sensor->bdev->dev, &dev_attr_temp_sremote)) { ++ printk (KERN_ERR ++ "bmi_sensor.c (%d): attr (TEMP sremote) failed.\n", ++ slot); ++ goto sysfs_err9; ++ } ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_UREM_MSB, &temp_datam)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP read (UREM MSB) error\n"); ++ goto sysfs_err10; ++ } ++ ++ if(ReadByte_TEMP(adap, SENSOR_TEMP_UREM_LSB, &temp_datal)) { ++ printk(KERN_ERR "bmi_sensor.c: TEMP read (UREM LSB) error\n"); ++ goto sysfs_err10; ++ } ++ ++ if(device_create_file(&sensor->bdev->dev, &dev_attr_temp_uremote)) { ++ printk (KERN_ERR ++ "bmi_sensor.c (%d): attr (TEMP uremote) failed.\n", ++ slot); ++ goto sysfs_err10; ++ } ++ ++ printk(KERN_INFO "bmi_sensor.c: initial Remote temperature (unsigned) = 0x%x\n", ++ (temp_datam << 8) | temp_datal); ++ ++ if(factory_test == 1) { ++ printk(KERN_INFO "bmi_sensor.c: TEMPERATURE Sensor present in slot %d\n", slot); ++ } ++ } ++ ++ if(sensor->eeprom.motion_present == SENSOR_DEVICE_PRESENT) { ++ if(device_create_file(&sensor->bdev->dev, &dev_attr_motion)) { ++ printk (KERN_ERR ++ "bmi_sensor.c (%d): attr (motion) failed.\n", ++ slot); ++ goto sysfs_err11; ++ } ++ ++ printk(KERN_INFO "bmi_sensor.c: initial Motion state = 0x%x\n", ++ bmi_slot_gpio_read_bit(slot, SENSOR_GPIO_MOT_DET)); ++ ++ if(factory_test == 1) { ++ printk(KERN_INFO "bmi_sensor.c: MOTION Sensor present in slot %d\n", slot); ++ } ++ } ++ ++ if(sensor->eeprom.accel_present == SENSOR_DEVICE_PRESENT) { ++ struct sensor_acc_rw acc_rw; ++ ++ acc_rw.address = SENSOR_ACC_ID; ++ acc_rw.count = 1; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC read (ID) error\n"); ++ goto sysfs_err12; ++ } ++ ++ if(acc_rw.data[0] != SENSOR_ACC_ID_DATA) { ++ printk(KERN_ERR "bmi_sensor.c: ACC ID error (read=0x%x, expected=0x%x)\n", ++ acc_rw.data[0], SENSOR_ACC_ID_DATA); ++ goto sysfs_err12; ++ } ++ ++ acc_rw.address = SENSOR_ACC_RATE; ++ acc_rw.count = 1; ++ acc_rw.data[0] = SENSOR_ACC_RC_3200_1600; ++ if(WriteByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC write (RATE) error\n"); ++ goto sysfs_err12; ++ } ++ ++ acc_rw.address = SENSOR_ACC_POWER; ++ acc_rw.count = 1; ++ acc_rw.data[0] = SENSOR_ACC_P_NORM; ++ if(WriteByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC write (RATE) error\n"); ++ goto sysfs_err12; ++ } ++ ++ acc_rw.address = SENSOR_ACC_DF; ++ acc_rw.count = 1; ++ acc_rw.data[0] = SENSOR_ACC_DF_LENGTH; ++ if(WriteByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC write (DF) error\n"); ++ goto sysfs_err12; ++ } ++ ++ mdelay(20); ++ ++ acc_rw.address = SENSOR_ACC_DX0; ++ acc_rw.count = 2; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC read (DX0) error\n"); ++ goto sysfs_err12; ++ } ++ ++ printk(KERN_INFO "bmi_sensor.c: initial ACC X state = 0x%x\n", ++ (acc_rw.data[0] << 8) | acc_rw.data[1]); ++ ++ acc_rw.address = SENSOR_ACC_DY0; ++ acc_rw.count = 2; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC read (DY0) error\n"); ++ goto sysfs_err12; ++ } ++ ++ printk(KERN_INFO "bmi_sensor.c: initial ACC Y state = 0x%x\n", ++ (acc_rw.data[0] << 8) | acc_rw.data[1]); ++ ++ acc_rw.address = SENSOR_ACC_DZ0; ++ acc_rw.count = 2; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC read (DZ0) error\n"); ++ goto sysfs_err12; ++ } ++ ++ printk(KERN_INFO "bmi_sensor.c: initial ACC Z state = 0x%x\n", ++ (acc_rw.data[0] << 8) | acc_rw.data[1]); ++ ++ if(device_create_file(&sensor->bdev->dev, &dev_attr_accel)) { ++ printk (KERN_ERR ++ "bmi_sensor.c (%d): attr (accel) failed.\n", ++ slot); ++ goto sysfs_err12; ++ } ++ ++ if(factory_test == 1) { ++ printk(KERN_INFO "bmi_sensor.c: ACCELEROMETER Sensor present in slot %d\n", slot); ++ } ++ } ++ ++ if(sensor->eeprom.acc302_present == SENSOR_DEVICE_PRESENT) { ++ struct sensor_acc_rw acc_rw; ++ ++ acc_rw.address = SENSOR_A3_WAI; ++ acc_rw.count = 1; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC302 read (WAI) error\n"); ++ goto sysfs_err12; ++ } ++ ++ if(acc_rw.data[0] != SENSOR_A3_WAI_ID) { ++ printk(KERN_ERR "bmi_sensor.c: ACC302 ID error (read=0x%x, expected=0x%x)\n", ++ acc_rw.data[0], SENSOR_A3_WAI_ID); ++ goto sysfs_err12; ++ } ++ ++ acc_rw.address = SENSOR_A3_CTRL1; ++ acc_rw.count = 1; ++ if(factory_test) ++ acc_rw.data[0] = SENSOR_A3_CTRL1_DR400 | SENSOR_A3_CTRL1_PU | ++ SENSOR_A3_CTRL1_STP | SENSOR_A3_CTRL1_STM | SENSOR_A3_CTRL1_XYZEN; ++ else ++ acc_rw.data[0] = SENSOR_A3_CTRL1_DR400 | SENSOR_A3_CTRL1_PU ++ | SENSOR_A3_CTRL1_XYZEN; ++ if(WriteByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC302 write (RATE) error\n"); ++ goto sysfs_err12; ++ } ++ ++ acc_rw.address = SENSOR_A3_CTRL3; ++ acc_rw.count = 1; ++ acc_rw.data[0] = SENSOR_A3_CTRL3_IL; ++ if(WriteByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC302 write (RATE) error\n"); ++ goto sysfs_err12; ++ } ++ ++ mdelay(20); ++ ++ acc_rw.address = SENSOR_A3_OUTX; ++ acc_rw.count = 1; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC302 read (OUTX) error\n"); ++ goto sysfs_err12; ++ } ++ ++ printk(KERN_INFO "bmi_sensor.c: initial ACC302 X state = 0x%x\n", ++ acc_rw.data[0]); ++ ++ acc_rw.address = SENSOR_A3_OUTY; ++ acc_rw.count = 1; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC302 read (OUTY) error\n"); ++ goto sysfs_err12; ++ } ++ ++ printk(KERN_INFO "bmi_sensor.c: initial ACC302 Y state = 0x%x\n", ++ acc_rw.data[0]); ++ ++ acc_rw.address = SENSOR_A3_OUTZ; ++ acc_rw.count = 1; ++ if(ReadByte_ACC(adap, &acc_rw)) { ++ printk(KERN_ERR "bmi_sensor.c: ACC302 read (OUTZ) error\n"); ++ goto sysfs_err12; ++ } ++ ++ printk(KERN_INFO "bmi_sensor.c: initial ACC302 Z state = 0x%x\n", ++ acc_rw.data[0]); ++ ++ if(device_create_file(&sensor->bdev->dev, &dev_attr_accel)) { ++ printk (KERN_ERR ++ "bmi_sensor.c (%d): attr (accel) failed.\n", ++ slot); ++ goto sysfs_err12; ++ } ++ ++ if(factory_test == 1) { ++ printk(KERN_INFO "bmi_sensor.c: ISL302 ACCELEROMETER Sensor present in slot %d\n", slot); ++ } ++ } ++ ++ if(sensor->eeprom.aproximity_present == SENSOR_DEVICE_PRESENT) { ++ unsigned char aprox_data; ++ unsigned int read_data; ++ int ret; ++ ++ // enable sensor ++ if(ReadByte_IOX(adap, IOX_INPUT1_REG, &iox_data)) { ++ printk(KERN_ERR "bmi_sensor.c: IOX error in slot %d\n", slot); ++ goto sysfs_err13; ++ } ++ iox_data &= ~(0x1 << SENSOR_IOX_PROX_EN_N); ++ if(WriteByte_IOX(adap, IOX_OUTPUT1_REG, iox_data)) { ++ printk(KERN_ERR "bmi_sensor.c: IOX error in slot %d\n", slot); ++ goto sysfs_err13; ++ } ++ ++ // start burst to LED ++ iox_data |= (0x1 << SENSOR_IOX_PROX_RST_N); ++ if(WriteByte_IOX(adap, IOX_OUTPUT1_REG, iox_data)) ++ goto sysfs_err13; ++ ++ // set up timer ++ sensor->aprox_timer.expires = jiffies + sensor->aprox_duration; ++ add_timer (&sensor->aprox_timer); ++ ++ // wait for timer ++ ret = down_interruptible(&sensor->sem); ++ sensor->aprox_int_en = 1; ++ sensor->aprox_int_fl = 0; ++ up(&sensor->sem); ++ wait_event_interruptible(sensor->aprox_wait_queue, (sensor->aprox_int_fl == 1)); ++ ++ // stop burst to LED ++ if(ReadByte_IOX(adap, IOX_INPUT1_REG, &iox_data)) ++ goto sysfs_err13; ++ iox_data &= ~(0x1 << SENSOR_IOX_PROX_RST_N); ++ if(WriteByte_IOX(adap, IOX_OUTPUT1_REG, iox_data)) ++ goto sysfs_err13; ++ ++ // digital output ++ read_data = (iox_data & (0x1 << SENSOR_IOX_PROX_OUT)) << 14; ++ ++ // read ADC - analog output ++ if(WriteByte_ADC(adap, SENSOR_ADC_APROXIMITY | SENSOR_ADC_PD_OFF)) ++ goto sysfs_err13; ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, &aprox_data)) ++ goto sysfs_err13; ++ read_data |= aprox_data; ++ ++ printk(KERN_INFO "bmi_sensor.c: initial analog proximity = 0x%x\n", read_data); ++ ++ if(device_create_file(&sensor->bdev->dev, &dev_attr_aprox)) { ++ printk (KERN_ERR ++ "bmi_sensor.c (%d): attr (aprox) failed.\n", ++ slot); ++ goto sysfs_err13; ++ } ++ ++ if(factory_test == 1) { ++ printk(KERN_INFO "bmi_sensor.c: Analog PROXIMITY Sensor present in slot %d\n", slot); ++ } ++ } ++ ++ if(sensor->eeprom.alight_present == SENSOR_DEVICE_PRESENT) { ++ unsigned char adc_data[2]; ++ ++ if(WriteByte_ADC(adap, SENSOR_ADC_LIGHT)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC write (Analog Light) error\n"); ++ goto sysfs_err14; ++ } ++ ++ mdelay(1); ++ ++ if(ReadByte_ADC(adap, adc_data)) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read (Humidity) error\n"); ++ goto sysfs_err14; ++ } ++ ++ printk(KERN_INFO "bmi_sensor.c: initial Analog Light = 0x%x\n", ++ (adc_data[0] << 8) | adc_data[1]); ++ ++ if(device_create_file(&sensor->bdev->dev, &dev_attr_alight)) { ++ printk (KERN_ERR ++ "bmi_sensor.c (%d): attr (alight) failed.\n", ++ slot); ++ goto sysfs_err14; ++ } ++ ++ if(factory_test == 1) { ++ printk(KERN_INFO "bmi_sensor.c: Analog LIGHT Sensor present in slot %d\n", slot); ++ } ++ } ++ ++ if(sensor->eeprom.dlight_present == SENSOR_DEVICE_PRESENT) { ++ unsigned char dl_data[2]; ++ ++ if(WriteByte_PL(adap, SENSOR_DL_CMD, SENSOR_DL_CMD_ADC_EN)) { ++ printk(KERN_ERR "bmi_sensor.c: PL write (Digital Light) error\n"); ++ goto sysfs_err15; ++ } ++ ++ mdelay(20); ++ ++ if(ReadByte_PL(adap, SENSOR_DL_SENSOR_MSB, &dl_data[0])) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read (Digital Light) error\n"); ++ goto sysfs_err15; ++ } ++ ++ if(ReadByte_PL(adap, SENSOR_DL_SENSOR_MSB, &dl_data[1])) { ++ printk(KERN_ERR "bmi_sensor.c: ADC read (Digital Light) error\n"); ++ goto sysfs_err15; ++ } ++ printk(KERN_INFO "bmi_sensor.c: initial Digital Light = %d\n", ++ (dl_data[0] << 8) | dl_data[1]); ++ ++ // clear interrupts ++ if(ReadByte_PL(adap, SENSOR_DL_CONT, &dl_data[0])) { ++ printk(KERN_ERR "bmi_sensor.c: DL read error\n"); ++ } ++ dl_data[0] &= ~(SENSOR_DL_CONT_INT); ++ if(WriteByte_PL(adap, SENSOR_DL_CONT, dl_data[0])) { ++ printk(KERN_ERR "bmi_sensor.c: DL write error\n"); ++ } ++ if(WriteByte_DL_IC(adap)) { ++ printk(KERN_ERR "bmi_sensor.c: DL interrupt clear error\n"); ++ } ++ ++ if(device_create_file(&sensor->bdev->dev, &dev_attr_dlight)) { ++ printk (KERN_ERR ++ "bmi_sensor.c (%d): attr (Digital Light) failed.\n", ++ slot); ++ goto sysfs_err15; ++ } ++ ++ if(factory_test == 1) { ++ printk(KERN_INFO "bmi_sensor.c: Digital LIGHT Sensor present in slot %d\n", slot); ++ } ++ } ++ ++ if(ReadByte_IOX(adap, IOX_INPUT0_REG, &iox_data)) { // clear IOX interrupts ++ printk (KERN_ERR ++ "bmi_sensor.c(%d): IOX0 interrupt clear fail.\n", ++ slot); ++ goto sysfs_err16; ++ } ++ ++ if(ReadByte_IOX(adap, IOX_INPUT1_REG, &iox_data)) { // clear IOX interrupts ++ printk (KERN_ERR ++ "bmi_sensor.c(%d): IOX1 interrupt clear fail.\n", ++ slot); ++ goto sysfs_err16; ++ } ++ ++ // request PIM interrupt ++ irq = bmi_device_get_status_irq(bdev); ++ sprintf(sensor->int_name, "bmi_sensor%d", slot); ++ //pjg if(request_irq(irq, &module_irq_handler, 0, sensor->int_name, sensor)) { ++ //pjg printk(KERN_ERR "bmi_sensor.c: Can't allocate irq %d or find Sensor in slot %d\n", ++ //pjg irq, slot); ++ //pjg goto sysfs_err16; ++ //pjg } ++ ++ return 0; ++ ++sysfs_err16: ++ if(sensor->eeprom.dlight_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_dlight); ++ } ++sysfs_err15: ++ if(sensor->eeprom.alight_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_alight); ++ } ++sysfs_err14: ++ if(sensor->eeprom.aproximity_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_aprox); ++ } ++sysfs_err13: ++ if(sensor->eeprom.accel_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_accel); ++ } ++sysfs_err12: ++ if(sensor->eeprom.motion_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_motion); ++ } ++sysfs_err11: ++ if(sensor->eeprom.temperature_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_temp_uremote); ++ } ++sysfs_err10: ++ if(sensor->eeprom.temperature_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_temp_sremote); ++ } ++sysfs_err9: ++ if(sensor->eeprom.temperature_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_temp_local); ++ } ++sysfs_err8: ++ if(sensor->eeprom.sound_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_sound_peak); ++ } ++sysfs_err7: ++ if(sensor->eeprom.sound_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_sound_avg); ++ } ++sysfs_err6: ++ if(sensor->eeprom.light_proximity_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_proximity); ++ } ++sysfs_err5: ++ if(sensor->eeprom.light_proximity_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_ir); ++ } ++sysfs_err4: ++ if(sensor->eeprom.light_proximity_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_als); ++ } ++sysfs_err3: ++ if(sensor->eeprom.dcompass_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_dcompass); ++ } ++sysfs_err2: ++ if(sensor->eeprom.acompass_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_acompass); ++ } ++sysfs_err1: ++ if(sensor->eeprom.humidity_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_humidity); ++ } ++error: ++ sensor->class_dev = NULL; ++ cdev_del(&sensor->cdev); ++ device_destroy(bmi_class, MKDEV(major, slot)); ++ bmi_device_set_drvdata(bdev, 0); ++ sensor->bdev = 0; ++ printk(KERN_ERR "bmi_sensor.c: probe slot %d FAILED\n", slot); ++ return -ENODEV; ++ ++} ++ ++// remove PIM ++void bmi_sensor_remove(struct bmi_device *bdev) ++{ ++ int slot; ++ struct bmi_sensor *sensor; ++ struct class *bmi_class; ++ int irq; ++ ++ slot = bmi_device_get_slot(bdev); ++ sensor = &bmi_sensor[slot]; ++ ++ irq = bmi_device_get_status_irq(bdev); ++ free_irq(irq, sensor); ++ ++ destroy_workqueue(sensor->workqueue); ++ ++ if(sensor->eeprom.humidity_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_humidity); ++ } ++ if(sensor->eeprom.acompass_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_acompass); ++ } ++ if(sensor->eeprom.dcompass_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_dcompass); ++ } ++ if(sensor->eeprom.light_proximity_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_als); ++ device_remove_file(&sensor->bdev->dev, &dev_attr_ir); ++ device_remove_file(&sensor->bdev->dev, &dev_attr_proximity); ++ } ++ if(sensor->eeprom.sound_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_sound_avg); ++ device_remove_file(&sensor->bdev->dev, &dev_attr_sound_peak); ++ } ++ if(sensor->eeprom.temperature_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_temp_local); ++ device_remove_file(&sensor->bdev->dev, &dev_attr_temp_sremote); ++ device_remove_file(&sensor->bdev->dev, &dev_attr_temp_uremote); ++ } ++ if(sensor->eeprom.motion_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_motion); ++ } ++ if(sensor->eeprom.acc302_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_accel); ++ } ++ if(sensor->eeprom.accel_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_accel); ++ } ++ if(sensor->eeprom.aproximity_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_aprox); ++ del_timer(&sensor->aprox_timer); ++ } ++ if(sensor->eeprom.alight_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_alight); ++ } ++ if(sensor->eeprom.dlight_present == SENSOR_DEVICE_PRESENT) { ++ device_remove_file(&sensor->bdev->dev, &dev_attr_dlight); ++ } ++ ++ bmi_slot_gpio_configure_all_as_inputs(slot); ++ ++ bmi_class = bmi_get_bmi_class(); ++ device_destroy(bmi_class, MKDEV(major, slot)); ++ ++ sensor->class_dev = 0; ++ ++ cdev_del(&sensor->cdev); ++ ++ // de-attach driver-specific struct from bmi_device structure ++ bmi_device_set_drvdata(bdev, 0); ++ sensor->bdev = 0; ++ ++ return; ++} ++ ++/* ++ * module routines ++ */ ++ ++static int __init bmi_sensor_init(void) ++{ ++ dev_t dev_id; ++ int retval; ++ ++ // alloc char driver with 4 minor numbers ++ retval = alloc_chrdev_region(&dev_id, 0, 4, "BMI SENSOR Driver"); ++ if(retval) { ++ return -ENODEV; ++ } ++ ++ major = MAJOR(dev_id); ++ retval = bmi_register_driver(&bmi_sensor_driver); ++ if(retval) { ++ unregister_chrdev_region(dev_id, 4); ++ return -ENODEV; ++ } ++ ++ if(factory_test) { ++ printk(KERN_INFO "bmi_sensor.c: Factory Test mode enabled\n"); ++ if(eeprom_init) ++ printk(KERN_INFO "bmi_sensor.c: eeprom init = 0x%x\n", eeprom_init); ++ if(xdac_init) ++ printk(KERN_INFO "bmi_sensor.c: XDAC init = 0x%x\n", xdac_init); ++ if(ydac_init) ++ printk(KERN_INFO "bmi_sensor.c: YDAC init = 0x%x\n", ydac_init); ++ if(zdac_init) ++ printk(KERN_INFO "bmi_sensor.c: ZDAC init = 0x%x\n", zdac_init); ++ } ++ ++ if(fcc_test) ++ printk(KERN_INFO "bmi_sensor.c: FCC Test mode enabled\n"); ++ ++ printk(KERN_INFO "bmi_sensor.c: BMI_SENSOR Driver v%s \n", BMISENSOR_VERSION); ++ ++ return 0; ++} ++ ++static void __exit bmi_sensor_cleanup(void) ++{ ++ dev_t dev_id; ++ ++ bmi_unregister_driver(&bmi_sensor_driver); ++ ++ dev_id = MKDEV(major, 0); ++ unregister_chrdev_region(dev_id, 4); ++ return; ++} ++ ++module_init(bmi_sensor_init); ++module_exit(bmi_sensor_cleanup); ++ ++module_param(factory_test, ushort, S_IRUGO); ++MODULE_PARM_DESC(factory_test, "Factory Test code enable"); ++ ++module_param(eeprom_init, int, S_IRUGO); ++MODULE_PARM_DESC(eeprom_init, "Factory presence EEPROM programming"); ++ ++module_param(xdac_init, ushort, S_IRUGO); ++MODULE_PARM_DESC(xdac_init, "Factory EEPROM XDAC programming"); ++ ++module_param(ydac_init, ushort, S_IRUGO); ++MODULE_PARM_DESC(ydac_init, "Factory EEPROM YDAC programming"); ++ ++module_param(zdac_init, ushort, S_IRUGO); ++MODULE_PARM_DESC(zdac_init, "Factory EEPROM ZDAC programming"); ++ ++module_param(fcc_test, ushort, S_IRUGO); ++MODULE_PARM_DESC(fcc_test, "FCC Test code enable"); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Peter Giacomini "); ++MODULE_DESCRIPTION("BMI Sensor device driver"); ++MODULE_SUPPORTED_DEVICE("bmi_sensor_cntl_mX"); ++ +--- /dev/null ++++ git/drivers/bmi/pims/sound/Makefile +@@ -0,0 +1,6 @@ ++# ++# BMI PIMS ++# ++ ++obj-$(CONFIG_BMI_AUDIO) += bmi_audio.o ++ +--- /dev/null ++++ git/drivers/bmi/pims/sound/bmi_audio.c +@@ -0,0 +1,4434 @@ ++/* ++ * bmi_audio.c ++ * ++ * BMI audio device driver for audio PIMs ++ * ++ * The BMI Audio driver and this API were developed to support ++ * audio playback and record on the BUG audio PIMs. ++ * ++ * The following operating modes are supported: ++ * ++ * Operating Mode PIM ++ * ---------------------------- ------- ++ * Stereo DAC Playback Yes ++ * Stereo ADC Record Yes ++ * Output Amplifier Control Yes ++ * Input Mixer Control Yes ++ * ++ * This file also implements the sound driver mixer interface for ALSA. ++ * ++ * Playback and Recording supports 11025, 22050, and 44100 kHz for stereo. ++ * ++ * Future Enhanement Options: ++ * 48000-based rates ++ * efx control ++ * I2S -> TDM mode ++ * power management ++ */ ++ ++/* ++ * This code was derived from the following sources: ++ * ++ * @file pmic_audio.c ++ * @file mxc-alsa-mixer.c ++ * @file mxc-alsa-pmic.c ++ * ++ * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#undef CODEC // disable CODEC access for code testing ++#define CODEC // enable CODEC access for code testing ++ ++#define DEBUG // enable debug printk ++#undef DEBUG // disable debug printk ++ ++#ifdef DEBUG ++ ++# define DDPRINTK(fmt, args...) printk(KERN_ERR"%s :: %d :: %s - " \ ++ fmt, __FILE__,__LINE__,__FUNCTION__ , ## args) ++# define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args) ++# define PRINTK(fmt) printk(KERN_INFO fmt) ++ ++# define FUNC_START DPRINTK(" func start\n") ++# define FUNC_END DPRINTK(" func end\n") ++ ++# define FUNC_ERR printk(KERN_ERR"%s :: %d :: %s err= %d \n", \ ++ __FILE__,__LINE__,__FUNCTION__ ,err) ++ ++#else // DEBUG ++ ++#define DDPRINTK(fmt, args...) do {} while(0) ++#define DPRINTK(fmt, args...) do {} while(0) ++#define PRINTK(fmt) do {} while(0) ++ ++#endif // DEBUG ++ ++#include ++#include ++#include ++#include ++#include ++ ++// BMI/BUG interfaces ++#include ++#include ++#include ++#include ++#include ++ ++// control interface - LED/RESET/MODULE ACTIVATION ++#include ++#include ++#include ++#include ++ ++// I2C interface - IOX/CODEC ++#include ++#include ++ ++// Input interface - BUTTONS/JACKS ++#include ++#include ++ ++// includes from mxc-alsa-mixer.c: ++#include ++#include ++#include ++#include ++#include ++#include ++#include "../../../mxc/bug_audio/bug-alsa-common.h" ++ ++// includes from mxc-alsa-pmic.c: ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_PM ++#include ++#endif // CONFIG_PM ++ ++#include ++#include ++#include ++#include ++ ++#include "../../../../arch/arm/mach-mx3/crm_regs.h" ++#include "../../../mxc/ssi/ssi.h" ++#include "../../../mxc/ssi/registers.h" ++#include "../../../mxc/dam/dam.h" ++ ++// Global variables ++static ushort fcc_test = 0; ++static ushort output_ints = 0; ++ ++// BMI defines ++#define BMIAUDIO_VERSION "1.0" ++#define MAX_STRG (20) ++#define WORK_DELAY (1) // input debounce ++ ++// BMI private device structure ++struct bmi_audio ++{ ++ struct bmi_device *bdev; // BMI device ++ struct cdev cdev; // control character device ++ struct device *class_dev; // control device class ++ unsigned int active; // PIM active ++ unsigned int irq; // interrupt number ++ char int_name[MAX_STRG]; // interrupt name for /proc ++ struct input_dev *input_dev; // button/insertion input device ++}; ++ ++static struct bmi_audio bmi_audio[BMI_AUDIO_PIM_NUM]; // PIM structures ++static int major; // control device major ++ ++// ++// I2C ++// ++ ++// I2C Slave Addresses ++#define BMI_IOX_I2C_ADDRESS 0x71 // 7-bit address ++#define BMI_CODEC_I2C_ADDRESS 0x18 // 7-bit address ++ ++// I2C IOX register definitions ++#define IOX_INPUT_REG 0x0 // IOX input data register ++#define IOX_OUTPUT_REG 0x1 // IOX output data register ++#define IOX_POLARITY_REG 0x2 // IOX polarity data register ++#define IOX_CONTROL 0x3 // IOX direction control register ++#define IOX_AMP (0) // bit 0 - amplifier off (O - low active) ++#define IOX_SPARE (1) // bit 1 - spare ++#define IOX_VOLP (2) // bit 2 - VOLP (I - interrupt) ++#define IOX_VOLD (3) // bit 3 - VOLD (I - interrupt) ++#define IOX_HP_INS (4) // bit 4 - HP_INS (I - interrupt) ++#define IOX_MIC_INS (5) // bit 5 - MIC_INS (I - interrupt) ++#define IOX_LI_INS (6) // bit 6 - LI_INS (I - interrupt) ++#define IOX_LO_INS (7) // bit 7 - LO_INS (I - interrupt) ++ ++// ++// I2C routines ++// ++ ++// read byte from I2C IO expander ++static int ReadByte_IOX (struct i2c_adapter *adap, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ ++ // Read Byte with Pointer ++ rmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[0].flags = 0; // write ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; // read ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ret = i2c_transfer (adap, rmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "ReadByte_IOX() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++// write byte to I2C IO expander ++static int WriteByte_IOX (struct i2c_adapter *adap, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ // Write Byte with Pointer ++ wmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[0].flags = 0; // write ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[1].flags = 0; // write ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ ret = i2c_transfer (adap, wmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "WriteByte_IOX() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++#ifdef CODEC ++// read byte from I2C CODEC ++static int ReadByte_CODEC (struct i2c_adapter *adap, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ ++ // Read Byte with Pointer ++ rmsg[0].addr = BMI_CODEC_I2C_ADDRESS; ++ rmsg[0].flags = 0; // write ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_CODEC_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; // read ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ret = i2c_transfer (adap, rmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "ReadByte_CODEC() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++// write byte to I2C CODEC ++static int WriteByte_CODEC (struct i2c_adapter *adap, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ // Write Byte with Pointer ++ wmsg[0].addr = BMI_CODEC_I2C_ADDRESS; ++ wmsg[0].flags = 0; // write ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_CODEC_I2C_ADDRESS; ++ wmsg[1].flags = 0; // write ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ++ ret = i2c_transfer (adap, wmsg, num_msgs); ++ ++ if (ret == 2) { ++ ret = 0; ++ } ++ else { ++ printk (KERN_ERR "WriteByte_CODEC() - i2c_transfer() failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++#endif // CODEC ++ ++// ++// control cdev routines ++// ++ ++// open ++int cntl_open (struct inode *inode, struct file *file) ++{ ++ struct bmi_audio *audio; ++ ++ audio = container_of (inode->i_cdev, struct bmi_audio, cdev); ++ file->private_data = audio; ++ return 0; ++ ++} ++ ++// release ++int cntl_release (struct inode *inode, struct file *file) ++{ ++ file->private_data = 0; ++ return 0; ++} ++ ++static int configure_CODEC(struct i2c_adapter *adap, struct bmi_audio *audio); ++ ++// ioctl ++int cntl_ioctl (struct inode *inode, struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct bmi_audio *audio = (struct bmi_audio *) (file->private_data); ++ struct codec_xfer codec_xfer; ++ struct i2c_adapter *adap; ++ unsigned char iox_data; ++ int slot; ++ ++ // error if audio/bdev not present ++ if (audio == 0) ++ return -ENODEV; ++ ++ if (audio->bdev == 0) ++ return -ENODEV; ++ ++ adap = bmi_device_get_i2c_adapter (audio->bdev); ++ slot = bmi_device_get_slot (audio->bdev); ++ ++ // get codec transfer structure ++ if ((cmd == BMI_AUDIO_WCODEC) || (cmd == BMI_AUDIO_RCODEC)) { ++ if (copy_from_user (&codec_xfer, (struct codec_xfer *) arg, sizeof(struct codec_xfer))) { ++ printk (KERN_INFO "bmi_audio.c: ioctl(%d): copy_from_user error\n", slot); ++ return -EFAULT; ++ } ++ } ++ ++ // ioctl's ++ switch (cmd) { ++ ++ case BMI_AUDIO_RLEDOFF: ++ bmi_slot_gpio_write_bit (slot, GPIO_RED, BMI_GPIO_ON); // Red LED=OFF ++ break; ++ ++ case BMI_AUDIO_RLEDON: ++ bmi_slot_gpio_write_bit (slot, GPIO_RED, BMI_GPIO_OFF); // Red LED=ON ++ break; ++ ++ case BMI_AUDIO_GLEDOFF: ++ bmi_slot_gpio_write_bit (slot, GPIO_GREEN, BMI_GPIO_ON); // Greem LED=OFF ++ break; ++ ++ case BMI_AUDIO_GLEDON: ++ bmi_slot_gpio_write_bit (slot, GPIO_GREEN, BMI_GPIO_OFF); // Greem LED=ON ++ break; ++ ++ case BMI_AUDIO_SPKON: ++ { ++ printk(KERN_INFO "BMI_AUDIO: SPKOFF Called...\n"); ++ if (ReadByte_IOX (adap, IOX_OUTPUT_REG, &iox_data)) ++ return -ENODEV; ++ printk(KERN_INFO "BMI_AUDIO: IOX Output Read: 0x%x\n", iox_data); ++ if (WriteByte_IOX (adap, IOX_OUTPUT_REG, (iox_data | (1 << IOX_AMP)))) ++ return -ENODEV; ++ } ++ break; ++ case BMI_AUDIO_SPKOFF: ++ { ++ printk(KERN_INFO "BMI_AUDIO: SPKON Called...\n"); ++ if (ReadByte_IOX (adap, IOX_OUTPUT_REG, &iox_data)) ++ return -ENODEV; ++ printk(KERN_INFO "BMI_AUDIO: IOX Output Read: 0x%x\n", iox_data); ++ if (WriteByte_IOX (adap, IOX_OUTPUT_REG, (iox_data & ~(1 << IOX_AMP)))) ++ return -ENODEV; ++ } ++ break; ++ case BMI_AUDIO_SETRST: ++ bmi_slot_gpio_configure_as_output (slot, GPIO_RESET, BMI_GPIO_OFF); // RST = 0; ++ break; ++ ++ case BMI_AUDIO_CLRRST: ++ bmi_slot_gpio_configure_as_output (slot, GPIO_RESET, BMI_GPIO_ON); // RST = 1; ++ break; ++ ++ case BMI_AUDIO_GETSTAT: ++ { ++ int read_data; ++ ++ if(ReadByte_IOX (adap, IOX_INPUT_REG, &iox_data)) ++ return -ENODEV; ++ ++ read_data = iox_data | (bmi_read_gpio_data_reg(slot) << 8); ++ ++ if(put_user(read_data, (int __user *) arg)) ++ return -EFAULT; ++ } ++ break; ++ ++ case BMI_AUDIO_ACTIVATE: ++ audio->active = 0; ++ switch (slot) { ++ case 0: ++ if (bmi_audio[2].active == 0) { ++ audio->active = 1; ++ } ++ break; ++ case 1: ++ if (bmi_audio[3].active == 0) { ++ audio->active = 1; ++ } ++ break; ++ case 2: ++ if (bmi_audio[0].active == 0) { ++ audio->active = 1; ++ } ++ break; ++ case 3: ++ if (bmi_audio[1].active == 0) { ++ audio->active = 1; ++ } ++ break; ++ } ++#ifdef CODEC ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, 0x0)) ++ return -ENODEV; ++ if (audio->active) { // power-up ADC ++ if (WriteByte_CODEC (adap, CODEC_L1L_LPGA, CODEC_L_PGA(0x00) | CODEC_LX_PGA_PU)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_L1R_RPGA, CODEC_L_PGA(0x00) | CODEC_LX_PGA_PU)) ++ return -ENODEV; ++ configure_CODEC(adap, audio); ++ } else { // power-down ADC ++ if (WriteByte_CODEC (adap, CODEC_L1L_LPGA, 0x38)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_L1R_RPGA, 0x38)) ++ return -ENODEV; ++ } ++#endif // CODEC ++ ++ case BMI_AUDIO_DEACTIVATE: ++#ifdef CODEC ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, 0x0)) ++ return -ENODEV; ++ // power-down ADC ++ if (WriteByte_CODEC (adap, CODEC_L1L_LPGA, 0x38)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_L1R_RPGA, 0x38)) ++ return -ENODEV; ++#endif // CODEC ++ audio->active = 0; ++ break; ++ ++ case BMI_AUDIO_WCODEC: ++#ifdef CODEC ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, codec_xfer.page)) ++ return -ENODEV; ++ // write codec register ++ if (WriteByte_CODEC (adap, codec_xfer.reg, codec_xfer.data)) ++ return -ENODEV; ++#endif // CODEC ++ break; ++ ++ case BMI_AUDIO_RCODEC: ++#ifdef CODEC ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, codec_xfer.page)) ++ return -ENODEV; ++ // read codec register ++ if (ReadByte_CODEC (adap, codec_xfer.reg, &codec_xfer.data)) ++ return -ENODEV; ++ if (copy_to_user ((struct codec_xfer *) arg, &codec_xfer, ++ sizeof(struct codec_xfer))) ++ return -EFAULT; ++#endif // CODEC ++ break; ++ ++ default: ++ return -ENOTTY; ++ } ++ ++ return 0; ++} ++ ++// control file operations ++struct file_operations cntl_fops = { ++ .owner = THIS_MODULE, ++ .ioctl = cntl_ioctl, ++ .open = cntl_open, ++ .release = cntl_release, ++}; ++ ++// functionality from mxc-alsa-pmic.h: ++#define DAM_PORT_4 port_4 ++#define DAM_PORT_5 port_5 ++#define TX_WATERMARK 0x4 ++#define RX_WATERMARK 0x6 ++ ++// functionality from mxc-alsa-pmic.c: ++ ++/* ++ * driver buffer policy. ++ * Customize here if the sound is not correct ++ */ ++#define MAX_BUFFER_SIZE (32*1024) ++#define DMA_BUF_SIZE (8*1024) ++#define MIN_PERIOD_SIZE 64 ++#define MIN_PERIOD 2 ++#define MAX_PERIOD 255 ++ ++#define AUD_MUX_CONF 0x0031010 ++#define MASK_2_TS 0xfffffffc ++#define SOUND_CARD13_NAME "PIM_AUDIO13" ++#define SOUND_CARD24_NAME "PIM_AUDIO24" ++ ++// These defines enable DMA chaining for playback and capture respectively. ++#define MXC_SOUND_PLAYBACK_CHAIN_DMA_EN 1 ++#define MXC_SOUND_CAPTURE_CHAIN_DMA_EN 1 ++ ++// ID for the PIM cards ++static char id13[] = "PIM_AUDIO13"; // slots 1 & 3 ++static char id24[] = "PIM_AUDIO24"; // slots 2 & 4 ++ ++#define MXC_ALSA_MAX_PCM_DEV 1 ++#define MXC_ALSA_MAX_PLAYBACK 1 ++#define MXC_ALSA_MAX_CAPTURE 1 ++ ++#define PLAYBACK_STREAM (0) ++#define CAPTURE_STREAM (1) ++ ++#define NUM_CARDS (2) ++ ++/* ++ * This structure is the global configuration of the soundcard ++ * that are accessed by the mixer as well as by the playback/recording ++ * stream. This contains various settings. ++ */ ++typedef struct audio_mixer_control { ++ ++ /* ++ * This variable holds the current volume for ouput devices ++ */ ++ int vol_for_output[OP_MAXDEV]; ++ ++ /* ++ * This variable holds the current volume for input devices ++ */ ++ int vol_for_input[IP_MAXDEV]; ++ ++ /* ++ * This variable holds the current volume for playback devices. ++ */ ++ int master_volume_out; ++ ++ /* ++ * These variables holds the current state of the jack indicators ++ */ ++ int hp_indicator; ++ int mic_indicator; ++ int li_indicator; ++ int lo_indicator; ++ ++ /* ++ * Semaphore used to control the access to this structure. ++ */ ++ struct semaphore sem; ++ ++ /* ++ * These variables are set by PCM stream ++ */ ++ int codec_playback_active; ++ int codec_capture_active; ++ ++} audio_mixer_control_t; ++ ++/* ++ * This structure represents an audio stream in term of ++ * channel DMA, HW configuration on CODEC and AudioMux/SSI ++ */ ++typedef struct audio_stream { ++ /* ++ * identification string ++ */ ++ char *id; ++ ++ /* ++ * numeric identification ++ */ ++ int stream_id; ++ ++ /* ++ * SSI ID on the ARM side ++ */ ++ int ssi; ++ ++ /* ++ * DAM port on the ARM side ++ */ ++ int dam_port; ++ ++ /* ++ * device identifier for DMA ++ */ ++ int dma_wchannel; ++ ++ /* ++ * we are using this stream for transfer now ++ */ ++ int active:1; ++ ++ /* ++ * current transfer period ++ */ ++ int period; ++ ++ /* ++ * current count of transfered periods ++ */ ++ int periods; ++ ++ /* ++ * are we recording - flag used to do DMA trans. for sync ++ */ ++ int tx_spin; ++ ++ /* ++ * Previous offset value for resume ++ */ ++ unsigned int old_offset; ++ ++ /* ++ * for locking in DMA operations ++ */ ++ spinlock_t dma_lock; ++ ++ /* ++ * Alsa substream pointer ++ */ ++ struct snd_pcm_substream *stream; ++ ++} audio_stream_t; ++ ++/* ++ * This structure represents the CODEC sound card with its ++ * streams and its shared parameters ++ */ ++typedef struct snd_card_mxc_bmi_audio { ++ /* ++ * ALSA sound card handle ++ */ ++ struct snd_card *card; ++ ++ /* ++ * ALSA pcm driver type handle ++ */ ++ struct snd_pcm *pcm[MXC_ALSA_MAX_PCM_DEV]; ++ ++ /* ++ * playback & capture streams handle ++ * We can support a maximum of 1 playback streams ++ * We can support a maximum of 1 capture streams ++ */ ++ audio_stream_t s[MXC_ALSA_MAX_CAPTURE + MXC_ALSA_MAX_PLAYBACK]; ++ ++} mxc_bmi_audio_t; ++ ++/* ++ * bmi audio chip parameters for IP/OP and volume controls ++ */ ++audio_mixer_control_t audio_mixer_control[NUM_CARDS]; ++ ++/* ++ * Global variable that represents the CODEC soundcard. ++ */ ++mxc_bmi_audio_t *mxc_audio[NUM_CARDS] = { NULL, NULL }; ++ ++/* ++ * Supported playback rates array ++ */ ++static unsigned int playback_rates_stereo[] = { ++ 8000, ++ 11025, ++ 12000, ++ 16000, ++ 22050, ++ 24000, ++ 32000, ++ 44100, ++ 48000, ++ 88200, ++ 96000 ++}; ++ ++/* ++ * Supported capture rates array ++ */ ++static unsigned int capture_rates_stereo[] = { ++ 8000, ++ 11025, ++ 12000, ++ 16000, ++ 22050, ++ 24000, ++ 32000, ++ 44100, ++ 48000, ++ 88200, ++ 96000 ++}; ++ ++/* ++ * this structure represents the sample rates supported ++ * by CODEC for playback operations on DAC. ++ */ ++static struct snd_pcm_hw_constraint_list hw_playback_rates_stereo = { ++ .count = ARRAY_SIZE(playback_rates_stereo), ++ .list = playback_rates_stereo, ++ .mask = 0, ++}; ++ ++/* ++ * this structure represents the sample rates supported ++ * by capture operations on ADC. ++ */ ++static struct snd_pcm_hw_constraint_list hw_capture_rates_stereo = { ++ .count = ARRAY_SIZE(capture_rates_stereo), ++ .list = capture_rates_stereo, ++ .mask = 0, ++}; ++ ++/* ++ * This function configures audio multiplexer to support ++ * audio data routing in CODEC slave mode. ++ * ++ * @param ssi SSI of the ARM to connect to the DAM. ++ */ ++void configure_dam_bmi_master(int ssi) ++{ ++ int source_port; ++ int target_port; ++ ++ if (ssi == SSI1) { ++ PRINTK("DAM: port 1 -> port 4\n"); ++ source_port = port_1; ++ target_port = port_4; ++ } else { ++ PRINTK("DAM: port 2 -> port 5\n"); ++ source_port = port_2; ++ target_port = port_5; ++ } ++ ++ dam_reset_register (source_port); ++ dam_reset_register (target_port); ++ ++ dam_select_mode (source_port, normal_mode); ++ dam_select_mode (target_port, normal_mode); ++ ++ dam_set_synchronous (source_port, true); ++ dam_set_synchronous (target_port, true); ++ ++ dam_select_RxD_source (source_port, target_port); ++ dam_select_RxD_source (target_port, source_port); ++ ++ dam_select_TxFS_direction (source_port, signal_in); ++ dam_select_TxFS_direction (target_port, signal_out); ++ dam_select_TxFS_source (target_port, false, source_port); ++ ++ dam_select_TxClk_direction (source_port, signal_in); ++ dam_select_TxClk_direction (target_port, signal_out); ++ dam_select_TxClk_source (target_port, false, source_port); ++ ++ dam_select_RxFS_direction (source_port, signal_in); ++ dam_select_RxFS_direction (target_port, signal_out); ++ dam_select_RxFS_source (source_port, false, target_port); ++ dam_select_RxFS_source (target_port, false, source_port); ++ ++ dam_select_RxClk_direction (source_port, signal_in); ++ dam_select_RxClk_direction (target_port, signal_out); ++ dam_select_RxClk_source (source_port, false, target_port); ++ dam_select_RxClk_source (target_port, false, source_port); ++} ++ ++void ssi_rx_sampleRate (int ssi, int samplerate) { ++ struct clk *ssi_clk; ++ ++ ssi_rx_clock_divide_by_two (ssi, false); ++ ssi_rx_clock_prescaler (ssi, false); ++ ssi_rx_frame_rate (ssi, 2); ++ ++ ssi_clk = clk_get (NULL, "usb_pll.0"); ++ ++ if (ssi == SSI1) { ++ ssi_clk = clk_get (NULL, "ssi_clk.0"); ++ } else { ++ ssi_clk = clk_get (NULL, "ssi_clk.1"); ++ } ++ ++ clk_set_rate (ssi_clk, clk_round_rate (ssi_clk, 11289600)); ++ switch (samplerate) { ++ case 8000: ++ ssi_rx_prescaler_modulus (ssi, 17); ++ break; ++ case 11025: ++ ssi_rx_prescaler_modulus (ssi, 12); ++ break; ++ case 16000: ++ ssi_rx_prescaler_modulus (ssi, 8); ++ break; ++ case 22050: ++ ssi_rx_prescaler_modulus (ssi, 6); ++ break; ++ default: ++ if (samplerate != 44100) ++ printk (KERN_ERR ++ "ssi_rx_sampleRate(): samplerate=%d not supported (default to 44100).\n", ++ samplerate); ++ ++ ssi_rx_prescaler_modulus (ssi, 3); ++ break; ++ } ++} ++ ++void ssi_tx_sampleRate (int ssi, int samplerate) { ++ struct clk *ssi_clk; ++ ++ ssi_tx_clock_divide_by_two (ssi, false); ++ ssi_tx_clock_prescaler (ssi, false); ++ ssi_tx_frame_rate (ssi, 2); ++ ++ ssi_clk = clk_get (NULL, "usb_pll.0"); ++ ++ if (ssi == SSI1) { ++ ssi_clk = clk_get (NULL, "ssi_clk.0"); ++ } else { ++ ssi_clk = clk_get (NULL, "ssi_clk.1"); ++ } ++ ++ clk_set_rate (ssi_clk, clk_round_rate (ssi_clk, 11289600)); ++ switch (samplerate) { ++ case 8000: ++ ssi_tx_prescaler_modulus (ssi, 17); ++ break; ++ case 11025: ++ ssi_tx_prescaler_modulus (ssi, 12); ++ break; ++ case 16000: ++ ssi_tx_prescaler_modulus (ssi, 8); ++ break; ++ case 22050: ++ ssi_tx_prescaler_modulus (ssi, 6); ++ break; ++ default: ++ if (samplerate != 44100) ++ printk (KERN_ERR ++ "ssi_tx_sampleRate(): samplerate=%d not supported (default to 44100).\n", ++ samplerate); ++ ++ ssi_tx_prescaler_modulus (ssi, 3); ++ break; ++ } ++} ++ ++/* ++ * This function configures the SSI in order to receive audio ++ * from CODEC (recording). Configuration of SSI consists mainly in ++ * setting the following: ++ * ++ * 1) SSI to use (SSI1 or SSI2) ++ * 2) SSI mode (normal or network. We use always network mode) ++ * 3) SSI STCCR register settings, which control the sample rate (BCL and ++ * FS clocks) ++ * 4) Watermarks for SSI FIFOs as well as timeslots to be used. ++ * 5) Enable SSI. ++ * ++ * @param substream pointer to the structure of the current stream. ++ */ ++void configure_ssi_rx (int ssi) ++{ ++ DPRINTK("configure_ssi_rx: SSI%d\n", ssi + 1); ++ ++ // receive set up ++ ssi_rx_shift_direction (ssi, ssi_msb_first); ++ ssi_rx_clock_polarity (ssi, ssi_clock_on_falling_edge); ++ ssi_rx_frame_sync_active (ssi, ssi_frame_sync_active_low); ++ ssi_rx_frame_sync_length (ssi, ssi_frame_sync_one_word); ++ ssi_rx_early_frame_sync (ssi, ssi_frame_sync_one_bit_before); ++ ssi_rx_word_length (ssi, ssi_16_bits); ++ ssi_rx_bit0 (ssi, false); ++ ++ // FIFO set up ++ ssi_rx_fifo_full_watermark (ssi, ssi_fifo_0, RX_WATERMARK); ++ ssi_rx_fifo_enable (ssi, ssi_fifo_0, true); ++} ++ ++/* ++ * This function configures the SSI in order to ++ * send data to CODEC. Configuration of SSI consists ++ * mainly in setting the following: ++ * ++ * 1) SSI to use (SSI1 or SSI2) ++ * 2) SSI mode (normal for normal use e.g. playback, network for mixing) ++ * 3) SSI STCCR register settings, which control the sample rate (BCL and ++ * FS clocks) ++ * 4) Watermarks for SSI FIFOs as well as timeslots to be used. ++ * 5) Enable SSI. ++ * ++ * @param substream pointer to the structure of the current stream. ++ */ ++void configure_ssi_tx (int ssi) ++{ ++ DPRINTK("configure_ssi_tx: SSI%d\n", ssi + 1); ++ ++ // disable SSI ++ ssi_clock_off (ssi, false); ++ ++ // I2S master, 16 bits, 44.1 KHz ++ // basic I2S settings ++ ssi_network_mode (ssi, true); ++ ssi_synchronous_mode (ssi, true); ++ ssi_tx_shift_direction (ssi, ssi_msb_first); ++ ssi_tx_clock_polarity (ssi, ssi_clock_on_falling_edge); ++ ssi_tx_frame_sync_active (ssi, ssi_frame_sync_active_low); ++ ssi_tx_frame_sync_length (ssi, ssi_frame_sync_one_word); ++ ssi_tx_early_frame_sync (ssi, ssi_frame_sync_one_bit_before); ++ ssi_tx_word_length (ssi, ssi_16_bits); ++ ssi_tx_bit0 (ssi, false); ++ ++ // clocks are being provided by SSI ++ ssi_tx_frame_direction (ssi, ssi_tx_rx_internally); ++ ssi_tx_clock_direction (ssi, ssi_tx_rx_internally); ++ ++ // FIFO set up ++ ssi_tx_fifo_enable (ssi, ssi_fifo_0, true); ++ ssi_tx_fifo_empty_watermark (ssi, ssi_fifo_0, TX_WATERMARK); ++ ++ // Clocking ++ ssi_tx_sampleRate (ssi, 44100); ++ ssi_system_clock (ssi, true); ++ ++ // enable ssi ++ ssi_i2s_mode (ssi, i2s_master); ++ ssi_enable (ssi, true); ++} ++ ++/* ++ * This function configures number of channels for next audio operation ++ * (recording/playback) Number of channels define if sound is stereo ++ * or mono. ++ * ++ * @param substream pointer to the structure of the current stream. ++ * ++ */ ++void set_bmi_channels (struct snd_pcm_substream *substream) ++{ ++ mxc_bmi_audio_t *chip; ++ audio_stream_t *s; ++ ++ chip = snd_pcm_substream_chip (substream); ++ s = &chip->s[substream->pstr->stream]; ++ ++ ssi_tx_mask_time_slot (s->ssi, MASK_2_TS); ++ ssi_rx_mask_time_slot (s->ssi, MASK_2_TS); ++} ++ ++/* ++ * This function configures the DMA channel used to transfer ++ * audio from MCU to CODEC ++ * ++ * @param substream pointer to the structure of the current stream. ++ * @param callback pointer to function that will be ++ * called when a SDMA TX transfer finishes. ++ * ++ * @return 0 on success, -1 otherwise. ++ */ ++static int ++configure_write_channel (audio_stream_t *s, mxc_dma_callback_t callback, int stream_id) ++{ ++ int ret = -1; ++ int channel = -1; ++ ++ if (s->ssi == SSI1) ++ channel = mxc_dma_request (MXC_DMA_SSI1_16BIT_TX0, "ALSA TX DMA1"); ++ else ++ channel = mxc_dma_request (MXC_DMA_SSI2_16BIT_TX0, "ALSA TX DMA2"); ++ ++ if (channel < 0) { ++ PRINTK("error requesting a write dma channel\n"); ++ return -1; ++ } ++ ++ ret = mxc_dma_callback_set (channel, (mxc_dma_callback_t) callback, (void *) s); ++ if (ret != 0) { ++ mxc_dma_free (channel); ++ return -1; ++ } ++ s->dma_wchannel = channel; ++ ++ return 0; ++} ++ ++/* ++ * This function configures the DMA channel used to transfer ++ * audio from CODEC to MCU ++ * ++ * @param substream pointer to the structure of the current stream. ++ * @param callback pointer to function that will be ++ * called when a SDMA RX transfer finishes. ++ * ++ * @return 0 on success, -1 otherwise. ++ */ ++static int configure_read_channel (audio_stream_t *s, ++ mxc_dma_callback_t callback) ++{ ++ int ret = -1; ++ int channel = -1; ++ ++ if (s->ssi == SSI1) ++ channel = mxc_dma_request (MXC_DMA_SSI1_16BIT_RX0, "ALSA RX DMA1"); ++ else ++ channel = mxc_dma_request (MXC_DMA_SSI2_16BIT_RX0, "ALSA RX DMA2"); ++ ++ if (channel < 0) { ++ PRINTK("error requesting a read dma channel\n"); ++ return -1; ++ } ++ ++ ret = ++ mxc_dma_callback_set (channel, (mxc_dma_callback_t) callback, ++ (void *) s); ++ if (ret != 0) { ++ mxc_dma_free (channel); ++ return -1; ++ } ++ s->dma_wchannel = channel; ++ ++ return 0; ++} ++ ++/* ++ * This function frees the stream structure ++ * ++ * @param s pointer to the structure of the current stream. ++ */ ++static void audio_dma_free (audio_stream_t *s) ++{ ++ /* ++ * There is nothing to be done here since the dma channel has been ++ * freed either in the callback or in the stop method ++ */ ++} ++ ++/* ++ * This function gets the dma pointer position during record. ++ * Our DMA implementation does not allow to retrieve this position ++ * when a transfer is active, so, it answers the middle of ++ * the current period beeing transfered ++ * ++ * @param s pointer to the structure of the current stream. ++ * ++ */ ++static u_int audio_get_capture_dma_pos (audio_stream_t *s) ++{ ++ struct snd_pcm_substream *substream; ++ struct snd_pcm_runtime *runtime; ++ unsigned int offset; ++ ++ substream = s->stream; ++ runtime = substream->runtime; ++ offset = 0; ++ ++ // tx_spin value is used here to check if a transfer is active ++ if (s->tx_spin) { ++ offset = (runtime->period_size * (s->periods)) + 0; ++ if (offset >= runtime->buffer_size) ++ offset = 0; ++ DPRINTK("MXC: audio_get_dma_pos offset %d\n", offset); ++ } else { ++ offset = (runtime->period_size * (s->periods)); ++ if (offset >= runtime->buffer_size) ++ offset = 0; ++ DPRINTK("MXC: audio_get_dma_pos BIS offset %d\n", offset); ++ } ++ ++ return offset; ++} ++ ++/* ++ * This function gets the dma pointer position during playback. ++ * Our DMA implementation does not allow to retrieve this position ++ * when a transfer is active, so, it answers the middle of ++ * the current period beeing transfered ++ * ++ * @param s pointer to the structure of the current stream. ++ * ++ */ ++static u_int audio_get_playback_dma_pos (audio_stream_t *s) ++{ ++ struct snd_pcm_substream *substream; ++ struct snd_pcm_runtime *runtime; ++ unsigned int offset; ++ ++ substream = s->stream; ++ runtime = substream->runtime; ++ offset = 0; ++ ++ // tx_spin value is used here to check if a transfer is active ++ if (s->tx_spin) { ++ offset = (runtime->period_size * (s->periods)) + 0; ++ if (offset >= runtime->buffer_size) ++ offset = 0; ++ DPRINTK("MXC: audio_get_dma_pos offset %d\n", offset); ++ } else { ++ offset = (runtime->period_size * (s->periods)); ++ if (offset >= runtime->buffer_size) ++ offset = 0; ++ DPRINTK("MXC: audio_get_dma_pos BIS offset %d\n", offset); ++ } ++ ++ return offset; ++} ++ ++/* ++ * This function stops the current dma transfer for playback ++ * and clears the dma pointers. ++ * ++ * @param substream pointer to the structure of the current stream. ++ * ++ */ ++static void audio_playback_stop_dma (audio_stream_t *s) ++{ ++ unsigned long flags; ++ struct snd_pcm_substream *substream; ++ struct snd_pcm_runtime *runtime; ++ unsigned int dma_size; ++ unsigned int offset; ++ ++ substream = s->stream; ++ runtime = substream->runtime; ++ dma_size = frames_to_bytes (runtime, runtime->period_size); ++ offset = dma_size * s->periods; ++ ++ spin_lock_irqsave (&s->dma_lock, flags); ++ ++ PRINTK("MXC : audio_stop_dma active = 0\n"); ++ s->active = 0; ++ s->period = 0; ++ s->periods = 0; ++ ++ // this stops the dma channel and clears the buffer ptrs ++ mxc_dma_disable (s->dma_wchannel); ++ dma_unmap_single (NULL, runtime->dma_addr + offset, dma_size, ++ DMA_TO_DEVICE); ++ ++ spin_unlock_irqrestore (&s->dma_lock, flags); ++} ++ ++/* ++ * This function stops the current dma transfer for capture ++ * and clears the dma pointers. ++ * ++ * @param substream pointer to the structure of the current stream. ++ * ++ */ ++static void audio_capture_stop_dma (audio_stream_t *s) ++{ ++ unsigned long flags; ++ struct snd_pcm_substream *substream; ++ struct snd_pcm_runtime *runtime; ++ unsigned int dma_size; ++ unsigned int offset; ++ ++ substream = s->stream; ++ runtime = substream->runtime; ++ dma_size = frames_to_bytes (runtime, runtime->period_size); ++ offset = dma_size * s->periods; ++ ++ spin_lock_irqsave (&s->dma_lock, flags); ++ ++ PRINTK("MXC : audio_stop_dma active = 0\n"); ++ s->active = 0; ++ s->period = 0; ++ s->periods = 0; ++ ++ // this stops the dma channel and clears the buffer ptrs ++ mxc_dma_disable (s->dma_wchannel); ++ dma_unmap_single (NULL, runtime->dma_addr + offset, dma_size, ++ DMA_FROM_DEVICE); ++ ++ spin_unlock_irqrestore (&s->dma_lock, flags); ++} ++ ++/* ++ * This function is called whenever a new audio block needs to be ++ * transferred to CODEC. The function receives the address and the size ++ * of the new block and start a new DMA transfer. ++ * ++ * @param substream pointer to the structure of the current stream. ++ * ++ */ ++static void audio_playback_dma (audio_stream_t *s) ++{ ++ struct snd_pcm_substream *substream; ++ struct snd_pcm_runtime *runtime; ++ unsigned int dma_size = 0; ++ unsigned int offset; ++ int ret = 0; ++ mxc_dma_requestbuf_t dma_request; ++ int device; ++ ++ substream = s->stream; ++ runtime = substream->runtime; ++ device = substream->pcm->device; ++ ++ DPRINTK("\nDMA direction %d\(0 is playback 1 is capture)\n", ++ s->stream_id); ++ ++ memset (&dma_request, 0, sizeof (mxc_dma_requestbuf_t)); ++ ++ if (s->active) { ++ if (ssi_get_status(s->ssi) & ssi_transmitter_underrun_0) { ++ ssi_enable (s->ssi, false); ++ ssi_transmit_enable (s->ssi, false); ++ ssi_enable (s->ssi, true); ++ } ++ dma_size = frames_to_bytes (runtime, runtime->period_size); ++ DPRINTK("s->period (%x) runtime->periods (%d)\n", ++ s->period, runtime->periods); ++ DPRINTK("runtime->period_size (%d) dma_size (%d)\n", ++ (unsigned int) runtime->period_size, ++ runtime->dma_bytes); ++ ++ offset = dma_size * s->period; ++ snd_assert (dma_size <= DMA_BUF_SIZE,); ++ ++ dma_request.src_addr = (dma_addr_t) (dma_map_single (NULL, ++ runtime-> ++ dma_area + ++ offset, ++ dma_size, ++ DMA_TO_DEVICE)); ++ ++ if (s->ssi == SSI1) ++ dma_request.dst_addr = (dma_addr_t) (SSI1_BASE_ADDR + MXC_SSI1STX0); ++ else ++ dma_request.dst_addr = (dma_addr_t) (SSI2_BASE_ADDR + MXC_SSI2STX0); ++ dma_request.num_of_bytes = dma_size; ++ ++ DPRINTK("MXC: Start DMA offset (%d) size (%d)\n", offset, ++ runtime->dma_bytes); ++ ++ mxc_dma_config (s->dma_wchannel, &dma_request, 1, ++ MXC_DMA_MODE_WRITE); ++ ret = mxc_dma_enable (s->dma_wchannel); ++ ssi_transmit_enable (s->ssi, true); ++ ssi_enable (s->ssi, true); ++ s->tx_spin = 1; /* FGA little trick to retrieve DMA pos */ ++ ++ if (ret) { ++ DPRINTK("audio_process_dma: cannot queue DMA buffer\ ++ (%i)\n", ret); ++ return; ++ } ++ s->period++; ++ s->period %= runtime->periods; ++ ++#ifdef MXC_SOUND_PLAYBACK_CHAIN_DMA_EN ++ if ((s->period > s->periods) && ((s->period - s->periods) > 1)) { ++ PRINTK("audio playback chain dma: already double buffered\n"); ++ return; ++ } ++ ++ if ((s->period < s->periods) ++ && ((s->period + runtime->periods - s->periods) > 1)) { ++ PRINTK("audio playback chain dma: already double buffered\n"); ++ return; ++ } ++ ++ if (s->period == s->periods) { ++ PRINTK("audio playback chain dma: s->period == s->periods\n"); ++ return; ++ } ++ ++ if (snd_pcm_playback_hw_avail(runtime) < ++ 2 * runtime->period_size) { ++ PRINTK("audio playback chain dma: available data is not enough\n"); ++ return; ++ } ++ ++ PRINTK("audio playback chain dma:to set up the 2nd dma buffer\n"); ++ offset = dma_size * s->period; ++ dma_request.src_addr = (dma_addr_t) (dma_map_single (NULL, ++ runtime-> ++ dma_area + ++ offset, ++ dma_size, ++ DMA_TO_DEVICE)); ++ mxc_dma_config (s->dma_wchannel, &dma_request, 1, ++ MXC_DMA_MODE_WRITE); ++ ret = mxc_dma_enable (s->dma_wchannel); ++ ++ s->period++; ++ s->period %= runtime->periods; ++#endif // MXC_SOUND_PLAYBACK_CHAIN_DMA_EN ++ } ++} ++ ++/* ++ * This function is called whenever a new audio block needs to be ++ * transferred from CODEC. The function receives the address and the size ++ * of the block that will store the audio samples and start a new DMA transfer. ++ * ++ * @param substream pointer to the structure of the current stream. ++ * ++ */ ++static void audio_capture_dma (audio_stream_t *s) ++{ ++ struct snd_pcm_substream *substream; ++ struct snd_pcm_runtime *runtime; ++ unsigned int dma_size; ++ unsigned int offset; ++ int ret = 0; ++ mxc_dma_requestbuf_t dma_request; ++ ++ substream = s->stream; ++ runtime = substream->runtime; ++ ++ DPRINTK("\nDMA direction %d\ ++ (0 is playback 1 is capture)\n", s->stream_id); ++ ++ memset (&dma_request, 0, sizeof (mxc_dma_requestbuf_t)); ++ ++ if (s->active) { ++ dma_size = frames_to_bytes (runtime, runtime->period_size); ++ DPRINTK("s->period (%x) runtime->periods (%d)\n", ++ s->period, runtime->periods); ++ DPRINTK("runtime->period_size (%d) dma_size (%d)\n", ++ (unsigned int) runtime->period_size, ++ runtime->dma_bytes); ++ ++ offset = dma_size * s->period; ++ snd_assert (dma_size <= DMA_BUF_SIZE,); ++ ++ dma_request.dst_addr = (dma_addr_t) (dma_map_single(NULL, ++ runtime-> ++ dma_area + ++ offset, ++ dma_size, ++ DMA_FROM_DEVICE)); ++ if (s->ssi == SSI1) ++ dma_request.src_addr = (dma_addr_t) (SSI1_BASE_ADDR + MXC_SSI1SRX0); ++ else ++ dma_request.src_addr = (dma_addr_t) (SSI2_BASE_ADDR + MXC_SSI2SRX0); ++ dma_request.num_of_bytes = dma_size; ++ ++ DPRINTK("MXC: Start DMA offset (%d) size (%d)\n", offset, ++ runtime->dma_bytes); ++ ++ mxc_dma_config (s->dma_wchannel, &dma_request, 1, ++ MXC_DMA_MODE_READ); ++ ret = mxc_dma_enable (s->dma_wchannel); ++ ++ s->tx_spin = 1; /* FGA little trick to retrieve DMA pos */ ++ ++ if (ret) { ++ DPRINTK("audio_process_dma: cannot queue DMA buffer\ ++ (%i)\n", ret); ++ return; ++ } ++ s->period++; ++ s->period %= runtime->periods; ++ ++#ifdef MXC_SOUND_CAPTURE_CHAIN_DMA_EN ++ if ((s->period > s->periods) && ((s->period - s->periods) > 1)) { ++ PRINTK("audio capture chain dma: already double buffered\n"); ++ return; ++ } ++ ++ if ((s->period < s->periods) ++ && ((s->period + runtime->periods - s->periods) > 1)) { ++ PRINTK("audio capture chain dma: already double buffered\n"); ++ return; ++ } ++ ++ if (s->period == s->periods) { ++ PRINTK("audio capture chain dma: s->period == s->periods\n"); ++ return; ++ } ++ ++ if (snd_pcm_capture_hw_avail (runtime) < ++ 2 * runtime->period_size) { ++ PRINTK("audio capture chain dma: available data is not enough\n"); ++ return; ++ } ++ ++ PRINTK("audio capture chain dma:to set up the 2nd dma buffer\n"); ++ offset = dma_size * s->period; ++ dma_request.dst_addr = (dma_addr_t) (dma_map_single(NULL, ++ runtime-> ++ dma_area + ++ offset, ++ dma_size, ++ DMA_FROM_DEVICE)); ++ mxc_dma_config (s->dma_wchannel, &dma_request, 1, ++ MXC_DMA_MODE_READ); ++ ret = mxc_dma_enable (s->dma_wchannel); ++ ++ s->period++; ++ s->period %= runtime->periods; ++#endif // MXC_SOUND_CAPTURE_CHAIN_DMA_EN ++ } ++} ++ ++/* ++ * This is a callback which will be called ++ * when a TX transfer finishes. The call occurs ++ * in interrupt context. ++ * ++ * @param dat pointer to the structure of the current stream. ++ * ++ */ ++static void audio_playback_dma_callback (void *data, int error, ++ unsigned int count) ++{ ++ audio_stream_t *s; ++ struct snd_pcm_substream *substream; ++ struct snd_pcm_runtime *runtime; ++ unsigned int dma_size; ++ unsigned int previous_period; ++ unsigned int offset; ++ ++ s = data; ++ substream = s->stream; ++ runtime = substream->runtime; ++ previous_period = s->periods; ++ dma_size = frames_to_bytes (runtime, runtime->period_size); ++ offset = dma_size * previous_period; ++ ++ s->tx_spin = 0; ++ s->periods++; ++ s->periods %= runtime->periods; ++ ++ // Give back to the CPU the access to the non cached memory ++ dma_unmap_single (NULL, runtime->dma_addr + offset, dma_size, ++ DMA_TO_DEVICE); ++ ++ /* ++ * If we are getting a callback for an active stream then we inform ++ * the PCM middle layer we've finished a period ++ */ ++ if (s->active) ++ snd_pcm_period_elapsed (s->stream); ++ ++ spin_lock (&s->dma_lock); ++ ++ // Trig next DMA transfer ++ audio_playback_dma (s); ++ ++ spin_unlock (&s->dma_lock); ++} ++ ++/* ++ * This is a callback which will be called when a RX transfer finishes. The ++ * call occurs in interrupt context. ++ * ++ * @param substream pointer to the structure of the current stream. ++ */ ++static void audio_capture_dma_callback (void *data, int error, ++ unsigned int count) ++{ ++ audio_stream_t *s; ++ struct snd_pcm_substream *substream; ++ struct snd_pcm_runtime *runtime; ++ unsigned int dma_size; ++ unsigned int previous_period; ++ unsigned int offset; ++ ++ s = data; ++ substream = s->stream; ++ runtime = substream->runtime; ++ previous_period = s->periods; ++ dma_size = frames_to_bytes (runtime, runtime->period_size); ++ offset = dma_size * previous_period; ++ ++ s->tx_spin = 0; ++ s->periods++; ++ s->periods %= runtime->periods; ++ ++ // Give back to the CPU the access to the non cached memory ++ dma_unmap_single (NULL, runtime->dma_addr + offset, dma_size, ++ DMA_FROM_DEVICE); ++ ++ /* ++ * If we are getting a callback for an active stream then we inform ++ * the PCM middle layer we've finished a period ++ */ ++ if (s->active) ++ snd_pcm_period_elapsed (s->stream); ++ ++ spin_lock (&s->dma_lock); ++ ++ // Trig next DMA transfer ++ audio_capture_dma (s); ++ ++ spin_unlock (&s->dma_lock); ++} ++ ++/* ++ * This function is a dispatcher of command to be executed ++ * by the driver for playback. ++ * ++ * @param substream pointer to the structure of the current stream. ++ * @param cmd command to be executed ++ * ++ * @return 0 on success, -1 otherwise. ++ */ ++static int ++snd_mxc_audio_playback_trigger (struct snd_pcm_substream *substream, int cmd) ++{ ++ mxc_bmi_audio_t *chip; ++ int stream_id = PLAYBACK_STREAM; ++ audio_stream_t *s; ++ int err; ++ int device; ++ ++ device = substream->pcm->device; ++ chip = snd_pcm_substream_chip (substream); ++ stream_id = substream->pstr->stream; ++ s = &chip->s[stream_id]; ++ err = 0; ++ ++ // note local interrupts are already disabled in the midlevel code ++ spin_lock (&s->dma_lock); ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ PRINTK("MXC: SNDRV_PCM_TRIGGER_START\n"); ++ s->tx_spin = 0; ++ // requested stream startup ++ s->active = 1; ++ audio_playback_dma (s); ++ break; ++ case SNDRV_PCM_TRIGGER_STOP: ++ PRINTK("MXC: SNDRV_PCM_TRIGGER_STOP\n"); ++ // requested stream shutdown ++ audio_playback_stop_dma (s); ++ break; ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ PRINTK("MXC : SNDRV_PCM_TRIGGER_SUSPEND active = 0\n"); ++ s->active = 0; ++ s->periods = 0; ++ break; ++ case SNDRV_PCM_TRIGGER_RESUME: ++ PRINTK("MXC: SNDRV_PCM_TRIGGER_RESUME\n"); ++ s->active = 1; ++ s->tx_spin = 0; ++ audio_playback_dma (s); ++ break; ++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ PRINTK("MXC: SNDRV_PCM_TRIGGER_PAUSE_PUSH\n"); ++ s->active = 0; ++ break; ++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ PRINTK("MXC: SNDRV_PCM_TRIGGER_PAUSE_RELEASE\n"); ++ s->active = 1; ++ if (s->old_offset) { ++ s->tx_spin = 0; ++ audio_playback_dma (s); ++ break; ++ } ++ break; ++ default: ++ err = -EINVAL; ++ break; ++ } ++ spin_unlock (&s->dma_lock); ++ return err; ++} ++ ++/* ++ * This function is a dispatcher of command to be executed ++ * by the driver for capture. ++ * ++ * @param substream pointer to the structure of the current stream. ++ * @param cmd command to be executed ++ * ++ * @return 0 on success, -1 otherwise. ++ */ ++static int ++snd_mxc_audio_capture_trigger (struct snd_pcm_substream *substream, int cmd) ++{ ++ mxc_bmi_audio_t *chip; ++ int stream_id; ++ audio_stream_t *s; ++ int err; ++ ++ chip = snd_pcm_substream_chip (substream); ++ stream_id = substream->pstr->stream; ++ s = &chip->s[stream_id]; ++ err = 0; ++ ++ // note local interrupts are already disabled in the midlevel code ++ spin_lock (&s->dma_lock); ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ PRINTK("MXC: SNDRV_PCM_TRIGGER_START\n"); ++ s->tx_spin = 0; ++ // requested stream startup ++ s->active = 1; ++ audio_capture_dma (s); ++ break; ++ case SNDRV_PCM_TRIGGER_STOP: ++ PRINTK("MXC: SNDRV_PCM_TRIGGER_STOP\n"); ++ // requested stream shutdown ++ audio_capture_stop_dma (s); ++ break; ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ PRINTK("MXC : SNDRV_PCM_TRIGGER_SUSPEND active = 0\n"); ++ s->active = 0; ++ s->periods = 0; ++ break; ++ case SNDRV_PCM_TRIGGER_RESUME: ++ PRINTK("MXC: SNDRV_PCM_TRIGGER_RESUME\n"); ++ s->active = 1; ++ s->tx_spin = 0; ++ audio_capture_dma (s); ++ break; ++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ PRINTK("MXC: SNDRV_PCM_TRIGGER_PAUSE_PUSH\n"); ++ s->active = 0; ++ break; ++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ PRINTK("MXC: SNDRV_PCM_TRIGGER_PAUSE_RELEASE\n"); ++ s->active = 1; ++ if (s->old_offset) { ++ s->tx_spin = 0; ++ audio_capture_dma (s); ++ break; ++ } ++ break; ++ default: ++ err = -EINVAL; ++ break; ++ } ++ spin_unlock (&s->dma_lock); ++ return err; ++} ++ ++/* ++ * This function configures the hardware to allow audio ++ * playback operations. It is called by ALSA framework. ++ * ++ * @param substream pointer to the structure of the current stream. ++ * ++ * @return 0 on success, -1 otherwise. ++ */ ++static int snd_mxc_audio_playback_prepare (struct snd_pcm_substream *substream) ++{ ++ mxc_bmi_audio_t *chip; ++ audio_stream_t *s; ++ int ssi; ++ int device = -1; ++ int stream_id = PLAYBACK_STREAM; ++ struct snd_pcm_runtime *runtime; ++ ++ device = substream->pcm->device; ++ ++ chip = snd_pcm_substream_chip (substream); ++ runtime = substream->runtime; ++ s = &chip->s[stream_id]; ++ ssi = s->ssi; ++ ++ configure_dam_bmi_master (ssi); ++ configure_ssi_rx (ssi); ++ ssi_rx_sampleRate (ssi, runtime->rate); ++ configure_ssi_tx (ssi); ++ ssi_tx_sampleRate (ssi, runtime->rate); ++ set_bmi_channels (substream); ++ ssi_interrupt_enable (ssi, ssi_tx_dma_interrupt_enable); ++ ssi_interrupt_enable(ssi, ssi_tx_interrupt_enable); ++ ssi_interrupt_enable (ssi, ssi_tx_fifo_0_empty); ++ ssi_enable(ssi, true); ++ ++ s->period = 0; ++ s->periods = 0; ++ ++ msleep (100); ++ ++ return 0; ++} ++ ++/* ++ * This function gets the current capture pointer position. ++ * It is called by ALSA framework. ++ * ++ * @param substream pointer to the structure of the current stream. ++ * ++ */ ++static snd_pcm_uframes_t ++snd_mxc_audio_capture_pointer (struct snd_pcm_substream *substream) ++{ ++ mxc_bmi_audio_t *chip; ++ ++ chip = snd_pcm_substream_chip (substream); ++ return audio_get_capture_dma_pos (&chip->s[substream->pstr->stream]); ++} ++ ++/* ++ * This function gets the current playback pointer position. ++ * It is called by ALSA framework. ++ * ++ * @param substream pointer to the structure of the current stream. ++ * ++ */ ++static snd_pcm_uframes_t ++snd_mxc_audio_playback_pointer (struct snd_pcm_substream *substream) ++{ ++ mxc_bmi_audio_t *chip; ++ int device; ++ int stream_id; ++ device = substream->pcm->device; ++ stream_id = PLAYBACK_STREAM; ++ chip = snd_pcm_substream_chip (substream); ++ return audio_get_playback_dma_pos (&chip->s[stream_id]); ++} ++ ++/* ++ * This structure reprensents the capabilities of the driver ++ * in capture mode. ++ * It is used by ALSA framework. ++ */ ++static struct snd_pcm_hardware snd_mxc_bmi_capture = { ++ .info = (SNDRV_PCM_INFO_INTERLEAVED | ++ SNDRV_PCM_INFO_BLOCK_TRANSFER | ++ SNDRV_PCM_INFO_MMAP | ++ SNDRV_PCM_INFO_MMAP_VALID | ++ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), ++ .formats = SNDRV_PCM_FMTBIT_S16_LE, ++ .rates = (SNDRV_PCM_RATE_8000_96000 | SNDRV_PCM_RATE_CONTINUOUS), ++ .rate_min = 8000, ++ .rate_max = 96000, ++ .channels_min = 1, ++ .channels_max = 2, ++ .buffer_bytes_max = MAX_BUFFER_SIZE, ++ .period_bytes_min = MIN_PERIOD_SIZE, ++ .period_bytes_max = DMA_BUF_SIZE, ++ .periods_min = MIN_PERIOD, ++ .periods_max = MAX_PERIOD, ++ .fifo_size = 0, ++}; ++ ++/* ++ * This structure reprensents the capabilities of the driver ++ * in playback mode for ST-Dac. ++ * It is used by ALSA framework. ++ */ ++static struct snd_pcm_hardware snd_mxc_bmi_playback_stereo = { ++ .info = (SNDRV_PCM_INFO_INTERLEAVED | ++ SNDRV_PCM_INFO_BLOCK_TRANSFER | ++ SNDRV_PCM_INFO_MMAP | ++ SNDRV_PCM_INFO_MMAP_VALID | ++ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), ++ .formats = SNDRV_PCM_FMTBIT_S16_LE, ++ .rates = (SNDRV_PCM_RATE_8000_96000 | SNDRV_PCM_RATE_CONTINUOUS), ++ .rate_min = 8000, ++ .rate_max = 96000, ++ .channels_min = 1, ++ .channels_max = 2, ++ .buffer_bytes_max = MAX_BUFFER_SIZE, ++ .period_bytes_min = MIN_PERIOD_SIZE, ++ .period_bytes_max = DMA_BUF_SIZE, ++ .periods_min = MIN_PERIOD, ++ .periods_max = MAX_PERIOD, ++ .fifo_size = 0, ++}; ++ ++/* ++ * This function opens a CODEC audio device in playback mode ++ * It is called by ALSA framework. ++ * ++ * @param substream pointer to the structure of the current stream. ++ * ++ * @return 0 on success, -1 otherwise. ++ */ ++static int snd_card_mxc_audio_playback_open (struct snd_pcm_substream *substream) ++{ ++ mxc_bmi_audio_t *chip; ++ struct snd_pcm_runtime *runtime; ++ int stream_id = -1; ++ int err; ++ int device = -1; ++ ++ device = substream->pcm->device; ++ ++ chip = snd_pcm_substream_chip (substream); ++ runtime = substream->runtime; ++ stream_id = PLAYBACK_STREAM; ++ ++ err = -1; ++ ++ audio_mixer_control[chip->s->ssi].codec_playback_active = 1; ++ ++ chip->s[stream_id].stream = substream; ++ ++ runtime->hw = snd_mxc_bmi_playback_stereo; ++ ++ if ((err = snd_pcm_hw_constraint_integer (runtime, ++ SNDRV_PCM_HW_PARAM_PERIODS)) < ++ 0) ++ return err; ++ if ((err = snd_pcm_hw_constraint_list (runtime, 0, SNDRV_PCM_HW_PARAM_RATE, ++ &hw_playback_rates_stereo)) < 0) ++ return err; ++ ++ msleep (10); ++ ++ // setup DMA controller for playback ++ if ((err = ++ configure_write_channel (&mxc_audio[chip->s->ssi]->s[stream_id], ++ audio_playback_dma_callback, ++ stream_id)) < 0) ++ return err; ++ ++ return 0; ++} ++ ++/* ++ * This function closes an CODEC audio device for playback. ++ * It is called by ALSA framework. ++ * ++ * @param substream pointer to the structure of the current stream. ++ * ++ * @return 0 on success, -1 otherwise. ++ */ ++static int snd_card_mxc_audio_playback_close (struct snd_pcm_substream *substream) ++{ ++ mxc_bmi_audio_t *chip; ++ audio_stream_t *s; ++ int ssi; ++ int device, stream_id = -1; ++ ++ device = substream->pcm->device; ++ stream_id = PLAYBACK_STREAM; ++ ++ chip = snd_pcm_substream_chip (substream); ++ s = &chip->s[stream_id]; ++ ssi = s->ssi; ++ ++ audio_mixer_control[chip->s->ssi].codec_playback_active = 0; ++ ++ ssi_tx_fifo_enable (ssi, ssi_fifo_0, false); ++ ssi_interrupt_disable (ssi, ssi_tx_interrupt_enable); ++ ssi_interrupt_disable (ssi, ssi_tx_dma_interrupt_enable); ++ ssi_interrupt_disable (ssi, ssi_tx_fifo_0_empty); ++ mxc_dma_free ((mxc_audio[ssi]->s[stream_id]).dma_wchannel); ++ ++ chip->s[stream_id].stream = NULL; ++ ++ return 0; ++} ++ ++/* ++ * This function closes a audio device for capture. ++ * It is called by ALSA framework. ++ * ++ * @param substream pointer to the structure of the current stream. ++ * ++ * @return 0 on success, -1 otherwise. ++ */ ++static int snd_card_mxc_audio_capture_close (struct snd_pcm_substream *substream) ++{ ++ mxc_bmi_audio_t *chip; ++ audio_stream_t *s; ++ int ssi; ++ ++ chip = snd_pcm_substream_chip (substream); ++ s = &chip->s[substream->pstr->stream]; ++ ssi = s->ssi; ++ ++ audio_mixer_control[ssi].codec_capture_active = 0; ++ ++ ssi_rx_fifo_enable (ssi, ssi_fifo_0, false); ++ ssi_interrupt_disable(ssi, ssi_rx_interrupt_enable); ++ ssi_interrupt_disable (ssi, ssi_rx_dma_interrupt_enable); ++ ssi_interrupt_disable (ssi, ssi_rx_fifo_0_full); ++ mxc_dma_free ((mxc_audio[ssi]->s[1]).dma_wchannel); ++ ++ chip->s[substream->pstr->stream].stream = NULL; ++ ++ return 0; ++} ++ ++/* ++ * This function configure the Audio HW in terms of memory allocation. ++ * It is called by ALSA framework. ++ * ++ * @param substream pointer to the structure of the current stream. ++ * ++ * @return 0 on success, -1 otherwise. ++ */ ++static int snd_mxc_audio_hw_params (struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *hw_params) ++{ ++ struct snd_pcm_runtime *runtime; ++ int ret; ++ ++ runtime = substream->runtime; ++ ret = ++ snd_pcm_lib_malloc_pages (substream, params_buffer_bytes (hw_params)); ++ if (ret < 0) ++ return ret; ++ ++ runtime->dma_addr = virt_to_phys (runtime->dma_area); ++ ++ DPRINTK("MXC: snd_mxc_audio_hw_params runtime->dma_addr 0x(%x)\n", ++ (unsigned int) runtime->dma_addr); ++ DPRINTK("MXC: snd_mxc_audio_hw_params runtime->dma_area 0x(%x)\n", ++ (unsigned int) runtime->dma_area); ++ DPRINTK("MXC: snd_mxc_audio_hw_params runtime->dma_bytes 0x(%x)\n", ++ (unsigned int) runtime->dma_bytes); ++ ++ return ret; ++} ++ ++/* ++ * This function frees the audio hardware at the end of playback/capture. ++ * ++ * @param substream pointer to the structure of the current stream. ++ * ++ * @return 0 on success, -1 otherwise. ++ */ ++static int snd_mxc_audio_hw_free (struct snd_pcm_substream *substream) ++{ ++ return snd_pcm_lib_free_pages (substream); ++} ++ ++/* ++ * This function configures the hardware to allow audio ++ * capture operations. It is called by ALSA framework. ++ * ++ * @param substream pointer to the structure of the current stream. ++ * ++ * @return 0 on success, -1 otherwise. ++ */ ++static int snd_mxc_audio_capture_prepare (struct snd_pcm_substream *substream) ++{ ++ mxc_bmi_audio_t *chip; ++ audio_stream_t *s; ++ struct snd_pcm_runtime *runtime; ++ int ssi; ++ ++ chip = snd_pcm_substream_chip (substream); ++ runtime = substream->runtime; ++ s = &chip->s[substream->pstr->stream]; ++ ssi = s->ssi; ++ ++ DPRINTK("substream->pstr->stream %d\n", substream->pstr->stream); ++ DPRINTK("SSI%d\n", ssi + 1); ++ ++ configure_dam_bmi_master (ssi); ++ configure_ssi_tx (ssi); ++ ssi_tx_sampleRate (ssi, runtime->rate); ++ configure_ssi_rx (ssi); ++ ssi_rx_sampleRate (ssi, runtime->rate); ++ ++ ssi_interrupt_enable (ssi, ssi_rx_fifo_0_full); ++ ssi_interrupt_enable (ssi, ssi_rx_dma_interrupt_enable); ++ ssi_interrupt_enable (ssi, ssi_rx_interrupt_enable); ++ set_bmi_channels (substream); ++ ssi_receive_enable (ssi, true); ++ ++ msleep(20); ++ ++ s->period = 0; ++ s->periods = 0; ++ ++ return 0; ++} ++ ++/* ++ * This function opens an audio device in capture mode on Codec. ++ * It is called by ALSA framework. ++ * ++ * @param substream pointer to the structure of the current stream. ++ * ++ * @return 0 on success, -1 otherwise. ++ */ ++static int snd_card_mxc_audio_capture_open (struct snd_pcm_substream *substream) ++{ ++ mxc_bmi_audio_t *chip; ++ struct snd_pcm_runtime *runtime; ++ int stream_id; ++ int err; ++ ++ chip = snd_pcm_substream_chip (substream); ++ runtime = substream->runtime; ++ stream_id = substream->pstr->stream; ++ err = -1; ++ ++ audio_mixer_control[chip->s->ssi].codec_capture_active = 1; ++ ++ chip->s[stream_id].stream = substream; ++ ++ if (stream_id == SNDRV_PCM_STREAM_CAPTURE) { ++ runtime->hw = snd_mxc_bmi_capture; ++ } else { ++ return err; ++ } ++ ++ if ((err = snd_pcm_hw_constraint_integer (runtime, ++ SNDRV_PCM_HW_PARAM_PERIODS)) < ++ 0) { ++ return err; ++ } ++ ++ if ((err = snd_pcm_hw_constraint_list (runtime, 0, ++ SNDRV_PCM_HW_PARAM_RATE, ++ &hw_capture_rates_stereo)) < 0) { ++ return err; ++ } ++ ++ // setup DMA controller for Record ++ err = configure_read_channel (&mxc_audio[chip->s->ssi]->s[SNDRV_PCM_STREAM_CAPTURE], ++ audio_capture_dma_callback); ++ if (err < 0) { ++ return err; ++ } ++ ++ msleep (50); ++ ++ return 0; ++} ++ ++/* ++ * This structure is the list of operation that the driver ++ * must provide for the capture interface ++ */ ++static struct snd_pcm_ops snd_card_mxc_audio_capture_ops = { ++ .open = snd_card_mxc_audio_capture_open, ++ .close = snd_card_mxc_audio_capture_close, ++ .ioctl = snd_pcm_lib_ioctl, ++ .hw_params = snd_mxc_audio_hw_params, ++ .hw_free = snd_mxc_audio_hw_free, ++ .prepare = snd_mxc_audio_capture_prepare, ++ .trigger = snd_mxc_audio_capture_trigger, ++ .pointer = snd_mxc_audio_capture_pointer, ++}; ++ ++/* ++ * This structure is the list of operation that the driver ++ * must provide for the playback interface ++ */ ++static struct snd_pcm_ops snd_card_mxc_audio_playback_ops = { ++ .open = snd_card_mxc_audio_playback_open, ++ .close = snd_card_mxc_audio_playback_close, ++ .ioctl = snd_pcm_lib_ioctl, ++ .hw_params = snd_mxc_audio_hw_params, ++ .hw_free = snd_mxc_audio_hw_free, ++ .prepare = snd_mxc_audio_playback_prepare, ++ .trigger = snd_mxc_audio_playback_trigger, ++ .pointer = snd_mxc_audio_playback_pointer, ++}; ++ ++/* ++ * This functions initializes the capture audio device supported by ++ * CODEC IC. ++ * ++ * @param mxc_audio pointer to the sound card structure ++ * @param device SSI interface ++ */ ++void init_device_capture (mxc_bmi_audio_t *mxc_audio, int device) ++{ ++ audio_stream_t *audio_stream; ++ ++ audio_stream = &mxc_audio->s[SNDRV_PCM_STREAM_CAPTURE]; ++ ++ /* ++ * These parameters defines the identity of ++ * the device (stereoadc or stereodac) ++ */ ++ if (device == 0) { ++ audio_stream->ssi = SSI1; ++ audio_stream->dam_port = DAM_PORT_4; ++ } else { ++ audio_stream->ssi = SSI2; ++ audio_stream->dam_port = DAM_PORT_5; ++ } ++} ++ ++/* ++ * This functions initializes the playback audio device supported by ++ * CODEC IC. ++ * ++ * @param mxc_audio pointer to the sound card structure. ++ * @param device SSI interface ++ */ ++void init_device_playback (mxc_bmi_audio_t *mxc_audio, int device) ++{ ++ audio_stream_t *audio_stream; ++ audio_stream = &mxc_audio->s[0]; ++ ++ /* These parameters defines the identity of ++ * the device (codec or stereodac) ++ */ ++ if (device == 0) { ++ audio_stream->ssi = SSI1; ++ audio_stream->dam_port = DAM_PORT_4; ++ } else { ++ audio_stream->ssi = SSI2; ++ audio_stream->dam_port = DAM_PORT_5; ++ } ++} ++ ++void mxc_bmi_mixer_controls_init (mxc_bmi_audio_t *mxc_audio, int device) ++{ ++ audio_mixer_control_t *audio_control; ++ struct i2c_adapter *adap = 0; ++ char iox_data[1]; ++ int i = 0; ++ ++ audio_control = &audio_mixer_control[device]; ++ ++ memset (audio_control, 0, sizeof (audio_mixer_control_t)); ++ sema_init (&audio_control->sem, 1); ++ ++ for (i = 0; i < OP_MAXDEV; i++) { ++ audio_control->vol_for_output[i] = 9; // maximum gain ++ } ++ for (i = 0; i < IP_MAXDEV; i++) { ++ audio_control->vol_for_input[i] = 4; // gain = -6 dB ++ } ++ ++ audio_control->master_volume_out = 127; ++ ++ if(device == 0) { ++ if (bmi_audio[0].active == 1) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[0].bdev); ++ } else if (bmi_audio[2].active == 1) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[2].bdev); ++ } ++ } else { ++ if (bmi_audio[1].active == 1) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[1].bdev); ++ } else if (bmi_audio[3].active == 1) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[3].bdev); ++ } ++ } ++ ++ if (adap) { ++ // IOX status ++ if (ReadByte_IOX (adap, IOX_INPUT_REG, iox_data) == 0) { ++ audio_control->lo_indicator = (*iox_data >> IOX_LO_INS) & 0x1; ++ audio_control->li_indicator = (*iox_data >> IOX_LI_INS) & 0x1; ++ audio_control->mic_indicator = (*iox_data >> IOX_MIC_INS) & 0x1; ++ audio_control->hp_indicator = (*iox_data >> IOX_HP_INS) & 0x1; ++ } ++ } ++} ++ ++/* ++ * This functions initializes the audio devices supported by ++ * CODEC IC. ++ * ++ * @param mxc_audio pointer to the sound card structure. ++ * @param device SSi interface ++ */ ++void mxc_bmi_audio_init (mxc_bmi_audio_t *mxc_audio, int device) ++{ ++ mxc_audio->s[SNDRV_PCM_STREAM_PLAYBACK].id = "Audio out"; ++ mxc_audio->s[SNDRV_PCM_STREAM_PLAYBACK].stream_id = SNDRV_PCM_STREAM_PLAYBACK; ++ mxc_audio->s[SNDRV_PCM_STREAM_CAPTURE].id = "Audio in"; ++ mxc_audio->s[SNDRV_PCM_STREAM_CAPTURE].stream_id = SNDRV_PCM_STREAM_CAPTURE; ++ ++ init_device_playback (mxc_audio, device); ++ init_device_capture (mxc_audio, device); ++} ++ ++/* ++ * This function initializes the soundcard structure. ++ * ++ * @param mxc_audio pointer to the sound card structure. ++ * @param device the device index (zero based) ++ * ++ * @return 0 on success, -1 otherwise. ++ */ ++static int __init snd_card_mxc_audio_pcm (mxc_bmi_audio_t *mxc_audio, int device) ++{ ++ struct snd_pcm *pcm; ++ int err; ++ ++ // Create a new PCM instance with 1 capture stream and 1 playback substream ++ if (device == 0) { ++ if ((err = snd_pcm_new (mxc_audio->card, "PIM_AUDIO13", 0, 1, 1, &pcm)) < 0) { ++ return err; ++ } ++ } else { ++ if ((err = snd_pcm_new (mxc_audio->card, "PIM_AUDIO24", 0, 1, 1, &pcm)) < 0) { ++ return err; ++ } ++ } ++ ++ /* ++ * this sets up our initial buffers and sets the dma_type to isa. ++ * isa works but I'm not sure why (or if) it's the right choice ++ * this may be too large, trying it for now ++ */ ++ snd_pcm_lib_preallocate_pages_for_all (pcm, SNDRV_DMA_TYPE_CONTINUOUS, ++ snd_dma_continuous_data ++ (GFP_KERNEL), MAX_BUFFER_SIZE * 2, ++ MAX_BUFFER_SIZE * 2); ++ ++ snd_pcm_set_ops (pcm, SNDRV_PCM_STREAM_PLAYBACK, ++ &snd_card_mxc_audio_playback_ops); ++ snd_pcm_set_ops (pcm, SNDRV_PCM_STREAM_CAPTURE, ++ &snd_card_mxc_audio_capture_ops); ++ ++ pcm->private_data = mxc_audio; ++ pcm->info_flags = 0; ++ if (device == 0) ++ strncpy (pcm->name, SOUND_CARD13_NAME, sizeof (pcm->name)); ++ else ++ strncpy (pcm->name, SOUND_CARD24_NAME, sizeof (pcm->name)); ++ mxc_audio->pcm[0] = pcm; ++ mxc_bmi_audio_init (mxc_audio, device); ++ mxc_bmi_mixer_controls_init (mxc_audio, device); ++ ++ return 0; ++} ++ ++#if 0 //pjg - POWER_MANAGEMENT ++#ifdef CONFIG_PM ++/* ++ * This function suspends all active streams. ++ * ++ * TBD ++ * ++ * @param card pointer to the sound card structure. ++ * @param state requested state ++ * ++ * @return 0 on success, -1 otherwise. ++ */ ++static int snd_mxc_audio_suspend (struct bmi_device *bdev, ++ pm_message_t state) ++{ ++ struct snd_card *card = bmi_device_get_drvdata (bdev); ++ mxc_bmi_audio_t *chip = card->private_data; ++ ++ snd_power_change_state (card, SNDRV_CTL_POWER_D3hot); ++ snd_pcm_suspend_all (chip->pcm[0]); ++ //mxc_alsa_audio_shutdown (chip); ++ ++ return 0; ++} ++ ++/* ++ * This function resumes all suspended streams. ++ * ++ * TBD ++ * ++ * @param card pointer to the sound card structure. ++ * @param state requested state ++ * ++ * @return 0 on success, -1 otherwise. ++ */ ++static int snd_mxc_audio_resume (struct bmi_device *bdev) ++{ ++ struct snd_card *card = bmi_device_get_drvdata (bdev); ++ ++ snd_power_change_state (card, SNDRV_CTL_POWER_D0); ++ ++ return 0; ++} ++#endif // CONFIG_PM ++#endif //pjg - POWER_MANAGEMENT ++ ++/* ++ * This function frees the sound card structure ++ * ++ * @param card pointer to the sound card structure. ++ * ++ * @return 0 on success, -1 otherwise. ++ */ ++void snd_mxc_audio_free (struct snd_card *card) ++{ ++ mxc_bmi_audio_t *chip; ++ ++ chip = card->private_data; ++ audio_dma_free (&chip->s[SNDRV_PCM_STREAM_PLAYBACK]); ++ audio_dma_free (&chip->s[SNDRV_PCM_STREAM_CAPTURE]); ++ mxc_audio[chip->s->ssi] = NULL; ++ card->private_data = NULL; ++ kfree (chip); ++ ++} ++ ++/* ++ * Input interrupt handler and support routines ++ */ ++ ++ // work handler ++void bmiaudio_input_work (void *arg, int slot) { ++ struct bmi_audio *audio = (struct bmi_audio *) arg; ++ audio_mixer_control_t *audio_control; ++ struct i2c_adapter *adap; ++ unsigned char iox_data[1]; ++ int input_data; ++ ++ if (audio->bdev == 0) { ++ printk (KERN_INFO ++ "bmi_audio.c: bmi_audio_input work called with no bdev (slot %d)\n", ++ slot); ++ return; ++ } ++ ++ if (bmi_device_present (audio->bdev) == 0) { ++ printk (KERN_INFO ++ "bmi_audio.c: bmi_audio_input work called with no bdev active (slot %d)\n", ++ slot); ++ return; ++ } ++ ++ adap = bmi_device_get_i2c_adapter (audio->bdev); ++ ++ // IOX status ++ if (ReadByte_IOX (adap, IOX_INPUT_REG, iox_data) != 0) { ++ return; ++ } ++ input_data = 0; ++ if ((*iox_data & GETSTAT_VOLP) == 0) ++ input_data |= VOLUME_UP; ++ if ((*iox_data & GETSTAT_VOLD) == 0) ++ input_data |= VOLUME_DOWN; ++ if ((*iox_data & GETSTAT_LI_INS) == GETSTAT_LI_INS) ++ input_data |= LINEIN_INSERTED; ++ if ((*iox_data & GETSTAT_MIC_INS) != GETSTAT_MIC_INS) ++ input_data |= MICROPHONE_INSERTED; ++ if (output_ints) { ++ if ((*iox_data & GETSTAT_LO_INS) == GETSTAT_LO_INS) ++ input_data |= LINEOUT_INSERTED; ++ if ((*iox_data & GETSTAT_HP_INS) == GETSTAT_HP_INS) ++ input_data |= HEADPHONE_INSERTED; ++ } ++ input_report_abs (audio->input_dev, ABS_MISC, input_data); ++ input_sync (audio->input_dev); ++ ++ if ((slot == 0) || (slot == 2)) { ++ audio_control = &audio_mixer_control[0]; ++ } else { ++ audio_control = &audio_mixer_control[1]; ++ } ++ ++ if (down_interruptible (&audio_control->sem) == 0) { ++ audio_control->lo_indicator = (*iox_data >> IOX_LO_INS) & 0x1; ++ audio_control->li_indicator = (*iox_data >> IOX_LI_INS) & 0x1; ++ audio_control->mic_indicator = (*iox_data >> IOX_MIC_INS) & 0x1; ++ audio_control->hp_indicator = (*iox_data >> IOX_HP_INS) & 0x1; ++ up (&audio_control->sem); ++ } ++ ++ enable_irq (audio->irq); ++ return; ++} ++ ++void bmiaudio_input_work0 (struct work_struct *work) { ++ bmiaudio_input_work (&bmi_audio[0], 0); ++} ++ ++void bmiaudio_input_work1 (struct work_struct *work) { ++ bmiaudio_input_work (&bmi_audio[1], 1); ++} ++ ++void bmiaudio_input_work2 (struct work_struct *work) { ++ bmiaudio_input_work (&bmi_audio[2], 2); ++} ++ ++void bmiaudio_input_work3 (struct work_struct *work) { ++ bmiaudio_input_work (&bmi_audio[3], 3); ++} ++ ++DECLARE_DELAYED_WORK(bmiaudio_work0, bmiaudio_input_work0); ++DECLARE_DELAYED_WORK(bmiaudio_work1, bmiaudio_input_work1); ++DECLARE_DELAYED_WORK(bmiaudio_work2, bmiaudio_input_work2); ++DECLARE_DELAYED_WORK(bmiaudio_work3, bmiaudio_input_work3); ++ ++static irqreturn_t module_irq_handler (int irq, void *dummy) ++{ ++ disable_irq_nosync (irq); ++ ++ switch (irq) { ++ case M1_IRQ: ++ schedule_delayed_work (&bmiaudio_work0, WORK_DELAY); ++ break; ++ case M2_IRQ: ++ schedule_delayed_work (&bmiaudio_work1, WORK_DELAY); ++ break; ++ case M3_IRQ: ++ schedule_delayed_work (&bmiaudio_work2, WORK_DELAY); ++ break; ++ case M4_IRQ: ++ schedule_delayed_work (&bmiaudio_work3, WORK_DELAY); ++ break; ++ } ++ return IRQ_HANDLED; ++} ++ ++/* ++ * Configure the CODEC registers to the initial values ++ */ ++ ++static int configure_CODEC(struct i2c_adapter *adap, struct bmi_audio *audio) ++{ ++ unsigned char codec_data[1]; ++ ++ // page select = 0 ++ if (WriteByte_CODEC (adap, CODEC_PAGE_SEL, 0x00)) ++ goto nodev; ++ if (ReadByte_CODEC (adap, CODEC_PAGE_SEL, codec_data)) ++ goto nodev; ++ if (*codec_data != 0x00) ++ goto nodev; ++ ++ // ADC,DAC SR = SR/1 ++ if (WriteByte_CODEC (adap, CODEC_SAMPLE_RATE, (CODEC_SR1 << CODEC_SR_SHIFT) | CODEC_SR1)) ++ goto nodev; ++ ++ // PLL disabled, Q = 2 => Fsref = 46875 Hz ++ if (WriteByte_CODEC (adap, CODEC_PLLA, CODEC_PLLA_DIS | CODEC_PLLA_Q(2))) ++ goto nodev; ++ ++ // CODEC datapath normal ++ if (WriteByte_CODEC (adap, CODEC_DATAPATH, ++ CODEC_DP_44 | CODEC_DP_L(CODEC_DP_REVERSE) | CODEC_DP_R(CODEC_DP_NORMAL))) ++ goto nodev; ++ ++ // CODEC is slave ++ if (WriteByte_CODEC (adap, CODEC_AIFA, CODEC_AIFA_BCLK_S | CODEC_AIFA_WCLK_S | ++ CODEC_AIFA_DOUT_TS | CODEC_AIFA_CLK_F | CODEC_AIFA_FX_OFF)) ++ goto nodev; ++ ++ // CODEC is in I2S mode, WL = 32 ++ if (WriteByte_CODEC (adap, CODEC_AIFB, CODEC_AIFB_I2S | CODEC_AIFB_32)) ++ goto nodev; ++ ++ // HP outputs AC coupled ++ if (WriteByte_CODEC (adap, CODEC_HS, CODEC_HS_COUPLED | CODEC_HS_ADIFF)) ++ goto nodev; ++ ++ // ADC PGA not muted, maximum gain ++ if (WriteByte_CODEC (adap, CODEC_LADC_PGA, CODEC_ADC_PGA_G(0x3C))) // 59 dB ++ goto nodev; ++ if (WriteByte_CODEC (adap, CODEC_RADC_PGA, CODEC_ADC_PGA_G(0x3C))) // 59 dB ++ goto nodev; ++ ++ // M3R -> [LR]PGA -6 dB gain, M3L muted ++ if (WriteByte_CODEC (adap, CODEC_M3_LPGA, CODEC_M3_PGA_R(0x04) | CODEC_M3_PGA_LOFF)) ++ goto nodev; ++ if (WriteByte_CODEC (adap, CODEC_M3_RPGA, CODEC_M3_PGA_R(0x04) | CODEC_M3_PGA_LOFF)) ++ goto nodev; ++ ++ // L1 -> [LR]PGA gain = -6 dB ++ // selectively activate ADC ++ if (audio->active) { ++ if (WriteByte_CODEC (adap, CODEC_L1L_LPGA, CODEC_L_PGA(0x04) | CODEC_LX_PGA_PU)) ++ goto nodev; ++ if (WriteByte_CODEC (adap, CODEC_L1R_RPGA, CODEC_L_PGA(0x04) | CODEC_LX_PGA_PU)) ++ goto nodev; ++ } else { ++ if (WriteByte_CODEC (adap, CODEC_L1L_LPGA, CODEC_L_PGA(0x0F))) ++ goto nodev; ++ if (WriteByte_CODEC (adap, CODEC_L1R_RPGA, CODEC_L_PGA(0x0F))) ++ goto nodev; ++ } ++ ++ // L2 -> [LR]PGA gain = -6 dB ++ if (WriteByte_CODEC (adap, CODEC_L2L_LPGA, CODEC_L_PGA(0x04))) ++ goto nodev; ++ if (WriteByte_CODEC (adap, CODEC_L2R_RPGA, CODEC_L_PGA(0x04))) ++ goto nodev; ++ ++ // MIC Bias = 2V ++ if (WriteByte_CODEC (adap, CODEC_MIC_BIAS, CODEC_MIC_BIAS_2V)) ++ goto nodev; ++ ++ // {LR]AGC A ++ if (WriteByte_CODEC (adap, CODEC_MIC_LAGC_A, CODEC_MIC_AGC_EN)) ++ goto nodev; ++ if (WriteByte_CODEC (adap, CODEC_MIC_LAGC_A, CODEC_MIC_AGC_EN)) ++ goto nodev; ++ ++ // {LR]AGC B ++ if (WriteByte_CODEC (adap, CODEC_MIC_LAGC_B, CODEC_MIC_AGC_MG(0x40))) // 30 dB, 0xEC=59 dB ++ goto nodev; ++ if (WriteByte_CODEC (adap, CODEC_MIC_RAGC_B, CODEC_MIC_AGC_MG(0x40))) // 30 dB, 0xEC=59 dB ++ goto nodev; ++ ++ // DAC powered up ++ if (WriteByte_CODEC (adap, CODEC_DAC_PWR, ++ CODEC_DAC_PWR_L_EN | CODEC_DAC_PWR_R_EN | CODEC_DAC_PWR_HP_ISE)) ++ goto nodev; ++ if (WriteByte_CODEC (adap, CODEC_DAC_HPWR, CODEC_DAC_HPWR_HPL_DIFF)) ++ goto nodev; ++ if (WriteByte_CODEC (adap, CODEC_DAC_HPOS, CODEC_DAC_HPOS_SS_DIS)) ++ goto nodev; ++ ++ // DAC volume = max ++ if (WriteByte_CODEC (adap, CODEC_DAC_LVOL, CODEC_DAC_VOL(0x0))) ++ goto nodev; ++ if (WriteByte_CODEC (adap, CODEC_DAC_RVOL, CODEC_DAC_VOL(0x0))) ++ goto nodev; ++ ++ // MIC3->speaker ++ if(fcc_test) ++ if (WriteByte_CODEC (adap, CODEC_PGAR_HPLCOM, 0x80)) ++ goto nodev; ++ ++ // output switching volume = max ++ if (WriteByte_CODEC (adap, CODEC_DACL1_HPL, CODEC_HP_EN | CODEC_HP_VOL(0x0))) ++ goto nodev; ++ if (WriteByte_CODEC (adap, CODEC_DACL1_HPLCOM, CODEC_HP_EN | CODEC_HP_VOL(0x0))) ++ goto nodev; ++ ++ if (WriteByte_CODEC (adap, CODEC_DACR1_HPR, CODEC_HP_EN | CODEC_HP_VOL(0x0))) ++ goto nodev; ++ if (WriteByte_CODEC (adap, CODEC_DACR1_HPRCOM, CODEC_HP_EN | CODEC_HP_VOL(0x0))) ++ goto nodev; ++ ++ if (WriteByte_CODEC (adap, CODEC_DACL1_LLOPM, CODEC_HP_EN | CODEC_HP_VOL(0x0))) ++ goto nodev; ++ if (WriteByte_CODEC (adap, CODEC_DACR1_RLOPM, CODEC_HP_EN | CODEC_HP_VOL(0x0))) ++ goto nodev; ++ ++ // output levels = max ++ if (WriteByte_CODEC (adap, CODEC_HPLOUT, ++ CODEC_HPX_LC(0x09) | CODEC_HPX_EN | CODEC_HPX_PD | CODEC_HPX_PC)) ++ goto nodev; ++ if (WriteByte_CODEC (adap, CODEC_HPLCOM, ++ CODEC_HPX_LC(0x09) | CODEC_HPX_EN | CODEC_HPX_PD | CODEC_HPX_PC)) ++ goto nodev; ++ if (WriteByte_CODEC (adap, CODEC_HPROUT, ++ CODEC_HPX_LC(0x09) | CODEC_HPX_EN | CODEC_HPX_PD | CODEC_HPX_PC)) ++ goto nodev; ++ if (WriteByte_CODEC (adap, CODEC_HPRCOM, ++ CODEC_HPX_LC(0x09) | CODEC_HPX_EN | CODEC_HPX_PD | CODEC_HPX_PC)) ++ goto nodev; ++ if (WriteByte_CODEC (adap, CODEC_LLOPM, ++ CODEC_HPX_LC(0x09) | CODEC_HPX_EN | CODEC_HPX_PD | CODEC_HPX_PC)) ++ goto nodev; ++ if (WriteByte_CODEC (adap, CODEC_RLOPM, ++ CODEC_HPX_LC(0x09) | CODEC_HPX_EN | CODEC_HPX_PD | CODEC_HPX_PC)) ++ goto nodev; ++ ++ // clocking ++ if (WriteByte_CODEC (adap, CODEC_CLK, CODEC_CLK_CLKDIV)) ++ goto nodev; ++ if (WriteByte_CODEC (adap, CODEC_CLKGEN, CODEC_CLKGEN_C_M)) ++ goto nodev; ++ return (0); ++ ++nodev: ++ WriteByte_CODEC (adap, CODEC_L1L_LPGA, 0x38); ++ WriteByte_CODEC (adap, CODEC_L1R_RPGA, 0x38); ++ return -ENODEV; ++} ++ ++/* ++ * This function initializes the driver in terms of BMI and ++ * CODEC functionality. ++ * ++ * @return 0 on success, >0 otherwise. ++ */ ++static int mxc_alsa_audio_probe (struct bmi_device *bdev) ++{ ++ int rc = 0; ++ struct bmi_audio *audio; ++ struct i2c_adapter *adap; ++ struct cdev *cdev; ++ struct class *bmi_class; ++ int slot; ++ dev_t dev_id; ++ int ssi; ++ unsigned char iox_data[1]; ++ ++ // bmi set-up ++ slot = bmi_device_get_slot (bdev); ++ adap = bmi_device_get_i2c_adapter (bdev); ++ audio = &bmi_audio[slot]; ++ ++ audio->bdev = 0; ++ ++ // Create 1 minor device ++ cdev = &audio->cdev; ++ cdev_init (cdev, &cntl_fops); ++ ++ dev_id = MKDEV(major, slot); ++ rc = cdev_add (cdev, dev_id, 1); ++ if (rc) ++ return rc; ++ ++ // Create class device ++ bmi_class = bmi_get_bmi_class (); ++ audio->class_dev = device_create (bmi_class, NULL, MKDEV(major, slot), audio, "bmi_audio_ctrl_m%i", slot+1); ++ ++ if (IS_ERR(audio->class_dev)) { ++ printk (KERN_ERR "Unable to create class_device for bmi_audio_m%i; errno = %ld\n", ++ slot+1, PTR_ERR(audio->class_dev)); ++ cdev_del (&audio->cdev); ++ audio->class_dev = NULL; ++ return -ENODEV; ++ } ++ ++ // bind driver and bmi_device ++ audio->bdev = bdev; ++ ++ // check for opposite side already active ++ switch (slot) { ++ case 0: ++ ssi = 0; ++ if (bmi_audio[2].active == 0) { ++ mxc_audio[0]->card->dev = &bdev->dev; ++ audio->active = 1; ++ } ++ break; ++ case 1: ++ ssi = 1; ++ if (bmi_audio[3].active == 0) { ++ mxc_audio[1]->card->dev = &bdev->dev; ++ audio->active = 1; ++ } ++ break; ++ case 2: ++ ssi = 0; ++ if (bmi_audio[0].active == 0) { ++ mxc_audio[0]->card->dev = &bdev->dev; ++ audio->active = 1; ++ } ++ break; ++ case 3: ++ ssi = 1; ++ if (bmi_audio[1].active == 0) { ++ mxc_audio[1]->card->dev = &bdev->dev; ++ audio->active = 1; ++ } ++ break; ++ } ++ ++ bmi_device_set_drvdata (bdev, &bmi_audio[slot]); ++ ++ // Initialize GPIOs (turn LED's on ) ++ // bmi_slot_gpio_configure_as_output (int slot, int gpio, int data) ++ bmi_slot_gpio_configure_as_output (slot, GPIO_RED, BMI_GPIO_OFF); // Red LED=ON ++ bmi_slot_gpio_configure_as_output (slot, GPIO_GREEN, BMI_GPIO_OFF); // Green LED=ON ++ bmi_slot_gpio_configure_as_output (slot, GPIO_RESET, BMI_GPIO_OFF); // Assert RST = 0; ++ bmi_slot_gpio_configure_as_input (slot, GPIO_SPARE); // unused ++ ++ mdelay (200); ++ ++ // turn LED's off ++ bmi_slot_gpio_write_bit (slot, GPIO_RED, BMI_GPIO_ON); // Red LED=OFF ++ bmi_slot_gpio_write_bit (slot, GPIO_GREEN, BMI_GPIO_ON); // Green LED=OFF ++ ++ // release reset ++ bmi_slot_gpio_write_bit (slot, GPIO_RESET, BMI_GPIO_ON); // Reset = 1 ++ ++ // configure IOX ++ if (WriteByte_IOX (adap, IOX_OUTPUT_REG, 0x01)) ++ goto nodev; ++ ++ if (output_ints) { ++ if (WriteByte_IOX (adap, IOX_CONTROL, 0xFC)) // IOX[1:0]=OUT, IOX[7:2]=IN ++ goto nodev; ++ } else { ++ if (WriteByte_IOX (adap, IOX_CONTROL, 0x6C)) // IOX[7,4,1:0]=OUT, IOX[6:5,3:2]=IN ++ goto nodev; ++ } ++ ++ if (ReadByte_IOX (adap, IOX_INPUT_REG, iox_data)) // clear interrupts ++ goto nodev; ++ ++ printk (KERN_INFO "bmi_audio.c: probe(%d) IOX = 0x%x\n", slot, *iox_data & 0xFF); ++ ++#ifdef CODEC // CODEC ++ // configure codec ++ if (configure_CODEC(adap, audio)) ++ goto nodev; ++#endif // CODEC ++ ++ // set up input interrupt ++ audio->irq = bmi_device_get_status_irq (bdev); ++ snprintf (audio->int_name, sizeof (audio->int_name), "bmi_audio_stat_m%d", slot + 1); ++ if (request_irq (audio->irq, &module_irq_handler, 0, audio->int_name, &bmi_audio[slot])) { ++ printk (KERN_ERR "bmi_audio.c: Can't allocate irq %d or find audio in slot %d\n", ++ audio->irq, slot + 1); ++ device_destroy (bmi_class, MKDEV(major, slot)); ++ cdev_del (&audio->cdev); ++ audio->class_dev = NULL; ++ return -EBUSY; ++ } ++ ++ // power stablization delay ++ mdelay (500); ++ return 0; ++ ++nodev: ++ device_destroy (bmi_class, MKDEV(major, slot)); ++ cdev_del (&audio->cdev); ++ audio->class_dev = NULL; ++ return -ENODEV; ++} ++ ++void mxc_alsa_audio_remove (struct bmi_device *bdev) ++{ ++ struct bmi_audio *audio = (struct bmi_audio *) (bmi_device_get_drvdata (bdev)); ++ int slot = bmi_device_get_slot (bdev); ++ struct class *bmi_class; ++ ++ // release sound card srtucture ++ if (bmi_audio[slot].active && ((slot == 0) || (slot == 2))) ++ mxc_audio[0]->card->dev = NULL; ++ else if (bmi_audio[slot]. active && ((slot == 1) || (slot == 3))) ++ mxc_audio[1]->card->dev = NULL; ++ ++ // remove input interrupt scheduled work ++ free_irq (bmi_device_get_status_irq (bdev), &bmi_audio[slot]); ++ switch(slot) { ++ case 0: ++ cancel_delayed_work(&bmiaudio_work0); ++ break; ++ case 1: ++ cancel_delayed_work(&bmiaudio_work1); ++ break; ++ case 2: ++ cancel_delayed_work(&bmiaudio_work2); ++ break; ++ case 3: ++ cancel_delayed_work(&bmiaudio_work3); ++ break; ++ } ++ ++ ++ // deconfigure GPIO ++ bmi_slot_gpio_configure_all_as_inputs (slot); ++ ++ // remove class device ++ bmi_class = bmi_get_bmi_class (); ++ device_destroy (bmi_class, MKDEV(major, slot)); ++ ++ // clean slot structure ++ cdev_del (&audio->cdev); ++ audio->class_dev = NULL; ++ audio->bdev = NULL; ++ audio->active = 0; ++ ++ // de-attach driver-specific struct from bmi_device structure ++ bmi_device_set_drvdata (bdev, 0); ++ ++ return; ++} ++ ++// BMI device ID table ++static struct bmi_device_id bmi_audio_tbl[] = ++{ ++ { ++ .match_flags = BMI_DEVICE_ID_MATCH_VENDOR | BMI_DEVICE_ID_MATCH_PRODUCT, ++ .vendor = BMI_VENDOR_BUG_LABS, ++ .product = BMI_PRODUCT_AUDIO, ++ .revision = BMI_ANY, ++ }, ++ { 0, }, // terminate list ++}; ++MODULE_DEVICE_TABLE(bmi, bmi_audio_tbl); ++ ++static struct bmi_driver bmi_audio_driver = { ++ .name = "bmi_audio", ++ .id_table = bmi_audio_tbl, ++ .probe = mxc_alsa_audio_probe, ++ .remove = mxc_alsa_audio_remove, ++#if 0 //pjg - POWER_MANAGEMENT ++#ifdef CONFIG_PM ++ .suspend = snd_mxc_audio_suspend, ++ .resume = snd_mxc_audio_resume, ++#endif ++#endif //pjg - POWER_MANAGEMENT ++ .driver = { ++ .name = "pim_ALSA", ++ }, ++}; ++ ++// mxc-alsa-mixer.c ++ ++/* ++ * These are the functions implemented in the ALSA PCM driver that ++ * are used for mixer operations ++ * ++ */ ++ ++ // ++ // DAC Volume control ++ // ++ // PIM_AUDIO13 ++static int bmi_pb_volume_put0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ struct i2c_adapter *adap = 0; ++ int volume; ++ ++ // calculate register value ++ volume = uvalue->value.integer.value[0]; ++ volume = 127 - volume; ++ ++ // get I2C dapter ++ if (bmi_audio[0].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[0].bdev); ++ } else if (bmi_audio[2].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[2].bdev); ++ } ++ ++#ifdef CODEC ++ // set volume ++ if (adap) { ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, 0x0)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_DAC_LVOL, CODEC_DAC_VOL(volume))) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_DAC_RVOL, CODEC_DAC_VOL(volume))) ++ return -ENODEV; ++ } else { ++ return -1; ++ } ++#endif // CODEC ++ ++ if (down_interruptible (&audio_mixer_control[0].sem)) ++ return -EINTR; ++ ++ audio_mixer_control[0].master_volume_out = uvalue->value.integer.value[0]; ++ ++ up (&audio_mixer_control[0].sem); ++ ++ return 0; ++} ++static int bmi_pb_volume_info0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 127; ++ uinfo->value.integer.step = 1; ++ return 0; ++} ++ ++static int bmi_pb_volume_get0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ struct i2c_adapter *adap = 0; ++ char val[1]; ++ ++ *val = 0x0; ++ ++ // get I2C dapter ++ if (bmi_audio[0].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[0].bdev); ++ } else if (bmi_audio[2].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[2].bdev); ++ } ++ ++#ifdef CODEC ++ if (adap) { ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, 0x0)) ++ return -ENODEV; ++ if (ReadByte_CODEC (adap, CODEC_DAC_LVOL, val)) ++ return -ENODEV; ++ } else { ++ *val = 0; ++ } ++#endif // CODEC ++ ++ uvalue->value.integer.value[0] = 127 - ((int) *val); ++ ++#ifdef CODEC ++ if (adap) ++ return 0; ++ else ++ return -1; ++#endif // CODEC ++ return 0; ++} ++ ++struct snd_kcontrol_new bmi_control_pb_vol0 __devinitdata = { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "Master Playback Volume", ++ .index = 0x00, ++ .info = bmi_pb_volume_info0, ++ .get = bmi_pb_volume_get0, ++ .put = bmi_pb_volume_put0, ++ .private_value = 0xffab1, ++}; ++ ++// PIM_AUDIO24 ++static int bmi_pb_volume_put1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ struct i2c_adapter *adap = 0; ++ int volume; ++ ++ // calculate register value ++ volume = uvalue->value.integer.value[0]; ++ volume = 127 - volume; ++ ++ // get I2C dapter ++ if (bmi_audio[1].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[1].bdev); ++ } else if (bmi_audio[3].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[3].bdev); ++ } ++ ++#ifdef CODEC ++ // set volume ++ if (adap) { ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, 0x0)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_DAC_LVOL, CODEC_DAC_VOL(volume))) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_DAC_RVOL, CODEC_DAC_VOL(volume))) ++ return -ENODEV; ++ } else { ++ return -1; ++ } ++#endif // CODEC ++ ++ if (down_interruptible (&audio_mixer_control[1].sem)) ++ return -EINTR; ++ ++ audio_mixer_control[1].master_volume_out = uvalue->value.integer.value[0]; ++ ++ up (&audio_mixer_control[1].sem); ++ ++ return 0; ++} ++static int bmi_pb_volume_info1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 127; ++ uinfo->value.integer.step = 1; ++ return 0; ++} ++ ++static int bmi_pb_volume_get1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ struct i2c_adapter *adap = 0; ++ char val[1]; ++ ++ *val = 0x0; ++ ++ // get I2C dapter ++ if (bmi_audio[1].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[1].bdev); ++ } else if (bmi_audio[3].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[3].bdev); ++ } ++ ++#ifdef CODEC ++ if (adap) { ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, 0x0)) ++ return -ENODEV; ++ if (ReadByte_CODEC (adap, CODEC_DAC_LVOL, val)) ++ return -ENODEV; ++ } else { ++ *val = 0; ++ } ++#endif // CODEC ++ ++ uvalue->value.integer.value[0] = 127 - ((int) *val); ++ ++#ifdef CODEC ++ if (adap) ++ return 0; ++ else ++ return -1; ++#endif // CODEC ++ return 0; ++} ++ ++struct snd_kcontrol_new bmi_control_pb_vol1 __devinitdata = { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "Master Playback Volume", ++ .index = 0x00, ++ .info = bmi_pb_volume_info1, ++ .get = bmi_pb_volume_get1, ++ .put = bmi_pb_volume_put1, ++ .private_value = 0xffab1, ++}; ++ ++// ++// LI (L1) Volume control ++// ++// PIM_AUDIO13 ++static int bmi_li_volume_put0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ struct i2c_adapter *adap = 0; ++ int volume; ++ ++ // calculate register value ++ volume = uvalue->value.integer.value[0]; ++ volume = 8 - volume; ++ if (volume == 0) ++ volume = 0xF; // mute ++ ++ // get I2C dapter ++ if (bmi_audio[0].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[0].bdev); ++ } else if (bmi_audio[2].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[2].bdev); ++ } ++ ++#ifdef CODEC ++ // set volume ++ if (adap) { ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, 0x0)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_L1L_LPGA, CODEC_L_PGA(volume) | CODEC_LX_PGA_PU)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_L1R_RPGA, CODEC_L_PGA(volume) | CODEC_LX_PGA_PU)) ++ return -ENODEV; ++ } else { ++ return -1; ++ } ++#endif // CODEC ++ ++ if (down_interruptible (&audio_mixer_control[0].sem)) ++ return -EINTR; ++ ++ audio_mixer_control[0].vol_for_input[IP_LINEIN] = uvalue->value.integer.value[0]; ++ ++ up (&audio_mixer_control[0].sem); ++ ++ return 0; ++} ++static int bmi_li_volume_info0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 8; ++ uinfo->value.integer.step = 1; ++ return 0; ++} ++ ++static int bmi_li_volume_get0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ if (down_interruptible (&audio_mixer_control[0].sem)) ++ return -EINTR; ++ ++ uvalue->value.integer.value[0] = audio_mixer_control[0].vol_for_input[IP_LINEIN]; ++ ++ up (&audio_mixer_control[0].sem); ++ ++ return 0; ++} ++ ++struct snd_kcontrol_new bmi_control_li_vol0 __devinitdata = { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "Linein Capture Volume/Mute", ++ .index = 0x00, ++ .info = bmi_li_volume_info0, ++ .get = bmi_li_volume_get0, ++ .put = bmi_li_volume_put0, ++ .private_value = 0xffab3, ++}; ++ ++// PIM_AUDIO24 ++static int bmi_li_volume_put1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ struct i2c_adapter *adap = 0; ++ int volume; ++ ++ // calculate register value ++ volume = uvalue->value.integer.value[0]; ++ volume = 8 - volume; ++ if (volume == 0) ++ volume = 0xF; // mute ++ ++ // get I2C dapter ++ if (bmi_audio[1].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[1].bdev); ++ } else if (bmi_audio[3].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[3].bdev); ++ } ++ ++#ifdef CODEC ++ // set volume ++ if (adap) { ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, 0x0)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_L1L_LPGA, CODEC_L_PGA(volume) | CODEC_LX_PGA_PU)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_L1R_RPGA, CODEC_L_PGA(volume) | CODEC_LX_PGA_PU)) ++ return -ENODEV; ++ } else { ++ return -1; ++ } ++#endif // CODEC ++ ++ if (down_interruptible (&audio_mixer_control[1].sem)) ++ return -EINTR; ++ ++ audio_mixer_control[1].vol_for_input[IP_LINEIN] = uvalue->value.integer.value[0]; ++ ++ up (&audio_mixer_control[1].sem); ++ ++ return 0; ++} ++static int bmi_li_volume_info1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 8; ++ uinfo->value.integer.step = 1; ++ return 0; ++} ++ ++static int bmi_li_volume_get1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ if (down_interruptible (&audio_mixer_control[1].sem)) ++ return -EINTR; ++ ++ uvalue->value.integer.value[0] = audio_mixer_control[1].vol_for_input[IP_LINEIN]; ++ ++ up (&audio_mixer_control[1].sem); ++ ++ return 0; ++} ++ ++struct snd_kcontrol_new bmi_control_li_vol1 __devinitdata = { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "Linein Capture Volume/Mute", ++ .index = 0x00, ++ .info = bmi_li_volume_info1, ++ .get = bmi_li_volume_get1, ++ .put = bmi_li_volume_put1, ++ .private_value = 0xffab3, ++}; ++ ++// ++// MIC (L2) Volume control ++// ++// PIM_AUDIO13 ++static int bmi_mic_volume_put0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ struct i2c_adapter *adap = 0; ++ int volume; ++ ++ // calculate register value ++ volume = uvalue->value.integer.value[0]; ++ volume = 8 - volume; ++ if (volume == 0) ++ volume = 0xF; // mute ++ ++ // get I2C dapter ++ if (bmi_audio[0].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[0].bdev); ++ } else if (bmi_audio[2].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[2].bdev); ++ } ++ ++#ifdef CODEC ++ // set volume ++ if (adap) { ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, 0x0)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_L2L_LPGA, CODEC_L_PGA(volume))) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_L2R_RPGA, CODEC_L_PGA(volume))) ++ return -ENODEV; ++ } else { ++ return -1; ++ } ++#endif // CODEC ++ ++ if (down_interruptible (&audio_mixer_control[0].sem)) ++ return -EINTR; ++ ++ audio_mixer_control[0].vol_for_input[IP_MIC] = uvalue->value.integer.value[0]; ++ ++ up (&audio_mixer_control[0].sem); ++ ++ return 0; ++} ++static int bmi_mic_volume_info0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 8; ++ uinfo->value.integer.step = 1; ++ return 0; ++} ++ ++static int bmi_mic_volume_get0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ if (down_interruptible (&audio_mixer_control[0].sem)) ++ return -EINTR; ++ ++ uvalue->value.integer.value[0] = audio_mixer_control[0].vol_for_input[IP_MIC]; ++ ++ up (&audio_mixer_control[0].sem); ++ ++ return 0; ++} ++ ++struct snd_kcontrol_new bmi_control_mic_vol0 __devinitdata = { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "Mic Capture Volume/Mute", ++ .index = 0x00, ++ .info = bmi_mic_volume_info0, ++ .get = bmi_mic_volume_get0, ++ .put = bmi_mic_volume_put0, ++ .private_value = 0xffab4, ++}; ++ ++// PIM_AUDIO24 ++static int bmi_mic_volume_put1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ struct i2c_adapter *adap = 0; ++ int volume; ++ ++ // calculate register value ++ volume = uvalue->value.integer.value[0]; ++ volume = 8 - volume; ++ if (volume == 0) ++ volume = 0xF; // mute ++ ++ // get I2C dapter ++ if (bmi_audio[1].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[1].bdev); ++ } else if (bmi_audio[3].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[3].bdev); ++ } ++ ++#ifdef CODEC ++ // set volume ++ if (adap) { ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, 0x0)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_L2L_LPGA, CODEC_L_PGA(volume))) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_L2R_RPGA, CODEC_L_PGA(volume))) ++ return -ENODEV; ++ } else { ++ return -1; ++ } ++#endif // CODEC ++ ++ if (down_interruptible (&audio_mixer_control[1].sem)) ++ return -EINTR; ++ ++ audio_mixer_control[1].vol_for_input[IP_MIC] = uvalue->value.integer.value[0]; ++ ++ up (&audio_mixer_control[1].sem); ++ ++ return 0; ++} ++static int bmi_mic_volume_info1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 8; ++ uinfo->value.integer.step = 1; ++ return 0; ++} ++ ++static int bmi_mic_volume_get1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ if (down_interruptible (&audio_mixer_control[1].sem)) ++ return -EINTR; ++ ++ uvalue->value.integer.value[0] = audio_mixer_control[1].vol_for_input[IP_MIC]; ++ ++ up (&audio_mixer_control[1].sem); ++ ++ return 0; ++} ++ ++struct snd_kcontrol_new bmi_control_mic_vol1 __devinitdata = { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "Mic Capture Volume/Mute", ++ .index = 0x00, ++ .info = bmi_mic_volume_info1, ++ .get = bmi_mic_volume_get1, ++ .put = bmi_mic_volume_put1, ++ .private_value = 0xffab4, ++}; ++ ++// ++// EMIC (L3) Volume control ++// ++// PIM_AUDIO13 ++static int bmi_emic_volume_put0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ struct i2c_adapter *adap = 0; ++ int volume; ++ ++ // calculate register value ++ volume = uvalue->value.integer.value[0]; ++ volume = 8 - volume; ++ if (volume == 0) ++ volume = 0xF; // mute ++ ++ // get I2C dapter ++ if (bmi_audio[0].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[0].bdev); ++ } else if (bmi_audio[2].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[2].bdev); ++ } ++ ++#ifdef CODEC ++ // set volume ++ if (adap) { ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, 0x0)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_M3_LPGA, CODEC_M3_PGA_R(volume))) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_M3_RPGA, CODEC_M3_PGA_R(volume))) ++ return -ENODEV; ++ } else { ++ return -1; ++ } ++#endif // CODEC ++ ++ if (down_interruptible (&audio_mixer_control[0].sem)) ++ return -EINTR; ++ ++ audio_mixer_control[0].vol_for_input[IP_EMIC] = uvalue->value.integer.value[0]; ++ ++ up (&audio_mixer_control[0].sem); ++ ++ return 0; ++} ++static int bmi_emic_volume_info0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 8; ++ uinfo->value.integer.step = 1; ++ return 0; ++} ++ ++static int bmi_emic_volume_get0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ if (down_interruptible (&audio_mixer_control[0].sem)) ++ return -EINTR; ++ ++ uvalue->value.integer.value[0] = audio_mixer_control[0].vol_for_input[IP_EMIC]; ++ ++ up (&audio_mixer_control[0].sem); ++ ++ return 0; ++} ++ ++struct snd_kcontrol_new bmi_control_emic_vol0 __devinitdata = { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "Emic Capture Volume/Mute", ++ .index = 0x00, ++ .info = bmi_emic_volume_info0, ++ .get = bmi_emic_volume_get0, ++ .put = bmi_emic_volume_put0, ++ .private_value = 0xffab5, ++}; ++ ++// PIM_AUDIO24 ++static int bmi_emic_volume_put1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ struct i2c_adapter *adap = 0; ++ int volume; ++ ++ // calculate register value ++ volume = uvalue->value.integer.value[0]; ++ volume = 8 - volume; ++ if (volume == 0) ++ volume = 0xF; // mute ++ ++ // get I2C dapter ++ if (bmi_audio[1].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[1].bdev); ++ } else if (bmi_audio[3].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[3].bdev); ++ } ++ ++#ifdef CODEC ++ // set volume ++ if (adap) { ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, 0x0)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_M3_LPGA, CODEC_M3_PGA_R(volume))) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_M3_RPGA, CODEC_M3_PGA_R(volume))) ++ return -ENODEV; ++ } else { ++ return -1; ++ } ++#endif // CODEC ++ ++ if (down_interruptible (&audio_mixer_control[1].sem)) ++ return -EINTR; ++ ++ audio_mixer_control[1].vol_for_input[IP_EMIC] = uvalue->value.integer.value[0]; ++ ++ up (&audio_mixer_control[1].sem); ++ ++ return 0; ++} ++static int bmi_emic_volume_info1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 8; ++ uinfo->value.integer.step = 1; ++ return 0; ++} ++ ++static int bmi_emic_volume_get1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ if (down_interruptible (&audio_mixer_control[1].sem)) ++ return -EINTR; ++ ++ uvalue->value.integer.value[0] = audio_mixer_control[1].vol_for_input[IP_EMIC]; ++ ++ up (&audio_mixer_control[1].sem); ++ ++ return 0; ++} ++ ++struct snd_kcontrol_new bmi_control_emic_vol1 __devinitdata = { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "Emic Capture Volume/Mute", ++ .index = 0x00, ++ .info = bmi_emic_volume_info1, ++ .get = bmi_emic_volume_get1, ++ .put = bmi_emic_volume_put1, ++ .private_value = 0xffab5, ++}; ++ ++// ++// HEADPHONE (HP[LR]OUT) Volume control ++// ++// PIM_AUDIO13 ++static int bmi_hp_volume_put0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ struct i2c_adapter *adap = 0; ++ int volume; ++ ++ // calculate register value ++ volume = uvalue->value.integer.value[0]; ++ ++ // get I2C dapter ++ if (bmi_audio[0].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[0].bdev); ++ } else if (bmi_audio[2].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[2].bdev); ++ } ++ ++#ifdef CODEC ++ // set volume ++ if (adap) { ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, 0x0)) ++ return -ENODEV; ++ if (volume == 0) { ++ if (WriteByte_CODEC (adap, CODEC_HPLOUT, 0x0)) // mute ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_HPROUT, 0x0)) // mute ++ return -ENODEV; ++ } else { ++ if (WriteByte_CODEC (adap, CODEC_HPLOUT, CODEC_HPX_LC(volume) ++ | CODEC_HPX_EN | CODEC_HPX_PD | CODEC_HPX_PC)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_HPROUT, CODEC_HPX_LC(volume) ++ | CODEC_HPX_EN | CODEC_HPX_PD | CODEC_HPX_PC)) ++ return -ENODEV; ++ } ++ } else { ++ return -1; ++ } ++#endif // CODEC ++ ++ if (down_interruptible (&audio_mixer_control[0].sem)) ++ return -EINTR; ++ ++ audio_mixer_control[0].vol_for_output[OP_HEADPHONE] = uvalue->value.integer.value[0]; ++ ++ up (&audio_mixer_control[0].sem); ++ ++ return 0; ++} ++static int bmi_hp_volume_info0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 9; ++ uinfo->value.integer.step = 1; ++ return 0; ++} ++ ++static int bmi_hp_volume_get0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ if (down_interruptible (&audio_mixer_control[0].sem)) ++ return -EINTR; ++ ++ uvalue->value.integer.value[0] = audio_mixer_control[0].vol_for_output[OP_HEADPHONE]; ++ ++ up (&audio_mixer_control[0].sem); ++ ++ return 0; ++} ++ ++struct snd_kcontrol_new bmi_control_hp_vol0 __devinitdata = { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "Headphone Playback Volume/Mute", ++ .index = 0x00, ++ .info = bmi_hp_volume_info0, ++ .get = bmi_hp_volume_get0, ++ .put = bmi_hp_volume_put0, ++ .private_value = 0xffab4, ++}; ++ ++ // PIM_AUDIO24 ++static int bmi_hp_volume_put1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ struct i2c_adapter *adap = 0; ++ int volume; ++ ++ // calculate register value ++ volume = uvalue->value.integer.value[0]; ++ ++ // get I2C dapter ++ if (bmi_audio[1].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[1].bdev); ++ } else if (bmi_audio[3].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[3].bdev); ++ } ++ ++#ifdef CODEC ++ // set volume ++ if (adap) { ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, 0x0)) ++ return -ENODEV; ++ if (volume == 0) { ++ if (WriteByte_CODEC (adap, CODEC_HPLOUT, 0x0)) // mute ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_HPROUT, 0x0)) // mute ++ return -ENODEV; ++ } else { ++ if (WriteByte_CODEC (adap, CODEC_HPLOUT, CODEC_HPX_LC(volume) ++ | CODEC_HPX_EN | CODEC_HPX_PD | CODEC_HPX_PC)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_HPROUT, CODEC_HPX_LC(volume) ++ | CODEC_HPX_EN | CODEC_HPX_PD | CODEC_HPX_PC)) ++ return -ENODEV; ++ } ++ } else { ++ return -1; ++ } ++#endif // CODEC ++ ++ if (down_interruptible (&audio_mixer_control[1].sem)) ++ return -EINTR; ++ ++ audio_mixer_control[1].vol_for_output[OP_HEADPHONE] = uvalue->value.integer.value[0]; ++ ++ up (&audio_mixer_control[1].sem); ++ ++ return 0; ++} ++static int bmi_hp_volume_info1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 9; ++ uinfo->value.integer.step = 1; ++ return 0; ++} ++ ++static int bmi_hp_volume_get1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ if (down_interruptible (&audio_mixer_control[1].sem)) ++ return -EINTR; ++ ++ uvalue->value.integer.value[0] = audio_mixer_control[1].vol_for_output[OP_HEADPHONE]; ++ ++ up (&audio_mixer_control[1].sem); ++ ++ return 0; ++} ++ ++struct snd_kcontrol_new bmi_control_hp_vol1 __devinitdata = { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "Headphone Playback Volume/Mute", ++ .index = 0x00, ++ .info = bmi_hp_volume_info1, ++ .get = bmi_hp_volume_get1, ++ .put = bmi_hp_volume_put1, ++ .private_value = 0xffab4, ++}; ++ ++// ++// Speaker (HP[LR]COM) Volume control ++// ++// PIM_AUDIO13 ++static int bmi_spkr_volume_put0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ struct i2c_adapter *adap = 0; ++ int volume; ++ ++ // calculate register value ++ volume = uvalue->value.integer.value[0]; ++ ++ // get I2C dapter ++ if (bmi_audio[0].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[0].bdev); ++ } else if (bmi_audio[2].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[2].bdev); ++ } ++ ++#ifdef CODEC ++ // set volume ++ if (adap) { ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, 0x0)) ++ return -ENODEV; ++ if (volume == 0) { ++ if (WriteByte_CODEC (adap, CODEC_HPLCOM, 0x0)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_HPRCOM, 0x0)) ++ return -ENODEV; ++ } else { ++ if (WriteByte_CODEC (adap, CODEC_HPLCOM, CODEC_HPX_LC(volume) ++ | CODEC_HPX_EN | CODEC_HPX_PD | CODEC_HPX_PC)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_HPRCOM, CODEC_HPX_LC(volume) ++ | CODEC_HPX_EN | CODEC_HPX_PD | CODEC_HPX_PC)) ++ return -ENODEV; ++ } ++ } else { ++ return -1; ++ } ++#endif // CODEC ++ ++ if (down_interruptible (&audio_mixer_control[0].sem)) ++ return -EINTR; ++ ++ audio_mixer_control[0].vol_for_output[OP_SPEAKER] = uvalue->value.integer.value[0]; ++ ++ up (&audio_mixer_control[0].sem); ++ ++ return 0; ++} ++static int bmi_spkr_volume_info0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 9; ++ uinfo->value.integer.step = 1; ++ return 0; ++} ++ ++static int bmi_spkr_volume_get0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ if (down_interruptible (&audio_mixer_control[0].sem)) ++ return -EINTR; ++ ++ uvalue->value.integer.value[0] = audio_mixer_control[0].vol_for_output[OP_SPEAKER]; ++ ++ up (&audio_mixer_control[0].sem); ++ ++ return 0; ++} ++ ++struct snd_kcontrol_new bmi_control_spkr_vol0 __devinitdata = { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "Speaker Playback Volume/Mute", ++ .index = 0x00, ++ .info = bmi_spkr_volume_info0, ++ .get = bmi_spkr_volume_get0, ++ .put = bmi_spkr_volume_put0, ++ .private_value = 0xffab5, ++}; ++ ++// PIM_AUDIO24 ++static int bmi_spkr_volume_put1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ struct i2c_adapter *adap = 0; ++ int volume; ++ ++ // calculate register value ++ volume = uvalue->value.integer.value[0]; ++ ++ // get I2C dapter ++ if (bmi_audio[1].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[1].bdev); ++ } else if (bmi_audio[3].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[3].bdev); ++ } ++ ++#ifdef CODEC ++ // set volume ++ if (adap) { ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, 0x0)) ++ return -ENODEV; ++ if (volume == 0) { ++ if (WriteByte_CODEC (adap, CODEC_HPLCOM, 0x0)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_HPRCOM, 0x0)) ++ return -ENODEV; ++ } else { ++ if (WriteByte_CODEC (adap, CODEC_HPLCOM, CODEC_HPX_LC(volume) ++ | CODEC_HPX_EN | CODEC_HPX_PD | CODEC_HPX_PC)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_HPRCOM, CODEC_HPX_LC(volume) ++ | CODEC_HPX_EN | CODEC_HPX_PD | CODEC_HPX_PC)) ++ return -ENODEV; ++ } ++ } else { ++ return -1; ++ } ++#endif // CODEC ++ ++ if (down_interruptible (&audio_mixer_control[1].sem)) ++ return -EINTR; ++ ++ audio_mixer_control[1].vol_for_output[OP_SPEAKER] = uvalue->value.integer.value[0]; ++ ++ up (&audio_mixer_control[1].sem); ++ ++ return 0; ++} ++static int bmi_spkr_volume_info1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 9; ++ uinfo->value.integer.step = 1; ++ return 0; ++} ++ ++static int bmi_spkr_volume_get1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ if (down_interruptible (&audio_mixer_control[1].sem)) ++ return -EINTR; ++ ++ uvalue->value.integer.value[0] = audio_mixer_control[1].vol_for_output[OP_SPEAKER]; ++ ++ up (&audio_mixer_control[1].sem); ++ ++ return 0; ++} ++ ++struct snd_kcontrol_new bmi_control_spkr_vol1 __devinitdata = { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "Speaker Playback Volume/Mute", ++ .index = 0x00, ++ .info = bmi_spkr_volume_info1, ++ .get = bmi_spkr_volume_get1, ++ .put = bmi_spkr_volume_put1, ++ .private_value = 0xffab5, ++}; ++ ++// ++// Line out ([LR]LOP) Volume control ++// ++// PIM_AUDIO13 ++static int bmi_lo_volume_put0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ struct i2c_adapter *adap = 0; ++ int volume; ++ ++ // calculate register value ++ volume = uvalue->value.integer.value[0]; ++ ++ // get I2C dapter ++ if (bmi_audio[0].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[0].bdev); ++ } else if (bmi_audio[2].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[2].bdev); ++ } ++ ++#ifdef CODEC ++ // set volume ++ if (adap) { ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, 0x0)) ++ return -ENODEV; ++ if (volume == 0) { ++ if (WriteByte_CODEC (adap, CODEC_LLOPM, 0x0)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_RLOPM, 0x0)) ++ return -ENODEV; ++ } else { ++ if (WriteByte_CODEC (adap, CODEC_LLOPM, CODEC_HPX_LC(volume) ++ | CODEC_HPX_EN | CODEC_HPX_PD | CODEC_HPX_PC)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_RLOPM, CODEC_HPX_LC(volume) ++ | CODEC_HPX_EN | CODEC_HPX_PD | CODEC_HPX_PC)) ++ return -ENODEV; ++ } ++ } else { ++ return -1; ++ } ++#endif // CODEC ++ ++ if (down_interruptible (&audio_mixer_control[0].sem)) ++ return -EINTR; ++ ++ audio_mixer_control[0].vol_for_output[OP_LINEOUT] = uvalue->value.integer.value[0]; ++ ++ up (&audio_mixer_control[0].sem); ++ ++ return 0; ++} ++static int bmi_lo_volume_info0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 9; ++ uinfo->value.integer.step = 1; ++ return 0; ++} ++ ++static int bmi_lo_volume_get0 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ if (down_interruptible (&audio_mixer_control[0].sem)) ++ return -EINTR; ++ ++ uvalue->value.integer.value[0] = audio_mixer_control[0].vol_for_output[OP_LINEOUT]; ++ ++ up (&audio_mixer_control[0].sem); ++ ++ return 0; ++} ++ ++struct snd_kcontrol_new bmi_control_lo_vol0 __devinitdata = { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "Lineout Playback Volume/Mute", ++ .index = 0x00, ++ .info = bmi_lo_volume_info0, ++ .get = bmi_lo_volume_get0, ++ .put = bmi_lo_volume_put0, ++ .private_value = 0xffab6, ++}; ++ ++// PIM_AUDIO24 ++static int bmi_lo_volume_put1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ struct i2c_adapter *adap = 0; ++ int volume; ++ ++ // calculate register value ++ volume = uvalue->value.integer.value[0]; ++ ++ // get I2C dapter ++ if (bmi_audio[1].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[1].bdev); ++ } else if (bmi_audio[3].active) { ++ adap = bmi_device_get_i2c_adapter (bmi_audio[3].bdev); ++ } ++ ++#ifdef CODEC ++ // set volume ++ if (adap) { ++ // write page register ++ if (WriteByte_CODEC (adap, 0x0, 0x0)) ++ return -ENODEV; ++ if (volume == 0) { ++ if (WriteByte_CODEC (adap, CODEC_LLOPM, 0x0)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_RLOPM, 0x0)) ++ return -ENODEV; ++ } else { ++ if (WriteByte_CODEC (adap, CODEC_LLOPM, CODEC_HPX_LC(volume) ++ | CODEC_HPX_EN | CODEC_HPX_PD | CODEC_HPX_PC)) ++ return -ENODEV; ++ if (WriteByte_CODEC (adap, CODEC_RLOPM, CODEC_HPX_LC(volume) ++ | CODEC_HPX_EN | CODEC_HPX_PD | CODEC_HPX_PC)) ++ return -ENODEV; ++ } ++ } else { ++ return -1; ++ } ++#endif // CODEC ++ ++ if (down_interruptible (&audio_mixer_control[1].sem)) ++ return -EINTR; ++ ++ audio_mixer_control[1].vol_for_output[OP_LINEOUT] = uvalue->value.integer.value[0]; ++ ++ up (&audio_mixer_control[1].sem); ++ ++ return 0; ++} ++static int bmi_lo_volume_info1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 9; ++ uinfo->value.integer.step = 1; ++ return 0; ++} ++ ++static int bmi_lo_volume_get1 (struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uvalue) ++{ ++ if (down_interruptible (&audio_mixer_control[1].sem)) ++ return -EINTR; ++ ++ uvalue->value.integer.value[0] = audio_mixer_control[1].vol_for_output[OP_LINEOUT]; ++ ++ up (&audio_mixer_control[1].sem); ++ ++ return 0; ++} ++ ++struct snd_kcontrol_new bmi_control_lo_vol1 __devinitdata = { ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "Lineout Playback Volume/Mute", ++ .index = 0x00, ++ .info = bmi_lo_volume_info1, ++ .get = bmi_lo_volume_get1, ++ .put = bmi_lo_volume_put1, ++ .private_value = 0xffab6, ++}; ++ ++/* ++ * This function registers the control components of ALSA Mixer ++ * It is called by ALSA PCM init. ++ * ++ * @param card pointer to the ALSA sound card structure. ++ * @param device SSI interface ++ * ++ * @return 0 on success, -ve otherwise. ++ */ ++int bug_alsa_create_ctl (struct snd_card *card, void *p_value, int device) ++{ ++ int rc = 0; ++ ++ if (device == 0) { ++ if ((rc = ++ snd_ctl_add (card, snd_ctl_new1 (&bmi_control_pb_vol0, p_value))) < 0) ++ return rc; ++ } else { ++ if ((rc = ++ snd_ctl_add (card, snd_ctl_new1 (&bmi_control_pb_vol1, p_value))) < 0) ++ return rc; ++ } ++ ++ if (device == 0) { ++ if ((rc = ++ snd_ctl_add (card, snd_ctl_new1 (&bmi_control_li_vol0, p_value))) < 0) ++ return rc; ++ } else { ++ if ((rc = ++ snd_ctl_add (card, snd_ctl_new1 (&bmi_control_li_vol1, p_value))) < 0) ++ return rc; ++ } ++ ++ if (device == 0) { ++ if ((rc = ++ snd_ctl_add (card, snd_ctl_new1 (&bmi_control_mic_vol0, p_value))) < 0) ++ return rc; ++ } else { ++ if ((rc = ++ snd_ctl_add (card, snd_ctl_new1 (&bmi_control_mic_vol1, p_value))) < 0) ++ return rc; ++ } ++ ++ if (device == 0) { ++ if ((rc = ++ snd_ctl_add (card, snd_ctl_new1 (&bmi_control_emic_vol0, p_value))) < 0) ++ return rc; ++ } else { ++ if ((rc = ++ snd_ctl_add (card, snd_ctl_new1 (&bmi_control_emic_vol1, p_value))) < 0) ++ return rc; ++ } ++ ++ if (device == 0) { ++ if ((rc = ++ snd_ctl_add (card, snd_ctl_new1 (&bmi_control_hp_vol0, p_value))) < 0) ++ return rc; ++ } else { ++ if ((rc = ++ snd_ctl_add (card, snd_ctl_new1 (&bmi_control_hp_vol1, p_value))) < 0) ++ return rc; ++ } ++ ++ if (device == 0) { ++ if ((rc = ++ snd_ctl_add (card, snd_ctl_new1 (&bmi_control_spkr_vol0, p_value))) < 0) ++ return rc; ++ } else { ++ if ((rc = ++ snd_ctl_add (card, snd_ctl_new1 (&bmi_control_spkr_vol1, p_value))) < 0) ++ return rc; ++ } ++ ++ if (device == 0) { ++ if ((rc = ++ snd_ctl_add (card, snd_ctl_new1 (&bmi_control_lo_vol0, p_value))) < 0) ++ return rc; ++ } else { ++ if ((rc = ++ snd_ctl_add (card, snd_ctl_new1 (&bmi_control_lo_vol1, p_value))) < 0) ++ return rc; ++ } ++ ++ return 0; ++} ++ ++/************************************************************************** ++ * Module initialization and termination functions. ++ * ++ * Note that if this code is compiled into the kernel, then the ++ * module_init() function will be called within the device_initcall() ++ * group. ++ ************************************************************************** ++ */ ++ ++/* ++ * @name Audio Driver Loading/Unloading Functions ++ * These non-exported internal functions are used to support the audio ++ * device driver initialization and de-initialization operations. ++ */ ++ ++/* ++ * @brief This is the audio device driver initialization function. ++ * ++ * This function is called by the kernel when this device driver is first ++ * loaded. ++ */ ++ ++char const input_name0[MAX_STRG] = "bmi_audio_status_m1"; ++char const input_name1[MAX_STRG] = "bmi_audio_status_m2"; ++char const input_name2[MAX_STRG] = "bmi_audio_status_m3"; ++char const input_name3[MAX_STRG] = "bmi_audio_status_m4"; ++ ++static int __init bmi_audio_init (void) ++{ ++ int rc = 0; ++ dev_t dev_id; ++ int idn; ++ int iidn; ++ struct snd_card *card; ++ struct snd_card *card1; ++ ++ printk (KERN_INFO "BMI Audio driver loading...\n"); ++ ++ // alloc char driver with 4 minor numbers ++ rc = alloc_chrdev_region (&dev_id, 0, 4, "BMI AUDIO Driver"); ++ if (rc) { ++ printk (KERN_ERR "bmi_audio_init: Can't allocate chrdev region\n"); ++ return -ENODEV; ++ } ++ major = MAJOR(dev_id); ++ ++ // Allocate and Register input devices - bmi_audio_status_m[1234] ++ for (idn = BMI_AUDIO_M1; idn < BMI_AUDIO_PIM_NUM; idn++) { ++ bmi_audio[idn].input_dev = input_allocate_device(); ++ if (!bmi_audio[idn].input_dev) { ++ for (iidn = BMI_AUDIO_M1; iidn < idn; iidn++) ++ input_unregister_device (bmi_audio[iidn].input_dev); ++ unregister_chrdev_region (dev_id, 4); ++ printk (KERN_ERR "bmi_audio_init: Can't allocate input_dev[%d]\n", idn); ++ return -ENOMEM; ++ } ++ ++ // set up input device ++ switch (idn) { ++ case BMI_AUDIO_M1: ++ bmi_audio[idn].input_dev->name = input_name0; ++ bmi_audio[idn].input_dev->phys = input_name0; ++ break; ++ case BMI_AUDIO_M2: ++ bmi_audio[idn].input_dev->name = input_name1; ++ bmi_audio[idn].input_dev->phys = input_name1; ++ break; ++ case BMI_AUDIO_M3: ++ bmi_audio[idn].input_dev->name = input_name2; ++ bmi_audio[idn].input_dev->phys = input_name2; ++ break; ++ case BMI_AUDIO_M4: ++ bmi_audio[idn].input_dev->name = input_name3; ++ bmi_audio[idn].input_dev->phys = input_name3; ++ break; ++ } ++ bmi_audio[idn].input_dev->id.bustype = BUS_BMI; ++ //bmi_audio[idn].input_dev->private = &bmi_audio[idn]; ++ bmi_audio[idn].input_dev->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS); ++ bmi_audio[idn].input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); ++ ++ // register input device ++ if (input_register_device (bmi_audio[idn].input_dev)) { ++ printk (KERN_ERR "bmi_audio_init() - input_register_device failed.\n"); ++ for (iidn = BMI_AUDIO_M1; iidn < idn; iidn++) ++ input_unregister_device (bmi_audio[iidn].input_dev); ++ unregister_chrdev_region (dev_id, 4); ++ return -ENODEV; ++ } ++ } ++ ++ // clear bmi devices and active bits ++ bmi_audio[0].bdev = NULL; ++ bmi_audio[1].bdev = NULL; ++ bmi_audio[2].bdev = NULL; ++ bmi_audio[3].bdev = NULL; ++ bmi_audio[0].active = 0; ++ bmi_audio[1].active = 0; ++ bmi_audio[2].active = 0; ++ bmi_audio[3].active = 0; ++ ++ // allocate private structure ++ mxc_audio[0] = kcalloc (1, sizeof (mxc_bmi_audio_t), GFP_KERNEL); ++ if (mxc_audio[0] == NULL) { ++ for (idn = BMI_AUDIO_M1; idn < BMI_AUDIO_PIM_NUM; idn++) ++ input_unregister_device (bmi_audio[idn].input_dev); ++ unregister_chrdev_region (dev_id, 4); ++ return -ENODEV; ++ } ++ ++ // allocate private structure ++ mxc_audio[1] = kcalloc (1, sizeof (mxc_bmi_audio_t), GFP_KERNEL); ++ if (mxc_audio[1] == NULL) { ++ kfree (mxc_audio[0]); ++ for (idn = BMI_AUDIO_M1; idn < BMI_AUDIO_PIM_NUM; idn++) ++ input_unregister_device (bmi_audio[idn].input_dev); ++ unregister_chrdev_region (dev_id, 4); ++ return -ENODEV; ++ } ++ ++ // register the soundcards ++ // modules 1 and 3 ++ card = snd_card_new (1, id13, THIS_MODULE, sizeof (mxc_bmi_audio_t)); ++ if (card == NULL) { ++ kfree (mxc_audio[1]); ++ kfree (mxc_audio[0]); ++ for (idn = BMI_AUDIO_M1; idn < BMI_AUDIO_PIM_NUM; idn++) ++ input_unregister_device (bmi_audio[idn].input_dev); ++ unregister_chrdev_region (dev_id, 4); ++ return -ENODEV; ++ } ++ ++ card->private_data = (void *) mxc_audio[0]; ++ card->private_free = snd_mxc_audio_free; ++ ++ // register pcm ++ mxc_audio[0]->card = card; ++ if ((rc = snd_card_mxc_audio_pcm (mxc_audio[0], 0)) < 0) { ++ snd_card_free (card); ++ kfree (mxc_audio[1]); ++ kfree (mxc_audio[0]); ++ for (idn = BMI_AUDIO_M1; idn < BMI_AUDIO_PIM_NUM; idn++) ++ input_unregister_device (bmi_audio[idn].input_dev); ++ unregister_chrdev_region (dev_id, 4); ++ return -ENODEV; ++ } ++ ++ // register mixer ++ if (0 == bug_alsa_create_ctl (card, (void *) &audio_mixer_control[0], 0)) ++ printk (KERN_INFO "Control ALSA component registered\n"); ++ ++ spin_lock_init (&(mxc_audio[0]->s[0].dma_lock)); ++ spin_lock_init (&(mxc_audio[0]->s[1].dma_lock)); ++ ++ strcpy (card->driver, "PIM_AUDIO13"); ++ strcpy (card->shortname, "PIM13-audio"); ++ sprintf (card->longname, "PIM13 Freescale MX31"); ++ ++ // register sound card ++ if ((rc = snd_card_register (card)) == 0) { ++ PRINTK(KERN_INFO "MXC PIM13 audio support initialized\n"); ++ } else { ++ snd_card_free (card); ++ kfree (mxc_audio[1]); ++ kfree (mxc_audio[0]); ++ for (idn = BMI_AUDIO_M1; idn < BMI_AUDIO_PIM_NUM; idn++) ++ input_unregister_device (bmi_audio[idn].input_dev); ++ unregister_chrdev_region (dev_id, 4); ++ return -ENODEV; ++ } ++ ++ // modules 2 and 4 ++ card1 = snd_card_new (2, id24, THIS_MODULE, sizeof (mxc_bmi_audio_t)); ++ if (card1 == NULL) { ++ snd_card_free (card); ++ kfree (mxc_audio[1]); ++ kfree (mxc_audio[0]); ++ for (idn = BMI_AUDIO_M1; idn < BMI_AUDIO_PIM_NUM; idn++) ++ input_unregister_device (bmi_audio[idn].input_dev); ++ unregister_chrdev_region (dev_id, 4); ++ return -ENODEV; ++ } ++ ++ card1->private_data = (void *) mxc_audio[1]; ++ card1->private_free = snd_mxc_audio_free; ++ ++ // register pcm ++ mxc_audio[1]->card = card1; ++ if ((rc = snd_card_mxc_audio_pcm (mxc_audio[1], 1)) < 0) { ++ snd_card_free (card1); ++ snd_card_free (card); ++ kfree (mxc_audio[1]); ++ kfree (mxc_audio[0]); ++ for (idn = BMI_AUDIO_M1; idn < BMI_AUDIO_PIM_NUM; idn++) ++ input_unregister_device (bmi_audio[idn].input_dev); ++ unregister_chrdev_region (dev_id, 4); ++ return -ENODEV; ++ } ++ ++ // register mixer ++ if (0 == bug_alsa_create_ctl (card1, (void *) &audio_mixer_control[1], 1)) ++ printk (KERN_INFO "Control ALSA component registered\n"); ++ ++ spin_lock_init (&(mxc_audio[1]->s[0].dma_lock)); ++ spin_lock_init (&(mxc_audio[1]->s[1].dma_lock)); ++ ++ strcpy (card1->driver, "PIM_AUDIO24"); ++ strcpy (card1->shortname, "PIM24-audio"); ++ sprintf (card1->longname, "PIM24 Freescale MX31"); ++ ++ // register sound card ++ if ((rc = snd_card_register (card1)) == 0) { ++ PRINTK(KERN_INFO "MXC PIM24 audio support initialized\n"); ++ } else { ++ snd_card_free (card1); ++ snd_card_free (card); ++ kfree (mxc_audio[1]); ++ kfree (mxc_audio[0]); ++ for (idn = BMI_AUDIO_M1; idn < BMI_AUDIO_PIM_NUM; idn++) ++ input_unregister_device (bmi_audio[idn].input_dev); ++ unregister_chrdev_region (dev_id, 4); ++ } ++ ++ // register with BMI ++ rc = bmi_register_driver (&bmi_audio_driver); ++ if (rc) { ++ printk (KERN_ERR "bmi_audio.c: Can't register bmi_audio_driver\n"); ++ snd_card_free (card1); ++ snd_card_free (card); ++ kfree (mxc_audio[1]); ++ kfree (mxc_audio[0]); ++ for (idn = BMI_AUDIO_M1; idn < BMI_AUDIO_PIM_NUM; idn++) ++ input_unregister_device (bmi_audio[idn].input_dev); ++ unregister_chrdev_region (dev_id, 4); ++ return rc; ++ } ++ ++ // turn on I2S transceiver ++ bmi_activate_audio_ports(); ++ ++ //configure DAM and SSI ++ configure_dam_bmi_master (0); ++ configure_dam_bmi_master (1); ++ configure_ssi_rx (0); ++ configure_ssi_rx (1); ++ configure_ssi_tx (0); ++ configure_ssi_tx (1); ++ ++ printk (KERN_INFO "bmi_audio.c: BMI_AUDIO Driver v%s \n", BMIAUDIO_VERSION); ++ if(fcc_test) ++ printk (KERN_INFO "bmi_audio.c: FCC Test mode enabled\n"); ++ if(output_ints) ++ printk (KERN_INFO "bmi_audio.c: Output Jack Interrupts enabled\n"); ++ return 0; ++} ++ ++/* ++ * @brief This is the audio device driver de-initialization function. ++ * ++ * This function is called by the kernel when this device driver is about ++ * to be unloaded. ++ */ ++static void __exit bmi_audio_exit (void) ++{ ++ dev_t dev_id; ++ int idn; ++ ++ printk (KERN_INFO "BMI Audio driver unloading...\n"); ++ ++ // delete scheduled work ++ flush_scheduled_work (); ++ ++ // remove bmi functionality ++ bmi_unregister_driver (&bmi_audio_driver); ++ ++ // free sound cards ++ snd_card_free (mxc_audio[0]->card); ++ snd_card_free (mxc_audio[1]->card); ++ ++ // free data structures ++ kfree (mxc_audio[0]); ++ kfree (mxc_audio[1]); ++ ++ // remove input devices ++ for (idn = BMI_AUDIO_M1; idn < BMI_AUDIO_PIM_NUM; idn++) ++ input_unregister_device (bmi_audio[idn].input_dev); ++ ++ // remove control cdev ++ dev_id = MKDEV(major, 0); ++ unregister_chrdev_region (dev_id, 4); ++ ++ // turn off I2S transceiver ++ bmi_inactivate_audio_ports(); ++ ++ printk (KERN_INFO "BMI Audio driver unloaded.\n"); ++ return; ++} ++ ++/* ++ * Module entry points and description information. ++ */ ++ ++module_init (bmi_audio_init); ++module_exit (bmi_audio_exit); ++ ++module_param(fcc_test, ushort, S_IRUGO); ++MODULE_PARM_DESC(fcc_test, "FCC Test code enable"); ++ ++module_param(output_ints, ushort, S_IRUGO); ++MODULE_PARM_DESC(fcc_test, "Output Jack Interrupts enable"); ++ ++MODULE_DESCRIPTION("BMI driver for ALSA"); ++MODULE_AUTHOR("EnCADIS Design, Inc. "); ++MODULE_LICENSE("GPL"); ++MODULE_SUPPORTED_DEVICE("PIM_AUDIO13"); ++MODULE_SUPPORTED_DEVICE("PIM_AUDIO24"); ++MODULE_SUPPORTED_DEVICE("bmi_audio_ctrl_m[1234]"); ++MODULE_SUPPORTED_DEVICE("bmi_audio_status_m[1234]"); ++ +--- /dev/null ++++ git/drivers/bmi/pims/vonhippel/Makefile +@@ -0,0 +1,6 @@ ++# ++# BMI PIMS ++# ++ ++obj-$(CONFIG_BMI_VH) += bmi_vh.o ++ +--- /dev/null ++++ git/drivers/bmi/pims/vonhippel/bmi_vh.c +@@ -0,0 +1,942 @@ ++/* ++ * bmi_vh.c ++ * ++ * BMI von Hippel device driver basic functionality ++ * ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/* ++ * Include files ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++#include ++ ++#define BMIVH_VERSION "1.0" ++#define RDAC_3_3V (0xAC) // 16.5K = 3.3V ++ ++/* ++ * Global variables ++ */ ++ ++static struct i2c_board_info iox_info = { ++ I2C_BOARD_INFO("VH_IOX", BMI_IOX_I2C_ADDRESS), ++}; ++ ++static struct i2c_board_info rdac_info = { ++ I2C_BOARD_INFO("VH_RDAC", VH_RDAC_I2C_ADDRESS), ++}; ++ ++static struct i2c_board_info adc_info = { ++ I2C_BOARD_INFO("VH_ADC", VH_ADC_I2C_ADDRESS), ++}; ++ ++static struct i2c_board_info dac_info = { ++ I2C_BOARD_INFO("VH_DAC", VH_DAC_I2C_ADDRESS), ++}; ++ ++ ++static ushort factory_test = 0; ++static ushort fcc_test = 0; ++static struct timer_list fcc_timer; ++static int fcc_state = 0x3; ++ ++// private device structure ++struct bmi_vh ++{ ++ struct bmi_device *bdev; // BMI device ++ struct cdev cdev; // control device ++ struct device *class_dev; // control class device ++ int open_flag; // single open flag ++ char int_name[20]; // interrupt name ++ struct i2c_client *iox; ++ struct i2c_client *rdac; ++ struct i2c_client *dac; ++ struct i2c_client *adc; ++ struct spi_device *spi; // SPI device ++ struct spi_board_info vh_spi_info; ++ char rbuf[BUF_MAX_SIZE]; // SPI read buffer ++ char wbuf[BUF_MAX_SIZE]; // SPI write buffer ++}; ++ ++static struct bmi_vh bmi_vh[4]; // per slot device structure ++static int major; // control device major ++ ++/* ++ * BMI set up ++ */ ++ ++// BMI device ID table ++static struct bmi_device_id bmi_vh_tbl[] = ++{ ++ { ++ .match_flags = BMI_DEVICE_ID_MATCH_VENDOR | BMI_DEVICE_ID_MATCH_PRODUCT, ++ .vendor = BMI_VENDOR_BUG_LABS, ++ .product = BMI_PRODUCT_VON_HIPPEL, ++ .revision = BMI_ANY, ++ }, ++ { 0, }, /* terminate list */ ++}; ++MODULE_DEVICE_TABLE(bmi, bmi_vh_tbl); ++ ++int bmi_vh_probe (struct bmi_device *bdev); ++void bmi_vh_remove (struct bmi_device *bdev); ++ ++// BMI driver structure ++static struct bmi_driver bmi_vh_driver = ++{ ++ .name = "bmi_vh", ++ .id_table = bmi_vh_tbl, ++ .probe = bmi_vh_probe, ++ .remove = bmi_vh_remove, ++}; ++ ++/* ++ * I2C set up ++ */ ++ ++// IOX ++// read byte from I2C IO expander ++static int ReadByte_IOX (struct i2c_client *client, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ ++ ret = i2c_master_send(client, &offset, 1); ++ if (ret == 1) ++ ret = i2c_master_recv(client, data, 1); ++ if (ret < 0) ++ printk (KERN_ERR "ReadByte_IOX() - i2c_transfer() failed...%d\n",ret); ++ return ret; ++} ++ ++// write byte to I2C IO expander ++static int WriteByte_IOX (struct i2c_client *client, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ unsigned char msg[2]; ++ ++ msg[0] = offset; ++ msg[1] = data; ++ ret = i2c_master_send(client, msg, sizeof(msg)); ++ ++ if (ret < 0) ++ printk (KERN_ERR "WriteByte_IOX() - i2c_transfer() failed...%d\n",ret); ++ ++ return ret; ++} ++ ++// RDAC ++// read byte from I2C LDO RDAC ++static int ReadByte_RDAC (struct i2c_client *client, unsigned char command, unsigned char *data) ++{ ++ int ret = 0; ++ ++ ret = i2c_master_send(client, &command, 1); ++ ++ if (ret < 0) ++ { ++ printk (KERN_ERR "ReadByte_RDAC() - i2c_master_send() failed...%d\n",ret); ++ return ret; ++ } ++ ret = i2c_master_recv(client, data, 1); ++ if (ret < 0) ++ printk (KERN_ERR "ReadByte_RDAC() - i2c_master_recv() failed...%d\n",ret); ++ return ret; ++} ++ ++// write byte to I2C LDO RDAC ++static int WriteByte_RDAC (struct i2c_client *client, unsigned char command, ++ unsigned char data, int send_data) ++{ ++ int ret = 0; ++ ++ unsigned char msg[2]; ++ ++ msg[0] = command; ++ msg[1] = data; ++ ++ if (send_data) ++ ret = i2c_master_send(client, msg, 2); ++ else ++ ret = i2c_master_send(client, &msg[0], 1); ++ if (ret < 0) ++ printk (KERN_ERR "WriteByte_RDAC() - i2c_transfer() failed...%d\n",ret); ++ ++ return ret; ++} ++ ++// ADC ++// read data from I2C ADC ++static int ReadByte_ADC (struct i2c_client *client, unsigned char *data) ++{ ++ int ret = 0; ++ ++ ret = i2c_master_recv(client, data, 3); ++ ++ if (ret < 0) ++ printk (KERN_ERR "ReadByte_ADC() - i2c_transfer() failed...%d\n",ret); ++ return ret; ++} ++ ++// write command to I2C ADC ++static int WriteByte_ADC (struct i2c_client *client, unsigned char w1, unsigned char w2) ++{ ++ int ret = 0; ++ unsigned char msg[2]; ++ ++ msg[0] = w1; ++ msg[1] = w2; ++ ret = i2c_master_send(client, msg, sizeof(msg)); ++ ++ if (ret < 0) ++ printk (KERN_ERR "WriteByte_ADC() - i2c_transfer() failed...%d\n",ret); ++ return ret; ++} ++ ++// DAC ++// read data from I2C DAC ++static int ReadByte_DAC (struct i2c_client *client, unsigned char command, unsigned char *data) ++{ ++ int ret = 0; ++ ++ ret = i2c_master_send(client, &command, 1); ++ if (ret == 1) ++ ret = i2c_master_recv(client, data, 2); ++ ++ if (ret < 0) ++ printk (KERN_ERR "ReadByte_DAC() - i2c_transfer() failed...%d\n",ret); ++ return ret; ++} ++ ++// write command to I2C DAC ++static int WriteByte_DAC (struct i2c_client *client, unsigned char w1, unsigned char w2, int send_w2) ++{ ++ int ret = 0; ++ unsigned char msg[2]; ++ ++ msg[0] = w1; ++ msg[1] = w2; ++ if (send_w2) ++ ret = i2c_master_send(client, msg, sizeof(msg)); ++ else ++ ret = i2c_master_send(client, &msg[0], 1); ++ ++ if (ret < 0) ++ printk (KERN_ERR "WriteByte_DAC() - i2c_transfer() failed...%d\n",ret); ++ return ret; ++} ++ ++ ++/* ++ * control device operations ++ */ ++ ++// open ++int cntl_open(struct inode *inode, struct file *file) ++{ ++ struct bmi_vh *vh; ++ ++ vh = container_of (inode->i_cdev, struct bmi_vh, cdev); ++ ++ // Enforce single-open behavior ++ ++ if (vh->open_flag) { ++ return -EBUSY; ++ } ++ vh->open_flag = 1; ++ ++ // Save vh_dev pointer for later. ++ ++ file->private_data = vh; ++ return 0; ++ ++} ++ ++// release ++int cntl_release(struct inode *inode, struct file *file) ++{ ++ struct bmi_vh *vh; ++ ++ vh = (struct bmi_vh *)(file->private_data); ++ vh->open_flag = 0; ++ return 0; ++} ++ ++// ioctl ++int cntl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct i2c_adapter *adap; ++ unsigned char iox_data; ++ unsigned char rdac_data; ++ // unsigned char buf[4]; ++ int ret = 0; ++ ++ struct bmi_vh *vh; ++ int slot; ++ ++ vh = (struct bmi_vh *)(file->private_data); ++ ++ // error if vh not present ++ if(vh->bdev == 0) ++ return -ENODEV; ++ ++ slot = vh->bdev->slot->slotnum; ++ adap = vh->bdev->slot->adap; ++ ++ // ioctl's ++ switch (cmd) { ++ ++ case BMI_VH_RLEDOFF: ++ bmi_slot_gpio_set (slot, ~VH_GPIO_RED_LED); // Red LED=OFF ++ break; ++ ++ case BMI_VH_RLEDON: ++ bmi_slot_gpio_set (slot, VH_GPIO_RED_LED); // Red LED=ON ++ break; ++ ++ case BMI_VH_GLEDOFF: ++ bmi_slot_gpio_set (slot, ~VH_GPIO_GREEN_LED); // Green LED=OFF ++ break; ++ ++ case BMI_VH_GLEDON: ++ bmi_slot_gpio_set (slot, VH_GPIO_GREEN_LED); // Green LED=ON ++ break; ++ ++ case BMI_VH_GETSTAT: ++ { ++ int read_data; ++ ++ if (ReadByte_IOX (vh->iox, IOX_INPUT_REG, &iox_data)) ++ return -ENODEV; ++ ++ read_data = iox_data | (bmi_slot_gpio_get(slot) << 8); ++ ++ if (put_user (read_data, (int __user *) arg)) ++ return -EFAULT; ++ } ++ break; ++ ++ case BMI_VH_MKGPIO_OUT: ++ if ((arg < VH_GPIO_0) || (arg > VH_GPIO_RED_LED)) ++ return -EINVAL; ++ //bmi_set_module_gpio_dir (slot, arg, BMI_GPIO_OUT); ++ break; ++ ++ case BMI_VH_MKGPIO_IN: ++ if ((arg < VH_GPIO_0) || (arg > VH_GPIO_RED_LED)) ++ return -EINVAL; ++ //bmi_set_module_gpio_dir (slot, arg, BMI_GPIO_IN); ++ break; ++ ++ case BMI_VH_SETGPIO: ++ if ((arg < VH_GPIO_0) || (arg > VH_GPIO_RED_LED)) ++ return -EINVAL; ++ //bmi_set_module_gpio_data (slot, arg, 0x1); ++ break; ++ ++ case BMI_VH_CLRGPIO: ++ if ((arg < VH_GPIO_0) || (arg > VH_GPIO_RED_LED)) ++ return -EINVAL; ++ //bmi_set_module_gpio_data (slot, arg, 0x0); ++ break; ++ ++ case BMI_VH_MKIOX_OUT: ++ if ((arg < VH_IOX_B0) || (arg > VH_IOX_B5)) ++ return -EINVAL; ++ { ++ unsigned char read_data; ++ ++ if (ReadByte_IOX (vh->iox, IOX_CONTROL, &iox_data)) ++ return -ENODEV; ++ ++ read_data = iox_data & ~(0x1 << arg); ++ ++ if (WriteByte_IOX (vh->iox, IOX_CONTROL, read_data)) ++ return -ENODEV; ++ } ++ break; ++ ++ case BMI_VH_MKIOX_IN: ++ if ((arg < VH_IOX_B0) || (arg > VH_IOX_B5)) ++ return -EINVAL; ++ { ++ unsigned char read_data; ++ ++ if (ReadByte_IOX (vh->iox, IOX_CONTROL, &iox_data)) ++ return -ENODEV; ++ ++ read_data = iox_data & (0x1 << arg); ++ ++ if (WriteByte_IOX (vh->iox, IOX_CONTROL, read_data)) ++ return -ENODEV; ++ } ++ break; ++ ++ case BMI_VH_SETIOX: ++ if ((arg < VH_IOX_B0) || (arg > VH_IOX_USB_VEN)) ++ return -EINVAL; ++ { ++ unsigned char read_data; ++ ++ if (ReadByte_IOX (vh->iox, IOX_OUTPUT_REG, &iox_data)) ++ return -ENODEV; ++ ++ read_data = iox_data | (0x1 << arg); ++ ++ if (WriteByte_IOX (vh->iox, IOX_OUTPUT_REG, read_data)) ++ return -ENODEV; ++ } ++ break; ++ ++ case BMI_VH_CLRIOX: ++ if ((arg < VH_IOX_B0) || (arg > VH_IOX_USB_VEN)) ++ return -EINVAL; ++ { ++ unsigned char read_data; ++ ++ if (ReadByte_IOX (vh->iox, IOX_OUTPUT_REG, &iox_data)) ++ return -ENODEV; ++ ++ read_data = iox_data & ~(0x1 << arg); ++ ++ if (WriteByte_IOX (vh->iox, IOX_OUTPUT_REG, read_data)) ++ return -ENODEV; ++ } ++ break; ++ ++ case BMI_VH_SETRDAC: ++ rdac_data = (unsigned char) (arg & 0xFF); ++ ++ if (WriteByte_RDAC (vh->rdac, VH_RD_CMD_RDAC, rdac_data, 1)) ++ return -ENODEV; ++ ++ if (WriteByte_RDAC (vh->rdac, VH_RD_CMD_EE, rdac_data, 1)) ++ return -ENODEV; ++ ++ break; ++ ++ case BMI_VH_RDRDAC: ++ ++ if (ReadByte_RDAC (vh->rdac, VH_RD_CMD_RDAC, &rdac_data)) ++ return -ENODEV; ++ ++ if(copy_to_user((unsigned int *) arg, &rdac_data, sizeof(int))) ++ ret = -EFAULT; ++ else ++ ret = 0; ++ ++ break; ++ ++ case BMI_VH_ADCWR: ++ { ++ struct vh_adc_wr *adc_wr = NULL; ++ ++ if ((adc_wr = kmalloc(sizeof(struct vh_adc_wr), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ if (copy_from_user(adc_wr, (struct vh_adc_wr *)arg, sizeof(struct vh_adc_wr))) { ++ kfree (adc_wr); ++ return -EFAULT; ++ } ++ if (WriteByte_ADC (vh->adc, adc_wr->w1, adc_wr->w2)) { ++ kfree (adc_wr); ++ return -ENODEV; ++ } ++ kfree (adc_wr); ++ } ++ break; ++ ++ case BMI_VH_ADCRD: ++ { ++ unsigned char adc_data[3]; ++ unsigned int ret_data; ++ ++ if (ReadByte_ADC(vh->adc, adc_data)) // read ADC conversion ++ return -ENODEV; ++ ++ ret_data = (unsigned int) ((adc_data[0] << 16) | (adc_data[1] << 8) | adc_data[2]); ++ if(copy_to_user((unsigned int *) arg, &ret_data, sizeof(int))) ++ ret = -EFAULT; ++ else ++ ret = 0; ++ } ++ ++ break; ++ ++ case BMI_VH_DACWR: ++ { ++ struct vh_dac_wr *dac_wr = NULL; ++ ++ if ((dac_wr = kmalloc(sizeof(struct vh_dac_wr), GFP_KERNEL)) == NULL) ++ return -ENOMEM; ++ if (copy_from_user(dac_wr, (struct vh_dac_wr *)arg, sizeof(struct vh_dac_wr))) { ++ kfree (dac_wr); ++ return -EFAULT; ++ } ++ if (dac_wr->w1 == VH_DAC_W1_UALL) { ++ if (WriteByte_DAC (vh->dac, dac_wr->w1, dac_wr->w2, 0)) { ++ kfree (dac_wr); ++ return -ENODEV; ++ } ++ } else { ++ if (WriteByte_DAC (vh->dac, dac_wr->w1, dac_wr->w2, 1)) { ++ kfree (dac_wr); ++ return -ENODEV; ++ } ++ } ++ kfree (dac_wr); ++ } ++ break; ++ ++ case BMI_VH_DACRD: ++ { ++ unsigned char dac_data[2]; ++ unsigned int command; ++ unsigned int ret_data; ++ ++ if (copy_from_user(&command, (unsigned int *)arg, sizeof(int))) { ++ return -EFAULT; ++ } ++ ++ if (!((command == VH_DAC_W1_RDA) || (command == VH_DAC_W1_RDB))) { ++ return -EINVAL; ++ } ++ ++ if (ReadByte_DAC(vh->dac, (unsigned char) command, dac_data)) { // read DAC value ++ return -ENODEV; ++ } ++ ++ ret_data = (unsigned int) ((dac_data[0] << 8) | dac_data[1]); ++ if(copy_to_user((unsigned int *) arg, &ret_data, sizeof(int))) { ++ ret = -EFAULT; ++ } else { ++ ret = 0; ++ } ++ } ++ ++ break; ++ ++ default: ++ return -ENOTTY; ++ } ++ ++ return 0; ++} ++ ++// control file operations ++struct file_operations cntl_fops = { ++ .owner = THIS_MODULE, ++ .ioctl = cntl_ioctl, ++ .open = cntl_open, ++ .release = cntl_release, ++}; ++ ++/* ++ * PIM functions ++ */ ++ ++// FCC test timer ++void ftimer(unsigned long arg) ++{ ++ struct bmi_vh *bmi_vh = (struct bmi_vh *) arg; ++ int slot = bmi_vh->bdev->slot->slotnum; ++ ++ /* bmi_set_module_gpio_data (slot, VH_GPIO_RED_LED, (fcc_state & 0x2) >> 1); ++ bmi_set_module_gpio_data (slot, VH_GPIO_GREEN_LED, fcc_state & 0x1);*/ ++ fcc_state = (fcc_state + 1) % 4; ++ del_timer (&fcc_timer); ++ fcc_timer.expires = jiffies + (2 * HZ); ++ add_timer (&fcc_timer); ++} ++ ++// interrupt handler ++static irqreturn_t module_irq_handler(int irq, void *dummy) ++{ ++ /*if (!factory_test) { ++ printk (KERN_ERR "Von Hippel USB power error - slot "); ++ switch (irq) { ++ case M1_IRQ: ++ printk (KERN_ERR "1 - powering off\n"); ++ bmi_slot_power_off (0); ++ break; ++ case M2_IRQ: ++ printk (KERN_ERR "2 - powering off\n"); ++ bmi_slot_power_off (1); ++ break; ++ case M3_IRQ: ++ printk (KERN_ERR "3 - powering off\n"); ++ bmi_slot_power_off (2); ++ break; ++ case M4_IRQ: ++ printk (KERN_ERR "3 - powering off\n"); ++ bmi_slot_power_off (3); ++ break; ++ } ++ } ++ disable_irq(irq);*/ ++ return IRQ_HANDLED; ++} ++ ++/* ++ * BMI functions ++ */ ++ ++// probe - insert PIM ++int bmi_vh_probe(struct bmi_device *bdev) ++{ ++ int err; ++ int slot; ++ struct bmi_vh *vh; ++ struct i2c_adapter *adap; ++ struct cdev *cdev; ++ struct class *bmi_class; ++ dev_t dev_id; ++ int irq; ++ unsigned char rdac_data[1]; ++ unsigned char adc_data[3]; ++ unsigned char dac_data[2]; ++ unsigned long speed = 1000000; ++ unsigned char mode = SPI_MODE_2; // von Hippel chip select must be low active ++ unsigned char bits_per_word = 32; ++ unsigned char iox_data; ++ unsigned char buf[4]; ++ struct spi_xfer spi_xfer; ++ int gpio_int; ++ ++ err = 0; ++ slot = bdev->slot->slotnum; ++ adap = bdev->slot->adap; ++ vh = &bmi_vh[slot]; ++ ++ vh->bdev = 0; ++ vh->open_flag = 0; ++ ++ // Create 1 minor device ++ cdev = &vh->cdev; ++ cdev_init (cdev, &cntl_fops); ++ ++ dev_id = MKDEV(major, slot); ++ err = cdev_add (cdev, dev_id, 1); ++ if (err) { ++ return err; ++ } ++ ++ // Create class device ++ bmi_class = bmi_get_class (); ++ vh->class_dev = device_create (bmi_class, NULL, MKDEV (major, slot), NULL, "bmi_vh_control_m%i", slot+1); ++ ++ if (IS_ERR(vh->class_dev)) { ++ printk (KERN_ERR "Unable to create " ++ "class_device for bmi_vh_m%i; errno = %ld\n", ++ slot+1, PTR_ERR(vh->class_dev)); ++ vh->class_dev = NULL; ++ cdev_del (&vh->cdev); ++ return -ENODEV; ++ } ++ ++ // bind driver and bmi_device ++ vh->bdev = bdev; ++ ++ ++ printk (KERN_INFO "bmi_vh.c: probe slot %d\n", slot); ++ vh->iox = i2c_new_device(bdev->slot->adap, &iox_info); ++ if (vh->iox == NULL) ++ printk(KERN_ERR "IOX NULL...\n"); ++ vh->rdac = i2c_new_device(bdev->slot->adap, &rdac_info); ++ if (vh->rdac == NULL) ++ printk(KERN_ERR "RDAC NULL...\n"); ++ vh->adc = i2c_new_device(bdev->slot->adap, &adc_info); ++ if (vh->adc == NULL) ++ printk(KERN_ERR "ADC NULL...\n"); ++ vh->dac = i2c_new_device(bdev->slot->adap, &dac_info); ++ if (vh->dac == NULL) ++ printk(KERN_ERR "DAC NULL...\n"); ++ ++ // SPI ++ strcpy(vh->vh_spi_info.modalias, "spidev"); ++ vh->vh_spi_info.max_speed_hz = speed; ++ vh->vh_spi_info.bus_num = bdev->slot->spi_bus_num; ++ vh->vh_spi_info.chip_select = bdev->slot->spi_cs; ++ vh->vh_spi_info.mode = mode; ++ ++ vh->spi = spi_new_device(spi_busnum_to_master(vh->vh_spi_info.bus_num), &vh->vh_spi_info) ; ++ if (!vh->spi) ++ printk(KERN_WARNING "VH: spi_new_device failed\n"); ++ ++ bmi_device_set_drvdata (bdev, vh); ++ // configure IOX ++ if (factory_test) { ++ if (WriteByte_IOX(vh->iox, IOX_OUTPUT_REG, 0x55) < 0) { // all outputs high ++ goto err1; ++ } ++ ++ if (WriteByte_IOX(vh->iox, IOX_CONTROL, 0xAA) < 0) { // IOX[7,5,3,1]=IN, IOX[6,4,2,0]=OUT ++ goto err1; ++ } ++ } else { ++ if (WriteByte_IOX(vh->iox, IOX_OUTPUT_REG, 0x7F) < 0) { // USB power on, other outputs high ++ goto err1; ++ } ++ ++ if (WriteByte_IOX(vh->iox, IOX_CONTROL, 0x80) < 0) { // IOX[7]=IN, IOX[6:0]=OUT ++ goto err1; ++ } ++ } ++ ++ mdelay(100); ++ ++ // read RDAC ++ if (ReadByte_RDAC(vh->rdac, VH_RD_CMD_RDAC, rdac_data) < 0) { // read LDO RDAC register ++ goto err1; ++ } ++ ++ printk (KERN_INFO "bmi_vh.c: probe RDAC = 0x%x\n", *rdac_data); ++ ++ if (factory_test) { ++ ++ mdelay(100); // RDAC recovery time ++ ++ // set LDO voltage to 3.3V ++ *rdac_data = (unsigned char) RDAC_3_3V; ++ ++ if (WriteByte_RDAC (vh->rdac, VH_RD_CMD_RDAC, *rdac_data, 1) < 0) { ++ goto err1; ++ } ++ ++ mdelay(100); ++ ++ if (WriteByte_RDAC (vh->rdac, VH_RD_CMD_EE, *rdac_data, 1) < 0) { ++ goto err1; ++ } ++ ++ mdelay(100); ++ ++ // read EEPROM ++ if (ReadByte_RDAC(vh->rdac, VH_RD_CMD_EE, rdac_data) < 0) { // read LDO EEPROM ++ goto err1; ++ } ++ ++ printk (KERN_INFO "bmi_vh.c: probe EEPROM = 0x%x\n", *rdac_data); ++ ++ mdelay(100); ++ } ++ ++ // read ADC ++ if (ReadByte_ADC(vh->adc, adc_data) < 0) { // read initial ADC conversion ++ goto err1; ++ } ++ ++ printk (KERN_INFO "bmi_vh.c: probe ADC = 0x%x%x%x\n", adc_data[0], adc_data[1], adc_data[2]); ++ ++ if (factory_test) { ++ ++ // power up DAC ++ if (WriteByte_DAC(vh->dac, VH_DAC_W1_EC, VH_DAC_BCH | VH_DAC_PU, 1) < 0) { ++ goto err1; ++ } ++ ++ // Write DAC data ++ if (WriteByte_DAC(vh->dac, VH_DAC_W1_ALL | 0x0, 0xF0, 1) < 0) { // write A, B, inputs and update ++ goto err1; ++ } ++ } ++ ++ // read DAC ++ if (ReadByte_DAC(vh->dac, VH_DAC_W1_RDA, dac_data) < 0) { // read initial DAC A value ++ goto err1; ++ } ++ ++ printk (KERN_INFO "bmi_vh.c: probe DAC = 0x%x%x\n", dac_data[0], dac_data[1]); ++ ++ ++ ++ // Initialize GPIOs (turn LED's on) ++ if (factory_test) { ++ bmi_slot_gpio_configure (slot, VH_GPIO_RED_LED); // (test I2S) ++ bmi_slot_gpio_configure (slot, VH_GPIO_GREEN_LED); // (test I2S) ++ bmi_slot_gpio_configure (slot, VH_GPIO_1); // (test I2S) ++ bmi_slot_gpio_configure (slot, VH_GPIO_0 | VH_GPIO_1); // (test interrupt) ++ } else { ++ bmi_slot_gpio_configure (slot, RED_LED |GREEN_LED ); // Red LED=ON ++ bmi_slot_gpio_set (slot, ~(RED_LED | GREEN_LED)); ++ mdelay(200); ++ ++ // turn LED's off ++ bmi_slot_gpio_set (slot, (RED_LED | GREEN_LED)); // Red, Green LED=OFF ++ ++ if (WriteByte_IOX(vh->iox, IOX_OUTPUT_REG, 0x70) < 0) { // USB power on, IOX[3:0] low, other outputs high ++ printk (KERN_ERR "bmi_vh.c: probe() - write IOX failed\n"); ++ //bmi_device_spi_cleanup(bdev); ++ goto err1; ++ } ++ } ++ ++ // request PIM interrupt ++ irq = bdev->slot->status_irq; ++ sprintf (vh->int_name, "bmi_vh%d", slot); ++ if (request_irq(irq, &module_irq_handler, 0, vh->int_name, vh)) { ++ printk (KERN_ERR "bmi_vh.c: Can't allocate irq %d or find von Hippel in slot %d\n", ++ irq, slot); ++ //bmi_device_spi_cleanup(bdev); ++ goto err1; ++ ++ //return -EBUSY; ++ } ++ ++ if (fcc_test) { ++ init_timer (&fcc_timer); ++ fcc_timer.data = (unsigned long) &bmi_vh[slot]; ++ fcc_timer.expires = jiffies + (2 * HZ); ++ fcc_timer.function = ftimer; ++ add_timer (&fcc_timer); ++ } ++ ++ ++ return 0; ++ ++ err1: ++ vh->class_dev = NULL; ++ cdev_del (&vh->cdev); ++ device_destroy (bmi_class, MKDEV(major, slot)); ++ bmi_device_set_drvdata (bdev, 0); ++ vh->bdev = 0; ++ i2c_unregister_device(vh->iox); ++ i2c_unregister_device(vh->rdac); ++ i2c_unregister_device(vh->adc); ++ i2c_unregister_device(vh->dac); ++ spi_unregister_device(vh->spi); ++ return -ENODEV; ++} ++ ++// remove PIM ++void bmi_vh_remove(struct bmi_device *bdev) ++{ ++ int slot; ++ struct bmi_vh *vh; ++ struct class *bmi_class; ++ int irq; ++ ++ printk(KERN_INFO "bmi_vh: Module Removed...\n"); ++ slot = bdev->slot->slotnum; ++ vh = &bmi_vh[slot]; ++ ++ i2c_unregister_device(vh->iox); ++ i2c_unregister_device(vh->rdac); ++ i2c_unregister_device(vh->adc); ++ i2c_unregister_device(vh->dac); ++ spi_unregister_device(vh->spi); ++ ++ if (factory_test) { ++ // disable uart transceiver ++ bmi_slot_uart_disable (slot); ++ } ++ ++ if (fcc_test) ++ del_timer (&fcc_timer); ++ ++ irq = bdev->slot->status_irq; ++ free_irq (irq, vh); ++ ++ bmi_slot_gpio_configure(slot, 0); ++ //bmi_device_spi_cleanup(bdev); ++ ++ bmi_class = bmi_get_class (); ++ device_destroy (bmi_class, MKDEV(major, slot)); ++ ++ vh->class_dev = 0; ++ ++ cdev_del (&vh->cdev); ++ ++ // de-attach driver-specific struct from bmi_device structure ++ bmi_device_set_drvdata (bdev, 0); ++ vh->bdev = 0; ++ ++ return; ++} ++ ++/* ++ * module routines ++ */ ++ ++static void __exit bmi_vh_cleanup(void) ++{ ++ dev_t dev_id; ++ ++ bmi_unregister_driver (&bmi_vh_driver); ++ ++ dev_id = MKDEV(major, 0); ++ unregister_chrdev_region (dev_id, 4); ++ return; ++} ++ ++static int __init bmi_vh_init(void) ++{ ++ dev_t dev_id; ++ int retval; ++ ++ // alloc char driver with 4 minor numbers ++ retval = alloc_chrdev_region (&dev_id, 0, 4, "BMI VH Driver"); ++ if (retval) { ++ return -ENODEV; ++ } ++ ++ major = MAJOR(dev_id); ++ retval = bmi_register_driver (&bmi_vh_driver); ++ if (retval) { ++ unregister_chrdev_region(dev_id, 4); ++ return -ENODEV; ++ } ++ ++ if(factory_test) ++ printk (KERN_INFO "bmi_vh.c: Factory Test mode enabled\n"); ++ ++ if(fcc_test) ++ printk (KERN_INFO "bmi_vh.c: FCC Test mode enabled\n"); ++ ++ printk (KERN_INFO "bmi_vh.c: BMI_VH Driver v%s \n", BMIVH_VERSION); ++ ++ return 0; ++} ++ ++ ++module_init(bmi_vh_init); ++module_exit(bmi_vh_cleanup); ++ ++module_param(factory_test, ushort, S_IRUGO); ++MODULE_PARM_DESC(factory_test, "Factory Test code enable"); ++ ++module_param(fcc_test, ushort, S_IRUGO); ++MODULE_PARM_DESC(fcc_test, "FCC Test code enable"); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Buglabs Inc."); ++MODULE_DESCRIPTION("BMI von Hippel device driver"); ++MODULE_SUPPORTED_DEVICE("bmi_vh_control_mX"); ++ +--- /dev/null ++++ git/drivers/bmi/pims/zb/Makefile +@@ -0,0 +1,5 @@ ++# ++# BMI PIMS ZigBee ++# ++bmi_zb-objs := bmi_zigbee.o bmi_zaccel.o bmi_zprotocol.o bmi_znetdev.o ++obj-$(CONFIG_BMI_ZB) += bmi_zb.o +--- /dev/null ++++ git/drivers/bmi/pims/zb/bmi_zaccel.c +@@ -0,0 +1,684 @@ ++/* ++ * ++ * bmi_zaccel.c ++ * ++ * API to Zaccel device ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++#include ++#include ++#include "bmi_zigbee.h" ++#include "bmi_zaccel.h" ++ ++int reset_count = 0; ++ ++int zb_ReadConfiguration(struct bmi_zb *zb, unsigned char configId, unsigned char *buf) ++{ ++ unsigned char data[128]; ++ unsigned char i, len; ++ ++ data[0] = 1; ++ data[1] = ZB_READ_CONFIG_REQ_0; ++ data[2] = ZB_READ_CONFIG_REQ_1; ++ data[3] = configId; ++ ++ // Write to the device ++ if(zaccel_spi_req(zb, data, 128) < 0) ++ { ++ return -1; ++ } ++ ++ /* ++ * Return value has format shown below. ++ * data[0] = Zaccetl return status ++ * data[1] = configID ++ * data[2] = len ++ * data[3-130] = value ++ */ ++ len = data[0]; ++ ++ /* ++ * truncate output to 128 bytes if it is longer than 128 byte. ++ * Zaccel data sheet indicates 0-128 bytes value. ++ * Add 3 byte header to the total length ++ */ ++ if(len > 128) ++ len = 128; ++ ++ for(i = 0; i < (len + 3); i++) ++ { ++ buf[i] = data[i]; ++ } ++ ++ return(len); ++} ++ ++unsigned char zb_WriteConfiguration(struct bmi_zb *zb, unsigned char configId, unsigned char len, unsigned char *value) ++{ ++ unsigned char data[128]; ++ int rc; ++ ++ if(len > 128) ++ { ++ /* Len exceeds the max size */ ++ rc = -1; ++ } ++ data[0] = 2 + len; ++ data[1] = ZB_WRITE_CONFIG_REQ_0; ++ data[2] = ZB_WRITE_CONFIG_REQ_1; ++ data[3] = configId; ++ data[4] = len; ++ ++ memcpy((unsigned char *)(&data[5]),value,len); ++ ++ /* Write to the device. */ ++ zaccel_spi_req(zb, data, 128); ++ ++ /* read return status */ ++ rc = data[3]; ++ ++ return rc; ++} ++ ++void zb_SoftReset(struct bmi_zb *zb) ++{ ++ unsigned char data[8]; ++ ++ data[0] = 1; ++ data[1] = SYS_RESET_REQ_0; ++ data[2] = SYS_RESET_REQ_1; ++ data[3] = 0; ++ ++ /* Write to the device. */ ++ zaccel_spi_req(zb, data, 8); ++} ++ ++void zb_sysVersion(struct bmi_zb *zb) ++{ ++ unsigned char data[16]; ++ ++ /* SYS_VERSION command returns 5 bytes of data */ ++ ++ data[0] = 0; ++ data[1] = SYS_VER_0; ++ data[2] = SYS_VER_1; ++ ++ /* Write to the device. */ ++ zaccel_spi_req(zb, data, 16); ++} ++ ++int zb_sysRFpowerAmp(struct bmi_zb *zb, unsigned char pa, unsigned char power) ++{ ++ unsigned char data[32]; ++ int rc = 0; ++ ++ if(power > SYS_RF_PA_MIN) ++ { ++ return -EINVAL; ++ } ++ ++ data[0] = 2; ++ data[1] = SYS_RF_POWER_AMP_0; ++ data[2] = SYS_RF_POWER_AMP_1; ++ data[3] = pa; ++ data[4] = power; ++ ++ /* Write to the device */ ++ zaccel_spi_req(zb, data, 32); ++ ++ /* compare the return values */ ++ if((data[3] != pa) || (data[4] != power)) ++ { ++ rc = -1; ++ } ++ ++ return rc; ++} ++ ++unsigned char zb_device_info_len[] = {1, 8, 2, 2, 8, 1, 2, 8}; ++ ++int zb_GetDeviceInfo(struct bmi_zb *zb, unsigned char param,unsigned char *buf) ++{ ++ unsigned char len; ++ unsigned char data[32]; ++ unsigned char i; ++ ++ if(param > ZB_DEVICE_LAST) ++ { ++ printk(KERN_WARNING "zb: invalid device info %d\n",param); ++ return -EINVAL; ++ } ++ ++ data[0] = 1; ++ data[1] = ZB_GET_DEVICE_INFO_0; ++ data[2] = ZB_GET_DEVICE_INFO_1; ++ data[3] = param; ++ ++ /* Write to the device. */ ++ zaccel_spi_req(zb, data, 32); ++ ++ /* data points to the value byte */ ++ len = zb_device_info_len[param]; ++ for(i = 0; i < len; i++) ++ { ++ buf[i] = data[i+4]; ++ } ++ ++ return(len); ++} ++ ++void zb_FindDeviceRequest(struct bmi_zb *zb, unsigned char *searchKey) ++{ ++ unsigned char data[16]; ++ ++ data[0] = 8; ++ data[1] = ZB_FIND_DEVICE_REQ_0; ++ data[2] = ZB_FIND_DEVICE_REQ_1; ++ ++ memcpy(&data[3],searchKey,8); ++ ++ /* Write to the device. */ ++ zaccel_spi_req(zb, data, 16); ++} ++ ++void zb_StartDevice(struct bmi_zb *zb, unsigned char option) ++{ ++ zb_WriteConfiguration(zb,ZCD_NV_STARTUP_OPTION,1,&option); ++ zb_Reset(zb,ZB_RESET); ++ udelay(10); ++ zb_Reset(zb,ZB_RELEASE); ++} ++ ++int zb_StartRequest(struct bmi_zb *zb) ++{ ++ unsigned char data[8]; ++ ++ data[0] = 0; ++ data[1] = ZB_START_REQ_0; ++ data[2] = ZB_START_REQ_1; ++ ++ zb->z_info.msg_flag &= ~START_CNF_BIT; ++ ++ /* Write to the device */ ++ zaccel_spi_req(zb, data, 8); ++ ++ return 0; ++} ++ ++unsigned char zb_PermitJoiningRequest(struct bmi_zb *zb, unsigned char *dest, unsigned char timeout) ++{ ++ unsigned char data[8]; ++ unsigned char rc; ++ ++ data[0] = 3; ++ data[1] = ZB_PERMIT_JOINING_REQ_0; ++ data[2] = ZB_PERMIT_JOINING_REQ_1; ++ data[3] = dest[0]; /* LSB of short address */ ++ data[4] = dest[1]; /* MSB of short address */ ++ data[5] = timeout; ++ ++ /* Write to the device */ ++ zaccel_spi_req(zb, data, 8); ++ ++ rc = data[3]; ++ ++ if(rc != Z_SUCCESS) ++ { ++ printk(KERN_WARNING "zb_PermitJoiningReques invalid 0x%x\n",rc); ++ } ++ ++ return rc; ++} ++ ++void zb_AllowBind(struct bmi_zb *zb, unsigned char timeout) ++{ ++ unsigned char data[8]; ++ ++ data[0] = 1; ++ data[1] = ZB_ALLOW_BIND_0; ++ data[2] = ZB_ALLOW_BIND_1; ++ data[3] = timeout; ++ ++ /* Write to the device */ ++ zaccel_spi_req(zb, data, 8); ++} ++ ++unsigned char zb_AppRegisterRequest(struct bmi_zb *zb, unsigned char len, unsigned char *app_info) ++{ ++ unsigned char *data; ++ unsigned char rc; ++ ++ data = kmalloc((len + ZCMD_HEADER), GFP_KERNEL); ++ ++ data[0] = len; ++ data[1] = ZB_APP_REGISTER_REQ_0; ++ data[2] = ZB_APP_REGISTER_REQ_1; ++ ++ memcpy(&data[3],app_info,len); ++ ++ zaccel_spi_req(zb,data, (len + ZCMD_HEADER)); ++ ++ /* Read return status */ ++ rc = data[3]; ++ if(rc == Z_SUCCESS) ++ { ++ zb->z_info.app_type = SAPI_TYPE; ++ } ++ ++ kfree(data); ++ ++ return rc; ++ ++} ++ ++unsigned char zb_AFRegisterRequest(struct bmi_zb *zb, unsigned char len, unsigned char *app_info) ++{ ++ unsigned char *data; ++ unsigned char rc; ++ ++ data = kmalloc((len + ZCMD_HEADER), GFP_KERNEL); ++ ++ data[0] = len; ++ data[1] = AF_REGISTER_0; ++ data[2] = AF_REGISTER_1; ++ ++ memcpy(&data[3],app_info,len); ++ ++ zaccel_spi_req(zb,data, (len + ZCMD_HEADER)); ++ ++ /* Read return status */ ++ rc = data[3]; ++ if(rc == Z_SUCCESS) ++ { ++ zb->z_info.app_type = AF_INTERFACE_TYPE; ++ } ++ ++ kfree(data); ++ ++ return rc; ++} ++ ++void zb_BindRequest(struct bmi_zb *zb, unsigned char create, unsigned char *bind_info) ++{ ++ unsigned char data[16]; ++ ++ data[0] = 0x0B; ++ data[1] = ZB_BIND_DEVICE_0; ++ data[2] = ZB_BIND_DEVICE_1; ++ data[3] = create; ++ ++ memcpy(&data[4], bind_info, 10); ++ ++ zaccel_spi_req(zb,data, 16); ++} ++ ++int zb_SendDataRequest(struct bmi_zb *zb, unsigned char *buf, unsigned char len) ++{ ++ unsigned char *data; ++ ++ /* ++ * The user sends data to the remote ZigBee. ++ * Check if we use the SAPI or the AF send message. ++ * We expect that the user format the content of the ++ * message correctly. ++ */ ++ data = kmalloc((len + ZCMD_HEADER),GFP_KERNEL); ++ data[0] = len; ++ ++ if(zb->z_info.app_type == AF_INTERFACE_TYPE) ++ { ++ data[1] = AF_DATA_REQ_0; ++ data[2] = AF_DATA_REQ_1; ++ } ++ else ++ { ++ /* anything else will use SAPI */ ++ data[1] = ZB_SEND_DATA_REQ_0; ++ data[2] = ZB_SEND_DATA_REQ_1; ++ } ++ ++ memcpy((unsigned char *)(&data[3]), buf, len ); ++ ++ zaccel_spi_req(zb,data,(len + ZCMD_HEADER)); ++ return 0; ++} ++ ++int zb_SysTestLoopback(struct bmi_zb *zb) ++{ ++ unsigned char *data; ++ unsigned char i, len; ++ unsigned char buf_len; ++ unsigned char pattern[32]; ++ int rc; ++ ++ len = 4; ++ buf_len = len + ZCMD_HEADER; ++ data = kmalloc(buf_len,GFP_KERNEL); ++ ++ data[0] = len; ++ data[1] = SYS_TEST_LOOPBACK_REQ_0; ++ data[2] = SYS_TEST_LOOPBACK_REQ_1; ++ ++ /* Prepare test pattern */ ++ pattern[0] = 0xAA; ++ pattern[1] = 0x55; ++ pattern[2] = 0x07; ++ pattern[3] = 0x5A; ++ pattern[4] = 0x63; ++ pattern[5] = 0x58; ++ pattern[6] = 0x74; ++ pattern[7] = 0x55; ++ pattern[8] = 0x02; ++ pattern[9] = 0x04; ++ pattern[10] = 0x08; ++ pattern[11] = 0x10; ++ pattern[12] = 0x20; ++ pattern[13] = 0xAA; ++ pattern[14] = 0x55; ++ ++ memcpy(&data[3],pattern,len); ++ ++#define TEST_LOOPBACKx ++#ifdef TEST_LOOPBACK ++ printk("Loopback pattern: "); ++ for(i = 0; i < buf_len; i++) ++ { ++ printk("%x ",data[i]); ++ } ++ printk(KERN_DEBUG "\n"); ++#endif ++ ++ zaccel_spi_req(zb,data,buf_len); ++ ++ /* Verify loopback results */ ++ if((data[1] == (SYS_TEST_LOOPBACK_REQ_0 | RSPS_CMD)) && ++ (data[2] == SYS_TEST_LOOPBACK_REQ_1)) ++ { ++ if(data[0] == len) ++ { ++ rc = 0; ++ for(i = 0; i < len; i++) ++ { ++ if(data[ZCMD_HEADER + i] != pattern[i]) ++ { ++ rc++; ++ printk(KERN_WARNING "error: zb test byte %d expects %x, gets %x\n",i,pattern[i],data[ZCMD_HEADER + i]); ++ } ++ } ++ } ++ else ++ { ++ rc = -2; ++ } ++ } ++ else ++ { ++ rc = -1; ++ } ++ ++ return rc; ++} ++ ++void zDeviceReport(struct bmi_zb *zb,unsigned char type, unsigned char len,unsigned char *buf) ++{ ++ unsigned char *msg; ++ ++ msg = kmalloc((ZCMD_HEADER + len),GFP_KERNEL); ++ ++ msg[0] = len; ++ msg[1] = ZB_DEVICE_INFO_CHG_0; ++ msg[2] = ZB_DEVICE_INFO_CHG_0; ++ memcpy(&msg[3],buf,len); ++ ++ len = ZCMD_HEADER + len; ++ ++#ifdef VE_OUT ++ /* Send message to the application layer through control socket */ ++ zb_rx(zb->netdev,msg,len,Z_CONTROL_SOCK); ++#endif ++ ++ kfree(msg); ++} ++ ++/* ++ * This routine send data originated by the user layer to ++ * the Z-Accel. ++ */ ++void zaccel_xmt(struct work_struct *work) ++{ ++ struct bmi_zb *zb; ++ struct zaccel_info *z_info; ++ struct zaccel_xmt_msg *msg; ++ ++ zb = container_of(work, struct bmi_zb, xmt_work); ++ z_info = &zb->z_info; ++ ++ while(!list_empty(&z_info->xmt_list)) ++ { ++ msg = list_entry(z_info->xmt_list.next, struct zaccel_xmt_msg, list); ++ ++ zb_SendDataRequest(zb, msg->buf, msg->len); ++ ++ list_del(z_info->xmt_list.next); ++ kfree(msg); ++ } ++} ++ ++/* ++ * zaccel_cmd_proc processes messages from the Zaccel. ++ */ ++ ++void zaccel_cmd_proc(struct bmi_zb *zb, unsigned char *buf) ++{ ++ struct zaccel_info *z_info; ++ struct net_zb *priv; ++ unsigned char len; ++ unsigned short cmd; ++ int rc; ++ ++ z_info = &zb->z_info; ++ ++ len = buf[0] + ZCMD_HEADER; ++ ++ /* process the message from Z-Accel */ ++ ++ cmd = ((((unsigned short)buf[1] << 8) & 0xFF00) | ++ ((unsigned short)buf[2] & 0x00FF)); ++ ++ switch(cmd) ++ { ++ case SYS_RESET_IND: ++ ++ if(buf[3] == 2) ++ { ++ /* count number of reset by watch-dog */ ++ reset_count++; ++ } ++ ++ printk(KERN_INFO "zb%d SYS_RESET_IND %d \n",zb->slot,reset_count); ++ /* rcv Z-Accel reset indication. */ ++ z_info->msg_flag |= RESET_IND_BIT; ++ wake_up_interruptible(&z_info->wait_queue); ++ ++ zb_rx(zb->netdev,buf,len,Z_CONTROL_SOCK); ++ break; ++ ++ case ZB_START_CONFIRM: ++ /* ++ * Z-Stack starts. Device is ready to run applicaton. ++ */ ++ z_info->msg_flag |= START_CNF_BIT; ++ wake_up_interruptible(&z_info->wait_queue); ++ break; ++ ++ case ZB_RCV_DATA_IND: ++ case AF_INCOMING_MSG: ++ /* ++ * Receive a packet from a remote device ++ * Send it to the user throught packet socket. ++ */ ++ len = buf[0]; ++ ++ if(zb->netdev) ++ { ++ rc = zb_rx(zb->netdev,&buf[3],len,Z_PACKET_SOCK); ++ priv = netdev_priv(zb->netdev); ++ if(rc >= 0) ++ { ++ priv->stats.rx_packets++; ++ priv->stats.rx_bytes += len; ++ } ++ else ++ { ++ priv->stats.rx_dropped++; ++ } ++ } ++ break; ++ ++ case ZB_BIND_CONFIRM: ++ printk(KERN_DEBUG "Rec BIND CNF - cmd %x %x rc %x len %d\n", ++ buf[3],buf[4],buf[5],len); ++ zb_rx(zb->netdev,buf,len,Z_CONTROL_SOCK); ++ break; ++ ++ case ZB_SEND_DATA_CONFIRM: ++ /* Return the results from zb_SendDataRequest */ ++ if(zb->netdev) ++ { ++ priv = netdev_priv(zb->netdev); ++ if(buf[4] == Z_SUCCESS) ++ priv->stats.tx_packets++; ++ else ++ { ++ printk(KERN_WARNING "ZB: send data failed 0x%x\n",buf[4]); ++ priv->stats.tx_dropped++; ++ } ++ zb_rx(zb->netdev,buf,len,Z_CONTROL_SOCK); ++ } ++ break; ++ ++ case ZDO_STATE_CHANGE_IND: ++ if((z_info->msg_flag & START_CNF_BIT) == 0) ++ { ++ z_info->msg_flag |= START_CNF_BIT; ++ wake_up_interruptible(&z_info->wait_queue); ++ } ++ break; ++ ++ default: ++ ++ /* send data to the user application */ ++ zb_rx(zb->netdev,buf,len,Z_CONTROL_SOCK); ++ break; ++ } ++} ++ ++int init_zaccel(struct bmi_zb *zb) ++{ ++ struct zaccel_info *z_info; ++ int rc = 0; ++ ++ z_info = &zb->z_info; ++ memset(z_info,0, sizeof(struct zaccel_info)); ++ ++ init_waitqueue_head(&z_info->wait_queue); ++ ++ INIT_LIST_HEAD(&z_info->xmt_list); ++ ++ INIT_WORK(&zb->xmt_work, zaccel_xmt); ++ ++ z_info->msg_flag = 0; ++ z_info->app_type = NO_APP_TYPE; ++ ++ /* Release Z-Accel */ ++ zb_Reset(zb,ZB_RELEASE); ++ ++ printk(KERN_DEBUG "wait for ZACCEL_RESET_IND\n"); ++ /* Wait for the reset indication message from Z-Accel */ ++ rc = wait_event_interruptible_timeout(z_info->wait_queue, ++ ((z_info->msg_flag & RESET_IND_BIT) != 0),Z_RESET_TIMEOUT); ++ ++ /* ++ * Run Loopback test to test SPI Interface. If this test fails, and ++ * SPI interface is bad, we probably would not get the reset indication ++ * message that we were waiting for previously. ++ */ ++ ++ if(rc == 0) ++ { ++ printk(KERN_ERR "bmi_zaccel: Z-Accel device failed\n"); ++ return -ENODEV; ++ ++ } ++ else ++ { ++ /* a short delay to make sure that Z-Accel is done ++ * initializing. Advice from TI ZigBee Forum discussion. ++ */ ++ mdelay(2000); ++ /* SPI loopback test */ ++ rc = zb_SysTestLoopback(zb); ++ if(rc != 0) ++ { ++ printk(KERN_ERR "bmi_zaccel: SPI Loopback test FAILED %d\n",rc); ++ return -ENODEV; ++ } ++ } ++ ++ /* print string for python factory test. Don't remove */ ++ printk(KERN_INFO "bmi_zaccel: SPI Loopback test PASSED\n"); ++ ++ printk(KERN_INFO "bmi_zaccel: Z-Accel is ready\n"); ++ ++ return 0; ++} ++ ++void remove_zaccel(struct bmi_zb *zb) ++{ ++ /* hold Zaccel reset */ ++ zb_Reset(zb,ZB_RESET); ++} ++ ++ ++void zaccel_getdev(struct bmi_zb *zb) ++{ ++ struct zaccel_info *z_info; ++ struct zaccel_device zdev; ++ ++ z_info = &zb->z_info; ++ ++ zb_GetDeviceInfo(zb,ZB_DEVICE_STATE, ++ (unsigned char *)&zdev.state); ++ zb_GetDeviceInfo(zb,ZB_DEVICE_IEEE_ADDR, ++ (unsigned char *)&zdev.device_ieee); ++ zb_GetDeviceInfo(zb,ZB_DEVICE_SHORT_ADDR, ++ (unsigned char *)&zdev.device_short); ++ zb_GetDeviceInfo(zb,ZB_PARENT_SHORT_ADDR, ++ (unsigned char *)&zdev.parent_short); ++ zb_GetDeviceInfo(zb,ZB_PARENT_IEEE_ADDR, ++ (unsigned char *)&zdev.parent_ieee); ++ zb_GetDeviceInfo(zb,ZB_DEVICE_CHANNEL, ++ (unsigned char *)&zdev.channel); ++ zb_GetDeviceInfo(zb,ZB_DEVICE_PANID, ++ (unsigned char *)&zdev.panid); ++ zb_GetDeviceInfo(zb,ZB_DEVICE_EXT_PANID, ++ (unsigned char *)&zdev.ext_panid); ++ ++ z_info->device.state = zdev.state; ++ memcpy(&z_info->device.device_ieee,&zdev.device_ieee,8); ++ memcpy(&z_info->device.device_short,&zdev.device_short,2); ++ memcpy(&z_info->device.parent_short,&zdev.parent_short,2); ++ memcpy(&z_info->device.parent_ieee,&zdev.parent_ieee,8); ++ z_info->device.channel = zdev.channel; ++ memcpy(&z_info->device.panid,&zdev.panid,2); ++ memcpy(&z_info->device.ext_panid,&zdev.ext_panid,8); ++} +--- /dev/null ++++ git/drivers/bmi/pims/zb/bmi_zaccel.h +@@ -0,0 +1,288 @@ ++/* ++ * File: drivers/bmi/pims/zb/zaccel.h ++ * Author: V. Thavisri ++ * ++ * This is the header file for the CC2480 TI on ++ * ZigBee module. It is derived from the following source ++ * ++ */ ++ ++ ++#ifndef _ZACCEL_H ++#define _ZACCEL_H ++ ++#define RSPS_CMD 0x40 ++/* SYS Interface commands */ ++#define SYS_RESET_REQ_0 0x41 ++#define SYS_RESET_REQ_1 0x00 ++#define SYS_RESET_IND 0x4180 ++#define SYS_VER_0 0x21 ++#define SYS_VER_1 0x02 ++#define SYS_OSAL_NV_READ 0x2108 ++#define SYS_OSAL_NV_WRITE 0x2109 ++#define SYS_OSAL_START_TIMER 0x210A ++#define SYS_OSAL_TIMER_EXPIRED 0x4181 ++#define SYS_RANDOM 0X210C ++#define SYS_ADC_READ 0x210D ++#define SYS_GPIO 0x210E ++#define SYS_TEST_RF_0 0x41 ++#define SYS_TEST_RF_1 0x40 ++#define SYS_TEST_LOOPBACK_REQ 0x2141 ++#define SYS_TEST_LOOPBACK_REQ_0 0x21 ++#define SYS_TEST_LOOPBACK_REQ_1 0x41 ++#define SYS_TEST_LOOPBACK_RSP 0x6141 ++#define SYS_RF_POWER_AMP_0 0x21 ++#define SYS_RF_POWER_AMP_1 0x10 ++#define SYS_RF_POWER_AMP_RSP 0x6110 ++ ++/* Configuration Interface Commands */ ++#define ZB_READ_CONFIG_REQ_0 0x26 ++#define ZB_READ_CONFIG_REQ_1 0x04 ++#define ZB_WRITE_CONFIG_REQ_0 0x26 ++#define ZB_WRITE_CONFIG_REQ_1 0x05 ++#define ZB_WRITE_CONFIG_RSP 0x6605 ++ ++/* ZigBee PIM specific commands */ ++#define ZB_DEVICE_INFO_CHG_0 0xFF ++#define ZB_DEVICE_INFO_CHG_1 0x00 ++ ++// Simple API Interface ++#define ZB_APP_REGISTER_REQ_0 0x26 ++#define ZB_APP_REGISTER_REQ_1 0x0A ++#define ZB_START_REQ_0 0x26 ++#define ZB_START_REQ_1 0x00 ++#define ZB_START_CONFIRM 0x4680 ++#define ZB_PERMIT_JOINING_REQ_0 0x26 ++#define ZB_PERMIT_JOINING_REQ_1 0x08 ++#define ZB_BIND_DEVICE_0 0x26 ++#define ZB_BIND_DEVICE_1 0x01 ++#define ZB_BIND_CONFIRM 0x4681 ++#define ZB_ALLOW_BIND_0 0x26 ++#define ZB_ALLOW_BIND_1 0x02 ++#define ZB_ALLOW_BIND_CONFIRM 0x4682 ++#define ZB_SEND_DATA_REQ_0 0x26 ++#define ZB_SEND_DATA_REQ_1 0x03 ++#define ZB_SEND_DATA_CONFIRM 0x4683 ++#define ZB_RCV_DATA_IND 0x4687 ++#define ZB_GET_DEVICE_INFO_0 0x26 ++#define ZB_GET_DEVICE_INFO_1 0x06 ++#define ZB_FIND_DEVICE_REQ_0 0x26 ++#define ZB_FIND_DEVICE_REQ_1 0x07 ++#define ZB_FIND_DEVICE_CONFIRM 0X4685 ++ ++// AF Interface ++#define AF_REGISTER_0 0x24 ++#define AF_REGISTER_1 0x00 ++#define AF_DATA_REQ_0 0x24 ++#define AF_DATA_REQ_1 0x01 ++#define AF_DATA_CONFIRM 0x4480 ++#define AF_INCOMING_MSG 0x4481 ++ ++// ZDO Interface ++#define ZDO_NWK_ADDR_REQ 0x2500 ++#define ZDO_IEEE_ADDR_REQ 0x2501 ++#define ZDO_NODE_DESC_REQ 0x2502 ++#define ZDO_NODE_DESC_RES 0x2582 ++#define ZDO_SIMPLE_DESC_REQ 0x2504 ++#define ZDO_SIMPLE_DESC_RSP 0x4584 ++#define ZDO_ACTIVE_EP_REQ 0x2505 ++#define ZDO_ACTIVE_EP_RSP 0x4585 ++#define ZDO_MATCH_DESC_REQ 0x2506 ++#define ZDO_MATCH_DESC_RSP 0x4586 ++#define ZDO_MATCH_DESC_RSP_SENT 0x45C2 ++#define ZDO_USER_DESC_REQ 0x2508 ++#define ZDO_USER_DESC_RSP 0x4588 ++#define ZDO_USER_DESC_SET 0x250B ++#define ZDO_USER_DESC_CONF 0x4589 ++#define ZDO_END_DEVICE_ANNCE 0x250A ++#define ZDO_END_DEVICE_ANNCE_IND 0x45C1 ++#define ZDO_END_DEVICE_BIND_REQ 0x2520 ++#define ZDO_END_DEVICE_BIND_RES_RSP 0x45A0 ++#define ZDO_BIND_REQ 0x2521 ++#define ZDO_BIND_RSP 0x45A1 ++#define ZDO_UNBIND_REQ 0x2522 ++#define ZDO_UNBIND_RSP 0x45A2 ++#define ZDO_MGMT_LQI_REQ 0x2531 ++#define ZDO_MGMT_LQI_RSP 0x45B1 ++#define ZDO_MGMT_LEAVE_REQ 0x2534 ++#define ZDO_MGMT_LEAVE_RSP 0x45B4 ++#define ZDO_MGMT_PERMIT_JOIN_REQ 0x2536 ++#define ZDO_MGMT_PERMIT_JOIN_RSP 0x45B6 ++#define ZDO_STATE_CHANGE_IND 0x45C0 ++ ++// ZCD_NV_STARTUP_OPTION value ++#define ZCD_STARTOPT_DEFAULT_CONFIG 0x01 ++#define ZCD_STARTOPT_DEFAULT_NETWORK 0x02 ++#define ZCD_STARTOPT_AUTO_START 0x04 ++#define ZCD_STARTOPT_VALID 0x02 // max valid option value ++#define ZCD_STARTOPT_MASK 0x03 ++ ++// ZCD_NV_LOGICAL_TYPE ++#define ZB_COORDINATOR 0x00 ++#define ZB_ROUTER 0x01 ++#define ZB_ENDDEVICE 0x02 ++#define ZB_VALID_DEVICE 0x02 ++#define ZB_DEVICE_MASK 0x03 ++#define ZB_INVALID_DEVICE 0xFF ++ ++// ZB_GET_DEVICE_INFO parameters ++#define ZB_DEVICE_STATE 0x00 ++#define ZB_DEVICE_IEEE_ADDR 0x01 ++#define ZB_DEVICE_SHORT_ADDR 0x02 ++#define ZB_PARENT_SHORT_ADDR 0x03 ++#define ZB_PARENT_IEEE_ADDR 0x04 ++#define ZB_DEVICE_CHANNEL 0x05 ++#define ZB_DEVICE_PANID 0x06 ++#define ZB_DEVICE_EXT_PANID 0x07 ++#define ZB_DEVICE_LAST 0x07 ++ ++/* Z-Accel command return value */ ++#define Z_SUCCESS 0x00 ++#define Z_FAILURE 0x01 ++#define Z_INVALID_PARAM 0x02 ++ ++#define Z_ALLOW_BIND 0xFF ++#define Z_DENY_BIND 0x00 ++ ++#define Z_PERMIT_JOIN 0xFF ++#define Z_DENY_JOIN 0x00 ++ ++#define Z_BIND_CREATE 0x01 ++#define Z_BIND_REMOVE 0x00 ++ ++#define Z_CONFIG_OFFSET 6 ++ ++#define SYS_RF_PA_MIN 25 /* valid power level 0 - 25 */ ++ ++// ZB_DEVICE_STATE definition ++typedef enum ++{ ++ DEV_HOLD, // Initialized - not started automatically ++ DEV_INIT, // Initialized - not connected to anything ++ DEV_NWK_DISC, // Discovering PAN's to join ++ DEV_NWK_JOINING, // Joining a PAN ++ DEV_NWK_REJOIN, // ReJoining a PAN, only for end devices ++ DEV_END_DEVICE_UNAUTH, // Joined but not yet authenticated by trust center ++ DEV_END_DEVICE, // Started as device after authentication ++ DEV_ROUTER, // Device joined, authenticated and is a router ++ DEV_COORD_STARTING, // Started as Zigbee Coordinator ++ DEV_ZB_COORD, // Started as Zigbee Coordinator ++ DEV_NWK_ORPHAN // Device has lost information about its parent.. ++} devStates_t; ++ ++// zstate - Z-Accel device state ++#define ZACCEL_RESET 0 ++#define ZACCEL_WAIT_RELEASE 1 ++#define ZACCEL_RESET_IND 2 ++#define ZACCEL_START_REQ 3 ++#define ZACCEL_START_CNF 4 ++#define ZACCEL_START_FAIL 5 ++#define ZACCEL_APP_START 6 ++#define ZACCEL_TERMINATE 7 ++#define ZACCEL_POLL_DONE 8 ++#define ZACCEL_UNDEFINE 0xFF ++ ++/* periodic timer runs every 50 ms */ ++#define Z_TIMER (50*HZ)/1000 ++#define Z_RESET_TIMEOUT (20*HZ) ++#define Z_CNF_TIMEOUT (15*HZ) ++#define Z_POLL_TIMER (50*HZ)/1000 ++#define Z_SRDY_TIMEOUT (4*HZ) ++ ++/* frequency to update zbinfo sysfs = (Z_TIMER * UPDATE_TICKS) */ ++#define UPDATE_TICKS 20 ++ ++/* Reset option for ioctl */ ++#define Z_DONT_RESET 0 ++#define Z_HW_RESET 1 ++#define Z_SW_RESET 2 ++ ++#define ZCMD_BUF (256 + 3) ++#define ZCMD_HEADER 3 ++ ++struct zaccel_app_id ++{ ++ unsigned char endpoint; ++ unsigned short profile_id; ++ unsigned short device_id; ++ unsigned char device_ver; ++ unsigned char unused; ++ unsigned char icmd_num; ++ ++}; ++struct zaccel_app_struct ++{ ++ struct zaccel_app_id info; ++ unsigned char commands[1]; ++}; ++ ++struct zaccel_version ++{ ++ unsigned char transportRev; ++ unsigned char product; ++ unsigned char majorRel; ++ unsigned char minorRel; ++ unsigned char hwRev; ++}; ++ ++struct zaccel_config ++{ ++ unsigned char device; // ZCD_NV_LOGICAL_TYPE ++ unsigned long chanlist; ++ unsigned short panid; ++}; ++ ++extern unsigned char zb_device_info_len[]; ++#define ZDEVICE_INFO_NUM 8 ++ ++struct zaccel_device ++{ ++ unsigned char state; ++ unsigned char device_ieee[8]; ++ unsigned char device_short[2]; ++ unsigned char parent_short[2]; ++ unsigned char parent_ieee[8]; ++ unsigned char channel; ++ unsigned char panid[2]; ++ unsigned char ext_panid[8]; ++}; ++ ++#define ZBIND_NUM_MAX 64 ++struct zaccel_info ++{ ++ unsigned char lastReset; ++ struct zaccel_version ver; ++ struct zaccel_device device; ++ ++ struct list_head xmt_list; ++ wait_queue_head_t wait_queue; ++ unsigned short msg_flag; ++ unsigned short app_type; ++}; ++ ++#define NO_APP_TYPE 0 ++#define SAPI_TYPE 1 ++#define AF_INTERFACE_TYPE 2 ++ ++#define ZBUF_MAX_SIZE 150 ++ ++/* struct zaccel_info msg_flag bit definition */ ++#define START_CNF_BIT 0x0001 ++#define RESET_IND_BIT 0x0002 ++ ++/* ++ * XMT_MSG_SIZE = Maximum length of the ZB_SEND_DATA_REQUEST content. ++ * 2 bytes Destination, 2 bytes Command ID, 1 byte Handle ++ * 1 byte Ack, 1 byte Radius, 1 byte len, up to 84 bytes data. ++ */ ++#define XMT_MSG_SIZE 92 ++ ++struct zaccel_xmt_msg ++{ ++ struct list_head list; ++ unsigned char len; ++ unsigned char buf[XMT_MSG_SIZE]; ++}; ++ ++ ++#endif // _ZACCEL_H +--- /dev/null ++++ git/drivers/bmi/pims/zb/bmi_zigbee.c +@@ -0,0 +1,1296 @@ ++/* ++ * bmi_zigbee.c ++ * ++ * BMI zigbee device driver ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/* ++ * Include files ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "bmi_zigbee.h" ++#include "bmi_zaccel.h" ++ ++#define BMIZIGBEE_VERSION "1.1" ++ ++// Global variables ++ ++static struct bmi_zb bmi_zb[4]; ++static int major; ++ ++/* ++ * BMI set up ++ */ ++ ++ // BMI device ID table ++static struct bmi_device_id bmi_zb_tbl[] = ++{ ++ { ++ .match_flags = BMI_DEVICE_ID_MATCH_VENDOR | BMI_DEVICE_ID_MATCH_PRODUCT, ++ .vendor = BMI_VENDOR_BUG_LABS, ++ .product = BMI_PRODUCT_ZIGBEE, ++ .revision = BMI_ANY, ++ }, ++ { 0, }, /* terminate list */ ++}; ++ ++MODULE_DEVICE_TABLE(bmi, bmi_zb_tbl); ++ ++int bmi_zb_probe(struct bmi_device *bdev); ++void bmi_zb_remove(struct bmi_device *bdev); ++ ++static struct semaphore spi_sem; ++ ++// BMI driver structure ++static struct bmi_driver bmi_zb_driver = ++{ ++ .name = "bmi_zb", ++ .id_table = bmi_zb_tbl, ++ .probe = bmi_zb_probe, ++ .remove = bmi_zb_remove, ++}; ++ ++// IOX ++// read byte from I2C IO expander ++static int ReadByte_IOX(struct i2c_adapter *adap, unsigned char offset, unsigned char *data) ++{ ++ int ret = 0; ++ struct i2c_msg rmsg[2]; ++ int num_msgs; ++ ++ ++ // Read Byte with Pointer ++ rmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[0].flags = 0; // write ++ rmsg[0].len = 1; ++ rmsg[0].buf = &offset; ++ ++ rmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ rmsg[1].flags = I2C_M_RD; // read ++ rmsg[1].len = 1; ++ rmsg[1].buf = data; ++ ++ num_msgs = 2; ++ ret = i2c_transfer(adap, rmsg, num_msgs); ++ ++ if(ret == 2) ++ { ++ ret = 0; ++ } ++ else ++ { ++ printk(KERN_ERR "ReadByte_IOX() - i2c_transfer() zb failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++// IOX ++// write byte from I2C IO expander ++static int WriteByte_IOX(struct i2c_adapter *adap, unsigned char offset, unsigned char data) ++{ ++ int ret = 0; ++ struct i2c_msg wmsg[2]; ++ int num_msgs; ++ ++ // Write Byte with Pointer ++ wmsg[0].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[0].flags = 0; // write ++ wmsg[0].len = 1; ++ wmsg[0].buf = &offset; ++ ++ wmsg[1].addr = BMI_IOX_I2C_ADDRESS; ++ wmsg[1].flags = 0; // write ++ wmsg[1].len = 1; ++ wmsg[1].buf = &data; ++ ++ num_msgs = 2; ++ ret = i2c_transfer(adap, wmsg, num_msgs); ++ ++ if(ret == 2) ++ { ++ ret = 0; ++ } ++ else ++ { ++ printk(KERN_ERR "WriteByte_IOX() - i2c_transfer() zb failed.\n"); ++ ret = -1; ++ } ++ return ret; ++} ++ ++// char device file operation controls the module LEDs and reset ++ ++// open ++int cntl_open(struct inode *inode, struct file *file) ++{ ++ struct bmi_zb *zb; ++ ++ zb = container_of(inode->i_cdev, struct bmi_zb, cdev); ++ ++ zb->open_flag++; ++ ++ // Save zb pointer for later. ++ file->private_data = zb; ++ return 0; ++} ++ ++// release ++int cntl_release(struct inode *inode, struct file *file) ++{ ++ struct bmi_zb *zb; ++ ++ zb = (struct bmi_zb *)(file->private_data); ++ zb->open_flag = 0; ++ return 0; ++} ++ ++ ++// ioctl ++int cntl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct i2c_adapter *adap; ++ struct bmi_zb *zb; ++ unsigned char buf[80]; ++ int slot; ++ int i; ++ ++ zb = (struct bmi_zb *)(file->private_data); ++ ++ // error if zb not present ++ if(zb->bdev == 0) ++ return -ENODEV; ++ ++ slot = zb->slot; ++ adap = zb->adap; ++ ++ zb->adap = adap; ++ ++ switch(cmd) ++ { ++ case BMI_ZB_RLEDOFF: ++ bmi_slot_gpio_write_bit(slot, ZB_GPIO_RED_LED, ZB_GPIO_LED_OFF); ++ break; ++ ++ case BMI_ZB_RLEDON: ++ bmi_slot_gpio_write_bit(slot, ZB_GPIO_RED_LED, ZB_GPIO_LED_ON); ++ break; ++ ++ case BMI_ZB_GLEDOFF: ++ bmi_slot_gpio_write_bit(slot, ZB_GPIO_GREEN_LED, ZB_GPIO_LED_OFF); ++ break; ++ ++ case BMI_ZB_GLEDON: ++ bmi_slot_gpio_write_bit(slot, ZB_GPIO_GREEN_LED, ZB_GPIO_LED_ON); ++ break; ++ ++ /* ++ * Below are unpublished commands, used for testing only. ++ */ ++ ++ case BMI_ZB_RESET: ++ i = (__user arg) & 0xF; ++ ++ if(i == 0) ++ { ++ printk("external reset\n"); ++ zb_Reset(zb,ZB_RESET); ++ mdelay(10); ++ zb_Reset(zb,ZB_RELEASE); ++ } ++ else if (i == 1) ++ { ++ printk("soft reset\n"); ++ zb_SoftReset(zb); ++ } ++ else if (i == 2) ++ { ++ printk("set startup option to default\n"); ++ buf[0] = 3; ++ zb_WriteConfiguration(zb,ZCD_NV_STARTUP_OPTION,1,(unsigned char *)&buf[0]); ++ } ++ ++ break; ++ ++ case BMI_ZB_SPI_SIG: ++ zb_ReadSRDY(zb,1); ++ zb_ReadMRDY(zb); ++ break; ++ ++ case BMI_ZB_LOOPBACK: ++ zb_SysTestLoopback(zb); ++ break; ++ ++ case BMI_ZB_STARTREQ: ++ zb_StartRequest(zb); ++ break; ++ ++ case BMI_ZB_UPDATE_STATE: ++ zaccel_getdev(zb); ++ break; ++ ++ default: ++ return -ENOTTY; ++ } ++ ++ return 0; ++ ++} ++ ++struct file_operations zb_fops = ++{ ++ .owner = THIS_MODULE, ++ .ioctl = cntl_ioctl, ++ .open = cntl_open, ++ .release = cntl_release, ++}; ++ ++ ++void set_MRDY(struct bmi_zb *zb) ++{ ++ /* Assert MRDY and SS pins */ ++ bmi_slot_gpio_write_bit(zb->slot, ZB_GPIO_MRDY, 0); ++ bmi_slot_gpio_write_bit(zb->slot, ZB_GPIO_SS, 0); ++} ++ ++ ++void clr_MRDY(struct bmi_zb *zb) ++{ ++ /* De-assert MRDY and SS pins */ ++ bmi_slot_gpio_write_bit(zb->slot, ZB_GPIO_MRDY, 1); ++ bmi_slot_gpio_write_bit(zb->slot, ZB_GPIO_SS, 1); ++} ++ ++static unsigned long jiff_interval(unsigned long start_time) ++{ ++ unsigned long tick; ++ ++ tick = jiffies; ++ if(tick >= start_time) ++ { ++ tick = tick - start_time; ++ } ++ else ++ { ++ tick = (0xFFFFFFFF - start_time) + tick; ++ } ++ ++ return tick; ++} ++ ++void zenable_irq(struct bmi_zb *zb) ++{ ++ zb->enable = 1; ++#ifdef VE_OUT ++ printk("e-IRQ %d depth %d\n",zb->irq,zb->int_depth); ++#endif ++ if(zb->int_depth != 0) ++ { ++ zb->int_depth--; ++ enable_irq(zb->irq); ++ } ++ else ++ { ++ printk("zenable_irq: unbalance irq %d\n",zb->irq); ++ } ++} ++ ++int wait_for_srdy(struct bmi_zb *zb,unsigned char type) ++{ ++ int rc = 0; ++ int err = 0; ++ ++ zb->srdy_state = ZB_SPI_WAIT_SRDY_H; ++ zb->start_time = jiffies; ++ ++ /* ++ * Queue work to poll for SRDY high. ++ * From experimenting in the lab, I found that sometimes it took longer ++ * for the SRDY to go high when the host sent an SREQ command ++ * than when the host responded to the device AREQ (SPI_POLL_TYPE) command. ++ * So we delay the work to poll SRDY in SPI_REQ_TYPE. ++ * This delay is more of a fine tune process, and can be changed ++ * as long as it doesn't exceed the SPI transaction processing ++ * to over 1 second. ++ */ ++ ++ if(type == SPI_POLL_TYPE) ++ { ++ zb->delay = 0; ++ } ++ else if(type == SPI_REQ_TYPE) ++ { ++ zb->delay = SPI_CHK_SRDY_JIFFIES; ++ } ++ ++ queue_delayed_work(zb->srdy_wq, &zb->srdy_work,zb->delay); ++ ++ /* ++ * I use wait_event_interruptible instead of ++ * wait_event_interruptible_timeout here because we schedule ++ * work queue to poll SRDY. The work schedules another ++ * work queue, if SRDY has not been changed. ++ * Using wait_event_interruptible_timeout can cause a race ++ * condition if the wait_event_interrupt_timeout timeout occurs while ++ * the work queue is running. ++ * ++ * The code wakes up when SRDY is high or when the work queue ++ * decides that it has waited too long. ++ */ ++ err = wait_event_interruptible(zb->srdy_queue, ++ ((zb->srdy_state == ZB_SPI_SRDY_HIGH) || ++ (zb->srdy_state == ZB_SPI_SRDY_EXP))); ++ ++ if(err != 0) ++ { ++ printk(KERN_WARNING "zb-%d wait_for_srdy err %d\n",zb->slot,err); ++ } ++ ++ if(zb->srdy_state == ZB_SPI_SRDY_EXP) ++ { ++ rc = -1; ++ } ++ ++ return rc; ++} ++ ++void zaccel_spi_poll(struct bmi_zb *zb) ++{ ++ struct spi_message msg; ++ unsigned char buf[ZCMD_HEADER + 256]; ++ unsigned char len; ++#define AREQ_DEBUGx ++#ifdef AREQ_DEBUG ++ int i; ++#endif ++ ++ struct spi_transfer t = ++ { ++ .len = SPI_MSG_HEADER_SIZE, ++ .cs_change = 0, ++ .delay_usecs = 0, ++ }; ++ ++ down(&spi_sem); ++ if(zb_ReadSRDY(zb,0) != 0) ++ { ++ /* ++ * check if SRDY is low. If not, don't run the routine. ++ * ++ * This routine is the IRQ bottom half, scheduled in the IRQ ++ * service routine. ++ * Sometimes, the SRDY goes high before the routine is executed. ++ * That happens when the zaccel_spi_req, which is scheduled to ++ * run on the same queue, is executed before ++ * zaccel_spi_poll is executed. Sometimes, ++ * the IRQ puts zaccel_spi_poll on the workqueue multiple times, ++ * each time when it sees SRDY low. ++ */ ++#ifdef DEBUG_OUT ++ printk("zaccel_spi_poll SRDY high, depth %d\n",zb->int_depth); ++#endif ++ ++ if(zb->int_depth != 0) ++ { ++ /* If the interrupt is disabled, enable it */ ++ zenable_irq(zb); ++ } ++ ++ up(&spi_sem); ++ return; ++ } ++ ++ set_MRDY(zb); ++ ++ buf[0] = 0; ++ buf[1] = 0; ++ buf[2] = 0; ++ ++ t.tx_buf = (const void *)buf; ++ t.rx_buf = buf; ++ t.len = SPI_MSG_HEADER_SIZE; ++ ++ /* Send three bytes of POLL command */ ++ spi_message_init(&msg); ++ spi_message_add_tail(&t, &msg); ++ ++ if((spi_sync(zb->spi, &msg) != 0) || (msg.status != 0)) ++ { ++ /* error reading the data. */ ++ printk(KERN_WARNING "send spi_sync error %d\n",msg.status); ++ clr_MRDY(zb); ++ up(&spi_sem); ++ zenable_irq(zb); ++ return; ++ } ++ ++ if(wait_for_srdy(zb,SPI_POLL_TYPE) < 0) ++ { ++ /* time out */ ++ printk(KERN_WARNING "%d - SRDY() high poll timeout\n",zb->slot); ++ clr_MRDY(zb); ++ up(&spi_sem); ++ zenable_irq(zb); ++ return; ++ } ++ ++ /* Read three bytes to get the message length */ ++ buf[0] = 0; ++ buf[1] = 0; ++ buf[2] = 0; ++ ++ t.tx_buf = (const void *)buf; ++ t.rx_buf = buf; ++ t.len = SPI_MSG_HEADER_SIZE, ++ t.cs_change = 0, ++ t.delay_usecs = 0, ++ ++ spi_message_init(&msg); ++ spi_message_add_tail(&t, &msg); ++ ++ if((spi_sync(zb->spi, &msg) != 0) || (msg.status != 0)) ++ { ++ /* error reading the data. */ ++ printk(KERN_WARNING "rcv1 spi_sync error %d\n",msg.status); ++ clr_MRDY(zb); ++ up(&spi_sem); ++ zenable_irq(zb); ++ return; ++ } ++ ++ /* buf[0] contains the length of the message */ ++ ++ if((buf[0] != 0) && (buf[0] != 0xFF)) ++ { ++ /* ++ * Read the rest of the message, if length != 0 */ ++ t.len = buf[0]; ++ ++ t.rx_buf = &buf[ZCMD_HEADER]; ++ spi_message_init(&msg); ++ ++ spi_message_add_tail(&t, &msg); ++ if((spi_sync(zb->spi, &msg) != 0) || (msg.status != 0)) ++ { ++ // error reading the data. Set length to zero. ++ buf[0] = 0; ++ printk(KERN_WARNING "rcv2 spi_sync error %d\n",msg.status); ++ } ++ } ++ ++ clr_MRDY(zb); ++ up(&spi_sem); ++ zenable_irq(zb); ++ ++ /* buf[0] has message length */ ++ len = buf[0]; ++ ++ if((buf[0] != 0xFF) && (buf[0] != 0)) ++ { ++#ifdef AREQ_DEBUG ++ printk("AREQ-%d: ",zb->slot); ++ for(i = 0; i < (len + 3); i++) ++ { ++ printk("%x ",buf[i]); ++ } ++ ++ printk("\n"); ++#endif ++ } ++ else ++ { ++ if(buf[0] == 0xFF) ++ printk(KERN_WARNING "invalid 0xFF\n"); ++ return; ++ } ++ ++ zaccel_cmd_proc(zb,buf); ++ return; ++} ++ ++void zaccel_chk_srdy(struct work_struct *work) ++{ ++ struct bmi_zb *zb; ++ ++ zb = container_of(work, struct bmi_zb, srdy_work); ++ ++ /* ++ * check SRDY value. If it matches what we are waiting ++ * for, we wake up the work on the queue. ++ * If not, we check the timer for timeout. ++ * If the timer is not expired, queue another zb->srdy_work, to ++ * check for the signal next time. ++ * If the timer is expired, set srdy_state to indicate timeout ++ * and wake up the work. ++ */ ++ ++ if((zb_ReadSRDY(zb,0) == 0) && (zb->srdy_state == ZB_SPI_WAIT_SRDY_L)) ++ { ++ zb->srdy_state = ZB_SPI_SRDY_LOW; ++ wake_up_interruptible(&zb->srdy_queue); ++ return; ++ } ++ else if((zb_ReadSRDY(zb,0) == 1) && (zb->srdy_state == ZB_SPI_WAIT_SRDY_H)) ++ { ++ zb->srdy_state = ZB_SPI_SRDY_HIGH; ++ wake_up_interruptible(&zb->srdy_queue); ++ return; ++ } ++ else if(jiff_interval(zb->start_time) < SPI_SRDY_H_TIMEOUT) ++ { ++ queue_delayed_work(zb->srdy_wq, &zb->srdy_work,zb->delay); ++ } ++ else ++ { ++ zb_ReadSRDY(zb,1); ++ printk(KERN_WARNING "zaccel_chk_srdy state %d\n",zb->srdy_state); ++ zb->srdy_state = ZB_SPI_SRDY_EXP; ++ wake_up_interruptible(&zb->srdy_queue); ++ } ++ ++} ++ ++/* work handler to process Z-Accel request */ ++void zaccel_poll_proc(struct work_struct *work) ++{ ++ struct bmi_zb *zb; ++ ++ zb = container_of(work, struct bmi_zb, spi_work); ++ ++ zaccel_spi_poll(zb); ++} ++ ++void zaccel_sreq_proc(struct work_struct *work) ++{ ++ struct bmi_zb *zb; ++ ++ unsigned char buf[320]; ++ struct spi_transfer t = ++ { ++ .tx_buf = (const void *)buf, ++ .rx_buf = buf, ++ .cs_change = 0, ++ .delay_usecs = 0, ++ }; ++ ++ unsigned char *rbuf; ++ struct spi_message msg; ++ unsigned char type; ++ unsigned short len; ++ int i; ++ int rc = 0; ++ ++ zb = container_of(work, struct bmi_zb, sreq_work); ++ ++ down(&spi_sem); ++ ++ rbuf = zb->sreq_buf; ++ len = (size_t)(rbuf[0] + ZCMD_HEADER); ++ type = rbuf[1] & SPI_CMD_TYPE_MASK; ++ ++ t.len = len; ++ t.tx_buf = rbuf; ++ ++#define SREQ_DEBUGx ++#ifdef SREQ_DEBUG ++ printk("SREQ-%d: ",zb->slot); ++ ++ for(i = 0; i < len; i++) ++ { ++ printk("%x ",rbuf[i]); ++ } ++ printk("\n"); ++ ++#endif ++ ++ set_MRDY(zb); ++ ++ zb->srdy_state = ZB_SPI_WAIT_SRDY_L; ++ ++ if(zb->enable == 1) ++ { ++ rc = wait_event_interruptible_timeout(zb->srdy_queue,zb->srdy_state == ZB_SPI_SRDY_LOW,SPI_SRDY_L_TIMEOUT); ++ if(rc == 0) ++ { ++ printk(KERN_WARNING "bmi_zb-%d: SRDY low timeout\n",zb->slot); ++ clr_MRDY(zb); ++ zb->srdy_state = ZB_SPI_POLL; ++ up(&spi_sem); ++ zb->sreq_ret = -1; ++ wake_up_interruptible(&zb->sreq_queue); ++ return; ++ } ++ } ++ else ++ { ++ /* ++ * The interrupt has been disabled, because SRDY is low ++ * prior to enter this routine. We proceed ahead with the ++ * SPI transaction. ++ */ ++ ++ if(zb_ReadSRDY(zb,0) != 0) ++ { ++ /* Double check that SRDY is low, if not, give warning */ ++ printk(KERN_WARNING "zaccel_req_proc interrupt disable SRDY high\n"); ++ } ++ } ++ ++ i = 0; ++ ++ spi_message_init(&msg); ++ spi_message_add_tail (&t, &msg); ++ ++ if(spi_sync(zb->spi, &msg) != 0 || msg.status != 0) ++ { ++ printk(KERN_WARNING "bmi_zb: a - spi_sync error %d\n",msg.status); ++ zb->sreq_ret = -ENODEV; ++ goto done; ++ } ++ ++ if(wait_for_srdy(zb,SPI_REQ_TYPE) < 0) ++ { ++ printk(KERN_WARNING "bmi_zb: SRDY wait to go high timeout\n"); ++ zb->sreq_ret = -1; ++ goto done; ++ } ++ ++ if(type == SPI_CMD_AREQ) ++ { ++ zb->sreq_ret = 0; ++ goto done; ++ } ++ ++ buf[0] = 0; /* Poll command has zero byte */ ++ buf[1] = 0; /* Poll command */ ++ buf[2] = 0; /* Poll command */ ++ ++ t.tx_buf = buf; ++ t.len = SPI_MSG_HEADER_SIZE; ++ ++ spi_message_init(&msg); ++ ++ spi_message_add_tail(&t, &msg); ++ if(spi_sync(zb->spi, &msg) != 0 || msg.status != 0) ++ { ++ printk(KERN_WARNING "bmi_zb: b- spi_sync error %d\n",msg.status); ++ zb->sreq_ret = -ENODEV; ++ goto done; ++ } ++ ++ /* Read the length of the data */ ++ if(buf[0] != 0) ++ { ++ // Set len to the length of the message and offset ++ // the buffer to after the header field. ++ t.len = buf[0]; ++ ++ t.tx_buf = (unsigned char *)buf + SPI_MSG_HEADER_SIZE; ++ t.rx_buf = (unsigned char *)buf + SPI_MSG_HEADER_SIZE; ++ spi_message_init(&msg); ++ ++ spi_message_add_tail(&t, &msg); ++ ++ rc = spi_sync(zb->spi, &msg); ++ clr_MRDY(zb); ++ ++ if(rc != 0 || msg.status != 0) ++ { ++ printk(KERN_WARNING "bmi_zb: c - spi_sync error %d\n",msg.status); ++ zb->sreq_ret = -ENODEV; ++ goto done; ++ } ++ } ++ ++ clr_MRDY(zb); ++ up(&spi_sem); ++ zenable_irq(zb); ++ ++ /* ++ * copy data back to the buffer. Make sure that we don't ++ * copy more data than the space available. ++ */ ++ ++ if(buf[0] != 0xFF) ++ { ++ /* copy data to the return buffer, as much as the length ++ * of the data or the buffer size (zb->sreq_len) ++ */ ++ if(zb->sreq_len > (buf[0] + 3)) ++ { ++ len = buf[0] + 3; ++ } ++ else ++ { ++ len = zb->sreq_len; ++ } ++ memcpy(rbuf,buf,len); ++ zb->sreq_ret = zb->sreq_len; ++ } ++ else ++ { ++ zb->sreq_ret = -2; ++ } ++ ++ /* We're done. Wake up the SREQ work */ ++ zb->srdy_state = ZB_SPI_POLL; ++ wake_up_interruptible(&zb->sreq_queue); ++ ++#define SRSP_DEBUGx ++#ifdef SRSP_DEBUG ++ printk("SRSP-%d: ",zb->slot); ++ if(buf[0] != 0xFF) ++ { ++ for(i = 0; i < len; i++) ++ { ++ printk("%x ",buf[i]); ++ } ++ } ++ else ++ { ++ printk("Invalid length\n"); ++ } ++ printk("\n"); ++#endif ++ ++ /* ++ * Sometimes, back-to-back write configuration ++ * can chock the Z-Accel, result in fail SPI transaction. ++ * Delay the return (wait_event_interruptible_timeout ++ * will timeout - no one wakes up the queue), to prevent the problem. ++ */ ++ rc = 0; ++ wait_event_interruptible_timeout(zb->delay_queue,(rc != 0), 5); ++ ++ return; ++ ++done: ++ clr_MRDY(zb); ++ zb->srdy_state = ZB_SPI_POLL; ++ up(&spi_sem); ++ zenable_irq(zb); ++ wake_up_interruptible(&zb->sreq_queue); ++ return; ++} ++ ++int config_ports(struct bmi_zb *zb) ++{ ++ struct i2c_adapter *adap; ++ int slot; ++ unsigned char iox_data; ++ ++ slot = zb->slot; ++ adap = zb->adap; ++ ++ /* ++ * Configure GPIO_RED_LED and GPIO_GREEN_LED as output ++ * and set them to low -- LEDs on ++ */ ++ ++ bmi_slot_gpio_configure_as_output(slot,ZB_GPIO_RED_LED,0); ++ bmi_slot_gpio_configure_as_output(slot,ZB_GPIO_GREEN_LED,0); ++ ++ /* ++ * Configure GPIO_SS and GPIO_MRDY as output ++ * and set them to high -- deassert ++ */ ++ ++ bmi_slot_gpio_configure_as_output(slot,ZB_GPIO_MRDY,1); ++ bmi_slot_gpio_configure_as_output(slot,ZB_GPIO_SS,1); ++ ++ /* ++ * Set ZB_RST to output port. ++ * Set LSR_MRDY_IOX and LSR_SRDY_IOX to input port. ++ */ ++ ++ if(ReadByte_IOX(adap, IOX_CONTROL, &iox_data)) ++ { ++ printk(KERN_ERR "Unable to ReadByte_IOX - zb slot %d\n",slot); ++ return -ENODEV; ++ } ++ ++ /* Set SRDY and MRDY port to input and RST to output */ ++ iox_data |= (ZB_IOX_SRDY | ZB_IOX_MRDY); ++ iox_data &= ~(ZB_IOX_RST); ++ ++ if(WriteByte_IOX(adap, IOX_CONTROL, iox_data)) ++ { ++ printk(KERN_ERR "Unable to WriteByte_IOX - zb slot %d\n",slot); ++ return -ENODEV; ++ } ++ ++ return 0; ++} ++ ++// interrupt handler ++static irqreturn_t module_irq_handler(int irq, void *dummy) ++{ ++ struct bmi_zb *zb; ++ ++ disable_irq_nosync(irq); ++ ++ switch(irq) ++ { ++ case M1_IRQ: ++ zb = &bmi_zb[0]; ++ break; ++ case M2_IRQ: ++ zb = &bmi_zb[1]; ++ break; ++ case M3_IRQ: ++ zb = &bmi_zb[2]; ++ break; ++ case M4_IRQ: ++ zb = &bmi_zb[3]; ++ break; ++ default: ++ return IRQ_HANDLED; ++ } ++ ++ zb->enable = 0; ++ zb->int_depth++; ++ ++ if(zb->srdy_state == ZB_INT_WAIT_SRDY) ++ { ++ /* ++ * This interrupt is a part of host SREQ or AREQ. ++ * Set srdy flag to 0 to indicate that SRDY pin is asserted. ++ * Wake up the zb->spi_queue that is waiting for the event. ++ */ ++ zb->srdy_state = ZB_INT_SRDY_LOW; ++ wake_up_interruptible(&zb->srdy_queue); ++ } ++ else ++ { ++ /* ++ * Z-Accel has an AREQ frame to send. ++ * Schedule SPI receive task to pull data out. ++ */ ++ queue_work(zb->spi_wq, &zb->spi_work); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++/* ++ * BMI functions ++ */ ++ ++int bmi_zb_probe(struct bmi_device *bdev) ++{ ++ struct bmi_zb *zb; ++ struct i2c_adapter *adap; ++ struct class *bmi_class; ++ struct cdev *cdev; ++ struct net_device *netdev; ++ struct net_zb *priv; ++ dev_t dev_id; ++ int slot; ++ int irq; ++ int err; ++ char name[IFNAMSIZ]; ++ ++ err = 0; ++ slot = bmi_device_get_slot(bdev); ++ adap = bmi_device_get_i2c_adapter(bdev); ++ ++ zb = &bmi_zb[slot]; ++ ++ zb->slot = slot; ++ zb->adap = adap; ++ ++ dev_id = MKDEV(major, slot); ++ ++ // Initialize GPIOs, turn on Red and Green LEDs. ++ if(config_ports(zb)) ++ { ++ printk(KERN_ERR "Unable to configure ZB port pins slot %d\n",(slot+1)); ++ return -EFAULT; ++ } ++ ++ // Hold Z-Accel reset ++ zb_Reset(zb,ZB_RESET); ++ ++ // setup SPI ++ printk(KERN_INFO "ZB SPI_MODE_2 clock %d\n",ZB_SPI_SPEED); ++ if(bmi_device_spi_setup(bdev, ZB_SPI_SPEED, SPI_MODE_2, ZB_SPI_BPW)) ++ { ++ printk(KERN_ERR "Unable to setup spi\n"); ++ return -EFAULT; ++ } ++ bmi_slot_spi_enable(slot); ++ ++ zb->spi = &bdev->spi; ++ zb->srdy_state = ZB_SPI_POLL; ++ ++ INIT_WORK(&zb->spi_work, zaccel_poll_proc); ++ INIT_WORK(&zb->sreq_work, zaccel_sreq_proc); ++ INIT_DELAYED_WORK(&zb->srdy_work, zaccel_chk_srdy); ++ ++ init_waitqueue_head(&zb->sreq_queue); ++ init_waitqueue_head(&zb->srdy_queue); ++ init_waitqueue_head(&zb->delay_queue); ++ ++ /* ++ * create a thread to handle SPI access. ++ * spi_sem allows one ZigBee module to perform and complete its ++ * SPI transaction before other Zigbee does its SPI. ++ */ ++ if(slot == 0) ++ { ++ zb->spi_wq = create_singlethread_workqueue("zaccel_spi0"); ++ zb->srdy_wq = create_singlethread_workqueue("zaccel_srdy0"); ++ } ++ else if(slot == 1) ++ { ++ zb->spi_wq = create_singlethread_workqueue("zaccel_spi1"); ++ zb->srdy_wq = create_singlethread_workqueue("zaccel_srdy1"); ++ } ++ else if(slot == 2) ++ { ++ zb->spi_wq = create_singlethread_workqueue("zaccel_spi2"); ++ zb->srdy_wq = create_singlethread_workqueue("zaccel_srdy2"); ++ } ++ else if(slot == 3) ++ { ++ zb->spi_wq = create_singlethread_workqueue("zaccel_spi3"); ++ zb->srdy_wq = create_singlethread_workqueue("zaccel_srdy3"); ++ } ++ ++ ++ if((!zb->spi_wq) && (!zb->srdy_wq)) ++ { ++ printk(KERN_ERR "ZB: create workqueue failed %d\n",slot); ++ if(zb->spi_wq) ++ { ++ destroy_workqueue(zb->spi_wq); ++ } ++ ++ if(zb->srdy_wq) ++ { ++ destroy_workqueue(zb->srdy_wq); ++ } ++ ++ bmi_slot_spi_disable(slot); ++ bmi_device_spi_cleanup(bdev); ++ return -ENOMEM; ++ } ++ ++ // request PIM interrupt ++ irq = bmi_device_get_status_irq(bdev); ++ zb->irq = irq; ++ zb->int_depth = 0; ++ ++ sprintf(zb->int_name, "bmi_zb%d", slot); ++ err = request_irq(irq, &module_irq_handler, 0, zb->int_name, zb); ++ if(err) ++ { ++ printk(KERN_ERR "bmi_zb.c: Can't allocate irq %d nor find ZB in slot %d \n", irq, slot); ++ destroy_workqueue(zb->spi_wq); ++ destroy_workqueue(zb->srdy_wq); ++ bmi_slot_spi_disable(slot); ++ bmi_device_spi_cleanup(bdev); ++ return -EBUSY; ++ } ++ ++ printk(KERN_INFO "bmi_zb.c: ZIGBEE create class device\n"); ++ bmi_class = bmi_get_bmi_class(); ++ zb->class_dev = device_create(bmi_class, NULL, dev_id, zb, ++ "bmi_zb%i", slot + 1); ++ ++ if(IS_ERR(zb->class_dev)) ++ { ++ printk(KERN_ERR "Unable to create " ++ "class_device for bmi_zb_%i; errno = %ld\n", ++ slot+1, PTR_ERR(zb->class_dev)); ++ zb->class_dev = NULL; ++ err = -ENODEV; ++ goto error; ++ } ++ ++ /* Allocate network device */ ++ sprintf(name, "zb%d",(slot+1)); ++ netdev = alloc_netdev(sizeof(struct net_zb),name,zb_net_setup); ++ if(!netdev) ++ { ++ printk(KERN_ERR "zb%d: cannot register net device \n",slot); ++ err = -ENOMEM; ++ goto error0; ++ ++ } ++ ++ priv = netdev_priv(netdev); ++ priv->zb = zb; ++ ++ err = init_zaccel(zb); ++ if(err < 0) ++ { ++ printk(KERN_ERR "zb%d: Z-Accel device not start\n",(slot+1)); ++ goto error1; ++ } ++ ++ err = register_netdev(netdev); ++ if(err < 0) ++ { ++ printk(KERN_WARNING "zb: cannot register net device\n"); ++ goto error1; ++ } ++ ++ zb_create_sysfs(netdev); ++ ++ zb->netdev = netdev; ++ ++ // bind driver and bmi_device ++ zb->bdev = bdev; ++ bmi_device_set_drvdata(bdev,zb); ++ ++ cdev = &zb->cdev; ++ cdev_init(cdev, &zb_fops); ++ err = cdev_add(cdev, dev_id, 1); ++ if(err < 0) ++ { ++ printk(KERN_ERR "Unable to add cdev for ZigBee module\n"); ++ goto error2; ++ } ++ ++ /* turn LED's off */ ++ bmi_set_module_gpio_data(slot, ZB_GPIO_RED_LED, ZB_GPIO_LED_OFF); ++ bmi_set_module_gpio_data(slot, ZB_GPIO_GREEN_LED, ZB_GPIO_LED_OFF); ++ ++ return 0; ++ ++error2: ++ zb_remove_sysfs(netdev); ++ zb->bdev = NULL; ++ bmi_device_set_drvdata(bdev,0); ++ ++ zb->netdev = NULL; ++ unregister_netdev(netdev); ++ ++error1: ++ remove_zaccel(zb); ++ free_netdev(netdev); ++ ++error0: ++ zb->class_dev = NULL; ++ device_destroy(bmi_class,dev_id); ++ ++error: ++ ++ free_irq(irq, zb); ++ zb->irq = 0; ++ destroy_workqueue(zb->spi_wq); ++ destroy_workqueue(zb->srdy_wq); ++ bmi_slot_spi_disable(slot); ++ bmi_device_spi_cleanup(bdev); ++ ++ printk(KERN_ERR "bmi_zb: modprobe error %d\n",err); ++ return err; ++} ++ ++/* remove PIM */ ++void bmi_zb_remove(struct bmi_device *bdev) ++{ ++ int slot; ++ int irq; ++ struct bmi_zb *zb; ++ struct class *bmi_class; ++ struct net_device *netdev; ++ ++ slot = bmi_device_get_slot(bdev); ++ zb = &bmi_zb[slot]; ++ ++ /* Free the interrupt first. This is to prevent stranded interrupt ++ * when we hold the Z-Accel reset. ++ */ ++ irq = bmi_device_get_status_irq(bdev); ++ free_irq(irq, zb); ++ ++ destroy_workqueue(zb->spi_wq); ++ destroy_workqueue(zb->srdy_wq); ++ ++ remove_zaccel(zb); ++ ++ cdev_del(&zb->cdev); ++ ++ /* Unregister and deallocate net_device */ ++ netdev = zb->netdev; ++ zb_remove_sysfs(netdev); ++ unregister_netdev(netdev); ++ free_netdev(netdev); ++ zb->netdev = NULL; ++ ++ zb->irq = 0; ++ zb->spi = (struct spi_device *)NULL; ++ bmi_slot_spi_disable(slot); ++ bmi_device_spi_cleanup(bdev); ++ ++ bmi_slot_gpio_configure_all_as_inputs(slot); ++ ++ bmi_class = bmi_get_bmi_class(); ++ device_destroy(bmi_class, MKDEV(major,slot)); ++ zb->class_dev = 0; ++ ++ /* de-attach driver-specific struct from bmi_device structure */ ++ bmi_device_set_drvdata(bdev,0); ++ zb->bdev = 0; ++ ++ printk(KERN_INFO "bmi_zb: remove completed\n"); ++ return; ++} ++ ++int zaccel_spi_req(struct bmi_zb *zb, unsigned char *rbuf, unsigned short buf_len) ++{ ++ int err; ++ ++ zb->sreq_buf = rbuf; ++ zb->sreq_len = buf_len; ++ ++ queue_work(zb->spi_wq, &zb->sreq_work); ++ zb->sreq_ret = 0xFF; ++ err = wait_event_interruptible_timeout(zb->sreq_queue,zb->sreq_ret != 0xFF,(5*HZ)); ++ if(err == 0) ++ { ++ printk(KERN_ERR "zaccel_spi_req timeout %d\n",zb->sreq_ret); ++ zb->sreq_ret = -ENODEV; ++ } ++ ++ return zb->sreq_ret; ++} ++ ++void zb_ReadMRDY(struct bmi_zb *zb) ++{ ++ int mrdy; ++ int ss; ++ ++ mrdy = bmi_slot_gpio_read_bit(zb->slot,ZB_GPIO_MRDY); ++ ss = bmi_slot_gpio_read_bit(zb->slot,ZB_GPIO_SS); ++ printk("zb-SPI: MRDY %d SS %d\n",mrdy,ss); ++} ++ ++int zb_ReadSRDY(struct bmi_zb *zb, int print) ++{ ++ int irq_pin; ++ int value; ++ ++ irq_pin = bmi_slot_status_irq_state(zb->slot); ++ ++ if(irq_pin == 1) ++ value = 0; ++ else ++ value = 1; ++ ++ if(print == 1) ++ printk("zb-SPI: srdy %d\n",value); ++ return value; ++} ++ ++/* Z-Accel hardware reset */ ++int zb_Reset(struct bmi_zb *zb, unsigned char state) ++{ ++ unsigned char iox_data; ++ ++ if(ReadByte_IOX (zb->adap, IOX_OUTPUT_REG, &iox_data)) ++ return -ENODEV; ++ ++ if(state == ZB_RESET) ++ { ++ iox_data &= ~ZB_IOX_RST; ++ } ++ else if(state == ZB_RELEASE) ++ { ++ zb->z_info.msg_flag &= ~RESET_IND_BIT; ++ iox_data |= ZB_IOX_RST; ++ } ++ ++ if(WriteByte_IOX (zb->adap, IOX_OUTPUT_REG, iox_data)) ++ return -ENODEV; ++ ++ return 0; ++} ++ ++static void __exit bmi_zb_cleanup(void) ++{ ++ dev_t dev_id; ++ ++ bmi_unregister_driver(&bmi_zb_driver); ++ ++ /* Unregister PF_ZACCEL socket */ ++ z_sock_exit(); ++ ++ dev_id = MKDEV(major, 0); ++ unregister_chrdev_region(dev_id, 4); ++ ++ return; ++} ++ ++static int __init bmi_zb_init(void) ++{ ++ dev_t dev_id; ++ int retval; ++ ++ // allocate char device for the module control. ++ retval = alloc_chrdev_region(&dev_id, 0, 4, "BMI ZigBee Driver"); ++ if(retval) ++ { ++ printk(KERN_ERR "Unable to allocate zb chardev_region\n"); ++ return -1; ++ } ++ major = MAJOR(dev_id); ++ ++ /* Register PF_ZACCEL protocol socket */ ++ retval = z_sock_init(); ++ if(retval) ++ { ++ unregister_chrdev_region(dev_id, 4); ++ printk(KERN_ERR "ZB: protocol register failed %d \n", retval); ++ return -1; ++ } ++ ++ init_MUTEX(&spi_sem); ++ ++ retval = bmi_register_driver(&bmi_zb_driver); ++ if(retval) ++ { ++ z_sock_exit(); ++ unregister_chrdev_region(dev_id, 4); ++ ++ printk(KERN_ERR "ZB: bmi_unregister_driver failed %d\n", retval); ++ return -1; ++ } ++ ++ printk(KERN_INFO "bmi_zb.c: BMI_ZIGBEE Driver v%s 0x%x\n", BMI_ZB_VERSION,BMI_PRODUCT_ZIGBEE); ++ ++ return 0; ++} ++ ++ ++module_init(bmi_zb_init); ++module_exit(bmi_zb_cleanup); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("V. Thavisri "); ++MODULE_DESCRIPTION("BMI ZigBee device driver"); ++MODULE_SUPPORTED_DEVICE("bmi_zigbee_control"); +--- /dev/null ++++ git/drivers/bmi/pims/zb/bmi_zigbee.h +@@ -0,0 +1,194 @@ ++/* ++ * File: ++ * Author: V. Thavisri ++ * ++ * Header file for the ZB module on the MX31 BUG platform. ++ */ ++#ifndef BMI_ZB_H ++#define BMI_ZB_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "bmi_zaccel.h" ++ ++#define BMI_ZB_VERSION "1.0" ++#define VE_DEBUG ++ ++// GPIO ++#define ZB_GPIO_RED_LED 3 ++#define ZB_GPIO_GREEN_LED 2 ++#define ZB_GPIO_MRDY 1 ++#define ZB_GPIO_SS 0 ++ ++#define ZB_GPIO_LED_ON 0 ++#define ZB_GPIO_LED_OFF 1 ++ ++#define BMI_IOX_I2C_ADDRESS 0x71 ++// I2C IOX register addressess ++#define IOX_INPUT_REG 0x0 ++#define IOX_OUTPUT_REG 0x1 ++#define IOX_POLARITY_REG 0x2 ++#define IOX_CONTROL 0x3 ++ ++#define ZB_IOX_RST 0x1 ++#define ZB_IOX_MRDY 0x2 ++#define ZB_IOX_SRDY 0x4 ++ ++// SPI parameters ++#define ZB_SPI_SPEED 2000000 ++#define ZB_SPI_BPW 8 ++ ++// SPI state ++// check the state when SRDY is asserted to determine which ++// SPI transaction the host wants to perform. ++#define ZB_SPI_POLL 0 ++#define ZB_SPI_WAIT_SRDY_L 1 ++#define ZB_SPI_SRDY_LOW 2 ++#define ZB_SPI_WAIT_SRDY_H 3 ++#define ZB_SPI_SRDY_HIGH 4 ++#define ZB_SPI_TIME2POLL 5 ++#define ZB_SPI_SRDY_EXP 6 ++#define ZB_SPI_WAIT_SRDY_Q 7 ++ ++#define ZB_INT_POLL 0 ++#define ZB_INT_WAIT_SRDY 1 ++#define ZB_INT_SRDY_LOW 2 ++ ++#define SPI_POLL_TYPE 0 ++#define SPI_REQ_TYPE 1 ++ ++#define ZB_RESET 0 ++#define ZB_RELEASE 1 ++ ++#define SPI_BUF_MAX_SIZE ZBUF_MAX_SIZE ++#define SPI_MSG_HEADER_SIZE 3 ++ ++#define SPI_CMD_POLL 0x00 ++#define SPI_CMD_SREQ 0x20 ++#define SPI_CMD_AREQ 0x40 ++#define SPI_CMD_TYPE_MASK (SPI_CMD_SREQ | SPI_CMD_AREQ) ++ ++#define SPI_CHK_SRDY_JIFFIES 1 ++#define SPI_CHK_SRDY_TIME 4000 ++#define SPI_SRDY_L_TIMEOUT (HZ>>1) ++#define SPI_SRDY_H_TIMEOUT (HZ>>1) ++ ++// Zigbee network private information ++struct net_zb ++{ ++ struct net_device *dev; ++ struct bmi_zb *zb; ++ struct net_device_stats stats; ++ unsigned char net_open; ++ unsigned char socket[Z_NUM_SOCK]; ++}; ++ ++struct bmi_zb ++{ ++ struct bmi_device *bdev; ++ struct cdev cdev; ++ struct net_device *netdev; ++ struct device *class_dev; ++ struct i2c_adapter *adap; ++ struct spi_device *spi; /* SPI device */ ++ ++ struct work_struct spi_work; /* work to process Poll req */ ++ struct work_struct xmt_work; /* work to xmt to device */ ++ struct work_struct sreq_work; /* work to process sreq */ ++ struct work_struct state_work; /* work to check device state */ ++ ++ struct delayed_work srdy_work; /* work to chk for SRDY */ ++ ++ unsigned long start_time; ++ unsigned long delay; ++ ++ struct workqueue_struct *spi_wq; ++ struct workqueue_struct *srdy_wq; ++ ++ wait_queue_head_t srdy_queue; ++ unsigned char srdy_state; ++ unsigned char enable; ++ unsigned char int_depth; ++ ++ wait_queue_head_t sreq_queue; ++ unsigned char *sreq_buf; ++ unsigned short sreq_len; ++ int sreq_ret; ++ ++ wait_queue_head_t delay_queue; ++ ++ char int_name[20]; /* interrupt name */ ++ int slot; /* base unit slot number */ ++ int open_flag; /* single open flag */ ++ int irq; ++ struct zaccel_info z_info; ++}; ++ ++extern int zb_Reset(struct bmi_zb *zb, unsigned char state); ++extern void zb_StartDevice(struct bmi_zb *zb, unsigned char option); ++extern int zb_StartRequest(struct bmi_zb *zb); ++extern void zb_spi_poll(void *arg); ++extern int zaccel_spi_req(struct bmi_zb *zb, unsigned char *data, unsigned short buf_len); ++extern int zaccel_SRDY_poll(struct bmi_zb *zb, unsigned char polarity); ++extern int zb_GetDeviceInfo(struct bmi_zb *zb, unsigned char param, unsigned char *buf); ++extern unsigned char zb_WriteConfiguration(struct bmi_zb *zb, unsigned char configId, unsigned char len, unsigned char *data); ++extern int zb_ReadConfiguration(struct bmi_zb *zb, unsigned char configId, ++ unsigned char *buf); ++extern int zb_zcommand(struct bmi_zb *zb, unsigned short cmd, unsigned char len, ++ unsigned char *buf); ++extern void zb_SoftReset(struct bmi_zb *zb); ++extern unsigned char zb_AppRegisterRequest(struct bmi_zb *zb, unsigned char len, ++ unsigned char *app_info); ++extern unsigned char zb_PermitJoiningRequest(struct bmi_zb *zb, ++ unsigned char *dest, unsigned char timeout); ++extern void zb_AllowBind(struct bmi_zb *zb, unsigned char timeout); ++extern void zb_BindRequest(struct bmi_zb *zb, unsigned char create, ++ unsigned char *bind_info); ++extern int zb_SendDataRequest(struct bmi_zb *zb, unsigned char *buf, ++ unsigned char len); ++extern void zb_FindDeviceRequest(struct bmi_zb *zb, unsigned char *searchKey); ++extern unsigned char zb_AFRegisterRequest(struct bmi_zb *zb, unsigned char len, unsigned char *app_info); ++extern int zb_sysRFpowerAmp(struct bmi_zb *zb, unsigned char pa, unsigned char power); ++ ++extern void zaccel_cmd_proc(struct bmi_zb *zb,unsigned char *buf); ++extern int zb_rx(struct net_device *dev, unsigned char *buf, ++ unsigned char len, unsigned short type); ++extern int z_sock_init(void); ++extern int zdev_setopt(struct net_device *dev,int cmd, int len, ++ unsigned char *buf); ++extern int zdev_getopt(struct net_device *dev, int cmd, int *len, ++ unsigned char *buf); ++ ++extern void zb_net_setup(struct net_device *dev); ++extern void zaccel_getdev(struct bmi_zb *zb); ++ ++extern void z_sock_exit(void); ++extern int z_sock_init(void); ++extern void zb_create_sysfs(struct net_device *net); ++extern void zb_remove_sysfs(struct net_device *net); ++extern int init_zaccel(struct bmi_zb *zb); ++extern void remove_zaccel(struct bmi_zb *zb); ++extern int zb_ReadSRDY(struct bmi_zb *zb, int print); ++extern void zb_ReadMRDY(struct bmi_zb *zb); ++extern void zaccel_spi_poll(struct bmi_zb *zb); ++extern int zb_SysTestLoopback(struct bmi_zb *zb); ++extern void zb_sysVersion(struct bmi_zb *zb); ++extern int zaccel_get_chanlist(struct bmi_zb *zb); ++ ++ ++ ++#endif // BMI_ZB_H +--- /dev/null ++++ git/drivers/bmi/pims/zb/bmi_znetdev.c +@@ -0,0 +1,977 @@ ++/* ++ * bmi_znetdev.c ++ * ++ * This file contains the zaccel network device driver codes. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "bmi_zigbee.h" ++#include "bmi_zaccel.h" ++ ++static int zb_open(struct net_device *dev) ++{ ++ struct bmi_zb *zb; ++ struct net_zb *priv; ++ struct zaccel_device *zdev; ++ ++ printk(KERN_DEBUG "bmi_znetdev: zb_open\n"); ++ priv = netdev_priv(dev); ++ zb = priv->zb; ++ zdev = &zb->z_info.device; ++ ++ priv->net_open = 1; ++ netif_start_queue(dev); ++ return 0; ++} ++ ++static int zb_close(struct net_device *dev) ++{ ++ struct net_zb *priv; ++ ++ printk(KERN_DEBUG "bmi_znetdev: zb_close\n"); ++ priv = netdev_priv(dev); ++ ++ priv->net_open = 0; ++ netif_stop_queue(dev); ++ ++ return 0; ++} ++ ++static int zb_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ++{ ++ unsigned char len_chk; ++ unsigned char offset; ++ struct net_zb *priv; ++ struct bmi_zb *zb; ++ struct zaccel_info *z_info; ++ ++ unsigned char *zapp; ++ unsigned char buf[32]; ++ unsigned short len; ++ unsigned char type; ++ unsigned char reason = 0; ++ unsigned char *user_pt; ++ unsigned char flag; ++ unsigned char state; ++ int i; ++ int rc = 0; ++ ++ priv = netdev_priv(dev); ++ zb = priv->zb; ++ z_info = &zb->z_info; ++ ++ switch(cmd) ++ { ++ case SIOCSRESET: ++ if(copy_from_user(buf, ifr->ifr_data, (2*sizeof(char)))) ++ { ++ printk(KERN_ERR "BMI_ZB_ANY_REQ cannot get commands\n"); ++ return -EFAULT; ++ } ++ ++ switch(buf[0]) ++ { ++ case Z_HW_RESET: ++ if(dev->flags & IFF_UP) ++ { ++ /* set flag to remember that IF is up previously */ ++ flag = IFF_UP; ++ dev->flags &= ~IFF_UP; ++ netif_stop_queue(dev); ++ } ++ ++ zb_Reset(zb,ZB_RESET); ++ udelay(10); ++ zb_Reset(zb,ZB_RELEASE); ++ ++ break; ++ ++ case Z_SW_RESET: ++ if(dev->flags & IFF_UP) ++ { ++ flag = IFF_UP; ++ dev->flags &= ~IFF_UP; ++ netif_stop_queue(dev); ++ } ++ ++ zb_SoftReset(zb); ++ break; ++ ++ case Z_DONT_RESET: ++ return 0; ++ ++ default: ++ printk(KERN_WARNING "zb ioctl reset - unknow reset type %d\n",buf[1]); ++ return -EINVAL; ++ } ++ ++ /* ++ * If reset the device, wait for it to come back and ++ * start Z-stack. ++ */ ++ rc = wait_event_interruptible_timeout(z_info->wait_queue, ++ ((z_info->msg_flag & RESET_IND_BIT) != 0),Z_RESET_TIMEOUT); ++ ++ if(rc == 0) ++ { ++ /* timeout and no indication received */ ++ reason = 1; ++ printk(KERN_ERR "zb: wait for reset IND timeout\n"); ++ rc = -EAGAIN; ++ } ++ else ++ { ++ ++#ifdef VE_OUT ++ if(flag & IFF_UP) ++ { ++ netif_start_queue(dev); ++ dev->flags |= IFF_UP; ++ } ++#endif ++ ++ rc = 0; ++ } ++ ++ if(rc == -EAGAIN) ++ { ++ /* copy extra code to the user space */ ++ if(copy_to_user(ifr->ifr_data,(void *)&reason,1)) ++ { ++ return -EFAULT; ++ } ++ } ++ ++ break; ++ ++ case SIOCGDEVICEINFO: ++ ++ if(copy_from_user(buf, ifr->ifr_data, 1)) ++ { ++ printk(KERN_ERR "SIOCGDEVICEINFO cannot get parameter\n"); ++ return -EFAULT; ++ } ++ ++ len = zb_GetDeviceInfo(zb,buf[0],buf); ++ ++ if(copy_to_user(ifr->ifr_data, buf, len)) ++ { ++ return -EFAULT; ++ } ++ ++ rc = (int)len; ++ break; ++ ++ case SIOCSAPPREGISTER: ++ if(copy_from_user(buf, ifr->ifr_data, sizeof(char))) ++ { ++ printk(KERN_ERR "SIOCSAPPREGISTER cannot get parameter\n"); ++ return -EFAULT; ++ } ++ ++ len = (unsigned short)buf[0]; ++ ++ /* ++ * Input Format: ++ * 1-byte message length ++ * x-bytes message (see below comment for msg format. ++ */ ++ ++ zapp = kmalloc(len,GFP_KERNEL); ++ if(zapp == NULL) ++ { ++ printk(KERN_WARNING "zb_ioctl no buf for cmd 0x%x\n",cmd); ++ return -ENOMEM; ++ } ++ ++ user_pt = (unsigned char *)ifr->ifr_data; ++ if(copy_from_user((void *)zapp, &user_pt[1], (unsigned long)len)) ++ { ++ kfree(zapp); ++ return -EFAULT; ++ } ++ ++ /* ++ * verify the length of the data. ++ * Format of message is (number in parenthesis = num of bytes) ++ * ++ * zapp[offset] content ++ * 0 appEndpoint(1) ++ * 1 appProfileID(2) ++ * 3 deviceId(2) ++ * 5 deviceVersion(1) ++ * 6 unused(1) ++ * 7 inputCommandNum(1) ++ * [8] [inputCommand(2),inputCommand(2), ...] ++ * 8 + (inputNum * 2) outputCommandNum(1) ++ * [outputCommand(2),outputCommand(2), ...] ++ */ ++ ++ /* 8 bytes between appEndpoint to inputCommandNum */ ++ len_chk = 8; ++ ++ /* ++ * Get the offset to outputCommandNum byte ++ * and add the number of inputCommand bytes and outputCommandNum ++ * byte to the len_chk. ++ */ ++ offset = (zapp[7] << 1) + 8; ++ len_chk += (zapp[7] << 1) + 1; ++ ++ /* Add the number of output command bytes */ ++ len_chk += (zapp[offset] << 1); ++ ++ if(len_chk != len) ++ { ++ /* ++ * The len of the input declared is less than the ++ * number of data required. ++ */ ++ kfree(zapp); ++ printk(KERN_WARNING "SIOCSAPPREGISTER: inconsistence len %d %d\n",len_chk,len); ++ return -EINVAL; ++ } ++ ++ buf[0] = zb_AppRegisterRequest(zb,len,zapp); ++ ++ if(buf[0] != 0) ++ { ++ rc = -1; ++ } ++ ++ if(copy_to_user(ifr->ifr_data,buf,1)) ++ { ++ printk(KERN_WARNING "SIOCAPP result dropped\n"); ++ } ++ ++ kfree(zapp); ++ ++ break; ++ ++ case SIOCSALLOWBIND: ++ if(copy_from_user(buf, ifr->ifr_data, sizeof(char))) ++ { ++ printk(KERN_ERR "SIOCSALLOWBIND cannot get parameter\n"); ++ return -EFAULT; ++ } ++ ++ /* ++ * Input format:\ ++ * 1-bytes timeout ++ */ ++ ++ zb_AllowBind(zb,buf[0]); ++ ++ break; ++ ++ case SIOCSSTARTREQ: ++ zb_StartRequest(zb); ++ rc = wait_event_interruptible_timeout(z_info->wait_queue, ++ ((z_info->msg_flag & START_CNF_BIT) != 0),Z_CNF_TIMEOUT); ++ ++ if(rc == 0) ++ { ++ /* timeout - We didn't receive START_CNF message nor ++ * ZDO_STATE_CHANGE_IND. This can happens if the ++ * end-device or router does not find a network. ++ * Check if the device state had changed from DEV_HOLD ++ * to anything else. If it does, the stack has started. ++ */ ++ zb_GetDeviceInfo(zb,ZB_DEVICE_STATE,(unsigned char *)&state); ++ if((state != DEV_HOLD) || (state != DEV_INIT)) ++ { ++ printk(KERN_DEBUG "stack starts, state %d\n",state); ++ rc = 0; ++ } ++ else ++ { ++ rc = -1; ++ printk(KERN_DEBUG "Stack fails to start\n"); ++ } ++ } ++ else ++ { ++ printk(KERN_DEBUG "rcv ZB_START_CONFIRM\n"); ++ rc = 0; ++ } ++ ++ break; ++ ++ case SIOCSPERMITJOINING: ++ if(copy_from_user(buf, ifr->ifr_data, 3)) ++ { ++ printk(KERN_ERR "SIOCSPERMITJOINING: read error\n"); ++ return -EFAULT; ++ } ++ ++ /* ++ * Input format: ++ * 2-bytes 16-bit device address ++ * 1-bytes timeout ++ */ ++#ifdef VE_OUT ++ printk(KERN_DEBUG "permitjoining address 0x%x timeout 0x%x\n",*(unsigned short *)buf,buf[2]); ++#endif ++ ++ buf[0] = zb_PermitJoiningRequest(zb,&buf[0],buf[2]); ++ ++ if(buf[0] != 0) ++ { ++ rc = -1; ++ } ++ ++ if(copy_to_user(ifr->ifr_data,buf,1)) ++ { ++ printk(KERN_WARNING "SIOCSPERMIT result dropped\n"); ++ } ++ ++ break; ++ ++ case SIOCSBIND: ++ if(copy_from_user(buf, ifr->ifr_data, 12)) ++ { ++ printk(KERN_ERR "SIOCSBIND cannot get parameter\n"); ++ return -EFAULT; ++ } ++ ++ if((buf[0] != Z_BIND_CREATE) && (buf[0] != Z_BIND_REMOVE)) ++ { ++ return -EINVAL; ++ } ++ ++ zb_BindRequest(zb,buf[0],&buf[1]); ++ ++ break; ++ ++ case SIOCSFINDDEVICE: ++ if(copy_from_user(buf, ifr->ifr_data, 8)) ++ { ++ printk(KERN_ERR "SIOCSFINDDEVICE cannot get parameter\n"); ++ return -EFAULT; ++ } ++ zb_FindDeviceRequest(zb,buf); ++ break; ++ ++ case SIOCSAFREGISTER: ++ if(copy_from_user(buf, ifr->ifr_data, sizeof(char))) ++ { ++ printk(KERN_ERR "SIOCSAPPREGISTER cannot get parameter\n"); ++ return -EFAULT; ++ } ++ ++ len = (unsigned short)buf[0]; ++ ++ /* ++ * Input Format: ++ * 1-byte message length ++ * x-bytes message (see below comment for msg format. ++ */ ++ ++ zapp = kmalloc(len,GFP_KERNEL); ++ if(zapp == NULL) ++ { ++ printk(KERN_WARNING "zb_ioctl no buf for cmd 0x%x\n",cmd); ++ return -ENOMEM; ++ } ++ ++ user_pt = (unsigned char *)ifr->ifr_data; ++ if(copy_from_user((void *)zapp, &user_pt[1], (unsigned long)len)) ++ { ++ kfree(zapp); ++ return -EFAULT; ++ } ++ ++ buf[0] = zb_AFRegisterRequest(zb,len,zapp); ++ if(buf[0] != 0) ++ { ++ rc = -1; ++ } ++ ++ if(copy_to_user(ifr->ifr_data,buf,1)) ++ { ++ printk(KERN_WARNING "SIOCAPP result dropped\n"); ++ } ++ ++ kfree(zapp); ++ break; ++ ++ case SIOCSPOWERAMP: ++ if(copy_from_user(buf, ifr->ifr_data, 2)) ++ { ++ printk(KERN_ERR "SIOCSPOWERAMP cannot get parameter\n"); ++ return -EFAULT; ++ } ++ ++ rc = zb_sysRFpowerAmp(zb,buf[0],buf[1]); ++ break; ++ ++ case SIOCSZCOMMAND: ++ ++ /* ++ * This command passes any Z-Accel command to the device and ++ * returns the reply back to the user. ++ * Message format: ++ * 1-byte length of data field ++ * 2-bytes command ++ * 0-128 bytes data ++ */ ++ if(copy_from_user(buf, ifr->ifr_data, 1)) ++ { ++ printk(KERN_ERR "SIOCSZCOMMAND cannot get parameter\n"); ++ return -EFAULT; ++ } ++ ++ user_pt = (unsigned char *)ifr->ifr_data; ++ len = (unsigned short)buf[0] + 3; ++ ++ if(len > ZCMD_BUF) ++ { ++ printk(KERN_WARNING "SIOCSZCOMMAND message is too long\n"); ++ return -EINVAL; ++ } ++ ++ zapp = kmalloc(ZCMD_BUF,GFP_KERNEL); ++ if(zapp == NULL) ++ { ++ printk(KERN_WARNING "SIOCSZCOMMAND no buf for the cmd\n"); ++ return -ENOMEM; ++ } ++ ++ if(copy_from_user(zapp, ifr->ifr_data, len)) ++ { ++ printk(KERN_ERR "SIOCSZCOMMAND cannot get parameter\n"); ++ return -EFAULT; ++ } ++ type = zapp[1] & SPI_CMD_TYPE_MASK; ++ ++#define VE_DEBUG ++#ifdef VE_DEBUGx ++ printk("len %d: ",len); ++ for(i = 0; i < len; i++) ++ { ++ printk("%x ",zapp[i]); ++ } ++ printk("\n"); ++#endif ++ ++ zaccel_spi_req(zb,zapp,len); ++ ++ /* ++ * read the length of the data, if it's SREQ command. ++ */ ++ ++ if(type != SPI_CMD_AREQ) ++ { ++ len = zapp[0]; ++ ++ if(copy_to_user(ifr->ifr_data,zapp,(len + 3))) ++ { ++ return -EFAULT; ++ } ++ } ++ rc = 0; ++ ++ break; ++ ++ default: ++ printk("zb_ioctl default cmd\n"); ++ rc = -EINVAL; ++ break; ++ ++ } ++ ++ return rc; ++} ++ ++/* ++ * zb_rx passes data from Z-Accel to the user via socket ++ */ ++int zb_rx(struct net_device *dev, unsigned char *buf, unsigned char len, unsigned short type) ++{ ++ struct sk_buff *skb; ++ struct net_zb *priv; ++ ++ if(!dev) ++ return -EINVAL; ++ ++ ++ priv = netdev_priv(dev); ++ ++ if(priv->socket[type] == Z_NO_SOCK) ++ { ++ return -EINVAL; ++ } ++ ++ /* ++ * Check if the device is bound to a socket. ++ * If not, drop the message. ++ */ ++ ++ dev->last_rx = jiffies; ++ ++ skb = dev_alloc_skb(len); ++ if(skb) ++ { ++ memcpy(skb_put(skb,len),buf,len); ++ ++ /* ++ * Set the device to zigbee. ++ * Set protocol number to zero, so the kernel will not ++ * pass it through the protocol stack. ++ */ ++ ++ skb->dev = dev; ++ skb->protocol = type; ++ ++ if(type == Z_PACKET_SOCK) ++ { ++ /* ++ * Increment packet count and notify kernel of ++ * the new packet. ++ */ ++ priv->stats.rx_packets++; ++ } ++ ++ netif_rx(skb); ++ } ++ else ++ { ++ if(type == Z_PACKET_SOCK) ++ priv->stats.rx_dropped++; ++ } ++ ++ return 0; ++} ++ ++int zb_tx(struct sk_buff *skb, struct net_device *dev) ++{ ++ struct bmi_zb *zb; ++ struct net_zb *priv; ++ struct zaccel_xmt_msg *msg; ++ unsigned char *buf; ++ ++ priv = netdev_priv(dev); ++ zb = priv->zb; ++ ++ if(skb->len > XMT_MSG_SIZE) ++ { ++ dev_kfree_skb(skb); ++ return -EINVAL; ++ } ++ ++ msg = (struct zaccel_xmt_msg *)kmalloc(sizeof(struct zaccel_xmt_msg), GFP_KERNEL); ++ buf = msg->buf; ++ ++ memcpy(buf,skb->data,skb->len); ++ ++ msg->len = skb->len; ++ ++ /* ++ * zb_tx is called by dev_queue_xmit, which requires atomic ++ * operation. We cannot call zb_SendDataRequest directly here ++ * to schedule SPI transfer to the Z-Accel because ++ * it causes "BUG: scheduling while atomic exception." ++ * We put the data in a message queue and ++ * schedule a work queue to call zb_SendDataRequest later. ++ */ ++ ++ list_add_tail(&msg->list, &zb->z_info.xmt_list); ++ schedule_work(&zb->xmt_work); ++ ++ /* Move this statistic to a real packet transmission location later */ ++ priv->stats.tx_packets++; ++ ++ dev->trans_start = jiffies; ++ ++ /* Free sku buffer */ ++ dev_kfree_skb(skb); ++ ++ return 0; ++} ++ ++struct net_device_stats *zb_stats(struct net_device *dev) ++{ ++ struct net_zb *priv = netdev_priv(dev); ++ ++ return &priv->stats; ++} ++ ++void zb_net_setup(struct net_device *dev) ++{ ++ struct net_zb *priv; ++ ++ priv = netdev_priv(dev); ++ ++ priv->dev = dev; ++ priv->socket[Z_PACKET_SOCK] = Z_NO_SOCK; ++ priv->socket[Z_CONTROL_SOCK] = Z_NO_SOCK; ++ ++ dev->open = zb_open; ++ dev->stop = zb_close; ++ dev->hard_start_xmit = zb_tx; ++ dev->tx_queue_len = 32; ++ dev->get_stats = zb_stats; ++ dev->do_ioctl = zb_ioctl; ++ dev->flags = 0; ++} ++ ++int zdev_setopt(struct net_device *dev,int cmd, int len, unsigned char *buf) ++{ ++ struct net_zb *priv = netdev_priv(dev); ++ struct bmi_zb *zb; ++ int rc; ++ ++ zb = priv->zb; ++ rc = (int)zb_WriteConfiguration(zb,(unsigned char)cmd,(unsigned char)len,buf); ++ return rc; ++} ++ ++int zdev_getopt(struct net_device *dev, int cmd, int *len, unsigned char *buf) ++{ ++ struct net_zb *priv = netdev_priv(dev); ++ struct bmi_zb *zb; ++ ++ zb = priv->zb; ++ ++ *len = (int)zb_ReadConfiguration(zb,(unsigned char)cmd,buf); ++ if(*len != 0) ++ { ++ return 0; ++ } ++ else ++ { ++ return -EFAULT; ++ } ++ ++} ++ ++static ssize_t show_device(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct net_device *net = to_net_dev(dev); ++ struct net_zb *priv = netdev_priv(net); ++ struct bmi_zb *zb = priv->zb; ++ int size = 0; ++ int rc; ++ unsigned char rbuf[8]; ++ ++ rc = zb_ReadConfiguration(zb,ZCD_NV_LOGICAL_TYPE,rbuf); ++ if(rc <= 0) ++ { ++ size = sprintf(buf,"Bad read. Try again\n"); ++ } ++ switch(rbuf[Z_CONFIG_OFFSET]) ++ { ++ case ZB_COORDINATOR: ++ size = sprintf(buf,"coordinator\n"); ++ break; ++ ++ case ZB_ROUTER: ++ size = sprintf(buf,"router\n"); ++ break; ++ ++ case ZB_ENDDEVICE: ++ size = sprintf(buf,"end-device\n"); ++ break; ++ ++ default: ++ size = sprintf(buf,"device-error\n"); ++ break; ++ } ++ return size; ++} ++ ++static ssize_t store_device(struct device *dev, struct device_attribute *attr, char *buf, size_t count) ++{ ++ struct net_device *net = to_net_dev(dev); ++ struct net_zb *priv = netdev_priv(net); ++ struct bmi_zb *zb = priv->zb; ++ int size; ++ unsigned char device; ++ ++ if(memcmp(buf, "coordinator",(count-1)) == 0) ++ { ++ printk(KERN_DEBUG "zb: config to coordinator\n"); ++ device = ZB_COORDINATOR; ++ } ++ else if(memcmp(buf, "router",(count-1)) == 0) ++ { ++ printk(KERN_DEBUG "zb: config to router\n"); ++ device = ZB_ROUTER; ++ } ++ else if(memcmp(buf, "end-device",(count-1)) == 0) ++ { ++ printk(KERN_DEBUG "zb: config to end-device\n"); ++ device = ZB_ENDDEVICE; ++ } ++ else ++ { ++ printk(KERN_DEBUG "zb: invalid config\n"); ++ size = sprintf(buf,"Invalid device. Try again\n"); ++ return count; ++ } ++ ++ if(zb_WriteConfiguration(zb,ZCD_NV_LOGICAL_TYPE,1,&device) != 0) ++ { ++ size = sprintf(buf,"Bad write. Try again\n"); ++ } ++ ++ return count; ++} ++ ++static ssize_t store_chanlist(struct device *dev, struct device_attribute *attr, char *buf, size_t count) ++{ ++ struct net_device *net = to_net_dev(dev); ++ struct net_zb *priv = netdev_priv(net); ++ struct bmi_zb *zb = priv->zb; ++ int size; ++ unsigned long chanlist; ++ unsigned char rbuf[4]; ++ ++ chanlist = simple_strtol(buf,NULL,16); ++ rbuf[0] = (unsigned char)(chanlist) & 0xFF; ++ rbuf[1] = (unsigned char)(chanlist >> 8) & 0xFF; ++ rbuf[2] = (unsigned char)(chanlist >> 16) & 0xFF; ++ rbuf[3] = (unsigned char)(chanlist >> 24) & 0xFF; ++ ++ if(zb_WriteConfiguration(zb,ZCD_NV_CHANLIST,4,(unsigned char *)rbuf) != 0) ++ { ++ size = sprintf(buf,"Bad write. Try again\n"); ++ } ++ ++ return count; ++} ++ ++static ssize_t show_chanlist(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct net_device *net = to_net_dev(dev); ++ struct net_zb *priv = netdev_priv(net); ++ struct bmi_zb *zb = priv->zb; ++ unsigned char rbuf[10]; ++ int size = 0; ++ int rc; ++ ++ rc = zb_ReadConfiguration(zb,ZCD_NV_CHANLIST,rbuf); ++ if(rc < 0) ++ { ++ size = sprintf(buf,"bad read. Try again\n"); ++ } ++ else ++ { ++ size = sprintf(buf,"%0x ",rbuf[Z_CONFIG_OFFSET+3]); ++ size += sprintf((buf+size),"%0x ",rbuf[Z_CONFIG_OFFSET+2]); ++ size += sprintf((buf+size),"%0x ",rbuf[Z_CONFIG_OFFSET+1]); ++ size += sprintf((buf+size),"%0x\n",rbuf[Z_CONFIG_OFFSET]); ++ } ++ return size; ++} ++ ++static ssize_t store_initop(struct device *dev, struct device_attribute *attr, char *buf, size_t count) ++{ ++ struct net_device *net = to_net_dev(dev); ++ struct net_zb *priv = netdev_priv(net); ++ struct bmi_zb *zb = priv->zb; ++ unsigned char option; ++ int size; ++ ++ option = (unsigned char)simple_strtol(buf,NULL,16); ++ option &= ZCD_STARTOPT_MASK; ++ ++ if(zb_WriteConfiguration(zb,ZCD_NV_STARTUP_OPTION,1,(unsigned char *)&option) != 0) ++ { ++ size = sprintf(buf,"Bad write. Try again\n"); ++ } ++ ++ return count; ++} ++ ++static ssize_t show_initop(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct net_device *net = to_net_dev(dev); ++ struct net_zb *priv = netdev_priv(net); ++ struct bmi_zb *zb = priv->zb; ++ unsigned char rbuf[10]; ++ int size = 0; ++ int rc; ++ ++ rc = zb_ReadConfiguration(zb,ZCD_NV_STARTUP_OPTION,(unsigned char *)&rbuf); ++ if(rc < 0) ++ { ++ size = sprintf(buf,"bad read. Try again\n"); ++ } ++ else ++ { ++ size = sprintf(buf,"%0x\n",rbuf[Z_CONFIG_OFFSET]); ++ } ++ ++ return size; ++} ++ ++static ssize_t store_panid(struct device *dev, struct device_attribute *attr, char *buf, size_t count) ++{ ++ struct net_device *net = to_net_dev(dev); ++ struct net_zb *priv = netdev_priv(net); ++ struct bmi_zb *zb = priv->zb; ++ unsigned short panid; ++ unsigned char rbuf[2]; ++ int size; ++ ++ panid = (unsigned short)simple_strtol(buf,NULL,16); ++ rbuf[0] = (unsigned char)(panid) & 0xFF; ++ rbuf[1] = (unsigned char)(panid >> 8) & 0xFF; ++ ++ if(zb_WriteConfiguration(zb,ZCD_NV_PANID,2,(unsigned char *)rbuf) != 0) ++ { ++ size = sprintf(buf,"Bad write read. Try again\n"); ++ } ++ ++ printk(KERN_DEBUG "zb: config panid 0x%x\n",panid); ++ return count; ++} ++ ++static ssize_t show_panid(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct net_device *net = to_net_dev(dev); ++ struct net_zb *priv = netdev_priv(net); ++ struct bmi_zb *zb = priv->zb; ++ unsigned char rbuf[10]; ++ int size = 0; ++ int rc; ++ ++ rc = zb_ReadConfiguration(zb,ZCD_NV_PANID,(unsigned char *)&rbuf); ++ if(rc < 0) ++ { ++ size = sprintf(buf,"bad read. Try again\n"); ++ } ++ else ++ { ++ size = sprintf(buf,"%0x ",rbuf[Z_CONFIG_OFFSET+1]); ++ size += sprintf((buf+size),"%0x\n",rbuf[Z_CONFIG_OFFSET]); ++ } ++ return size; ++} ++ ++static ssize_t show_zbinfo(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct net_device *net = to_net_dev(dev); ++ struct net_zb *priv = netdev_priv(net); ++ struct bmi_zb *zb = priv->zb; ++ struct zaccel_device *z_dev = &zb->z_info.device; ++ int size = 0; ++ ++ zaccel_getdev(zb); ++ ++ switch(z_dev->state) ++ { ++ case DEV_HOLD: ++ size = sprintf(buf,"DEV_HOLD\n"); ++ break; ++ ++ case DEV_INIT: ++ size = sprintf(buf,"DEV_INIT\n"); ++ break; ++ ++ case DEV_NWK_DISC: ++ size = sprintf(buf,"DEV_NWK_DISC\n"); ++ break; ++ ++ case DEV_NWK_JOINING: ++ size = sprintf(buf,"DEV_NWK_JOINING\n"); ++ break; ++ ++ case DEV_NWK_REJOIN: ++ size = sprintf(buf,"DEV_NWK_REJOIN\n"); ++ break; ++ ++ case DEV_END_DEVICE_UNAUTH: ++ size = sprintf(buf,"DEV_END_DEVICE_UNAUTH\n"); ++ break; ++ ++ case DEV_END_DEVICE: ++ size = sprintf(buf,"DEV_END_DEVICE\n"); ++ break; ++ ++ case DEV_ROUTER: ++ size = sprintf(buf,"DEV_ROUTER\n"); ++ break; ++ ++ case DEV_COORD_STARTING: ++ size = sprintf(buf,"DEV_COORD_STARTING\n"); ++ break; ++ ++ case DEV_ZB_COORD: ++ size = sprintf(buf,"DEV_ZB_COORD\n"); ++ break; ++ ++ case DEV_NWK_ORPHAN: ++ size = sprintf(buf,"DEV_NWK_ORHAN\n"); ++ break; ++ ++ default: ++ size = sprintf(buf,"UNKNOWN STATE %d\n",z_dev->state); ++ break; ++ } ++ ++ size += sprintf((buf+size),"device IEEE address: %x:%x:%x:%x:%x:%x:%x:%x\n", ++ z_dev->device_ieee[7],z_dev->device_ieee[6],z_dev->device_ieee[5], ++ z_dev->device_ieee[4],z_dev->device_ieee[3],z_dev->device_ieee[2], ++ z_dev->device_ieee[1],z_dev->device_ieee[0]); ++ size += sprintf((buf+size),"device short address: 0x%x %x\n", ++ z_dev->device_short[1],z_dev->device_short[0]); ++ size += sprintf((buf+size),"parent short address: 0x%x %x\n", ++ z_dev->parent_short[1],z_dev->parent_short[0]); ++ size += sprintf((buf+size),"parent IEEE address: %x:%x:%x:%x:%x:%x:%x:%x\n", ++ z_dev->parent_ieee[7],z_dev->parent_ieee[6],z_dev->parent_ieee[5], ++ z_dev->parent_ieee[4],z_dev->parent_ieee[3],z_dev->parent_ieee[2], ++ z_dev->parent_ieee[1],z_dev->parent_ieee[0]); ++ size += sprintf((buf+size),"channel: 0x%0x\n",z_dev->channel); ++ size += sprintf((buf+size),"PAN ID: 0x%0x %0x\n", ++ z_dev->panid[1],z_dev->panid[0]); ++ size += sprintf((buf+size),"extended PAN ID: %x:%x:%x:%x:%x:%x:%x:%x\n", ++ z_dev->ext_panid[7],z_dev->ext_panid[6],z_dev->ext_panid[5], ++ z_dev->ext_panid[4],z_dev->ext_panid[3],z_dev->ext_panid[2], ++ z_dev->ext_panid[1],z_dev->ext_panid[0]); ++ return size; ++} ++ ++ ++DEVICE_ATTR(device, (S_IRUGO | S_IWUSR), show_device, store_device); ++DEVICE_ATTR(panid, (S_IRUGO | S_IWUSR), show_panid, store_panid); ++DEVICE_ATTR(chanlist, (S_IRUGO | S_IWUSR), show_chanlist, store_chanlist); ++DEVICE_ATTR(initop, (S_IRUGO | S_IWUSR), show_initop, store_initop); ++DEVICE_ATTR(zbinfo, S_IRUGO, show_zbinfo, NULL); ++ ++void zb_create_sysfs(struct net_device *net) ++{ ++ struct device *dev = &(net->dev); ++ ++ if(device_create_file(dev,&dev_attr_device) < 0) ++ printk(KERN_WARNING "zb: failed to create device attribute\n"); ++ ++ if(device_create_file(dev,&dev_attr_panid) < 0) ++ printk(KERN_WARNING "zb: failed to create panid attribute\n"); ++ ++ if(device_create_file(dev,&dev_attr_chanlist) < 0) ++ printk(KERN_WARNING "zb: failed to create chanlist attribute\n"); ++ ++ if(device_create_file(dev,&dev_attr_initop) < 0) ++ printk(KERN_WARNING "zb: failed to create initop attribute\n"); ++ ++ if(device_create_file(dev,&dev_attr_zbinfo) < 0) ++ printk(KERN_WARNING "zb: failed to create zinfo attribute\n"); ++} ++ ++void zb_remove_sysfs(struct net_device *net) ++{ ++ struct device *dev = &(net->dev); ++ ++ device_remove_file(dev,&dev_attr_device); ++ device_remove_file(dev,&dev_attr_panid); ++ device_remove_file(dev,&dev_attr_chanlist); ++ device_remove_file(dev,&dev_attr_initop); ++ device_remove_file(dev,&dev_attr_zbinfo); ++} ++ +--- /dev/null ++++ git/drivers/bmi/pims/zb/bmi_zprotocol.c +@@ -0,0 +1,619 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include "bmi_zigbee.h" ++ ++HLIST_HEAD(zaccel_list); ++DEFINE_RWLOCK(zaccel_list_lock); ++ ++struct zaccel_sock { ++ struct sock sk; ++ struct packet_type zpacket_type; ++ spinlock_t bind_lock; ++ struct sockaddr_zb sockaddr; ++ struct net_device *dev; ++ ++}; ++ ++static inline struct zaccel_sock *z_sk(struct sock *sk) ++{ ++ return (struct zaccel_sock *)sk; ++} ++ ++static void zaccel_sock_destruct(struct sock *sk) ++{ ++ if(!sock_flag(sk,SOCK_DEAD)) { ++ printk("Attempt to release alive packet socket: %p\n",sk); ++ return; ++ } ++ ++ sk_refcnt_debug_dec(sk); ++} ++ ++static int z_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer) ++{ ++ struct sock *sk; ++ struct zaccel_sock *zsock; ++ struct sockaddr_zb *zaddr; ++ ++ printk("z_packet_getname\n"); ++ zaddr = (struct sockaddr_zb *)uaddr; ++ ++ sk = sock->sk; ++ zsock = z_sk(sk); ++ ++ if(zsock->dev == 0) ++ { ++ ++ printk(KERN_WARNING "sock not bound \n"); ++ /* the socket is not bound */ ++ return -ENODATA; ++ } ++ ++ zaddr->z_family = AF_ZACCEL; ++ zaddr->z_ifindex = zsock->sockaddr.z_ifindex; ++ zaddr->z_protocol = zsock->sockaddr.z_protocol; ++ memcpy(&zaddr->z_name, &zsock->sockaddr.z_name, 15); ++ ++ *uaddr_len = sizeof(struct sockaddr_zb); ++ return 0; ++ ++} ++ ++static struct proto zaccel_proto = { ++ .name = "Z_PACKET", ++ .owner = THIS_MODULE, ++ .obj_size = sizeof(struct zaccel_sock), ++}; ++ ++static int z_control_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) ++{ ++ struct sock *sk; ++ ++ sk = pt->af_packet_priv; ++ ++ /* put packet in receive queue */ ++ if(sock_queue_rcv_skb(sk,skb) == 0) ++ { ++ return 0; ++ } ++ ++ printk(KERN_WARNING "z_control_rcv drop\n"); ++ kfree_skb(skb); ++ return 0; ++ ++} ++ ++static int z_packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) ++{ ++ struct sock *sk; ++ ++ sk = pt->af_packet_priv; ++ ++ /* ++ * put the packet in the receive queue. ++ */ ++ ++ if(sock_queue_rcv_skb(sk,skb) == 0) ++ { ++ return 0; ++ } ++ ++ printk(KERN_WARNING "z_packet_rcv drop\n"); ++ kfree_skb(skb); ++ return 0; ++} ++ ++/* ++ * Pull a packet from our recieve queue and hand it to the user. ++ */ ++ ++static int z_recvmsg(struct kiocb *iocb, struct socket *sock, ++ struct msghdr *msg, size_t len, int flags) ++{ ++ struct sock *sk; ++ struct sk_buff *skb; ++ int skb_len; ++ struct net_device *dev; ++ struct zaccel_sock *zsock; ++ int ifindex; ++ int err; ++ ++ err = -EINVAL; ++ if(flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT)) ++ { ++ goto out; ++ } ++ ++ sk = sock->sk; ++ ++ zsock = z_sk(sk); ++ ++ ifindex = zsock->sockaddr.z_ifindex; ++ ++ dev = dev_get_by_index(&init_net, ifindex); ++ if(dev == NULL) ++ { ++ printk(KERN_WARNING "bmi_zprotocol: dev not found\n"); ++ return (-ENXIO); ++ } ++ ++ if(!(dev->flags & IFF_UP)) ++ { ++ printk("interface not up %d\n",(-ENETDOWN)); ++ dev_put(dev); ++ return -ENETDOWN; ++ } ++ ++ dev_put(dev); ++ ++ /* ++ * Get a datagram skbuff ++ */ ++ skb = skb_recv_datagram(sk,flags,flags&MSG_DONTWAIT,&err); ++ ++ if(skb == NULL) ++ { ++ goto out; ++ } ++ ++ /* ++ * If the input buffer is smaller than the message, truncate ++ * it. The user loses any data beyond it. ++ */ ++ skb_len = skb->len; ++ if(skb_len > len) ++ { ++ skb_len = len; ++ msg->msg_flags |= MSG_TRUNC; ++ } ++ ++ err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, skb_len); ++ if(err) ++ goto out_free; ++ ++ sock_recv_timestamp(msg, sk, skb); ++ ++ /* err returns data length if the copy is successful */ ++ err = skb_len; ++ ++out_free: ++ skb_free_datagram(sk,skb); ++ ++out: ++ return err; ++} ++ ++static int z_sendmsg(struct kiocb *iocb, struct socket *sock, ++ struct msghdr *msg, size_t len) ++{ ++ struct sock *sk = sock->sk; ++ struct sk_buff *skb; ++ struct net_device *dev; ++ struct zaccel_sock *zsock; ++ int ifindex; ++ int err; ++ ++ zsock = z_sk(sk); ++ ++ if(zsock->zpacket_type.type == Z_CONTROL_SOCK) ++ { ++ return -EPROTOTYPE; ++ } ++ ++ ifindex = zsock->sockaddr.z_ifindex; ++ ++ dev = dev_get_by_index(&init_net, ifindex); ++ if(dev == NULL) ++ { ++ printk(KERN_WARNING "bmi_zprotocol: dev not found\n"); ++ dev_put(dev); ++ return (-ENXIO); ++ } ++ ++ if(!(dev->flags & IFF_UP)) ++ { ++ printk(KERN_WARNING "bmi_zprotocol: interface not up %d\n",(-ENETDOWN)); ++ dev_put(dev); ++ return -ENETDOWN; ++ } ++ ++ if(len > 92) ++ { ++ /* message is too long */ ++ dev_put(dev); ++ return -EINVAL; ++ } ++ ++ skb = sock_alloc_send_skb(sk, len, msg->msg_flags & MSG_DONTWAIT, &err); ++ if(skb == NULL) ++ { ++ dev_put(dev); ++ printk(KERN_WARNING "bmi_zprotocol: sock_allock_send_skb failed %d\n",err); ++ return -ENOMEM; ++ } ++ ++ err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len); ++ if(err) ++ { ++ kfree_skb(skb); ++ dev_put(dev); ++ return -EFAULT; ++ } ++ ++ skb->dev = dev; ++ ++ /* ++ * dev_queue_xmit sends the packet directly to the driver. ++ */ ++ ++ err = dev_queue_xmit(skb); ++ if (err > 0) ++ { ++ kfree_skb(skb); ++ printk(KERN_WARNING "bmi_zprotocol: dev_queue_xmit failed %d\n",err); ++ dev_put(dev); ++ return(-ENETDOWN); ++ } ++ ++ dev_put(dev); ++ return(len); ++} ++ ++ ++static int z_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) ++{ ++ struct sock *sk = sock->sk; ++ char name[15]; ++ struct net_device *dev; ++ struct sockaddr_zb *z_addr; ++ struct zaccel_sock *zsock; ++ struct net_zb *priv; ++ unsigned char type; ++ int rc; ++ ++ z_addr = (struct sockaddr_zb *)uaddr; ++ ++ /* Get the name of the device */ ++ strlcpy(name,z_addr->z_name,sizeof(name)); ++ ++ rc = (int)strlen(name); ++ if(rc > 3) ++ { ++ return -EINVAL; ++ } ++ ++ if(memcmp(name,"zb",2)) ++ { ++ printk(KERN_WARNING "bmi_zprotocol: invalid name %s\n",name); ++ return -EINVAL; ++ } ++ ++ if((name[2] < 0x31) && (name[2] > 0x34)) ++ { ++ printk(KERN_WARNING "bmi_zprotocol: invalid slot %c\n",name[2]); ++ return -EINVAL; ++ } ++ ++ ++ zsock = z_sk(sk); ++ type = zsock->zpacket_type.type; ++ ++ /* search for the network interface by name */ ++ dev = dev_get_by_name(&init_net, name); ++ ++ /* ++ * check if the device has been bound to this socket type. ++ * If it has, return with error. ++ */ ++ ++ priv = netdev_priv(dev); ++ if(priv->socket[type] != Z_NO_SOCK) ++ { ++ dev_put(dev); ++ return -EISCONN; ++ } ++ ++ if(dev) ++ { ++ lock_sock(sk); ++ spin_lock(&zsock->bind_lock); ++ ++ if(zsock->dev && (zsock->dev != dev)) ++ { ++ /* This socket was bound. Unbind it first. */ ++ printk(KERN_INFO "unbound to previous device\n"); ++ __sock_put(sk); ++ ++ priv = netdev_priv(zsock->dev); ++ priv->socket[type] = Z_NO_SOCK; ++ ++ zsock->dev = NULL; ++ spin_unlock(&zsock->bind_lock); ++ dev_remove_pack(&zsock->zpacket_type); ++ spin_lock(&zsock->bind_lock); ++ } ++ ++ zsock->zpacket_type.dev = dev; ++ zsock->zpacket_type.af_packet_priv = sk; ++ ++ /* socket-dev information used by sendmsg */ ++ zsock->sockaddr.z_ifindex = dev->ifindex; ++ strlcpy(zsock->sockaddr.z_name,name,15); ++ ++ zsock->dev = dev; ++ ++ /* Add a packet handler to the networking stack. */ ++ dev_add_pack(&zsock->zpacket_type); ++ /* increment sk_refcnt */ ++ sock_hold(sk); ++ ++ /* Tell the device that it is bound to a socket */ ++ priv = netdev_priv(dev); ++ priv->socket[type] = 1; ++ ++ spin_unlock(&zsock->bind_lock); ++ release_sock(sk); ++ dev_put(dev); ++ return 0; ++ } ++ else ++ { ++ printk(KERN_WARNING "zb: dev %s not found\n",name); ++ return -ENODEV; ++ } ++} ++ ++static int z_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) ++{ ++ int rc; ++ ++ switch(cmd) ++ { ++ case SIOCGIFFLAGS: ++ case SIOCGIFNAME: ++ case SIOCGIFMTU: ++ case SIOCGIFINDEX: ++ case SIOCETHTOOL: ++ case SIOCSIFNAME: ++ case SIOCSIFFLAGS: ++ case SIOCSIFMTU: ++ /* ++ * return -ENOIOCTLCMD to sock_ioctl ++ * sock_ioctl will call dev_ioctl to take care of these cmds. ++ */ ++ rc = -ENOIOCTLCMD; ++ break; ++ default: ++ rc = 0; ++ break; ++ } ++ ++ return rc; ++} ++ ++static int z_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) ++{ ++ struct sock *sk = sock->sk; ++ struct zaccel_sock *zsock; ++ unsigned char buf[135]; /* 128 data + 6 fixed header + 1 just in case */ ++ ++ zsock = z_sk(sk); ++ ++ if(!zsock->dev) ++ { ++ printk(KERN_WARNING "bmi_zprotocol: device not attached\n"); ++ /* ++ * socket has no device attached ++ */ ++ return -ENOTCONN; ++ } ++ ++ if(level != SOL_ZACCEL) ++ { ++ return -ENOPROTOOPT; ++ } ++ ++ if(optlen > 135) ++ { ++ return -EINVAL; ++ } ++ ++ if(copy_from_user(buf,optval,optlen)) ++ { ++ return -EFAULT; ++ } ++ ++ if(zdev_setopt(zsock->dev,optname,optlen,buf)) ++ { ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int z_getsockopt(struct socket *sock, int level, int optname, ++ char __user *optval, int __user *optlen) ++ ++{ ++ struct sock *sk = sock->sk; ++ struct zaccel_sock *zsock; ++ unsigned char buf[135]; /* 128 data + 6 fixed header + 1 just in case */ ++ int len; ++ int rc; ++ ++ zsock = z_sk(sk); ++ ++ if(!zsock->dev) ++ { ++ /* socket has no device attached */ ++ return -ENOTCONN; ++ } ++ ++ if(level != SOL_ZACCEL) ++ return -ENOPROTOOPT; ++ ++ rc = zdev_getopt(zsock->dev,optname,&len,buf); ++ ++ if(!rc) ++ { ++ if(put_user(len, optlen)) ++ return -EFAULT; ++ /* Include 3 header bytes to the message */ ++ if(copy_to_user(optval, buf, (len+3))) ++ return -EFAULT; ++ } ++ ++ return rc; ++ ++} ++ ++static int z_release(struct socket *sock) ++{ ++ struct sock *sk; ++ struct zaccel_sock *zsock; ++ struct net_zb *priv; ++ ++ sk = sock->sk; ++ ++ if(!sk) ++ return 0; ++ ++ zsock = z_sk(sk); ++ ++ write_lock_bh(&zaccel_list_lock); ++ sk_del_node_init(sk); ++ write_unlock_bh(&zaccel_list_lock); ++ ++ if(zsock->dev) ++ { ++ priv = netdev_priv(zsock->dev); ++ priv->socket[zsock->zpacket_type.type] = Z_NO_SOCK; ++ ++ /* remove protocol handler */ ++ dev_remove_pack(&zsock->zpacket_type); ++ __sock_put(sk); ++ } ++ ++ /* detach socket from process context */ ++ sock_orphan(sk); ++ sock->sk = NULL; ++ ++ /* Purge queues */ ++ skb_queue_purge(&sk->sk_receive_queue); ++ ++ sk_refcnt_debug_release(sk); ++ ++ sock_put(sk); ++ return 0; ++} ++ ++static const struct proto_ops z_protocol_ops = { ++ .family = PF_ZACCEL, ++ .owner = THIS_MODULE, ++ .release = z_release, ++ .bind = z_bind, ++ .connect = sock_no_connect, ++ .socketpair = sock_no_socketpair, ++ .accept = sock_no_accept, ++ .getname = z_getname, ++ .poll = sock_no_poll, ++ .ioctl = z_ioctl, ++ .listen = sock_no_listen, ++ .shutdown = sock_no_shutdown, ++ .setsockopt = z_setsockopt, ++ .getsockopt = z_getsockopt, ++ .sendmsg = z_sendmsg, ++ .recvmsg = z_recvmsg, ++ .mmap = sock_no_mmap, ++ .sendpage = sock_no_sendpage, ++}; ++ ++int z_protocol_create(struct net *net, struct socket *sock, int protocol) ++{ ++ struct sock *sk; ++ struct zaccel_sock *zsock; ++ ++ if (net != &init_net) ++ { ++ return -EAFNOSUPPORT; ++ } ++ ++ sock->state = SS_UNCONNECTED; ++ if(sock->type != SOCK_RAW) ++ { ++ return -ESOCKTNOSUPPORT; ++ } ++ ++ sock->ops = &z_protocol_ops; ++ ++ sk = sk_alloc(net, AF_ZACCEL, GFP_KERNEL, &zaccel_proto); ++ if(sk == NULL) ++ { ++ return -ENOMEM; ++ } ++ ++ sock_init_data(sock, sk); ++ sk->sk_protocol = protocol; ++ sk->sk_family = PF_ZACCEL; ++ sk->sk_destruct = zaccel_sock_destruct; ++ sk_refcnt_debug_inc(sk); ++ ++ zsock = z_sk(sk); ++ ++ spin_lock_init(&zsock->bind_lock); ++ ++ if(protocol == Z_CONTROL_SOCK) ++ { ++ zsock->zpacket_type.func = z_control_rcv; ++ zsock->zpacket_type.type = Z_CONTROL_SOCK; ++ sk->sk_protocol = Z_CONTROL_SOCK; ++ } ++ else ++ { ++ zsock->zpacket_type.func = z_packet_rcv; ++ zsock->zpacket_type.type = Z_PACKET_SOCK; ++ sk->sk_protocol = Z_PACKET_SOCK; ++ } ++ zsock->zpacket_type.af_packet_priv = sk; ++ zsock->zpacket_type.dev = NULL; ++ ++ zsock->dev = NULL; ++ ++ /* Add a socket to the bound sockets list */ ++ write_lock_bh(&zaccel_list_lock); ++ sk_add_node(sk,&zaccel_list); ++ write_unlock_bh(&zaccel_list_lock); ++ ++ return 0; ++ ++} ++ ++static struct net_proto_family zaccel_family_ops = { ++ .family = PF_ZACCEL, ++ .create = z_protocol_create, ++ .owner = THIS_MODULE, ++}; ++ ++void z_sock_exit(void) ++{ ++ sock_unregister(PF_ZACCEL); ++} ++ ++int z_sock_init(void) ++{ ++ int res; ++ ++ res = sock_register(&zaccel_family_ops); ++ if(res) { ++ printk(KERN_WARNING "Failed to register PF_ZACCEL\n"); ++ } ++ ++ return res; ++} +--- /dev/null ++++ git/drivers/bmi/slots/Kconfig +@@ -0,0 +1,21 @@ ++# ++# BMI Slot Drivers ++# ++ ++menu "BMI Hardware Slot support" ++ ++config BUG_SLOT ++ tristate "Buglabs BUGBase BMI Slots" ++ default 'n' ++ depends on BMI && MACH_BUG ++ help ++ If you say yes to this option, support will be included for the Buglabs BUGBase BMI Slot/Module Ports. ++ ++config OMAP_SLOT ++ tristate "TI BeagBoard BMI Slots" ++ default 'n' ++ depends on BMI ++ help ++ If you say yes to this option, support will be included for the BeagleBoard Slot. ++ ++endmenu +--- /dev/null ++++ git/drivers/bmi/slots/Makefile +@@ -0,0 +1,6 @@ ++# ++# Makefile for BMI Slot drivers ++# ++ ++obj-$(CONFIG_BUG_SLOT) += slots_bug.o ++obj-$(CONFIG_OMAP_SLOT) += slots_beagle.o +--- /dev/null ++++ git/drivers/bmi/slots/slots_beagle.c +@@ -0,0 +1,267 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define BMI_GPIO_0 139 ++#define BMI_GPIO_1 158 ++#define BMI_GPIO_2 137 ++#define BMI_GPIO_3 136 ++ ++static int bl_present(struct bmi_slot* slot) ++{ ++ unsigned gpio = irq_to_gpio(slot->present_irq); ++ if (gpio_get_value(gpio)) ++ return 0; ++ else ++ return 1; ++} ++ ++static void bl_power_on(struct bmi_slot* slot) ++{ ++ return; ++} ++ ++static void bl_power_off(struct bmi_slot* slot) ++{ ++ return; ++} ++ ++static void bl_gpio_config(struct bmi_slot* slot, int mask) /*Configure gpios as inputs/ouputs*/ ++{ ++ int i; ++ ++ unsigned char *gpio = (unsigned char*) slot->slot_data; ++ ++ for (i = 0; i < 4 ; i++) ++ { ++ if ((mask >> i) & 0x1) ++ gpio_direction_output(gpio[i], 0); ++ else ++ gpio_direction_input(gpio[i]); ++ } ++ return; ++} ++ ++static int bl_gpio_get(struct bmi_slot* slot) ++{ ++ int i; ++ unsigned char *gpio = (unsigned char*) slot->slot_data; ++ unsigned char ret = 0; ++ ++ for (i = 3; i > -1 ; i--) ++ { ++ ret = (ret << 1) | gpio_get_value(gpio[i]); ++ } ++ ++ return ret; ++} ++ ++static void bl_gpio_set(struct bmi_slot* slot, int mask) ++{ ++ int i; ++ unsigned char *gpio = (unsigned char*) slot->slot_data; ++ ++ for (i = 0; i < 4 ; i++) ++ { ++ if ((mask >> i) & 0x1) ++ gpio_set_value(gpio[i], 1); ++ else ++ gpio_set_value(gpio[i], 0); ++ } ++ return; ++} ++ ++static void bl_uart_enable(struct bmi_slot* slot) ++{ ++ return; ++} ++ ++static void bl_uart_disable(struct bmi_slot* slot) ++{ ++ return; ++} ++ ++static void bl_spi_enable(struct bmi_slot* slot) ++{ ++ return; ++} ++ ++static void bl_spi_disable(struct bmi_slot* slot) ++{ ++ return; ++} ++ ++static void bl_audio_enable(struct bmi_slot* slot) ++{ ++ return; ++} ++ ++static void bl_audio_disable(struct bmi_slot* slot) ++{ ++ return; ++} ++ ++static void bl_batt_enable(struct bmi_slot* slot) ++{ ++ return; ++} ++ ++static void bl_batt_disable(struct bmi_slot* slot) ++{ ++ return; ++} ++ ++ ++struct slot_actions bl_actions = { ++ .present = bl_present, ++ .power_on = bl_power_on, ++ .power_off = bl_power_off, ++ .gpio_config = bl_gpio_config, ++ .gpio_get = bl_gpio_get, ++ .gpio_set = bl_gpio_set, ++ .uart_enable = bl_uart_enable, ++ .uart_disable = bl_uart_disable, ++ .spi_enable = bl_spi_enable, ++ .spi_disable = bl_spi_disable, ++ .audio_enable = bl_audio_enable, ++ .audio_disable = bl_audio_disable, ++ .batt_enable = bl_batt_enable, ++ .batt_disable = bl_batt_disable, ++}; ++ ++static int omapbmi_slot_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ return 0; ++} ++ ++static int omapbmi_slot_resume(struct platform_device *pdev) ++{ ++ return 0; ++} ++ ++static int omapbmi_slot_probe(struct platform_device *pdev) ++{ ++ struct bmi_slot *slot; ++ struct resource *irq_pres, *irq_stat; ++ // struct omap_bmi_platform_data *bmi_plat_data = pdev->dev.platform_data; ++ int ret = 0; ++ unsigned char* gpio; ++ ++ printk(KERN_INFO "Buglabs BeagleBUG Slots Driver...\n"); ++ irq_pres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); ++ if (!irq_pres) { ++ dev_err(&pdev->dev, "No presence irq resource...\n"); ++ return -ENODEV; ++ } ++ irq_stat = platform_get_resource(pdev, IORESOURCE_IRQ, 1); ++ if (!irq_stat) { ++ dev_err(&pdev->dev, "No status irq resource...\n"); ++ return -ENODEV; ++ } ++ ++ slot = kzalloc(sizeof(struct bmi_slot), GFP_KERNEL); ++ if (!slot) { ++ ret = -ENOMEM; ++ goto err_release; ++ } ++ ++ ret = gpio_request(irq_stat->start, "BMI SINT"); ++ if (ret) { ++ printk(KERN_ERR "slots_beagle: GPIO %d request failed...\n",irq_stat->start); ++ goto err_release; ++ } ++ ret = gpio_request(irq_pres->start, "BMI PINT"); ++ if (ret) { ++ printk(KERN_ERR "slots_beagle: GPIO %d request failed...\n",irq_pres->start); ++ goto err_release; ++ } ++ ++ ret = gpio_direction_input(irq_pres->start); ++ ++ gpio = kmalloc(4, GFP_KERNEL); ++ gpio_request(139,"BMI_0"); ++ gpio_request(158,"BMI_1"); ++ gpio_request(137,"BMI_2"); ++ gpio_request(136,"BMI_3"); ++ ++ gpio[0] = 139; ++ gpio[1] = 158; ++ gpio[2] = 137; ++ gpio[3] = 136; ++ ++ slot->slot_data = (void*)gpio; ++ slot->present_irq = gpio_to_irq(irq_pres->start); ++ slot->status_irq = gpio_to_irq(irq_stat->start); ++ slot->owner = THIS_MODULE; ++ slot->name = "omap_bug_slot"; ++ slot->slotdev.parent = &pdev->dev; ++ slot->adap = i2c_get_adapter(3); ++ slot->actions = &bl_actions; ++ slot->spi_bus_num = 3; ++ slot->spi_cs = 0; ++ ++ ++ ret = bmi_add_slot(slot); ++ if (ret) { ++ printk(KERN_ERR "slots_beagle: Trouble instantiating slot...%d\n", ret); ++ goto err_release; ++ } ++ return 0; ++ err_release: ++ kfree(slot->slot_data); ++ kfree(slot); ++ return ret; ++} ++ ++static int omapbmi_slot_remove(struct platform_device *pdev) ++{ ++ struct bmi_slot *slot = platform_get_drvdata(pdev); ++ //int id = pdev->id; ++ ++ bmi_del_slot(slot); ++ platform_set_drvdata(pdev, NULL); ++ kfree(slot->slot_data); ++ kfree(slot); ++ return 0; ++} ++ ++ ++static struct platform_driver omapbmi_slot_driver = { ++ .driver = { ++ .name = "omap_bmi_slot", ++ .owner = THIS_MODULE, ++ }, ++ .probe = omapbmi_slot_probe, ++ .remove = omapbmi_slot_remove, ++ .suspend = omapbmi_slot_suspend, ++ .resume = omapbmi_slot_resume, ++}; ++ ++static int __init omap_bmi_slot_init(void) ++{ ++ /* Register the device driver structure. */ ++ return platform_driver_register(&omapbmi_slot_driver); ++} ++ ++/*! ++ * This function is used to cleanup all resources before the driver exits. ++ */ ++static void __exit omap_bmi_slot_exit(void) ++{ ++ platform_driver_unregister(&omapbmi_slot_driver); ++} ++ ++module_init(omap_bmi_slot_init); ++module_exit(omap_bmi_slot_exit); ++ ++MODULE_AUTHOR("Matt Isaacs"); ++MODULE_DESCRIPTION("OMAP BMI Slot Driver"); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ git/drivers/bmi/slots/slots_bug.c +@@ -0,0 +1,231 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++//#include ++#include ++ ++static int bl_present(struct bmi_slot* slot) ++{ ++ int status; ++ ++ status = cpld_read_module_present_status(slot->slotnum); ++ if (status & 0x04) ++ return 1; ++ else ++ return 0; ++} ++ ++static void bl_power_on(struct bmi_slot* slot) ++{ ++ //gpio_power_on_slot (slot->slotnum); ++ return; ++} ++ ++static void bl_power_off(struct bmi_slot* slot) ++{ ++ //gpio_power_off_slot (slot->slotnum); ++ return; ++} ++ ++static void bl_gpio_config(struct bmi_slot* slot, int mask) /*Configure gpios as inputs/ouputs*/ ++{ ++ int i; ++ for (i = 0; i < 4; i++) { ++ cpld_set_module_gpio_dir(slot->slotnum, i, (mask & 0x1)); ++ mask = mask >> 1; ++ } ++ return; ++} ++ ++static int bl_gpio_get(struct bmi_slot* slot) ++{ ++ return cpld_read_gpio_data_reg(slot->slotnum); ++} ++ ++static void bl_gpio_set(struct bmi_slot* slot, int mask) ++{ ++ int i; ++ for (i = 0; i < 4; i++) { ++ cpld_set_module_gpio_data(slot->slotnum, i, (mask & 0x1)); ++ mask = mask >> 1; ++ } ++ return; ++} ++ ++static void bl_uart_enable(struct bmi_slot* slot) ++{ ++ cpld_uart_active(slot->slotnum); ++ return; ++} ++ ++static void bl_uart_disable(struct bmi_slot* slot) ++{ ++ cpld_uart_inactive(slot->slotnum); ++ return; ++} ++ ++static void bl_spi_enable(struct bmi_slot* slot) ++{ ++ //REVIST: ++ cpld_spi_active(0); ++ return; ++} ++ ++static void bl_spi_disable(struct bmi_slot* slot) ++{ ++ //REVIST: ++ cpld_spi_inactive(0); ++ return; ++} ++ ++static void bl_audio_enable(struct bmi_slot* slot) ++{ ++ cpld_activate_audio_ports(); ++ return; ++} ++ ++static void bl_audio_disable(struct bmi_slot* slot) ++{ ++ cpld_inactivate_audio_ports(); ++ return; ++} ++ ++static void bl_batt_enable(struct bmi_slot* slot) ++{ ++ cpld_set_module_battery_enable(slot->slotnum); ++ return; ++} ++ ++static void bl_batt_disable(struct bmi_slot* slot) ++{ ++ cpld_set_module_battery_disable(slot->slotnum); ++ return; ++} ++ ++/* ++static int mxcbmi_probe(struct platform_device *pdev); ++static int mxcbmi_slot_remove(struct platform_device *pdev); ++static int mxcbmi_suspend(struct platform_device *pdev, pm_message_t state); ++static int mxcbmi_resume(struct platform_device *pdev); ++*/ ++ ++struct slot_actions bl_actions = { ++ .present = bl_present, ++ .power_on = bl_power_on, ++ .power_off = bl_power_off, ++ .gpio_config = bl_gpio_config, ++ .gpio_get = bl_gpio_get, ++ .gpio_set = bl_gpio_set, ++ .uart_enable = bl_uart_enable, ++ .uart_disable = bl_uart_disable, ++ .spi_enable = bl_spi_enable, ++ .spi_disable = bl_spi_disable, ++ .audio_enable = bl_audio_enable, ++ .audio_disable = bl_audio_disable, ++ .batt_enable = bl_batt_enable, ++ .batt_disable = bl_batt_disable, ++}; ++ ++static int mxcbmi_slot_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ return 0; ++} ++ ++static int mxcbmi_slot_resume(struct platform_device *pdev) ++{ ++ return 0; ++} ++ ++static int mxcbmi_slot_probe(struct platform_device *pdev) ++{ ++ struct bmi_slot *slot; ++ struct resource *res, *irq_pres, *irq_stat; ++ struct mxc_bmi_platform_data *bmi_plat_data = pdev->dev.platform_data; ++ int ret = 0; ++ ++ printk(KERN_INFO "Buglabs BUGBase Slots Driver...\n"); ++ irq_pres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); ++ if (!irq_pres) { ++ dev_err(&pdev->dev, "No presence irq resource...\n"); ++ return -ENODEV; ++ } ++ irq_stat = platform_get_resource(pdev, IORESOURCE_IRQ, 1); ++ if (!irq_stat) { ++ dev_err(&pdev->dev, "No status irq resource...\n"); ++ return -ENODEV; ++ } ++ ++ slot = kzalloc(sizeof(struct bmi_slot), GFP_KERNEL); ++ if (!slot) { ++ ret = -ENOMEM; ++ goto err_release; ++ } ++ ++ ++ slot->present_irq = irq_pres->start; ++ slot->status_irq = irq_stat->start; ++ slot->owner = THIS_MODULE; ++ slot->name = "mxc_bug_slot"; ++ slot->slotdev.parent = &pdev->dev; ++ slot->adap = i2c_get_adapter(2 + pdev->id); ++ slot->actions = &bl_actions; ++ slot->spi_bus_num = 1; ++ slot->spi_cs = pdev->id; ++ ret = bmi_add_slot(slot); ++ if (ret) { ++ printk(KERN_ERR "slots_bug: Trouble instantiating slot...%d\n", ret); ++ goto err_release; ++ } ++ ret = 0; ++ err_release: ++ return ret; ++} ++ ++static int mxcbmi_slot_remove(struct platform_device *pdev) ++{ ++ struct bmi_slot *slot = platform_get_drvdata(pdev); ++ //int id = pdev->id; ++ ++ bmi_del_slot(slot); ++ platform_set_drvdata(pdev, NULL); ++ kfree(slot); ++ return 0; ++} ++ ++ ++static struct platform_driver mxcbmi_slot_driver = { ++ .driver = { ++ .name = "mxc_bmi_slot", ++ .owner = THIS_MODULE, ++ }, ++ .probe = mxcbmi_slot_probe, ++ .remove = mxcbmi_slot_remove, ++ .suspend = mxcbmi_slot_suspend, ++ .resume = mxcbmi_slot_resume, ++}; ++ ++static int __init mxc_bmi_slot_init(void) ++{ ++ /* Register the device driver structure. */ ++ return platform_driver_register(&mxcbmi_slot_driver); ++} ++ ++/*! ++ * This function is used to cleanup all resources before the driver exits. ++ */ ++static void __exit mxc_bmi_slot_exit(void) ++{ ++ platform_driver_unregister(&mxcbmi_slot_driver); ++} ++ ++module_init(mxc_bmi_slot_init); ++module_exit(mxc_bmi_slot_exit); ++ ++MODULE_AUTHOR("Matt Isaacs"); ++MODULE_DESCRIPTION("MXC BMI Slot Driver"); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ git/include/linux/bmi-ids.h +@@ -0,0 +1,30 @@ ++/* ++ * BMI Vendor and Product IDs ++ * ++ * Please keep sorted. ++ */ ++ ++/* BMI vendors */ ++ ++#define BMI_VENDOR_ILLEGAL_0 0x0 ++#define BMI_VENDOR_BUG_LABS 0x1 ++#define BMI_VENDOR_ILLEGAL_F 0xFFFF ++ ++ ++/* BMI products */ ++ ++#define BMI_PRODUCT_ILLEGAL_0 0x0000 ++#define BMI_PRODUCT_GPS_J32 0x0001 ++#define BMI_PRODUCT_MOT_ACCEL 0x0002 ++#define BMI_PRODUCT_LCD_SHARP_320X240 0x0003 ++#define BMI_PRODUCT_CAMERA_VS6624 0x0004 ++#define BMI_PRODUCT_CAMERA_OV2640 0x0005 ++#define BMI_PRODUCT_FACTORY_TEST 0x0006 ++#define BMI_PRODUCT_VON_HIPPEL 0x0007 ++#define BMI_PRODUCT_WIFI 0x0008 ++#define BMI_PRODUCT_ZIGBEE 0x0009 ++#define BMI_PRODUCT_AUDIO 0x000A ++#define BMI_PRODUCT_GSM 0x000B ++#define BMI_PRODUCT_PROJECTOR 0x000C ++#define BMI_PRODUCT_ILLEGAL_F 0xFFFF ++ +--- /dev/null ++++ git/include/linux/bmi.h +@@ -0,0 +1,142 @@ ++#ifndef __LINUX_BMI_H ++#define __LINUX_BMI_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++/* BMI bus device table constants */ ++#define BMI_ANY 0x0 ++ ++#define RED_LED 8 ++#define GREEN_LED 4 ++#define GPIO_1 2 ++#define GPIO_0 1 ++ ++struct bmi_slot; ++ ++struct slot_actions { ++ int (*present)(struct bmi_slot*); ++ void (*power_on)(struct bmi_slot*); ++ void (*power_off)(struct bmi_slot*); ++ void (*gpio_config)(struct bmi_slot*, int mask); /*Configure gpios as inputs/ouputs*/ ++ int (*gpio_get)(struct bmi_slot*); ++ void (*gpio_set)(struct bmi_slot*, int mask); ++ void (*uart_enable)(struct bmi_slot*); ++ void (*uart_disable)(struct bmi_slot*); ++ void (*spi_enable)(struct bmi_slot*); ++ void (*spi_disable)(struct bmi_slot*); ++ void (*audio_enable)(struct bmi_slot*); ++ void (*audio_disable)(struct bmi_slot*); ++ void (*batt_enable)(struct bmi_slot*); ++ void (*batt_disable)(struct bmi_slot*); ++}; ++ ++struct bmi_slot { ++ int slotnum; ++ char* name; ++ struct bmi_device *bdev; ++ struct module *owner; ++ struct device slotdev; ++ struct kref kref; ++ struct mutex pres_mutex; ++ struct list_head event_list; ++ unsigned int event_bits[1]; ++ ++ int present; ++ struct i2c_adapter *adap; ++ struct i2c_client *eeprom; ++ ++ ++ // struct spi_device spi; ++ int spi_bus_num; ++ int spi_cs; ++ ++ int present_irq; ++ int status_irq; ++ struct delayed_work work; ++ struct slot_actions* actions; ++ ++ void* slot_data; ++ ++}; ++ ++ ++/* BMI Device */ ++ ++struct bmi_device { ++ int devnum; ++ ++ struct device dev; ++ ++ struct mutex lock; ++ ++ ++ int present_irq_cnt; ++ int state; /* Make this an enum */ ++ ++ struct bmi_slot *slot; ++ ++ struct bmi_eeprom_data ident; ++ unsigned short vendor; ++ unsigned short product; ++ unsigned short revision; ++ ++ struct bmi_driver *driver; /* which driver has allocated this device */ ++ ++}; ++ ++#define to_bmi_device(n) container_of(n, struct bmi_device, dev); ++#define work_to_slot(w) container_of(container_of(w, \ ++ struct delayed_work, \ ++ work), \ ++ struct bmi_slot, \ ++ work) ++ ++ ++static inline void *bmi_device_get_drvdata (struct bmi_device *bdev) ++{ ++ return dev_get_drvdata (&bdev->dev); ++} ++ ++static inline void bmi_device_set_drvdata (struct bmi_device *bdev, void *data) ++{ ++ dev_set_drvdata(&bdev->dev, data); ++} ++ ++ ++/* BMI Driver */ ++ ++struct bmi_driver { ++ ++ char *name; ++ struct bmi_device_id *id_table; ++ struct device_driver driver; ++ int (*probe)(struct bmi_device *dev); ++ void (*remove)(struct bmi_device *dev); ++}; ++ ++extern struct bus_type bmi_bus_type; ++ ++#define to_bmi_driver(drv) container_of(drv,struct bmi_driver, driver) ++ ++int __must_check __bmi_register_driver(struct bmi_driver *, struct module *); ++static inline int __must_check bmi_register_driver(struct bmi_driver *driver) ++{ ++ return __bmi_register_driver(driver, THIS_MODULE); ++} ++ ++void bmi_unregister_driver(struct bmi_driver *drv); ++ ++struct bmi_device *bmi_alloc_dev(struct bmi_slot *slot); ++struct class* bmi_get_class (void); ++int bmi_add_slot(struct bmi_slot *slot); ++int bmi_del_slot(struct bmi_slot *slot); ++ ++#endif +--- /dev/null ++++ git/include/linux/bmi/at24c02.h +@@ -0,0 +1,26 @@ ++#include ++#include ++ ++/*-------------------------------- ++ * ++ * AT24C02 I2C Eeprom Device ++ * ++ *-------------------------------- ++ */ ++ ++ ++struct at24c02 { ++ ++ unsigned char addr; ++ struct i2c_adapter *adap; ++}; ++ ++void at24c02_init (struct at24c02 *dev, u8 addr, struct i2c_adapter *adap); ++ ++int at24c02_read_byte ( struct at24c02 *dev, u8 offset, u8 *data); ++int at24c02_write_byte ( struct at24c02 *dev, u8 offset, u8 data); ++int at24c02_read ( struct at24c02 *dev, u8 offset, u8 *data, int size); ++int at24c02_write_page ( struct at24c02 *dev, u8 offset, u8 *data, int size); ++ ++ ++ +--- /dev/null ++++ git/include/linux/bmi/bmi-bus.h +@@ -0,0 +1,21 @@ ++#ifndef BMI_BUS_H ++#define BMI_BUS_H ++ ++#include ++ ++#define BMI_MAX_SLOTS 1 ++ ++struct bmi_bus { ++ ++ struct bmi_device slot[BMI_MAX_SLOTS]; ++}; ++ ++ ++ ++extern struct bus_type bmi_bus_type; ++ ++struct bmi_device* bmi_get_bmi_device (int slot_num); ++ ++ ++#endif /* BMI_BUS_H */ ++ +--- /dev/null ++++ git/include/linux/bmi/bmi-control.h +@@ -0,0 +1,303 @@ ++/* ++ * Copyright 2007 EnCADIS Design, Inc. All Rights Reserved. ++ * Copyright 2007 Bug-Labs, Inc. All Rights Reserved. ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++#ifndef _BMI_CONTROL_H ++#define _BMI_CONTROL_H ++ ++#define BMI_M1 (0x0) ++#define BMI_M2 (0x1) ++#define BMI_M3 (0x2) ++#define BMI_M4 (0x3) ++#define BMI_GPIO_IN (0x0) ++#define BMI_GPIO_OUT (0x1) ++#define BMI_GPIO_ON (0x1) ++#define BMI_GPIO_OFF (0x0) ++ ++/*! ++ * This function configures the UART function for the IOMUX pins. ++ * ++ * @param port a UART port number (0-5) ++ * @param no_irda configure UART port for IRDA ++ */ ++void bmi_gpio_uart_active(int port, int no_irda); ++ ++/*! ++ * This function configures the UART function in the BMI. ++ * ++ * @param port a UART port number (0-5) ++ */ ++void bmi_uart_active(int port); ++ ++/*! ++ * This function configures the UART function in the BMI. ++ * ++ * @param port a UART port number (0-5) ++ */ ++void bmi_uart_inactive(int port); ++ ++/*! ++ * Setup GPIO for a CSPI device to be active ++ * ++ * @param cspi_mod an CSPI device ++ */ ++void bmi_gpio_spi_active(int cspi_mod); ++ ++/*! ++ * Setup BMI for a CSPI device to be active ++ * ++ * @param cspi_mod an CSPI device ++ */ ++void bmi_spi_active(int cspi_mod); ++ ++/*! ++ * Setup BMI for a CSPI device to be inactive ++ * ++ * @param cspi_mod an CSPI device ++ */ ++void bmi_spi_inactive(int cspi_mod); ++ ++/*! ++ * Setup GPIO for an I2C device to be active ++ * ++ * @param i2c_num an I2C device ++ */ ++void bmi_gpio_i2c_active(int i2c_num); ++ ++/*! ++ * Setup BMI for an I2C device to be active ++ */ ++void bmi_i2c_active(void); ++ ++/*! ++ * Setup BMI for an I2C device to be inactive ++ */ ++void bmi_i2c_inactive(void); ++ ++/* ++ * Setup GPIO for an I2S device to be active ++ */ ++void bmi_gpio_activate_audio_ports(void); ++ ++/*! ++ * Setup CPLD for an I2S device to be active ++ */ ++void bmi_activate_audio_ports(void); ++ ++/*! ++ * Setup CPLD for an I2S device to be inactive ++ */ ++void bmi_inactivate_audio_ports(void); ++ ++/*! ++ * Setup GPIO for the plug-in module LCD interface to be active ++ */ ++void bmi_gpio_lcd_active(void); ++ ++/*! ++ * Setup BMI for plug-in module LCD to be active ++ * ++ * @param port LCD serializer (0 or 1) ++ * @param pllc LCD serializer PLL divisor (0-7) ++ * @param mode LCD serializer bus mode (LCD_MODE_I80 or LCD_MODE_M68) ++ * ++ */ ++void bmi_lcd_active(int port, int pllc, int mode); ++ ++/*! ++ * Setup BMI for plug-in module LCD chip select to be active ++ * ++ * @param cs LCD chip select (LCD_MxCS x = 1,2,3,4) ++ * ++ */ ++void bmi_lcd_cs_active(int cs); ++ ++/*! ++ * Setup BMI for plug-in module LCD to be inactive ++ * ++ * @param port LCD serializer (0 or 1) ++ * ++ */ ++void bmi_lcd_inactive(int port); ++ ++/*! ++ * Setup BMI for plug-in module LCD chip select to be inactive ++ * ++ * @param cs LCD chip select (LCD_MxCS x = 1,2,3,4) ++ * ++ */ ++void bmi_lcd_cs_inactive(int cs); ++ ++/*! ++ * Setup pins for SLCD to be active ++ * ++ */ ++void bmi_slcd_gpio_config(void); ++ ++/*! ++ * Setup GPIO for sensor to be active ++ * ++ */ ++void bmi_gpio_sensor_active(void); ++ ++/*! ++ * Setup BMI for sensor to be active ++ * ++ * @param rclk_r pixclk edge (CAM_CLK_RISE or CAM_CLK_FALL) ++ */ ++void bmi_sensor_active(int rclk_r); ++ ++/*! ++ * Setup BMI for sensor to be inactive ++ */ ++void bmi_sensor_inactive(void); ++ ++/*! ++ * read BMI for sensor lock status ++ * ++ * @return camera serializer lock status (1 == locked) ++ */ ++int bmi_sensor_lock_status(void); ++ ++/* ++ * USB Host 2 GPIO config ++ * ++ * @return 0 ++ */ ++int bmi_gpio_usbh2_active(void); ++ ++/* ++ * USB Host 2 BMI config ++ * ++ * @param mtt - number of MTT's enabled in hub (USB_HUB_1_MTT or USB_HUB_4_MTT) ++ */ ++void bmi_usbh2_active(int mtt); ++ ++/* ++ * USB Host 2 BMI config inactive ++ */ ++void bmi_usbh2_inactive(void); ++ ++/* ++ * configure BMI Module GPIO direction ++ * ++ * @param module plug-in module (BMI, x= 1,2,3,4) ++ * @param bit GPIO bit (0-3) ++ * @param dir GPIO bit (BMI_GPIO_IN or BMI_GPIO_OUT) ++ */ ++void bmi_set_module_gpio_dir(int module, int bit, int dir); ++ ++/* ++ * read BMI GPIO Direction register ++ * ++ * @param module plug-in module (BMI_Mx, x= 1,2,3,4) ++ * @return module GPIO direction (4 LSB) ++ */ ++int bmi_read_gpio_direction_reg(int module); ++ ++/* ++ * set BMI Module GPIO data ++ * ++ * @param module plug-in module (BMI_Mx, x= 1,2,3,4) ++ * @param bit GPIO bit (0-3) ++ * @param value GPIO bit (0x0 or 0x1) ++ */ ++void bmi_set_module_gpio_data(int module, int bit, int value); ++ ++/* ++ * read BMI GPIO Data register ++ * ++ * @param module plug-in module (BMI_Mx, x= 1,2,3,4) ++ * @return module GPIO data (4 LSB) ++ */ ++int bmi_read_gpio_data_reg(int module); ++ ++/* ++ * set BMI Module battery enable ++ * ++ * @param module plug-in module (BMI_Mx, x= 1,2,3,4) ++ */ ++void bmi_set_module_battery_enable(int module); ++ ++/* ++ * set BMI Module battery disable ++ * ++ * @param module plug-in module (BMI_Mx, x= 1,2,3,4) ++ */ ++void bmi_set_module_battery_disable(int module); ++ ++/* ++ * read BMI module battery status ++ * ++ * @param module plug-in module (BMI_Mx, x= 1,2,3,4) ++ * @return state of module battery status bit ++ */ ++int bmi_read_module_battery_status(int module); ++ ++/* ++ * set BMI interrupt enable ++ * ++ * @param interrupt interrupt (INT_BUGRTC .. INT_M4_PRES) (defined in mx31bug.h) ++ */ ++void bmi_interrupt_enable(int interrupt); ++ ++/* ++ * set BMI interrupt disable ++ * ++ * @param interrupt interrupt (INT_BUGRTC .. INT_M4_PRES) (defined in mx31bug.h) ++ */ ++void bmi_interrupt_disable(int interrupt); ++ ++/* ++ * get BMI interrupt status ++ * ++ * @param interrupt interrupt (INT_BUGRTC .. INT_M4_PRES) (defined in mx31bug.h) ++ * @return 1 if set, 0 otherwise ++ */ ++int bmi_interrupt_status(int interrupt); ++ ++/* ++ * clear BMI module present interrupt bit ++ * ++ * @param module plug-in module (BMI_Mx, x= 1,2,3,4) ++ */ ++void bmi_clear_module_present_interrupt(int module); ++ ++/* ++ * enable I2C switches in BMI ++ */ ++void bmi_i2c_sw_enable(void); ++ ++/* ++ * disable I2C switches in BMI ++ */ ++void bmi_i2c_sw_disable(void); ++ ++/* ++ * read BMI module present status ++ * ++ * @param module plug-in module (BMI_Mx, x= 1,2,3,4) ++ * @return module present status (3 LSB = (OUT, IN, STATE_CHANGED)) ++ */ ++int bmi_read_module_present_status(int module); ++ ++/* ++ * BMI module present ++ * ++ * @param module plug-in module (BMI_Mx, x= 1,2,3,4) ++ * @return module present (1 = present, 0 = not present ) ++ */ ++int bmi_module_present (struct bmi_device *bdev); ++ ++ ++#endif // _BMI_CONTROL_H ++ +--- /dev/null ++++ git/include/linux/bmi/bmi-eeprom-data.h +@@ -0,0 +1,83 @@ ++#ifndef BMI_EEPROM_DATA_H ++#define BMI_EEPROM_DATA_H ++ ++#include ++ ++union _bmi_vendor { ++ __u16 vendor; ++ __u8 vendor_msb; ++ __u8 vendor_lsb; ++}; ++ ++union _bmi_product { ++ __u16 product; ++ __u8 product_msb; ++ __u8 product_lsb; ++}; ++ ++union _bmi_revision { ++ __u16 revision; ++ __u8 revision_msb; ++ __u8 revision_lsb; ++}; ++ ++struct bmi_eeprom_raw ++{ ++ __u8 format; /* byte 0x00 */ ++ __u8 vendor_msb; /* byte 0x01 */ ++ __u8 vendor_lsb; /* byte 0x02 */ ++ __u8 product_msb; /* byte 0x03 */ ++ __u8 product_lsb; /* byte 0x04 */ ++ __u8 revision_msb; /* byte 0x05 */ ++ __u8 revision_lsb; /* byte 0x06 */ ++ __u8 bus_usage; /* byte 0x07 */ ++ __u8 gpio_usage; /* byte 0x08 */ ++ __u8 power_use; /* byte 0x09 */ ++ __u8 power_charging; /* byte 0x0A */ ++ __u8 memory_size_msb; /* byte 0x0B */ ++ __u8 memory_size_lsb; /* byte 0x0C */ ++ __u8 serial_num_loc; /* byte 0x0D */ ++ __u8 serial_num_year; /* byte 0x0E */ ++ __u8 serial_num_week; /* byte 0x0F */ ++ __u8 serial_num_seq_msb; /* byte 0x10 */ ++ __u8 serial_num_seq_mid; /* byte 0x11 */ ++ __u8 serial_num_seq_lsb; /* byte 0x12 */ ++ __s8 description[108]; /* byte 0x13-0x7E */ ++ __u8 checksum; /* byte 0x7F */ ++}; ++ ++ ++#ifdef __KERNEL__ ++ ++struct bmi_eeprom_id ++{ ++ __u16 vendor; ++ __u16 product; ++ __u16 revision; ++}; ++ ++ ++enum { ++ BMI_EPSTATE_UNKNOWN = 0, ++ BMI_EPSTATE_I2C_READ_ERROR, ++ BMI_EPSTATE_CHECKSUM_ERROR, ++ BMI_EPSTATE_VALID, ++}; ++ ++extern void bmi_eeprom_get_id (struct bmi_eeprom_raw *raw, struct bmi_eeprom_id *epid); ++extern int bmi_eeprom_checksum_validate ( struct bmi_eeprom_raw *raw ); ++#endif /* __KERNEL__ */ ++ ++static inline __u8 bmi_eeprom_checksum ( struct bmi_eeprom_raw *raw ) ++{ ++ int i; ++ __u8 sum = 0; ++ __u8 *buf = (__u8*)raw; ++ ++ for (i = 0; i < (sizeof (struct bmi_eeprom_raw) - 1); i++) { ++ sum ^= *buf++; ++ } ++ return sum; ++} ++ ++#endif /* BMI_EEPROM_DATA_H */ +--- /dev/null ++++ git/include/linux/bmi/bmi-eeprom-driver.h +@@ -0,0 +1,113 @@ ++#ifndef BMI_EEPROM_DRIVER_H ++#define BMI_EEPROM_DRIVER_H ++ ++/******************************************************************************* ++ * Driver description: ++ * ++ * This driver provides operations that allow an application program to ++ * read and write the inventory eeprom on Bug Labs Bug PlugIn peripheral ++ * hardware modules. ++ * ++ * This driver is a character driver. ++ * ++ * Supported system calls ++ * ++ * This driver supports the following system calls: ++ * ++ * open() ++ * ++ * During the open() call, only driver initialization and house keeping ++ * are performed. The hardware is not touched. ++ * ++ * close() ++ * ++ * During the close() system call, only driver house keeping is performed. ++ * The hardware is not touched. ++ * ++ * ioctl() ++ * ++ * All of the ioctl() calls for this driver take 2 or 3 parameters. ++ * They are: ++ * file descriptor - obtained from open() call. ++ * ioctl command number - described below. ++ * void pointer to struct - ioctl command specific. ++ ++ * ioctl() return values: ++ * ++ * On success, all ioctl() calls return zero. ++ * ++ * On error, all ioctl() calls return -1 and errno is set appropriatly. ++ * Additional error information may be returned in the ioctl command ++ * structure. See the ioctl command structure declarations for more ++ * information. ++ * ++ ******************************************************************************* ++ */ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ ++/* ++ * Include the standard type definitions. ++ * The file to include depends on whether or not we are doing a kernel or ++ * application build. ++ */ ++#ifdef __KERNEL__ ++ #include ++#else ++ #include ++ #include ++#endif /* __KERNEL__ */ ++ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++//REWORK: Add documentation. ++ ++//REWORK: Where should this file live so that applications can #include it ? ++ ++ ++/* bmi_eeprom_request ++ ++ offset: 0 - 255 ++ size: 1- 256 ++ offset + size must be <= 256 ++ ++ */ ++struct bmi_eeprom_request { ++ int return_code; ++ int xfer_count; ++ int size; ++ int offset; ++ __u8 data[256]; ++}; ++ ++ ++/******************************************************************************* ++ * Ioctl type definition: ++ * ++ * The ioctl type (magic) number for this driver is BUG_EEPROM_IOC_TYPE ++ * ++ ******************************************************************************* ++ */ ++ ++#define BUG_EEPROM_IOC_TYPE 0xFE ++ ++/******************************************************************************* ++ * Ioctl command definitions: ++ * ++ * The ioctl calls supported by this driver are: ++ * ++ ******************************************************************************* ++ */ ++ ++#define BUG_EEPROM_READ \ ++ _IOR (BUG_EEPROM_IOC_TYPE, 0, struct bmi_eeprom_request) ++ ++#define BUG_EEPROM_WRITE \ ++ _IOW (BUG_EEPROM_IOC_TYPE, 0, struct bmi_eeprom_request) ++ ++#endif +--- /dev/null ++++ git/include/linux/bmi/bmi-eeprom.h +@@ -0,0 +1,75 @@ ++#ifndef BMI_EEPROM_H ++#define BMI_EEPROM_H ++ ++#include ++ ++union _bmi_vendor { ++ __u16 vendor; ++ __u8 vendor_msb; ++ __u8 vendor_lsb; ++}; ++ ++union _bmi_product { ++ __u16 product; ++ __u8 product_msb; ++ __u8 product_lsb; ++}; ++ ++union _bmi_revision { ++ __u16 revision; ++ __u8 revision_msb; ++ __u8 revision_lsb; ++}; ++ ++struct bmi_eeprom_data ++{ ++ __u8 format; /* byte 0x00 */ ++ __u8 vendor_msb; /* byte 0x01 */ ++ __u8 vendor_lsb; /* byte 0x02 */ ++ __u8 product_msb; /* byte 0x03 */ ++ __u8 product_lsb; /* byte 0x04 */ ++ __u8 revision_msb; /* byte 0x05 */ ++ __u8 revision_lsb; /* byte 0x06 */ ++/* __u16 vendor; */ ++/* __u16 product; */ ++/* __u16 revision; */ ++ __u8 bus_usage; /* byte 0x07 */ ++ __u8 gpio_usage; /* byte 0x08 */ ++ __u8 power_use; /* byte 0x09 */ ++ __u8 power_charging; /* byte 0x0A */ ++ __u8 memory_size_msb; /* byte 0x0B */ ++ __u8 memory_size_lsb; /* byte 0x0C */ ++ __u8 serial_num_loc; /* byte 0x0D */ ++ __u8 serial_num_year; /* byte 0x0E */ ++ __u8 serial_num_week; /* byte 0x0F */ ++ __u8 serial_num_seq_msb; /* byte 0x10 */ ++ __u8 serial_num_seq_mid; /* byte 0x11 */ ++ __u8 serial_num_seq_lsb; /* byte 0x12 */ ++ __s8 description[108]; /* byte 0x13-0x7E */ ++ __u8 checksum; /* byte 0x7F */ ++}; ++ ++ ++struct bmi_eeprom_id ++{ ++ __u16 vendor; ++ __u16 product; ++ __u16 revision; ++}; ++ ++ ++enum { ++ BMI_EPSTATE_UNKNOWN = 0, ++ BMI_EPSTATE_I2C_READ_ERROR, ++ BMI_EPSTATE_CHECKSUM_ERROR, ++ BMI_EPSTATE_VALID, ++}; ++ ++ ++//__u8 bmi_eeprom_checksum ( struct bmi_eeprom_data *raw ); ++int bmi_eeprom_checksum_validate ( struct bmi_eeprom_data *raw ); ++//extern void bmi_eeprom_get_id (struct bmi_eeprom_data *raw, struct bmi_eeprom_id *epid); ++//extern int bmi_eeprom_checksum_validate ( struct bmi_eeprom_data *raw ); ++ ++ ++#endif /* BMI_EEPROM_H */ +--- /dev/null ++++ git/include/linux/bmi/bmi-slot.h +@@ -0,0 +1,29 @@ ++#ifndef BMI_SLOT_H ++#define BMI_SLOT_H ++ ++//void bmi_slot_resrc_init(void); ++ ++void bmi_slot_power_on (int num); ++void bmi_slot_power_off (int num); ++ ++void bmi_slot_gpio_configure (int num, int gpio); ++int bmi_slot_gpio_get (int num); ++ ++void bmi_slot_gpio_set (int num, int data); ++void bmi_slot_uart_enable (int num); ++void bmi_slot_uart_disable (int num); ++ ++void bmi_slot_spi_enable (int num); ++void bmi_slot_spi_disable (int num); ++ ++void bmi_slot_audio_enable (int num); ++void bmi_slot_audio_disable (int num); ++ ++void bmi_slot_battery_enable (int num); ++void bmi_slot_battery_disable (int num); ++ ++int bmi_slot_module_present (int num); ++//int bmi_slot_status_irq_state (int num); ++ ++ ++#endif +--- /dev/null ++++ git/include/linux/bmi/bmi_audio.h +@@ -0,0 +1,449 @@ ++/* ++ * File: include/linux/bmi/bmi_audio.h ++ * Author: Peter Giacomini ++ * ++ * This is the application header file for the BMI bus audio plug-in ++ * module on the MX31 BUG platform. ++ */ ++ ++#ifndef BMI_AUDIO_H ++#define BMI_AUDIO_H ++ ++#include ++ ++// GPIO defines ++typedef enum { ++ GPIO_SPARE, // unused ++ GPIO_RESET, // CODEC reset ++ GPIO_GREEN, // green LED ++ GPIO_RED, // red LED ++} BMI_AUDIO_GPIO; ++ ++// GETSTAT defines ++typedef enum { ++ GETSTAT_AMP = 0x001, // IOX bit 0 - amplifier off (O - low active) ++ GETSTAT_ISPARE = 0x002, // IOX bit 1 - spare ++ GETSTAT_VOLP = 0x004, // IOX bit 2 - VOLP (I - interrupt) ++ GETSTAT_VOLD = 0x008, // IOX bit 3 - VOLD (I - interrupt) ++ GETSTAT_HP_INS = 0x010, // IOX bit 4 - HP_INS (I - interrupt) ++ GETSTAT_MIC_INS = 0x020, // IOX bit 5 - MIC_INS (I - interrupt) ++ GETSTAT_LI_INS = 0x040, // IOX bit 6 - LI_INS (I - interrupt) ++ GETSTAT_LO_INS = 0x080, // IOX bit 7 - LO_INS (I - interrupt) ++ GETSTAT_GSPARE = 0x100, // unused ++ GETSTAT_RESET = 0x200, // CODEC reset ++ GETSTAT_GREEN = 0x400, // green LED ++ GETSTAT_RED = 0x800, // red LED ++} BMI_AUDIO_GETSTAT; ++ ++// input event bit defintions ++typedef enum { ++ HEADPHONE_INSERTED = 0x001, // Detected headphone insertion ++ MICROPHONE_INSERTED = 0x002, // Detected microphone insertion ++ LINEOUT_INSERTED = 0x004, // Detected line out insertion ++ LINEIN_INSERTED = 0x008, // Detected line in insertion ++ VOLUME_DOWN = 0x010, // volume down button pressed ++ VOLUME_UP = 0x020, // volume up button pressed ++} BMI_AUDIO_EVENT; ++ ++// module numbers ++typedef enum { ++ BMI_AUDIO_M1, // PIM 1 ++ BMI_AUDIO_M2, // PIM 2 ++ BMI_AUDIO_M3, // PIM 3 ++ BMI_AUDIO_M4, // PIM 4 ++ BMI_AUDIO_PIM_NUM, // Number of PIMs ++} BMI_MODULE_NUMBERS; ++ ++// TI '3105 CODEC registers ++// Page 0 ++#define CODEC_PAGE_SEL 0x0 // page select ++#define CODEC_RESET 0x1 // reset (self-clearing) ++ #define CODEC_RESET_RESET 0x1 // reset (self-clearing) ++#define CODEC_SAMPLE_RATE 0x2 // ADC/DAC sample rate ++ #define CODEC_SR1 0x0 // ADC/DAC sample rate ++ #define CODEC_SR1_5 0x1 // ADC/DAC sample rate ++ #define CODEC_SR2 0x2 // ADC/DAC sample rate ++ #define CODEC_SR2_5 0x3 // ADC/DAC sample rate ++ #define CODEC_SR3 0x4 // ADC/DAC sample rate ++ #define CODEC_SR3_5 0x5 // ADC/DAC sample rate ++ #define CODEC_SR4 0x6 // ADC/DAC sample rate ++ #define CODEC_SR4_5 0x7 // ADC/DAC sample rate ++ #define CODEC_SR5 0x8 // ADC/DAC sample rate ++ #define CODEC_SR5_5 0x9 // ADC/DAC sample rate ++ #define CODEC_SR6 0xA // ADC/DAC sample rate ++ #define CODEC_SR_SHIFT (4) // ADC shift ++#define CODEC_PLLA 0x3 // PLL Programming A ++ #define CODEC_PLLA_EN 0x80 // PLL enabled ++ #define CODEC_PLLA_DIS 0x00 // PLL disabled ++ #define CODEC_PLLA_Q(x) (((x) & 0xF) << 3) // PLL Q ++ #define CODEC_PLLA_P(x) ((x) & 0x7) // PLL P ++#define CODEC_PLLB 0x4 // PLL Programming B ++ #define CODEC_PLLB_J(x) (((x) & 0x3F) << 2) // PLL J ++#define CODEC_PLLC_DMSB 0x5 // PLL D MSB ++#define CODEC_PLLD_DLSB 0x6 // PLL D LSB ++ #define CODEC_PLLD_D(x) (((x) & 0x3F) << 2) // PLL D LSB ++#define CODEC_DATAPATH 0x7 // Datapath set up ++ #define CODEC_DP_48 (0x00) // 48 kHz ++ #define CODEC_DP_44 (0x80) // 44.1 kHz ++ #define CODEC_ADR_DIS (0x00) // ADC Dual Rate ++ #define CODEC_ADR_EN (0x40) // ADC Dual Rate ++ #define CODEC_DDR_DIS (0x00) // DAC Dual Rate ++ #define CODEC_DDR_EN (0x20) // DAC Dual Rate ++ #define CODEC_DP_MUTED (0x00) // DAC Data Path ++ #define CODEC_DP_NORMAL (0x01) // DAC Data Path ++ #define CODEC_DP_REVERSE (0x02) // DAC Data Path ++ #define CODEC_DP_MONO (0x03) // DAC Data Path ++ #define CODEC_DP_L(x) ((x) << 3) // DAC Data Path Left ++ #define CODEC_DP_R(x) ((x) << 1) // DAC Data Path Right ++#define CODEC_AIFA 0x8 // Audio serial data IF control ++ #define CODEC_AIFA_BCLK_S 0x00 // BCLK is input ++ #define CODEC_AIFA_BCLK_M 0x80 // BCLK is output ++ #define CODEC_AIFA_WCLK_S 0x00 // WCLK is input ++ #define CODEC_AIFA_WCLK_M 0x40 // WCLK is output ++ #define CODEC_AIFA_DOUT_N 0x00 // Dout not tri-state ++ #define CODEC_AIFA_DOUT_TS 0x20 // Dout tri-states ++ #define CODEC_AIFA_CLK_G 0x00 // CLKs gated (Master mode only) ++ #define CODEC_AIFA_CLK_F 0x10 // CLKs free run (Master mode only) ++ #define CODEC_AIFA_FX_OFF 0x00 // disable 3-D EFX ++ #define CODEC_AIFA_FX_ON 0x04 // enable 3-D EFX ++#define CODEC_AIFB 0x9 // Audio serial data IF control ++ #define CODEC_AIFB_I2S 0x00 // MODE = I2S ++ #define CODEC_AIFB_DSP 0x40 // MODE = DSP ++ #define CODEC_AIFB_RJ 0x80 // MODE = Right Justified ++ #define CODEC_AIFB_LJ 0xC0 // MODE = Left Justified ++ #define CODEC_AIFB_16 0x00 // World Length = 16 bits ++ #define CODEC_AIFB_20 0x10 // World Length = 20 bits ++ #define CODEC_AIFB_24 0x20 // World Length = 24 bits ++ #define CODEC_AIFB_32 0x30 // World Length = 32 bits ++ #define CODEC_AIFB_256S 0x08 // 256-clock transfer mode (TDM) ++ #define CODEC_AIFB_DSYNC 0x04 // DAC resync ++ #define CODEC_AIFB_ASYNC 0x02 // ADC resync ++ #define CODEC_AIFB_MSYNC 0x01 // resync with soft-mute ++#define CODEC_AIF_WORD_OFFSET 0xA // data bit offset in frame ++#define CODEC_OVERFLOW 0xB // Overflow flags ++ #define CODEC_OF_LADC 0x80 // Left ADC ++ #define CODEC_OF_RADC 0x40 // Right ADC ++ #define CODEC_OF_LDAC 0x20 // Left DAC ++ #define CODEC_OF_RDAC 0x10 // Right DAC ++ #define CODEC_OF_PLLR(x) ((x) & 0xF) // PLL R ++#define CODEC_FILT_CONTROL 0xC // Filter Control ++ #define CODEC_FC_LADC_HP45 0x40 // Left ADC Filter Control ++ #define CODEC_FC_LADC_HP125 0x80 // Left ADC Filter Control ++ #define CODEC_FC_LADC_HP25 0xC0 // Left ADC Filter Control ++ #define CODEC_FC_RADC_HP45 0x10 // Right ADC Filter Control ++ #define CODEC_FC_RADC_HP125 0x20 // Right ADC Filter Control ++ #define CODEC_FC_RADC_HP25 0x30 // Right ADC Filter Control ++#define CODEC_HS 0xE // Headset/Button ++ #define CODEC_HS_COUPLED 0x80 // HP outputs AC-Coupled ++ #define CODEC_HS_ADIFF 0x40 // Output A differential ++ #define CODEC_HS_HSDET 0x10 // headset detected ++ #define CODEC_HS_BDIFF 0x08 // Output B differential ++#define CODEC_LADC_PGA 0xF // Left ADC PGA ++#define CODEC_RADC_PGA 0x10 // Right ADC PGA ++ #define CODEC_ADC_PGA_MUTE 0x80 // muted ++ #define CODEC_ADC_PGA_G(x) ((x) & 0x7F) // gain (0 to 59.5 dB) ++#define CODEC_M3_LPGA 0x11 // MIC3 -> LADC PGA ++#define CODEC_M3_RPGA 0x12 // MIC3 -> RADC PGA ++ #define CODEC_M3_PGA_LOFF (0xF << 4) // L input off ++ #define CODEC_M3_PGA_ROFF (0xF ) // R input off ++ #define CODEC_M3_PGA_L(x) (((x) & 0xF) << 4) // L input level (0 to -12 dB) ++ #define CODEC_M3_PGA_R(x) ((x) & 0xF) // R input level (0 to -12 dB) ++#define CODEC_L1L_LPGA 0x13 // L1 Left -> LADC PGA ++#define CODEC_L2L_LPGA 0x14 // L2 Left -> LADC PGA ++#define CODEC_L1R_LPGA 0x15 // L1 Right -> LADC PGA ++#define CODEC_L1R_RPGA 0x16 // R1 Right -> RADC PGA ++#define CODEC_L2R_RPGA 0x17 // L2 Right -> RADC PGA ++#define CODEC_L1L_RPGA 0x18 // L1 Left -> RADC PGA ++ #define CODEC_L_PGA(x) (((x) & 0xF) << 3) // input level (0 to -12 dB) ++ #define CODEC_LX_PGA_PU 0x04 // L1 power up ++ #define CODEC_L1L_PGA_SS(x) ((x) & 0x3) // L1 soft stepping ++ #define CODEC_L2L_LPGA_BIASED 0x04 // L2 Left weak bias ++#define CODEC_MIC_BIAS 0x19 // Mic Bias ++ #define CODEC_MIC_BIAS_PD 0x00 // powered down ++ #define CODEC_MIC_BIAS_2V 0x40 // 2V ++ #define CODEC_MIC_BIAS_2P5V 0x80 // 2.5V ++ #define CODEC_MIC_BIAS_AVDD 0xC0 // AVDD ++#define CODEC_MIC_LAGC_A 0x1A // L AGC A ++#define CODEC_MIC_RAGC_A 0x1D // R AGC A ++ #define CODEC_MIC_AGC_EN 0x80 // enable ++ #define CODEC_MIC_AGC_TL(x) (((x) & 0x7) << 4) // target level (-5.5 to -24 dB) ++ #define CODEC_MIC_AGC_AT(x) (((x) & 0x3) << 2) // attack time (8 to 20 ms) ++ #define CODEC_MIC_AGC_DT(x) ((x) & 0x3) // decay time (100 to 500 ms) ++#define CODEC_MIC_LAGC_B 0x1B // L AGC B ++#define CODEC_MIC_RAGC_B 0x1E // R AGC B ++ #define CODEC_MIC_AGC_MG(x) (((x) & 0x7F) << 1) // max gain (0 to 59.5 dB) ++#define CODEC_MIC_LAGC_C 0x1C // L AGC C ++#define CODEC_MIC_RAGC_C 0x1F // R AGC C ++ #define CODEC_MIC_AGC_H(x) (((x) & 0x3) << 6) // NG hysteresis (1 to 3 dB, off) ++ #define CODEC_MIC_AGC_T(x) (((x) & 0x3) << 6) // NG Threshold (off to -90 dB) ++ #define CODEC_MIC_AGC_SC 0x1 // clip stepping enable ++#define CODEC_MIC_LAGC_GAIN 0x20 // L AGC gain (-12 tp 59.5 dB) ++#define CODEC_MIC_RAGC_GAIN 0x21 // R AGC gain (-12 tp 59.5 dB) ++#define CODEC_MIC_LAGC_NGD 0x22 // L AGC NG debounce ++#define CODEC_MIC_RAGC_NGD 0x23 // R AGC NG debounce ++ #define CODEC_MIC_AGC_NGD_D(x) (((x) & 0x1F) << 3) // detect(0 to 1536 ms) ++ #define CODEC_MIC_AGC_NGD_C(x) ((x) & 0x7) // control (0 to 32 ms) ++#define CODEC_ADC_FLAG 0x24 // ADC flag ++ #define CODEC_ADC_FLAG_LPGA_S 0x80 // L ADC PGA gain equal ++ #define CODEC_ADC_FLAG_LPWR_S 0x40 // L ADC powered-up ++ #define CODEC_ADC_FLAG_LSIGD 0x20 // L AGC signal detected ++ #define CODEC_ADC_FLAG_LSAT 0x10 // L AGC saturation detected ++ #define CODEC_ADC_FLAG_RPGA_S 0x08 // R ADC PGA gain equal ++ #define CODEC_ADC_FLAG_RPWR_S 0x04 // R ADC powered-up ++ #define CODEC_ADC_FLAG_RSIGD 0x02 // R AGC signal detected ++ #define CODEC_ADC_FLAG_RSAT 0x01 // R AGC saturation detected ++#define CODEC_DAC_PWR 0x25 // DAC power and output driver ++#define CODEC_DAC_HPWR 0x26 // high-power output driver ++ #define CODEC_DAC_PWR_L_EN 0x80 // L power up ++ #define CODEC_DAC_PWR_R_EN 0x40 // R power up ++ #define CODEC_DAC_PWR_HP_DIFF 0x00 // differential of HPLOUT ++ #define CODEC_DAC_PWR_HP_VCM 0x10 // constant VCM ++ #define CODEC_DAC_PWR_HP_ISE 0x20 // independant single ended ++ #define CODEC_DAC_HPWR_HPL_DIFF 0x18 // short circuit protection ++ #define CODEC_DAC_HPWR_SS 0x04 // short circuit protection ++ #define CODEC_DAC_HPWR_SS_C 0x00 // limit current ++ #define CODEC_DAC_HPWR_SS_P 0x02 // power down ++#define CODEC_DAC_HPOS 0x28 // high-power output stage ++ #define CODEC_DAC_HPOS_CM1P35 0x00 // common mode = 1.35V ++ #define CODEC_DAC_HPOS_CM1P5 0x40 // common mode = 1.5V ++ #define CODEC_DAC_HPOS_CM1P65 0x80 // common mode = 1.65V ++ #define CODEC_DAC_HPOS_CM1P8 0xC0 // common mode = 1.8V ++ #define CODEC_DAC_HPOS_L2L_BYP 0x00 // L2 L bypass disabled ++ #define CODEC_DAC_HPOS_L2L_SE 0x10 // L2 L bypass = L2LP ++ #define CODEC_DAC_HPOS_L2L_BYP 0x00 // L2 R bypass disabled ++ #define CODEC_DAC_HPOS_L2R_SE 0x04 // L2 R bypass = L2RP ++ #define CODEC_DAC_HPOS_FS 0x00 // soft stepping: 1 / fs ++ #define CODEC_DAC_HPOS_2FS 0x01 // soft stepping: 1 / 2 fs ++ #define CODEC_DAC_HPOS_SS_DIS 0x02 // soft stepping disabled ++#define CODEC_DAC_OS 0x29 // output switching ++ #define CODEC_DAC_OS_L1 0x00 // L = L1 ++ #define CODEC_DAC_OS_L3 0x40 // L = L3 ++ #define CODEC_DAC_OS_L2 0x80 // L = L2 ++ #define CODEC_DAC_OS_R1 0x00 // R = R1 ++ #define CODEC_DAC_OS_R3 0x10 // R = R3 ++ #define CODEC_DAC_OS_R2 0x20 // R = R2 ++ #define CODEC_DAC_OS_VOL_S 0x00 // volume separate ++ #define CODEC_DAC_OS_VOL_R 0x01 // L follows R ++ #define CODEC_DAC_OS_VOL_L 0x02 // R follows L ++#define CODEC_DAC_PR 0x2A // pop reduction ++ #define CODEC_DAC_PR_DEL(x) (((x) & 0xF) << 4) // delay (0 us to 4 s) ++ #define CODEC_DAC_PR_RU(x) (((x) & 0x3) << 2) // ramp up (0 to 4 ms) ++ #define CODEC_DAC_CM_AVDD 0x00 // common mode from AVDD ++ #define CODEC_DAC_CM_BG 0x02 // common mode from band gap ++#define CODEC_DAC_LVOL 0x2B // Left volume ++#define CODEC_DAC_RVOL 0x2C // Right volume ++ #define CODEC_DAC_VOL_MUTE 0x80 // muted ++ #define CODEC_DAC_VOL(x) ((x) & 0x7F) // volume (0 to -63.5 dB) ++#define CODEC_L2L_HPL 0x2D // L2L -> HPLOUT ++#define CODEC_PGAL_HPL 0x2E // PGAL -> HPLOUT ++#define CODEC_DACL1_HPL 0x2F // DACL1 -> HPLOUT ++#define CODEC_L2R_HPL 0x30 // L2R -> HPLOUT ++#define CODEC_PGAR_HPL 0x31 // PGAR -> HPLOUT ++#define CODEC_DACR1_HPL 0x32 // DACLR -> HPLOUT ++#define CODEC_L2L_HPLCOM 0x34 // L2L -> HPLCOM ++#define CODEC_PGAL_HPLCOM 0x35 // PGAL -> HPLCOM ++#define CODEC_DACL1_HPLCOM 0x36 // DACL1 -> HPLCOM ++#define CODEC_L2R_HPLCOM 0x37 // L2R -> HPLCOM ++#define CODEC_PGAR_HPLCOM 0x38 // PGAR -> HPLCOM ++#define CODEC_DACR1_HPLCOM 0x39 // DACR1 -> HPLCOM ++#define CODEC_L2L_HPR 0x3B // L2L -> HPROUT ++#define CODEC_PGAL_HPR 0x3C // PGAL -> HPROUT ++#define CODEC_DACL1_HPR 0x3D // DACL1 -> HPROUT ++#define CODEC_L2R_HPR 0x3E // L2R -> HPROUT ++#define CODEC_PGAR_HPR 0x3F // PGAR -> HPROUT ++#define CODEC_DACR1_HPR 0x40 // DACLR -> HPROUT ++#define CODEC_L2L_HPRCOM 0x42 // L2L -> HPRCOM ++#define CODEC_PGAL_HPRCOM 0x43 // PGAL -> HPRCOM ++#define CODEC_DACL1_HPRCOM 0x44 // DACL1 -> HPRCOM ++#define CODEC_L2R_HPRCOM 0x45 // L2R -> HPRCOM ++#define CODEC_PGAR_HPRCOM 0x46 // PGAR -> HPRCOM ++#define CODEC_DACR1_HPRCOM 0x47 // DACLR -> HPRCOM ++#define CODEC_L2L_LLOPM 0x50 ++#define CODEC_PGAL_LLOPM 0x51 ++#define CODEC_DACL1_LLOPM 0x52 ++#define CODEC_L2R_LLOPM 0x53 ++#define CODEC_PGAR_LLOPM 0x54 ++#define CODEC_DACR1_LLOPM 0x55 ++#define CODEC_L2L_RLOPM 0x57 ++#define CODEC_PGA_RLOPM 0x58 ++#define CODEC_DACL1_RLOPM 0x59 ++#define CODEC_L2R_RLOPM 0x5A ++#define CODEC_PGAR_RLOPM 0x5B ++#define CODEC_DACR1_RLOPM 0x5C ++ #define CODEC_HP_EN 0x80 // enabled ++ #define CODEC_HP_VOL(x) ((x) & 0x7F) // see datasheet Table 6 ++#define CODEC_HPLOUT 0x33 // HPLOUT output level ++#define CODEC_HPLCOM 0x3A // HPLCOM output level ++#define CODEC_HPROUT 0x41 // HPROUT output level ++#define CODEC_HPRCOM 0x48 // HPRCOM output level ++#define CODEC_LLOPM 0x56 // LLOPM output level ++#define CODEC_RLOPM 0x5D // RLOPM output level ++ #define CODEC_HPX_LC(x) (((x) & 0xF) << 4) // output level ++ #define CODEC_HPX_EN 0x08 // not muted ++ #define CODEC_HPX_PD 0x04 // power down enable ++ #define CODEC_HPX_STAT 0x02 // gain not applied ++ #define CODEC_HPX_PC 0x01 // fully powered up ++#define CODEC_PSR 0x5E // Power Status ++ #define CODEC_PSR_LDPS 0x80 // L DAC ++ #define CODEC_PSR_DDPS 0x40 // R DAC ++ #define CODEC_PSR_LLOPM 0x10 // L LOPM ++ #define CODEC_PSR_RLOPM 0x08 // R LOPM ++ #define CODEC_PSR_HPLOUT 0x04 // HPLOUT ++ #define CODEC_PSR_HPLCOM 0x02 // HPLCOM ++#define CODEC_SS 0x5F // driver short circuit ++ #define CODEC_SS_HPLOUT 0x80 ++ #define CODEC_SS_HPROUT 0x40 ++ #define CODEC_SS_HPLCOM 0x20 ++ #define CODEC_SS_HPRCOM 0x10 ++ #define CODEC_SS_HPLCOM_PS 0x08 ++ #define CODEC_SS_HPRCOM_PS 0x04 ++#define CODEC_S_INT 0x60 // sticky interrupt ++#define CODEC_RT_INT 0x61 // real-time interrupt ++ #define CODEC_INT_HPLOUT_SS 0x80 ++ #define CODEC_INT_HPROUT_SS 0x40 ++ #define CODEC_INT_HPLCOM_SS 0x20 ++ #define CODEC_INT_HPRCOM_SS 0x10 ++ #define CODEC_INT_HS_DET 0x04 ++ #define CODEC_INT_LAGC_NG 0x02 ++ #define CODEC_INT_RAGC_NG 0x01 ++#define CODEC_CLK 0x65 // clock source ++ #define CODEC_CLK_PLLDIV 0x00 ++ #define CODEC_CLK_CLKDIV 0x01 ++#define CODEC_CLKGEN 0x66 // clock generation ++ #define CODEC_CLKGEN_C_M 0x02 // MCLK -> CLK ++ #define CODEC_CLKGEN_C_G 0x42 // GPIO2 -> CLK ++ #define CODEC_CLKGEN_C_B 0x82 // BCLK -> CLK ++ #define CODEC_CLKGEN_P_M 0x02 // MCLK -> PLL ++ #define CODEC_CLKGEN_P_G 0x12 // GPIO2 -> PLL ++ #define CODEC_CLKGEN_P_B 0x22 // BCLK -> PLL ++#define CODEC_LAGC_ATT 0x67 // L AGC Attack ++#define CODEC_RAGC_ATT 0x69 // R AGC Attack ++ #define CODEC_AGC_ATT_R26 0x00 // source reg 36 ++ #define CODEC_AGC_ATT_R103 0x80 // source reg 103 ++ #define CODEC_AGC_ATT_T(x) (((x) & 0x3) << 5) // time ++ #define CODEC_AGC_ATT_M(x) (((x) & 0xF) << 2) // multiplication ++#define CODEC_LAGC_DEC 0x68 // L AGC Decay ++#define CODEC_RAGC_DEC 0x6A // R AGC Decay ++ #define CODEC_AGC_DEC_R26 0x00 // source reg 36 ++ #define CODEC_AGC_DEC_R104 0x80 // source reg 104 ++ #define CODEC_AGC_DEC_T(x) (((x) & 0x3) << 5) // time ++ #define CODEC_AGC_DEC_M(x) (((x) & 0xF) << 2) // multiplication ++#define CODEC_DP_I2C 0x6B // digital path and I2C ++ #define CODEC_DP_I2C_LHPF_EN 0x80 ++ #define CODEC_DP_I2C_RHPF_EN 0x40 ++ #define CODEC_ADC_DFLDRD 0x00 ++ #define CODEC_ADC_DFLDRA 0x10 ++ #define CODEC_ADC_DFLARD 0x20 ++ #define CODEC_ADC_DFLARA 0x30 ++ #define CODEC_ADC_F_EN 0x08 ++ #define CODEC_I2C_ERR_DIS 0x04 ++ #define CODEC_I2C_HANG 0x01 ++#define CODEC_PASB 0x6C // passive analog bypass ++ #define CODEC_PASB_L2RP_RLOP 0x40 ++ #define CODEC_PASB_L1RP_RLOP 0x10 ++ #define CODEC_PASB_L2LP_LLOP 0x04 ++ #define CODEC_PASB_L1LP_LLOP 0x01 ++#define CODEC_DAC_QCA 0x6D // DAC current adjust ++#define CODEC_DAC_QCA_50 0x40 ++#define CODEC_DAC_QCA_100 0xC0 ++// Page 1 ++#define CODEC_EF_LN0M 0x1 ++#define CODEC_EF_LN0L 0x2 ++#define CODEC_EF_LN1M 0x3 ++#define CODEC_EF_LN1L 0x4 ++#define CODEC_EF_LN2M 0x5 ++#define CODEC_EF_LN2L 0x6 ++#define CODEC_EF_LN3M 0x7 ++#define CODEC_EF_LN3L 0x8 ++#define CODEC_EF_LN4M 0x9 ++#define CODEC_EF_LN4L 0xA ++#define CODEC_EF_LN5M 0xB ++#define CODEC_EF_LN5L 0xC ++ ++#define CODEC_EF_LD1M 0xD ++#define CODEC_EF_LD1L 0xE ++#define CODEC_EF_LD2M 0xF ++#define CODEC_EF_LD2L 0x10 ++#define CODEC_EF_LD4M 0x11 ++#define CODEC_EF_LD4L 0x12 ++#define CODEC_EF_LD5M 0x13 ++#define CODEC_EF_LD5L 0x14 ++ ++#define CODEC_DF_LN0M 0x15 ++#define CODEC_DF_LN0L 0x16 ++#define CODEC_DF_LN1M 0x17 ++#define CODEC_DF_LN1L 0x18 ++ ++#define CODEC_DF_LD1M 0x19 ++#define CODEC_DF_LD1L 0x1A ++ ++#define CODEC_EF_RN0M 0x1B ++#define CODEC_EF_RN0L 0x1C ++#define CODEC_EF_RN1M 0x1D ++#define CODEC_EF_RN1L 0x1E ++#define CODEC_EF_RN2M 0x1F ++#define CODEC_EF_RN2L 0x20 ++#define CODEC_EF_RN3M 0x21 ++#define CODEC_EF_RN3L 0x22 ++#define CODEC_EF_RN4M 0x23 ++#define CODEC_EF_RN4L 0x24 ++#define CODEC_EF_RN5M 0x25 ++#define CODEC_EF_RN5L 0x26 ++ ++#define CODEC_EF_RD1M 0x27 ++#define CODEC_EF_RD1L 0x28 ++#define CODEC_EF_RD2M 0x29 ++#define CODEC_EF_RD2L 0x2A ++#define CODEC_EF_RD4M 0x2B ++#define CODEC_EF_RD4L 0x2C ++#define CODEC_EF_RD5M 0x2D ++#define CODEC_EF_RD5L 0x2E ++ ++#define CODEC_DF_RN0M 0x2F ++#define CODEC_DF_RN0L 0x30 ++#define CODEC_DF_RN1M 0x31 ++#define CODEC_DF_RN1L 0x32 ++ ++#define CODEC_DF_RD1M 0x33 ++#define CODEC_DF_RD1L 0x34 ++ ++#define CODEC_3DAM 0x35 ++#define CODEC_3DAL 0x36 ++ ++#define CODEC_LHPN0M 0x41 ++#define CODEC_LHPN0L 0x42 ++#define CODEC_LHPN1M 0x43 ++#define CODEC_LHPN1L 0x44 ++#define CODEC_LHPD1M 0x45 ++#define CODEC_LHPD1L 0x46 ++ ++#define CODEC_RHPN0M 0x47 ++#define CODEC_RHPN0L 0x48 ++#define CODEC_RHPN1M 0x49 ++#define CODEC_RHPN1L 0x4A ++#define CODEC_RHPD1M 0x4B ++#define CODEC_RHPD1L 0x4C ++ ++struct codec_xfer { ++ unsigned char page; ++ unsigned char reg; ++ unsigned char data; ++} codec_xfer; ++ ++// IOCTL commands for BMI AUDIO driver ++#define BMI_AUDIO_RLEDOFF _IO(BMI_AUDIO_IOCTL, 0x1) // Turn off red LED ++#define BMI_AUDIO_RLEDON _IO(BMI_AUDIO_IOCTL, 0x2) // Turn on red LED ++#define BMI_AUDIO_GLEDOFF _IO(BMI_AUDIO_IOCTL, 0x3) // Turn off green LED ++#define BMI_AUDIO_GLEDON _IO(BMI_AUDIO_IOCTL, 0x4) // Turn on green LED ++#define BMI_AUDIO_SPKOFF _IO(BMI_AUDIO_IOCTL, 0x5) // Turn off speaker ++#define BMI_AUDIO_SPKON _IO(BMI_AUDIO_IOCTL, 0x6) // Turn on speaker ++#define BMI_AUDIO_GETSTAT _IOR(BMI_AUDIO_IOCTL, 0x9, unsigned int *) // READ IOX register ++#define BMI_AUDIO_SETRST _IO(BMI_AUDIO_IOCTL, 0xA) // Set RESET to '0' ++#define BMI_AUDIO_CLRRST _IO(BMI_AUDIO_IOCTL, 0xB) // Set RESET to '1' ++#define BMI_AUDIO_ACTIVATE _IO(BMI_AUDIO_IOCTL, 0xC) // Activate a module for audio capture ++#define BMI_AUDIO_DEACTIVATE _IO(BMI_AUDIO_IOCTL, 0xD) // Deactivate a module for audio capture ++#define BMI_AUDIO_WCODEC _IOW(BMI_AUDIO_IOCTL, 0xE, struct codec_xfer *) // write CODEC register ++#define BMI_AUDIO_RCODEC _IOR(BMI_AUDIO_IOCTL, 0xF, struct codec_xfer *) // read CODEC register ++ ++#endif /* BMI_AUDIO_H */ ++ +--- /dev/null ++++ git/include/linux/bmi/bmi_camera.h +@@ -0,0 +1,36 @@ ++/* ++ * File: include/linux/bmi/bmi_camera.h ++ * Author: Peter Giacomini ++ * ++ * This is the application header file for the BMI bus camera plug-in ++ * module on the MX31 BUG platform. ++ */ ++ ++#ifndef BMI_CAMERA_A_H ++#define BMI_CAMERA_A_H ++ ++#include ++#include ++ ++ // IOCTL commands for BMI Camera driver ++ ++#define BMI_CAM_FLASH_HIGH_BEAM _IOW(BMI_CAMERA_IOCTL, 0x1, __u32) ++#define BMI_CAM_FLASH_LOW_BEAM _IOW(BMI_CAMERA_IOCTL, 0x2, __u32) ++#define BMI_CAM_FLASH_LED_OFF _IOW(BMI_CAMERA_IOCTL, 0x3, __u32) ++#define BMI_CAM_FLASH_LED_ON _IOW(BMI_CAMERA_IOCTL, 0x4, __u32) ++ ++#define BMI_CAM_RED_LED_OFF _IOW(BMI_CAMERA_IOCTL, 0x5, __u32) // Turn off red LED ++#define BMI_CAM_RED_LED_ON _IOW(BMI_CAMERA_IOCTL, 0x6, __u32) // Turn on red LED ++#define BMI_CAM_GREEN_LED_OFF _IOW(BMI_CAMERA_IOCTL, 0x7, __u32) // Turn off green LED ++#define BMI_CAM_GREEN_LED_ON _IOW(BMI_CAMERA_IOCTL, 0x8, __u32) // Turn on green LED ++ ++#define BMI_CAM_SELECT _IOW(BMI_CAMERA_IOCTL, 0x9, __u32) // Select camera module ++#define BMI_CAM_GET_SELECTED _IOR(BMI_CAMERA_IOCTL, 0xA, __u32) // return selected camera module ++ ++ // input event definitions ++#define BN_SHUTTER BTN_0 ++#define BN_ZOOMIN BTN_1 ++#define BN_ZOOMOUT BTN_2 ++ ++#endif /* BMI_CAMERA_A_H */ ++ +--- /dev/null ++++ git/include/linux/bmi/bmi_gps.h +@@ -0,0 +1,30 @@ ++/* ++ * File: include/linux/bmi/bmi_gps.h ++ * Author: Peter Giacomini ++ * ++ * This is the application header file for the BMI bus gps plug-in ++ * module on the MX31 BUG platform. ++ */ ++ ++#ifndef BMI_GPS_H ++#define BMI_GPS_H ++ ++#include ++ ++ // IOCTL commands for BMI GPS driver ++#define BMI_GPS_RLEDOFF _IOW(BMI_GPS_IOCTL, 0x1, unsigned int) // Turn off red LED ++#define BMI_GPS_RLEDON _IOW(BMI_GPS_IOCTL, 0x2, unsigned int) // Turn on red LED ++#define BMI_GPS_GLEDOFF _IOW(BMI_GPS_IOCTL, 0x3, unsigned int) // Turn off green LED ++#define BMI_GPS_GLEDON _IOW(BMI_GPS_IOCTL, 0x4, unsigned int) // Turn on green LED ++#define BMI_GPS_SETBOOT _IOW(BMI_GPS_IOCTL, 0x5, unsigned int) // Set BOOT to '1' ++#define BMI_GPS_CLRBOOT _IOW(BMI_GPS_IOCTL, 0x6, unsigned int) // Set BOOT to '0' ++#define BMI_GPS_SETWAKE _IOW(BMI_GPS_IOCTL, 0x7, unsigned int) // Set WAKE to '1' ++#define BMI_GPS_CLRWAKE _IOW(BMI_GPS_IOCTL, 0x8, unsigned int) // Set WAKE to '0' ++#define BMI_GPS_GETSTAT _IOR(BMI_GPS_IOCTL, 0x9, unsigned int *) // READ IOX register ++#define BMI_GPS_SETRST _IOW(BMI_GPS_IOCTL, 0xA, unsigned int) // Set RESET to '0' ++#define BMI_GPS_CLRRST _IOW(BMI_GPS_IOCTL, 0xB, unsigned int) // Set RESET to '1' ++#define BMI_GPS_ACTIVE_ANT _IOW(BMI_GPS_IOCTL, 0xC, unsigned int) // Select Active Antenna ++#define BMI_GPS_PASSIVE_ANT _IOW(BMI_GPS_IOCTL, 0xD, unsigned int) // Select Passive Antenna ++ ++#endif /* BMI_GPS_H */ ++ +--- /dev/null ++++ git/include/linux/bmi/bmi_gsm.h +@@ -0,0 +1,33 @@ ++/* ++ * File: include/linux/bmi/bmi_gsm.h ++ * Author: Matt Isaacs ++ * ++ * This is the application header file for the BMI bus GSM/UMTS plug-in ++ * module on the MX31 BUG platform. ++ */ ++ ++#ifndef BMI_GSM_H ++#define BMI_GSM_H ++ ++#include ++ ++// GPIO ++#define GSM_GPIO_RED_LED 3 // default to input ++#define GSM_GPIO_GREEN_LED 2 // default to input ++#define GSM_GPIO_1 1 // default to input ++#define GSM_GPIO_0 0 // default to input ++ ++#define GSM_GPIO_LED_ON 0 ++#define GSM_GPIO_LED_OFF 1 ++ ++ ++// von hippel driver ioctl definitions ++#define BMI_GSM_RLEDOFF _IOW(BMI_GSM_IOCTL, 0x1, unsigned int) // Turn off red LED ++#define BMI_GSM_RLEDON _IOW(BMI_GSM_IOCTL, 0x2, unsigned int) // Turn on red LED ++#define BMI_GSM_GLEDOFF _IOW(BMI_GSM_IOCTL, 0x3, unsigned int) // Turn off green LED ++#define BMI_GSM_GLEDON _IOW(BMI_GSM_IOCTL, 0x4, unsigned int) // Turn on green LED ++#define BMI_GSM_GETSTAT _IOR(BMI_GSM_IOCTL, 0x5, unsigned int *) // READ IOX register ++ ++ ++#endif /* BMI_GSM_H */ ++ +--- /dev/null ++++ git/include/linux/bmi/bmi_ioctl.h +@@ -0,0 +1,27 @@ ++/* ++ * File: include/linux/bmi/bmi_ioctl.h ++ * Author: Peter Giacomini ++ * ++ * This is the header file for the BMI ioctl definitions ++ */ ++ ++#ifndef BMI_IOCTL_H ++#define BMI_IOCTL_H ++ ++ // IOCTL Magic Numbers ++#define BMI_CAMERA_IOCTL ('c') ++#define BMI_LCD_IOCTL ('l') ++#define BMI_GPS_IOCTL ('g') ++#define BMI_MDACC_IOCTL ('m') ++#define BMI_AUDIO_IOCTL ('a') ++#define BMI_VH_IOCTL ('v') ++#define BMI_WIFI_IOCTL ('W') ++#define BMI_ZIGBEE_IOCTL ('Z') ++#define BMI_GSM_IOCTL ('G') ++#define BMI_PROJECTOR_IOCTL ('p') ++#define BMI_SENSOR_IOCTL ('s') ++#define BMI_LCD2X_IOCTL ('x') ++#define BMI_RFID_IOCTL ('r') ++ ++#endif /* BMI_IOCTL_H */ ++ +--- /dev/null ++++ git/include/linux/bmi/bmi_lcd.h +@@ -0,0 +1,71 @@ ++/* ++ * File: include/linux/bmi/bmi_lcd.h ++ * Author: Peter Giacomini ++ * ++ * This is the application header file for the BMI bus lcd plug-in ++ * module on the MX31 BUG platform. ++ */ ++ ++#ifndef BMI_LCD_H ++#define BMI_LCD_H ++ ++#include ++#include ++ ++ // IOCTL commands for BMI LCD driver ++#define BMI_LCD_RLEDOFF _IOW(BMI_LCD_IOCTL, 0x1, __u32) // turn off Red LED ++#define BMI_LCD_RLEDON _IOW(BMI_LCD_IOCTL, 0x2, __u32) // turn on Red LED ++#define BMI_LCD_GLEDOFF _IOW(BMI_LCD_IOCTL, 0x3, __u32) // turn off Green LED ++#define BMI_LCD_GLEDON _IOW(BMI_LCD_IOCTL, 0x4, __u32) // turn on Green LED ++#define BMI_LCD_VSYNC_DIS _IOW(BMI_LCD_IOCTL, 0x5, __u32) // Enable VSYNC output buffer ++#define BMI_LCD_VSYNC_EN _IOW(BMI_LCD_IOCTL, 0x6, __u32) // Disable VSYNC output buffer ++#define BMI_LCD_EN _IOW(BMI_LCD_IOCTL, 0x7, __u32) // Enable LCD component ++#define BMI_LCD_DIS _IOW(BMI_LCD_IOCTL, 0x8, __u32) // Disable LCD component ++#define BMI_LCD_SER_EN _IOW(BMI_LCD_IOCTL, 0x9, __u32) // Enable Seriallizer component ++#define BMI_LCD_SER_DIS _IOW(BMI_LCD_IOCTL, 0xa, __u32) // Disable Seriallizer component ++#define BMI_LCD_SETRST _IOW(BMI_LCD_IOCTL, 0xb, __u32) // Disable entire module ++#define BMI_LCD_CLRRST _IOW(BMI_LCD_IOCTL, 0xc, __u32) // Enable entire module ++#define BMI_LCD_SET_BL _IOW(BMI_LCD_IOCTL, 0xd, __u32) // Set IOX backlight bits [2:0] ++#define BMI_LCD_GETSTAT _IOR(BMI_LCD_IOCTL, 0xe, __u32) // Get IOX state ++#define BMI_LCD_ACTIVATE _IOW(BMI_LCD_IOCTL, 0xf, __u32) // Activate SER, TS, ACCEL ++#define BMI_LCD_DEACTIVATE _IOW(BMI_LCD_IOCTL, 0x10, __u32) // Deactivate SER, TS, ACCEL ++#define BMI_LCD_SUSPEND _IOW(BMI_LCD_IOCTL, 0x11, __u32) // Power down module ++#define BMI_LCD_RESUME _IOW(BMI_LCD_IOCTL, 0x12, __u32) // Power up module ++ ++/*Izzy Additions*/ ++#define BMI_LCD_MIN_XC 0 ++#define BMI_LCD_MAX_XC 0x3fff ++#define BMI_LCD_MIN_YC 0 ++#define BMI_LCD_MAX_YC 0x3fff ++ ++/*struct lcd_ctl ++{ ++ int slot; ++ struct cdev cdev; ++ struct device *class_dev; ++}; ++*/ ++ ++// ++// Orientation - location of module 1-3 shorter edge (when facing LCD side) ++// when not FACEUP or FACEDOWN ++// ++// Note that orientation is only reported through bmi_lcd_ts[0-3] ++// ++#define ACC_PITCH_MSK (0xFFFF0000) ++#define ACC_ROLL_MSK (0xFFFF) ++ ++ // touch screen input devices ++enum { ++ BMI_TS_M1, // bmi_lcd_ts0 - slot 0 ++ BMI_TS_M2, // bmi_lcd_ts1 - slot 1 ++ BMI_TS_M3, // bmi_lcd_ts2 - slot 2 ++ BMI_TS_M4, // bmi_lcd_ts3 - slot 3 ++ BMI_TS_M13, // bmi_lcd_ts4 - slot 0 and 2 ++ BMI_TS_M24, // bmi_lcd_ts5 - slot 1 and 3 ++ BMI_TS_M1234, // bmi_lcd_ts6 - slot 0-3 ++ BMI_TS_NUM, ++} lcd_ts_t; ++ ++#endif /* BMI_LCD_H */ ++ +--- /dev/null ++++ git/include/linux/bmi/bmi_mdacc.h +@@ -0,0 +1,518 @@ ++/*----------------------------------------------------------------------------- ++ * ++ * File: include/linux/bmi/bug_mdacc.h ++ * ++ *----------------------------------------------------------------------------- ++ * This file contains information needed by application programs that use the ++ * Bug Motion Detector Accelerometer (MDACC) Plug-In Module. ++ * ++ * The Bug Motion Detector Accelerometer (MDACC) Plug-In Module is a circuit ++ * board that contains the following devices: ++ * ++ * a motion sensor, ++ * a 3-axis accelerometer ++ * a micro-controller. ++ * 1 Red LED ++ * 1 Green LED ++ * ++ * The micro-controller behaves as an SPI-slave device. The host controls ++ * the operation of the micro-controller by issuing sequences of SPI messages. ++ * The micro-controller periodically samples the motion sensor and the ++ * accelerometer. The micro-controller generates an interrupts to the host ++ * processor. The micro-controller provides data to the host in response ++ * to received SPI messages. ++ * ++ * Application software can the MDACC Plug-in modules using the following ++ * device drivers: ++ * ++ * BMI MDACC Control Driver ++ * BMI MDACC Motion Detector Driver ++ * BMI MDACC Accelerometer Driver ++ * ++ * These drivers allow for independent operation of MDACC peripheral devices. ++ * ++ * This file contains the interface definition for all 3 device drivers. ++ * ++ * --------------------------------------------------------------------------- ++ * ++ * Default Device Names: ++ * ++ * The following device nodes are created for each MDACC card present in the ++ * system. ++ * ++ * /dev/bmi_mdacc_ctl_mX where X = 1,2,3,4 (bmi connector number) ++ * /dev/bmi_mdacc_mot_mX where X = 1,2,3,4 (bmi connector number) ++ * /dev/bmi_mdacc_acc_mX where X = 1,2,3,4 (bmi connector number) ++ * ++ * If the MDACC is not present in a given slot, the corresponding device nodes ++ * are not created. ++ * ++ *---------------------------------------------------------------------------- ++ * ++ * BMI MDACC Control Driver ++ * ++ *---------------------------------------------------------------------------- ++ * ++ * This character driver provides access to the Red and Green LEDs via ++ * via the ioctl() system call. ++ * ++ * Supported system calls: open(), close(), ioctl(). ++ * ++ * The following IOCTL commands are defined for this driver. ++ * ++ * BMI_MDACC_CTL_RED_LED_OFF ++ * BMI_MDACC_CTL_RED_LED_ON ++ * BMI_MDACC_CTL_GREEN_LED_OFF ++ * BMI_MDACC_CTL_GREEN_LED_ON ++ * ++ * Note that the 3rd argument to the ioctl system call are not used by the ++ * ioctl commands listed above. ++ *---------------------------------------------------------------------------- ++ */ ++ ++/*---------------------------------------------------------------------------- ++ * ++ * BMI MDACC Motion Detector Driver ++ * ++ *---------------------------------------------------------------------------- ++ * ++ * This character driver provides access to the motion sensor via the SPI ++ * interface. This driver enforces single-open and stop-on-close behaviors. ++ * ++ * ++ * Supported system calls: open(), close(), ioctl(). read(), select(). ++ * ++ * BMI MDACC Motion Detector ioctl() interface ++ *-------------------------------------------- ++ * ++ * The following IOCTL commands are defined for this driver. ++ * ++ * BMI_MDACC_MOTION_DETECTOR_GET_STATUS ++ * BMI_MDACC_MOTION_DETECTOR_RUN ++ * BMI_MDACC_MOTION_DETECTOR_STOP ++ * ++ * ++ * The BMI_MDACC_MOTION_DETECTOR_RUN command sends an SPI message to the ++ * microcontroller to enable sampling of the motion detector status pin. ++ * This command does not use the 3rd parameter to the ioctl system call. ++ * ++ * The BMI_MDACC_MOTION_DETECTOR_STOP command sends an SPI message to the ++ * microcontroller to halt sampling of the motion detector status pin. ++ * This command does not use the 3rd parameter to the ioctl system call. ++ * ++ * The BMI_MDACC_MOTION_DETECTOR_GET_STATUS command gets the motion detector ++ * status byte that is maintained by the motion detector driver. ++ * The third argument to the ioctl system call should be the address of a ++ * the receive buffer that is 1 byte in size. ++ * ++ * Motion Detect Status Bit Descriptions ++ * --------------------------------------- ++ * ++ * The Motion Detect Status byte is returned by the system calls to the ++ * MDACC Motion Detector driver: ++ * ++ * ioctl(BMI_MDACC_MOTION_GET_STATUS) ++ * read() ++ * ++ * The following bits are defined in the status byte. ++ * ++ * BMI_MOTION_DETECT_STATUS ++ * ++ * This bit is the present status of the the motion detector status pin. ++ * A value of 1 indicates that motion is being detected. ++ * A value of 0 indicates that motion is not being detected. ++ * ++ * ++ * BMI_MOTION_DETECT_LATCHED_STATUS ++ * ++ * This bit is the latched status of the motion sensor. This bit is set to 1 ++ * when the BMI_MOTION_DETECT_STATUS bit changes from 0 to 1. This bit will ++ * be cleared as the result of an "ioctl(BMI_MDACC_MOTION_GET_STATUS)" or a ++ * read() system call. ++ * ++ * BMI_MOTION_DETECT_DELTA ++ * ++ * This bit indicates that the motion detector status has changed from 1 to 0 ++ * or has changed from 0 to 1. This bit will be cleared as the result of an ++ * "ioctl(BMI_MDACC_MOTION_GET_STATUS)" or read() system calls. ++ * ++ * ++ * BMI_MOTION_DETECT_ENABLED ++ * ++ * This bits is the state of the motion detector sampling and status reporting ++ * mechanism. A value of 1 indicates that the motion detector is enabled. A ++ * value of 0 indicates that the motion detector is disabled. ++ * ++ * ++ * Motion Detect read() system call ++ * -------------------------------- ++ * ++ * The read() call for this driver allows the application program to read the ++ * motion detector status only when the status has changed. ++ * ++ * Prior to issuing a read() to this driver, the application must enabled the ++ * motion detector using the "ioctl(BMI_MDACC_MOTION_DETECTOR_RUN)" command. ++ * ++ * read parameters: ++ * ++ * buffer: status byte destination address. ++ * size: 1 ++ * ++ * Motion Detect blocking read() behavior ++ * -------------------------------------- ++ * ++ * If the motion detector status HAS NOT changed, then the driver will sleep ++ * waiting for the motion detect status to change. ++ * ++ * If the driver is awoken by a Motion Detect status change interrupt, the ++ * underlying hardware will be accessed (for a second time) and the motion ++ * detect status will be updated. ++ * ++ * The status data byte will be copied to the user-supplied buffer. The ++ * following bits will then be cleared in the motion detect status byte: ++ * ++ * BMI_MOTION_DETECT_LATCHED_STATUS ++ * BMI_MOTION_DETECT_DELTA ++ * ++ * The driver will then be marked as "not-ready-to-read". ++ * ++ * If the the driver is awoken by a signal, the driver will return failure (-1) ++ * and errno will be set to ERESTARTSYS. ++ * ++ * ++ * Motion Detect non-blocking read() behavior ++ * ------------------------------------------ ++ * If the motion detector status HAS NOT changed prior to the non-blocking ++ * read() system call, then the driver will return failure (-1) and errno will ++ * be set to EAGAIN. ++ * ++ * If the motion detector status HAS changed prior to the non-blocking read() ++ * system call, the underlying hardware will be accessed and the motion detect ++ * status will be updated. The status data byte will be copied to the user ++ * supplied buffer. The following bits will then be cleared in the motion ++ * detect status byte: ++ * ++ * BMI_MOTION_DETECT_LATCHED_STATUS ++ * BMI_MOTION_DETECT_DELTA ++ * ++ * The driver will then be marked as "not-ready-to-read". ++ * ++ * ++ * Motion Detect select() system call ++ * ----------------------------------- ++ * ++ * This driver supports select() for read only. Select for write and ++ * exception is not supported. ++ * ++ * When a Motion Detect interrupt occurs, the file descriptor corresponding ++ * to the Motion Detector driver will be marked as "ready for read". ++ * ++ * --------------------------------------------------------------------------- ++ */ ++ ++ ++/*---------------------------------------------------------------------------- ++ * ++ * BMI MDACC Accelerometer Driver ++ * ++ *---------------------------------------------------------------------------- ++ * ++ * This character driver provides access to the accelerometer data via an SPI ++ * interface. This driver enforces single-open and stop-on-close behaviors. ++ * ++ * Supported system calls: open(), close(), ioctl(). read(), select(). ++ * ++ * ++ * MDACC Accelerometer Driver Configuration ++ * ----------------------------------------- ++ * ++ * The micro-controller on the MDACC Plug-In module uses an internal 10 bit A/D ++ * converter to sample the 3 analog output channels of the accelerometer ++ * device. The analog channels are sampled periodically at a rate that can be ++ * configured by an application program. When a set of 3 channel samples has ++ * been acquired, the micro-controller generates an interrupt to the host ++ * processor. The host processor then issues SPI messages to the ++ * micro-controller to obtain the 3 channel sample set. ++ * ++ * The MDACC Accelerometer Driver provides a read queue to store sample data ++ * until it can be read by the application program. The size of the read queue ++ * and a read-queue "ready" threshold can both be specified by the application ++ * program. ++ * ++ * ++ * MDACC Accelerometer Driver ioctl() interface ++ * -------------------------------------------- ++ ++ * The following IOCTL commands are defined for this driver. ++ * ++ * BMI_MDACC_ACCELEROMETER_SET_CONFIG ++ * BMI_MDACC_ACCELEROMETER_GET_CONFIG ++ * BMI_MDACC_ACCELEROMETER_RUN ++ * BMI_MDACC_ACCELEROMETER_STOP ++ * ++ * ++ * BMI_MDACC_ACCELEROMETER_SET_CONFIG ++ * ++ * This ioctl command transfers an mdacc_accel_config structure from the ++ * application program to the MDACC Accelerometer Driver. ++ * The third argument to this ioctl system call is the address of the an ++ * mdacc_accel_config structure. ++ * ++ * In the mdacc_accel_config structure, if the delay_mode field is 0, ++ * the values of the delay and delay resolution fields are ignored and ++ * and a default delay value of 4 milliseconds is used. ++ * ++ * BMI_MDACC_ACCELEROMETER_GET_CONFIG ++ * ++ * This ioctl command transfers an mdacc_accel_config structure from the ++ * MDACC Accelerometer Drive to the application program. ++ * The third argument to this ioctl system call is the address of the an ++ * mdacc_accel_config structure. ++ * ++ * ++ * BMI_MDACC_ACCELEROMETER_RUN ++ * ++ * This ioctl command will enable the accelerometer data aquistion in the MDACC ++ * Accelerometer Driver and in the MDACC micro-controller. The behavior of this ++ * ioctl command can also be invoked by an ++ ++ * "ioctl(BMI_MDACC_ACCELEROMETER_SET_CONFIG)" system call with ++ * "mdacc_accel_config.run = 1". ++ * ++ * BMI_MDACC_ACCELEROMETER_STOP ++ * ++ * This ioctl command will disable the accelerometer data aquistion in the MDACC ++ * Accelerometer Driver and in the MDACC micro-controller. The behavior of this ++ * ioctl command can also be invoked by an ++ * ++ * "ioctl(BMI_MDACC_ACCELEROMETER_SET_CONFIG)" system call with ++ * "mdacc_accel_config.run = 0". ++ * ++ * Note that this behavior is also invoked in the close() system call if the ++ * accelerometer had previously been enabled. ++ * ++ * ++ * MDACC Accelerometer Driver read() interface ++ * ------------------------------------------- ++ * ++ * The read() call for this driver allows the application program to read ++ * motion detector status only when the status has changed. ++ * ++ * Prior to issuing a read() to this driver, the application must enabled the ++ * motion detector using the "ioctl(BMI_MDACC_MOTION_DETECTOR_RUN)" command. ++ * ++ * read parameters: ++ * ++ * buffer: address of an array of mdacc_accel_sample structures. ++ * size: size of the mdacc_accel_sample array in bytes. ++ * ++ * Accelerometer blocking read() behavior ++ * -------------------------------------- ++ * ++ * If the accelerometer read queue DOES NOT contain at least "read-threshold" ++ * number of sample set entries, then the driver will sleep. ++ * ++ * If the the driver is awoken by a signal, the driver will return failure (-1) ++ * and errno will be set to ERESTARTSYS. ++ ++ * Otherwise, the requested number of sample sets are removed from the driver ++ * read queue and copied to user space. The number of bytes transfers will be ++ * returned to the application. ++ * ++ * At the end of the transfer, if the number of read queue entries is below the ++ * read-threshold, the the driver will then be marked as "not-ready-to-read". ++ * ++ * ++ * Accelerometer non-blocking read() behavior ++ * ------------------------------------------ ++ * If the accelerometer read queue DOES NOT contain at least "read-threshold" ++ * number of sample set entries, then the driver will return failure (-1) and ++ * errno will be set to EAGAIN. ++ * ++ * Otherwise, the requested number of sample sets are removed from the driver ++ * read queue and copied to user space. The number of bytes transfers will be ++ * returned to the application. ++ * ++ * At the end of the transfer, if the number of read queue entries is below the ++ * read-threshold, the the driver will then be marked as "not-ready-to-read". ++ * ++ * ++ * Accelerometer select() system call ++ * ----------------------------------- ++ * ++ * This driver supports select() for read only. Select for write and ++ * exception is not supported. ++ * ++ * When a data arrives and is inserted into the read queue and the number of ++ * queue entries meets or exceeds the read-threshold, the file descriptor ++ * corresponding to the Accelerometer driver will be marked as ++ * "ready for read". ++ * --------------------------------------------------------------------------- ++ * ++ * Accelerometer Data Samples ++ * --------------------------- ++ * ++ * The accelerometer analog outputs are sampled with a 10 bit A/D converter ++ * using 2.9V as a reference. ++ * ++ * An accelerometer output of 1.45V corresponds to "0g". ++ * ++ * The accelerometer outputs are scaled by the sensitivity settings. ++ * ++ * sensitivity scale factor ++ * --------------------------- ++ * 0 = 2.5G, 421 mV/G ++ * 1 = 3.3G, 316 mV/G ++ * 2 = 6.7G, 158 mV/G ++ * 3 = 10G, 105 mV/G ++ * ++ * The following equation converts an A/D sample to a G-Force value. ++ * ++ * G-force = ( ((digital sample) * (X mV/bit)) - 1450 mV) / (scale factor ) ++ * ++ * --------------------------------------------------------------------------- ++ * ++ * Accelerometer Coordinate System. ++ * ++ * ++ * z axis: perpendicular to PCB. ++ * y axis: parallel to the long edge of the connector. ++ * x axis: perpendicular to the short edge of the connector. ++ * ++ * ++ * Top View Side View ++ * ++ * +--------------------------------------+ +-+ ++ * | +x LEDS | | | ++ * | +------------------------+ | | +-----+ ++ * | -y | connector underneath | +y | | | ++ * | +------------------------+ | | +-----+ ++ * | ____ | | | ++ * | / \ | | | ++ * | | | | -z | | +z ++ * | \ ____ / | | | ++ * | | | | ++ * | motion sensor on top | | | ++ * | | | | ++ * | -x | | | ++ * +--------------------------------------+ +-+ ++ * ++ * --------------------------------------------------------------------------- ++ */ ++#ifndef LINUX_BMI_BMI_MDACC_H ++#define LINUX_BMI_BMI_MDACC_H ++ ++#include ++ ++/* ------------------------- ++ * ++ * MDACC Control Driver ++ * ++ *-------------------------- ++ */ ++#define BMI_MDACC_CTL_RED_LED_OFF \ ++ _IOW(BMI_MDACC_IOCTL, 0, char) // Turn off red LED ++ ++#define BMI_MDACC_CTL_RED_LED_ON \ ++ _IOW(BMI_MDACC_IOCTL, 1, char) // Turn on red LED ++ ++#define BMI_MDACC_CTL_GREEN_LED_OFF \ ++ _IOW(BMI_MDACC_IOCTL, 2, char) // Turn off green LED ++ ++#define BMI_MDACC_CTL_GREEN_LED_ON \ ++ _IOW(BMI_MDACC_IOCTL, 3, char) // Turn on green LED ++ ++ ++/* ------------------------------- ++ * ++ * MDACC Motion Detector Driver ++ * ++ *-------------------------------- ++ */ ++ ++/* Status Byte Bit Definitions */ ++ ++#define BMI_MOTION_DETECT_STATUS (1<<3) ++#define BMI_MOTION_DETECT_LATCHED_STATUS (1<<2) ++#define BMI_MOTION_DETECT_DELTA (1<<1) ++#define BMI_MOTION_DETECT_ENABLED (1<<0) ++ ++/* Ioctl Commands */ ++ ++#define BMI_MDACC_MOTION_DETECTOR_GET_STATUS \ ++ _IOR (BMI_MDACC_IOCTL, 4, char) ++ ++#define BMI_MDACC_MOTION_DETECTOR_RUN \ ++ _IOW (BMI_MDACC_IOCTL, 5, char) ++ ++#define BMI_MDACC_MOTION_DETECTOR_STOP \ ++ _IOW (BMI_MDACC_IOCTL, 6, char) ++ ++ ++/* ------------------------------- ++ * ++ * MDACC Accelerometer Driver ++ * ++ *-------------------------------- ++ */ ++struct mdacc_accel_sample { ++ ++ unsigned short adc_0; //accelerometer channel Z, 10 bit, left justified ++ //referenced to VCC = 2.9V ++ ++ unsigned short adc_1; //accelerometer channel Y, 10 bit, left justified. ++ //referenced to VCC = 2.9V. ++ ++ unsigned short adc_2; //accelerometer channel X, 10 bit, left justified. ++ //referenced to VCC = 2.9 V. ++}; ++ ++ ++struct mdacc_accel_config { ++ ++ int read_queue_size; // number of 6-byte sample sets. ++ ++ int read_queue_threshold; // number of 6-byte sample sets to queue ++ // before ready. ++ ++ unsigned short delay; // timer ticks between the start of 2 ++ // sucessive sample sets. ++ ++ unsigned char delay_resolution; // timer tick resolution ++ // 1 = 1 usec, ++ // 2 = 8 usec, ++ // 3 = 64 usec, ++ // 4 = 256 usec, ++ // 5 = 1024 usec ++ ++ unsigned char delay_mode; //0 = default delay = 5 millisecond, ++ // ignore delay and delay_resolution ++ //1 = configured delay ++ ++ unsigned char run; //0 = sampling disabled ++ //1 = sampling enabled ++ ++ unsigned char sensitivity; // 0 = 2.5G, 421 mV/G ++ // 1 = 3.3G, 316 mV/G ++ // 2 = 6.7G, 158 mV/G ++ // 3 = 10G, 105 mV/G ++ ++}; ++ ++ ++ ++#define BMI_MDACC_ACCELEROMETER_SET_CONFIG \ ++ _IOW (BMI_MDACC_IOCTL, 7, struct mdacc_accel_config) ++ ++#define BMI_MDACC_ACCELEROMETER_GET_CONFIG \ ++ _IOR (BMI_MDACC_IOCTL, 8, struct mdacc_accel_config) ++ ++ ++#define BMI_MDACC_ACCELEROMETER_RUN \ ++ _IOW (BMI_MDACC_IOCTL, 9, char) ++ ++#define BMI_MDACC_ACCELEROMETER_STOP \ ++ _IOW (BMI_MDACC_IOCTL, 10, char) ++ ++#define BMI_MDACC_LAST_USED (10) ++#endif +--- /dev/null ++++ git/include/linux/bmi/bmi_projector.h +@@ -0,0 +1,33 @@ ++/* ++ * File: include/linux/bmi/bmi_projector.h ++ * Author: Suresh Rao ++ * ++ * This is the application header file for the BMI bus projector plug-in ++ * module on the MX31 BUG platform. ++ */ ++ ++#ifndef BMI_PROJECTOR_H ++#define BMI_PROJECTOR_H ++ ++#include ++#include ++ ++// IOCTL commands for BMI PROJECTOR driver ++#define BMI_PROJECTOR_ON _IOW(BMI_PROJECTOR_IOCTL, 0x1, __u32) // turn on projector ++#define BMI_PROJECTOR_MODE _IOW(BMI_PROJECTOR_IOCTL, 0x2, __u32) // turn on projector ++#define BMI_PROJECTOR_OFF _IOW(BMI_PROJECTOR_IOCTL, 0x3, __u32) // turn off projector ++#define BMI_PROJECTOR_BATTERY _IOW(BMI_PROJECTOR_IOCTL, 0x4, __u32) // Battery charger on to bug from projector ++ ++// IOCTL commands for Encoder control ++#define BMI_PROJECTOR_HUE _IOW(BMI_PROJECTOR_IOCTL, 0x5, __u32) // Hue control in Encoder ++#define BMI_PROJECTOR_SATURATION _IOW(BMI_PROJECTOR_IOCTL, 0x6, __u32) // Saturation control in Encoder ++#define BMI_PROJECTOR_BRIGHTNESS _IOW(BMI_PROJECTOR_IOCTL, 0x7, __u32) // Brightness control in Encoder ++#define BMI_PROJECTOR_SHARPNESS _IOW(BMI_PROJECTOR_IOCTL, 0x8, __u32) // Sharpness control in Encoder ++#define BMI_PROJECTOR_CONTRAST _IOW(BMI_PROJECTOR_IOCTL, 0x9, __u32) // Contrast control in Encoder ++ ++/* BMI_PROJECTOR_MODE settings */ ++#define PROJECTOR_ECONOMY_MODE 0x0 ++#define PROJECTOR_BRIGHT_MODE 0x1 ++ ++#endif /* BMI_PROJECTOR_H */ ++ +--- /dev/null ++++ git/include/linux/bmi/bmi_sensor.h +@@ -0,0 +1,673 @@ ++/* ++ * File: include/linux/bmi/bmi_sensor.h ++ * Author: Peter Giacomini ++ * ++ * This is the application header file for the BMI bus sensor plug-in ++ * module on the MX31 BUG platform. ++ */ ++ ++#ifndef BMI_SENSOR_H ++#define BMI_SENSOR_H ++ ++#include ++#include ++ ++// GPIO ++#define SENSOR_GPIO_RED_LED 3 // output ++#define SENSOR_GPIO_GREEN_LED 2 // output ++#define SENSOR_GPIO_PDOUT 1 // input - aproximity detector state ++#define SENSOR_GPIO_MOT_DET 0 // input - motion detector state ++ ++#define SENSOR_GPIO_LED_ON 0 ++#define SENSOR_GPIO_LED_OFF 1 ++ ++// I2C ++// I2C Slave Addresses ++#define BMI_MEE_I2C_ADDRESS 0x51 // 7-bit address - Module specific EEPROM ++#define BMI_IOX_I2C_ADDRESS 0x74 // 7-bit address - 2 banks I2C IO expander ++#define BMI_ADC_I2C_ADDRESS 0x48 // 7-bit address - ADC - humidity/acompass/sound/alight/aproximity ++#define BMI_PL_I2C_ADDRESS 0x44 // 7-bit address - digital proximity/light ++#define BMI_DLIGHT_I2C_ADDRESS 0x44 // 7-bit address - digital light ++#define BMI_TEMP_I2C_ADDRESS 0x4C // 7-bit address - temperature ++#define BMI_ACCEL_I2C_ADDRESS 0x1D // 7-bit address - accelerometer ++#define BMI_DCOMP_I2C_ADDRESS 0x1C // 7-bit address - digital compass ++ ++// I2C IOX register addresses ++#define IOX_INPUT0_REG 0x0 ++#define IOX_INPUT1_REG 0x1 ++#define IOX_OUTPUT0_REG 0x2 ++#define IOX_OUTPUT1_REG 0x3 ++#define IOX_POLARITY0_REG 0x4 ++#define IOX_POLARITY1_REG 0x5 ++#define IOX_CONTROL0_REG 0x6 ++#define IOX_CONTROL1_REG 0x7 ++ ++// IOX bit definitions ++// bank 0 ++#define SENSOR_IOX_ACC_INT1 0 // Input - Accelerometer interrupt 1 ++#define SENSOR_IOX_ACC_INT2 1 // Input - Accelerometer interrupt 2 ++#define SENSOR_IOX_USB_FL_N 2 // Input - USB power interrupt ++#define SENSOR_IOX_USB_EN 3 // Output - USB power enable ++#define SENSOR_IOX_HUM_EN 4 // Output - Humidity sensor power enable ++#define SENSOR_IOX_MOT_DET 5 // Input - Motion Detector interrupt ++#define SENSOR_IOX_MOT_EN 6 // Output - Motion Detector interrupt enable ++#define SENSOR_IOX_COMP_RS_N 7 // Output - A/D Compass Reset (see Honeywell AN213) ++// bank 1 ++#define SENSOR_IOX_PROX_RST_N 0 // Output - Analog Proximity sensor reset ++#define SENSOR_IOX_PROX_EN_N 1 // Output - Analog Proximity sensor enable ++#define SENSOR_IOX_PROX_OUT 2 // Input - Analog Proximity sensor output ++#define SENSOR_IOX_S_PK_CLR_N 3 // Output - Sound peak detector clear ++#define SENSOR_IOX_TEMP_INT 4 // Input - Termperature interrupt ++#define SENSOR_IOX_PL_INT 5 // Input - Proximity/Light interrupt ++#define SENSOR_IOX_MIC_EN 6 // Output - Sound power enanle ++#define SENSOR_IOX_DCOMP_INT 7 // Input - Digital Compass Interrupt ++ ++// EEPROM contents ++struct sensor_eeprom_raw ++{ ++ __u8 xsf_msb; /* byte 0x00 */ // analog and digital compass ++ __u8 xsf_lsb; /* byte 0x01 */ // analog and digital compass ++ __u8 ysf_msb; /* byte 0x02 */ // analog and digital compass ++ __u8 ysf_lsb; /* byte 0x03 */ // analog and digital compass ++ __u8 zsf_msb; /* byte 0x04 */ // analog and digital compass ++ __u8 zsf_lsb; /* byte 0x05 */ // analog and digital compass ++ __u8 xoff_msb; /* byte 0x06 */ // analog and digital compass ++ __u8 xoff_lsb; /* byte 0x07 */ // analog and digital compass ++ __u8 yoff_msb; /* byte 0x08 */ // analog and digital compass ++ __u8 yoff_lsb; /* byte 0x09 */ // analog and digital compass ++ __u8 zoff_msb; /* byte 0x0A */ // analog and digital compass ++ __u8 zoff_lsb; /* byte 0x0B */ // analog and digital compass ++ __u8 xdac; /* byte 0x0C */ // digital compass ++ __u8 ydac; /* byte 0x0D */ // digital compass ++ __u8 zdac; /* byte 0x0E */ // digital compass ++ __u8 adc_present; /* byte 0x0F - 0x1 == present */ // TI/Burr-Brown ADS7828 ++ __u8 humidity_present; /* byte 0x10 - 0x1 == present */ // Honeywell HIH3030 ++ __u8 acompass_present; /* byte 0x11 - 0x1 == present */ // Honeywell HMC6042/HMC1041Z ++ __u8 light_proximity_present; /* byte 0x12 - 0x1 == present */ // Intersil ISL29018 ++ __u8 sound_present; /* byte 0x13 - 0x1 == present */ // discrete components ++ __u8 temperature_present; /* byte 0x14 - 0x1 == present */ // National LM95235 ++ __u8 motion_present; /* byte 0x15 - 0x1 == present */ // Panasonic AMN44121 ++ __u8 accel_present; /* byte 0x16 - 0x1 == present */ // Analog Devices ADXL345 ++ __u8 dcompass_present; /* byte 0x17 - 0x1 == present */ // AsahiKASEI AK8973 ++ __u8 aproximity_present; /* byte 0x18 - 0x1 == present */ // Avago APDS-9700 ++ __u8 alight_present; /* byte 0x19 - 0x1 == present */ // Avago APDS-9002 ++ __u8 dlight_present; /* byte 0x1A - 0x1 == present */ // Intersil ISL29003 ++ __u8 acc302_present; /* byte 0x1B - 0x1 == present */ // ST LIS302DL ++}; ++#define SENSOR_DEVICE_NOT_PRESENT (0x0) ++#define SENSOR_DEVICE_PRESENT (0x1) ++#define SENSOR_EE_SF_START (0x00) ++#define SENSOR_EE_OFF_START (0x06) ++#define SENSOR_EE_XDAC (0x0C) ++#define SENSOR_EE_YDAC (0x0D) ++#define SENSOR_EE_ZDAC (0x0E) ++#define SENSOR_PRESENT_START (0x0F) ++#define SENSOR_PRESENT_END (0x1B) ++ ++struct sensor_comp_cal ++{ ++ unsigned int xsf; ++ unsigned int ysf; ++ unsigned int zsf; ++ unsigned int xoff; ++ unsigned int yoff; ++ unsigned int zoff; ++}; ++ ++struct sensor_comp_dac ++{ ++ unsigned char xdac; ++ unsigned char ydac; ++ unsigned char zdac; ++}; ++ ++// ADC (ADS7828) - humidity/acompass/sound/alight/aproximity ++// command write ++#define SENSOR_ADC_D10P (0x00 << 4) // positive diff - ch0 & ch1 ++#define SENSOR_ADC_D23P (0x01 << 4) // positive diff - ch2 & ch3 ++#define SENSOR_ADC_D45P (0x02 << 4) // positive diff - ch4 & ch5 ++#define SENSOR_ADC_D67P (0x03 << 4) // positive diff - ch6 & ch7 ++#define SENSOR_ADC_D10N (0x04 << 4) // negative diff - ch0 & ch1 ++#define SENSOR_ADC_D23N (0x05 << 4) // negative diff - ch2 & ch3 ++#define SENSOR_ADC_D45N (0x06 << 4) // negative diff - ch4 & ch5 ++#define SENSOR_ADC_D67N (0x07 << 4) // negative diff - ch6 & ch7 ++#define SENSOR_ADC_CH0 (0x08 << 4) // single ended ch0 ++#define SENSOR_ADC_CH2 (0x09 << 4) // single ended ch2 ++#define SENSOR_ADC_CH4 (0x0A << 4) // single ended ch4 ++#define SENSOR_ADC_CH6 (0x0B << 4) // single ended ch6 ++#define SENSOR_ADC_CH1 (0x0C << 4) // single ended ch1 ++#define SENSOR_ADC_CH3 (0x0D << 4) // single ended ch3 ++#define SENSOR_ADC_CH5 (0x0E << 4) // single ended ch5 ++#define SENSOR_ADC_CH7 (0x0F << 4) // single ended ch7 ++#define SENSOR_ADC_PD_OFF (0x00 << 2) // full power down ++#define SENSOR_ADC_PD_IR (0x01 << 2) // power down internal reference ++#define SENSOR_ADC_PD_ADC (0x02 << 2) // power down ADC ++#define SENSOR_ADC_PD_ON (0x03 << 2) // power up ADC ++// data read ++#define SENSOR_ADC_DATA_MSB (0x0F) ++#define SENSOR_ADC_DATA_LSB (0xFF) ++ ++// ADC mapping ++#define SENSOR_ADC_SOUND_PEAK SENSOR_ADC_CH7 ++#define SENSOR_ADC_SOUND_AVG SENSOR_ADC_CH6 ++#define SENSOR_ADC_APROXIMITY SENSOR_ADC_CH5 // Analog proximity ++#define SENSOR_ADC_HUMIDITY SENSOR_ADC_CH4 ++#define SENSOR_ADC_LIGHT SENSOR_ADC_CH3 // Analog light ++#define SENSOR_ADC_ACOMPASS_Z SENSOR_ADC_CH2 // Analog compass ++#define SENSOR_ADC_ACOMPASS_Y SENSOR_ADC_CH1 // Analog compass ++#define SENSOR_ADC_ACOMPASS_X SENSOR_ADC_CH0 // Analog compass ++ ++// Light/Proximity ++#define SENSOR_PL_CMD1 (0x00) // command I ++ #define SENSOR_PL_CMD1_PD (0x00 << 5) // power down ++ #define SENSOR_PL_CMD1_ALS_1X (0x01 << 5) // ALS once ++ #define SENSOR_PL_CMD1_IR_1X (0x02 << 5) // IR once ++ #define SENSOR_PL_CMD1_PROX_1X (0x03 << 5) // Proximity once ++ #define SENSOR_PL_CMD1_ALS_CONT (0x05 << 5) // ALS continuous ++ #define SENSOR_PL_CMD1_IR_CONT (0x06 << 5) // IR continuous ++ #define SENSOR_PL_CMD1_PROX_CONT (0x07 << 5) // Proximity continuous ++ #define SENSOR_PL_CMD1_INT_TIMING (0x00) // Proximity continuous ++ #define SENSOR_PL_CMD1_EXT_TIMING (0x10) // Proximity continuous ++ #define SENSOR_PL_CMD1_DATA_ADC (0x00) // data is ADC value ++ #define SENSOR_PL_CMD1_DATA_TIMING (0x08) // data is ADC value ++ #define SENSOR_PL_CMD1_INT_STAT (0x04) // interrupt status ++ #define SENSOR_PL_CMD1_INT_1MS (0x00) // interrupt persist = 1 ms ++ #define SENSOR_PL_CMD1_INT_4MS (0x01) // interrupt persist = 4 ms ++ #define SENSOR_PL_CMD1_INT_8MS (0x02) // interrupt persist = 8 ms ++ #define SENSOR_PL_CMD1_INT_16MS (0x03) // interrupt persist = 16 ms ++#define SENSOR_PL_CMD2 (0x01) // command II ++ #define SENSOR_PL_CMD2_IR_LED_A (0x00) // sense IR from LED and ambient ++ #define SENSOR_PL_CMD2_IR_LED (0x80) // sense IR from LED only ++ #define SENSOR_PL_CMD2_MOD_DC (0x00) // IR LED modulation = DC ++ #define SENSOR_PL_CMD2_MOD_327K (0x40) // IR LED modulation = 327.7 kHz ++ #define SENSOR_PL_CMD2_DRIVE_12M (0x00 << 4) // IR drive current = 12.5 mA ++ #define SENSOR_PL_CMD2_DRIVE_25M (0x01 << 4) // IR drive current = 25 mA ++ #define SENSOR_PL_CMD2_DRIVE_50M (0x02 << 4) // IR drive current = 50 mA ++ #define SENSOR_PL_CMD2_DRIVE_100M (0x03 << 4) // IR drive current = 100 mA ++ #define SENSOR_PL_CMD2_ADC_RES_16 (0x00 << 2) // ADC resolution = 16 bits ++ #define SENSOR_PL_CMD2_ADC_RES_12 (0x01 << 2) // ADC resolution = 12 bits ++ #define SENSOR_PL_CMD2_ADC_RES_8 (0x02 << 2) // ADC resolution = 8 bits ++ #define SENSOR_PL_CMD2_ADC_RES_4 (0x03 << 2) // ADC resolution = 4 bits ++ #define SENSOR_PL_CMD2_ALS_RNG_1 (0x00) // ALS sensing = 1000 LUX ++ #define SENSOR_PL_CMD2_ALS_RNG_4 (0x01) // ALS sensing = 4000 LUX ++ #define SENSOR_PL_CMD2_ALS_RNG_16 (0x02) // ALS sensing = 16000 LUX ++ #define SENSOR_PL_CMD2_ALS_RNG_64 (0x03) // ALS sensing = 64000 LUX ++#define SENSOR_PL_DATA_LSB (0x02) // Data ++#define SENSOR_PL_DATA_MSB (0x03) // Data ++#define SENSOR_PL_INT_LT_LSB (0x04) // Low interrupt threshold LSB ++#define SENSOR_PL_INT_LT_MSB (0x05) // Low interrupt threshold MSB ++#define SENSOR_PL_INT_HT_LSB (0x06) // High interrupt threshold LSB ++#define SENSOR_PL_INT_HT_MSB (0x07) // High interrupt threshold MSB ++#define SENSOR_PL_EXT_SYNC (0x80) // write address to restart ADC integration ++ ++struct sensor_pl_rw { // see the datasheet ++ unsigned char cmd1; ++ unsigned char cmd2; ++ unsigned char dl; ++ unsigned char dm; ++ unsigned char int_lt_lsb; ++ unsigned char int_lt_msb; ++ unsigned char int_ht_lsb; ++ unsigned char int_ht_msb; ++}; ++ ++// Digital Light ++#define SENSOR_DL_CMD (0x00) // command ++ #define SENSOR_DL_CMD_ADC_EN (0x80) // enable ADC core ++ #define SENSOR_DL_CMD_ADC_DIS (0x00) // disable ADC core ++ #define SENSOR_DL_CMD_PD (0x40) // power down ++ #define SENSOR_DL_CMD_EXT_SYNC (0x20) // external sync ++ #define SENSOR_DL_CMD_MODE_D1 (0x00) // ADC work mode = Diode 1, 16 bits ++ #define SENSOR_DL_CMD_MODE_D2 (0x04) // ADC work mode = Diode 2, 16 bits ++ #define SENSOR_DL_CMD_MODE_DIFF (0x08) // ADC work mode = I1-I2, 15 bits ++ #define SENSOR_DL_CMD_W16 (0x00) // 2^16 cycles ++ #define SENSOR_DL_CMD_W12 (0x01) // 2^12 cycles ++ #define SENSOR_DL_CMD_W8 (0x02) // 2^8 cycles ++ #define SENSOR_DL_CMD_W4 (0x03) // 2^4 cycles ++#define SENSOR_DL_CONT (0x01) // control ++ #define SENSOR_DL_CONT_INT (0x20) // interrupt status ++ #define SENSOR_DL_G1 (0x00) // gain < 1000 LUX ++ #define SENSOR_DL_G4 (0x04) // gain < 4000 LUX ++ #define SENSOR_DL_G16 (0x08) // gain < 16000 LUX ++ #define SENSOR_DL_G64 (0x0C) // gain < 64000 LUX ++ #define SENSOR_DL_IP1 (0x00) // interrupt persistence = 1 cycle ++ #define SENSOR_DL_IP4 (0x01) // interrupt persistence = 4 cycle ++ #define SENSOR_DL_IP8 (0x02) // interrupt persistence = 8 cycle ++ #define SENSOR_DL_IP16 (0x03) // interrupt persistence = 16 cycle ++#define SENSOR_DL_INT_THI (0x02) // ++#define SENSOR_DL_INT_TLO (0x03) // ++#define SENSOR_DL_SENSOR_LSB (0x04) // ++#define SENSOR_DL_SENSOR_MSB (0x05) // ++#define SENSOR_DL_TIMER_LSB (0x06) // ++#define SENSOR_DL_TIMER_MSB (0x07) // ++#define SENSOR_DL_EXT_SYNC (0x80) // ++#define SENSOR_DL_INT_CLR (0x40) // ++ ++struct sensor_dl_rw { // see the datasheet ++ unsigned char cmd; ++ unsigned char control; ++ unsigned char int_thi; ++ unsigned char int_tlo; ++ unsigned int sensor_data; ++}; ++ ++// Temperature ++#define SENSOR_TEMP_LOC_MSB (0x00) // Local temperature MSB ++#define SENSOR_TEMP_ROFF_HIGH (0x11) // Remote offset high ++ // 10-bit plus sign format ++ #define SENSOR_TEMP_LOC_MSB_10B_SIGN (0x80) // Sign ++ #define SENSOR_TEMP_LOC_MSB_10B_64 (0x40) ++ #define SENSOR_TEMP_LOC_MSB_10B_32 (0x20) ++ #define SENSOR_TEMP_LOC_MSB_10B_16 (0x10) ++ #define SENSOR_TEMP_LOC_MSB_10B_8 (0x08) ++ #define SENSOR_TEMP_LOC_MSB_10B_4 (0x04) ++ #define SENSOR_TEMP_LOC_MSB_10B_2 (0x02) ++ #define SENSOR_TEMP_LOC_MSB_10B_1 (0x01) ++#define SENSOR_TEMP_LOC_LSB (0x30) // Local temperature LSB ++#define SENSOR_TEMP_ROFF_LOW (0x12) // Remote offset low ++ // 10-bit plus sign format ++ #define SENSOR_TEMP_LOC_LSB_10B_P5 (0x80) ++ #define SENSOR_TEMP_LOC_LSB_10B_P25 (0x40) ++ #define SENSOR_TEMP_LOC_LSB_10B_P125 (0x20) ++#define SENSOR_TEMP_REM_MSB (0x01) // Remote temperature MSB ++ // 12-bit plus sign format ++ #define SENSOR_TEMP_REM_MSB_12B_SIGN (0x80) // Sign ++ #define SENSOR_TEMP_REM_MSB_12B_64 (0x40) ++ #define SENSOR_TEMP_REM_MSB_12B_32 (0x20) ++ #define SENSOR_TEMP_REM_MSB_12B_16 (0x10) ++ #define SENSOR_TEMP_REM_MSB_12B_8 (0x08) ++ #define SENSOR_TEMP_REM_MSB_12B_4 (0x04) ++ #define SENSOR_TEMP_REM_MSB_12B_2 (0x02) ++ #define SENSOR_TEMP_REM_MSB_12B_1 (0x01) ++#define SENSOR_TEMP_REM_LSB (0x10) // Remote temperature LSB ++ // 12-bit plus sign format with filter off ++ #define SENSOR_TEMP_REM_LSB_12B_P5 (0x80) ++ #define SENSOR_TEMP_REM_LSB_12B_P25 (0x40) ++ #define SENSOR_TEMP_REM_LSB_12B_P125 (0x20) ++ // 12-bit plus sign format with filter on ++ #define SENSOR_TEMP_REM_LSB_12B_P0625 (0x10) ++ #define SENSOR_TEMP_REM_LSB_12B_P03125 (0x04) ++#define SENSOR_TEMP_UREM_MSB (0x31) // Remote unsigned temperature MSB ++ // 13-bit usigned format ++ #define SENSOR_TEMP_UREM_MSB_12B_128 (0x80) ++ #define SENSOR_TEMP_UREM_MSB_12B_64 (0x40) ++ #define SENSOR_TEMP_UREM_MSB_12B_32 (0x20) ++ #define SENSOR_TEMP_UREM_MSB_12B_16 (0x10) ++ #define SENSOR_TEMP_UREM_MSB_12B_8 (0x08) ++ #define SENSOR_TEMP_UREM_MSB_12B_4 (0x04) ++ #define SENSOR_TEMP_UREM_MSB_12B_2 (0x02) ++ #define SENSOR_TEMP_UREM_MSB_12B_1 (0x01) ++#define SENSOR_TEMP_UREM_LSB (0x32) // Remote unsigned temperature LSB ++ // 13-bit usigned format with filter off ++ #define SENSOR_TEMP_UREM_LSB_12B_P5 (0x80) ++ #define SENSOR_TEMP_UREM_LSB_12B_P25 (0x40) ++ #define SENSOR_TEMP_UREM_LSB_12B_P125 (0x20) ++ // 13-bit usigned format with filter on ++ #define SENSOR_TEMP_UREM_LSB_12B_P0625 (0x10) ++ #define SENSOR_TEMP_UREM_LSB_12B_P03125 (0x04) ++#define SENSOR_TEMP_CONF2 (0xBF) // Diode configuration ++ #define SENSOR_TEMP_CONF2_A0 (0x40) // A0 pin function ++ #define SENSOR_TEMP_CONF2_OS (0x00) // A0 pin function ++ #define SENSOR_TEMP_CONF2_OS_ON (0x20) // OS fault mask on ++ #define SENSOR_TEMP_CONF2_OS_OFF (0x00) // OS fault mask off ++ #define SENSOR_TEMP_CONF2_TCRIT_ON (0x10) // TCRIT fault mask on ++ #define SENSOR_TEMP_CONF2_TCRIT_OFF (0x00) // TCRIT fault mask off ++ #define SENSOR_TEMP_CONF2_DMOD1 (0x00) // Diode model 1 ++ #define SENSOR_TEMP_CONF2_DMOD2 (0x08) // Diode model 1 ++ #define SENSOR_TEMP_CONF2_FILT_OFF (0x00 << 1) // Filter off ++ #define SENSOR_TEMP_CONF2_FILT_ON (0x03 << 1) // Filter on ++#define SENSOR_TEMP_CONF1_RD (0x03) // General configuration ++#define SENSOR_TEMP_CONF1_WR (0x09) // General configuration ++ #define SENSOR_TEMP_CONF1_RUN (0x00) // Active/Converting ++ #define SENSOR_TEMP_CONF1_STOP (0x40) // Standby ++ #define SENSOR_TEMP_R_TCRIT_MASK_OFF (0x00) // Remote TCRIT ++ #define SENSOR_TEMP_R_TCRIT_MASK_ON (0x10) // Remote TCRIT ++ #define SENSOR_TEMP_R_OS_MASK_OFF (0x00) // Remote OS ++ #define SENSOR_TEMP_R_OS_MASK_ON (0x08) // Remote OS ++ #define SENSOR_TEMP_L_TCRIT_MASK_OFF (0x00) // Local TCRIT ++ #define SENSOR_TEMP_L_TCRIT_MASK_ON (0x04) // Local TCRIT ++ #define SENSOR_TEMP_L_OS_MASK_OFF (0x00) // Local OS ++ #define SENSOR_TEMP_L_OS_MASK_ON (0x02) // Local OS ++#define SENSOR_TEMP_CONV_RD (0x04) // Conversion rate ++#define SENSOR_TEMP_CONV_WR (0x0A) // Conversion rate ++ #define SENSOR_TEMP_CONV_CONT (0x00) // Continuous ++ #define SENSOR_TEMP_CONV_P364 (0x01) // .364 seconds ++ #define SENSOR_TEMP_CONV_1 (0x02) // 1 second ++ #define SENSOR_TEMP_CONV_2P5 (0x03) // 2.5 seconds ++#define SENSOR_TEMP_ONE_SHOT (0x0F) // Remote offset low ++#define SENSOR_TEMP_STAT1 (0x02) // Status 1 ++ #define SENSOR_TEMP_STAT1_BUSY (0x80) // Converting ++ #define SENSOR_TEMP_STAT1_ROS (0x10) // Remote OS ++ #define SENSOR_TEMP_STAT1_DFAULT (0x04) // Diode Fault ++ #define SENSOR_TEMP_STAT1_RTCRIT (0x02) // Remote TCRIT ++ #define SENSOR_TEMP_STAT1_LOC (0x01) // Local OS & TCRIT ++#define SENSOR_TEMP_STAT2 (0x33) // Status 2 ++ #define SENSOR_TEMP_STAT2_NR (0x80) // Not Ready - 30 ms power-up ++ #define SENSOR_TEMP_STAT2_TT (0x40) // TruTherm Diode detected ++#define SENSOR_TEMP_REM_OS_LIM_RD (0x07) // Remote OS limit ++#define SENSOR_TEMP_REM_OS_LIM_WR (0x0D) // Remote OS limit ++#define SENSOR_TEMP_LOC_OS_LIM (0x20) // Local OS limit ++#define SENSOR_TEMP_REM_TCRIT_LIM (0x19) // Remote T_Crit limit ++ #define SENSOR_TEMP_LIM_128 (0x80) ++ #define SENSOR_TEMP_LIM_64 (0x40) ++ #define SENSOR_TEMP_LIM_32 (0x20) ++ #define SENSOR_TEMP_LIM_16 (0x10) ++ #define SENSOR_TEMP_LIM_8 (0x08) ++ #define SENSOR_TEMP_LIM_4 (0x04) ++ #define SENSOR_TEMP_LIM_2 (0x02) ++ #define SENSOR_TEMP_LIM_1 (0x01) ++#define SENSOR_TEMP_HYSTERESIS (0x21) // Common hysteresis ++ #define SENSOR_TEMP_HYS_16 (0x10) ++ #define SENSOR_TEMP_HYS_8 (0x08) ++ #define SENSOR_TEMP_HYS_4 (0x04) ++ #define SENSOR_TEMP_HYS_2 (0x02) ++ #define SENSOR_TEMP_HYS_1 (0x01) ++#define SENSOR_TEMP_MAN_ID (0xFE) // Manufacture ID ++ #define SENSOR_TEMP_MAN_ID_DATA (0x01) // Manufacture ID ++#define SENSOR_TEMP_REV_ID (0xFF) // Revision ID ++ #define SENSOR_TEMP_REV_ID_DATA (0xB1) // Revision ID ++ ++struct sensor_temp_rw { // see the datasheet ++ unsigned char address; ++ unsigned char d1; ++}; ++ ++// accelerometer ++// ADXL345 ++#define SENSOR_ACC_ID (0x00) // Device ID ++ #define SENSOR_ACC_ID_DATA (0xE5) // Device ID ++#define SENSOR_ACC_TT (0x1D) // Tap threshold (62.5 mg/LSB) ++#define SENSOR_ACC_OFSX (0x1E) // X axis offset (15.6 mg/LSB) ++#define SENSOR_ACC_OFSY (0x1F) // Y axis offset (15.6 mg/LSB) ++#define SENSOR_ACC_OFSZ (0x20) // Z axis offset (15.6 mg/LSB) ++#define SENSOR_ACC_DUR (0x21) // Tap duration (625 us/LSB) ++#define SENSOR_ACC_LAT (0x22) // Tap latency (1.25 ms/LSB) ++#define SENSOR_ACC_WIN (0x23) // Tap window (1.25 ms/LSB) ++#define SENSOR_ACC_TAT (0x24) // Activity threshold (62.5 mg/LSB) ++#define SENSOR_ACC_TINAT (0x25) // Inactivity threshold (62.5 mg/LSB) ++#define SENSOR_ACC_TIM_INAT (0x26) // Inactivity time (1 s/LSB) ++#define SENSOR_ACC_AT_CONTROL (0x27) // Activity/Inactivity control ++ #define SENSOR_ACC_ATC_DC (0x00) // Active DC coupled ++ #define SENSOR_ACC_ATC_AC (0x80) // Active AC coupled ++ #define SENSOR_ACC_ATC_XE (0x40) // Active X enable ++ #define SENSOR_ACC_YTC_XE (0x20) // Active X enable ++ #define SENSOR_ACC_ZTC_XE (0x10) // Active X enable ++ #define SENSOR_ACC_ITC_DC (0x00) // Inactive DC coupled ++ #define SENSOR_ACC_ITC_AC (0x08) // Inactive AC coupled ++ #define SENSOR_ACC_ITC_XE (0x04) // Inactive X enable ++ #define SENSOR_ACC_ITC_YE (0x02) // Inactive Y enable ++ #define SENSOR_ACC_ITC_ZE (0x01) // Inactive Z enable ++#define SENSOR_ACC_T_FF (0x28) // Freefall Threshold (62.5 mg/LSB) ++#define SENSOR_ACC_TIM_FF (0x29) // Freefall Time (5 ms/LSB) ++#define SENSOR_ACC_TAP_AXES (0x2A) // Tap Axis control ++ #define SENSOR_ACC_TA_SUPRESS (0x08) // Supress Double Tap ++ #define SENSOR_ACC_TA_XYZE (0x07) // X,Y,Z Tap Enable ++ #define SENSOR_ACC_TA_XE (0x04) // X Tap Enable ++ #define SENSOR_ACC_TA_YE (0x02) // Y Tap Enable ++ #define SENSOR_ACC_TA_ZE (0x01) // Z Tap Enable ++#define SENSOR_ACC_TAP_STAT (0x2B) // Tap Status ++ #define SENSOR_ACC_TS_XA (0x40) // X Activity ++ #define SENSOR_ACC_TS_YA (0x20) // Y Activity ++ #define SENSOR_ACC_TS_ZA (0x10) // Z Activity ++ #define SENSOR_ACC_TS_XT (0x04) // X Tap ++ #define SENSOR_ACC_TS_YT (0x02) // Y Tap ++ #define SENSOR_ACC_TS_ZT (0x01) // Z Tap ++#define SENSOR_ACC_RATE (0x2C) // Data Rate control ++ #define SENSOR_ACC_RATE_LP (0x10) // Low Power Mode ++ #define SENSOR_ACC_RC_3200_1600 (0x0F) // _OUTPUT-DATA_BANDWIDTH ++ #define SENSOR_ACC_RC_1600_800 (0x0E) ++ #define SENSOR_ACC_RC_800_400 (0x0D) ++ #define SENSOR_ACC_RC_400_200 (0x0C) ++ #define SENSOR_ACC_RC_200_100 (0x0B) ++ #define SENSOR_ACC_RC_100_50 (0x0A) ++ #define SENSOR_ACC_RC_50_25 (0x09) ++ #define SENSOR_ACC_RC_25_12P5 (0x08) ++ #define SENSOR_ACC_RC_12P5_6P25 (0x07) ++ #define SENSOR_ACC_RC_6P25_3P125 (0x06) ++ #define SENSOR_ACC_RC_3P125_1P563 (0x05) ++ #define SENSOR_ACC_RC_1P563_P782 (0x04) ++ #define SENSOR_ACC_RC_P782_P39 (0x03) ++ #define SENSOR_ACC_RC_P39_P195 (0x02) ++ #define SENSOR_ACC_RC_P195_P098 (0x01) ++ #define SENSOR_ACC_RC_P098_P048 (0x00) ++#define SENSOR_ACC_POWER (0x2D) // Power control ++ #define SENSOR_ACC_P_LINK (0x20) // Activity/Inactivity Link mode ++ #define SENSOR_ACC_P_APM (0x10) // Auto Low Power ++ #define SENSOR_ACC_P_SM (0x00) // Standby ++ #define SENSOR_ACC_P_NORM (0x08) // Powered Up ++ #define SENSOR_ACC_P_SLEEP_NORM (0x00) // Not Sleep ++ #define SENSOR_ACC_P_SLEEP (0x04) // Sleep ++ #define SENSOR_ACC_P_W8 (0x00) // wakeup Frequency = 8 Hz ++ #define SENSOR_ACC_P_W4 (0x01) // wakeup Frequency = 4 Hz ++ #define SENSOR_ACC_P_W2 (0x02) // wakeup Frequency = 2 Hz ++ #define SENSOR_ACC_P_W1 (0x03) // wakeup Frequency = 1 Hz ++#define SENSOR_ACC_IE (0x2E) // Interrupt Enable ++#define SENSOR_ACC_IM (0x2F) // Interrupt Map ++#define SENSOR_ACC_IS (0x30) // Interrupt Source ++ #define SENSOR_ACC_I_DR (0x80) // Data Ready ++ #define SENSOR_ACC_I_ST (0x40) // Single Tap ++ #define SENSOR_ACC_I_DT (0x20) // Double Tap ++ #define SENSOR_ACC_I_A (0x10) // Activity ++ #define SENSOR_ACC_I_I (0x08) // Inactivity ++ #define SENSOR_ACC_I_FF (0x04) // Freefall ++ #define SENSOR_ACC_I_WM (0x02) // Watermark ++ #define SENSOR_ACC_I_OR (0x01) // Overrun ++#define SENSOR_ACC_DF (0x31) // Data Format ++ #define SENSOR_ACC_DF_SELF_TEST (0x80) // Self Test ++ #define SENSOR_ACC_DF_SPI_MODE4 (0x00) // SPI 4-Wire ++ #define SENSOR_ACC_DF_SPI_MODE3 (0x40) // SPI 3-Wire ++ #define SENSOR_ACC_DF_INT_INVERT (0x20) // Interrupt Active Low ++ #define SENSOR_ACC_DF_LENGTH (0x08) // 13-bit, 16g Enable ++ #define SENSOR_ACC_DF_POS (0x04) // MSB Left Justified ++ #define SENSOR_ACC_DF_R2 (0x00) // 2g ++ #define SENSOR_ACC_DF_R4 (0x01) // 4g ++ #define SENSOR_ACC_DF_R8 (0x02) // 8g ++ #define SENSOR_ACC_DF_R16 (0x03) // 16g ++#define SENSOR_ACC_DX0 (0x32) // Data X axis 0 (LSB) ++#define SENSOR_ACC_DX1 (0x33) // Data X axis 1 (MSB) ++#define SENSOR_ACC_DY0 (0x34) // Data Y axis 0 (LSB) ++#define SENSOR_ACC_DY1 (0x35) // Data Y axis 1 (MSB) ++#define SENSOR_ACC_DZ0 (0x36) // Data Z axis 0 (LSB) ++#define SENSOR_ACC_DZ1 (0x37) // Data Z axis 1 (MSB) ++#define SENSOR_ACC_FC (0x38) // FIFO Control ++ #define SENSOR_ACC_FC_BYP (0x00 << 6) // Bypass ++ #define SENSOR_ACC_FC_HOLD (0x01 << 6) // Hold after 32 ++ #define SENSOR_ACC_FC_OF (0x02 << 6) // Discard after 32 ++ #define SENSOR_ACC_FC_TRIG (0x03 << 6) // Hold on TRIGGER ++ #define SENSOR_ACC_FC_TRIG1 (0x00) // TRIGGER = INT1 ++ #define SENSOR_ACC_FC_TRIG2 (0x20) // TRIGGER = INT2 ++ #define SENSOR_ACC_FC_SAMP(x) (x) // See ADXL345 datasheet ++#define SENSOR_ACC_FS (0x39) // FIFO Status ++ #define SENSOR_ACC_FS_TRIG (0x80) // TRIGGER occurred ++ #define SENSOR_ACC_FS_ENTRIES_MSK (0x1F) // See ADXL345 datasheet ++ ++// ST LIS302DL ++#define SENSOR_A3_WAI (0x0F) // Device ID ++ #define SENSOR_A3_WAI_ID (0x3B) // Device ID ++#define SENSOR_A3_CTRL1 (0x20) // Control Register ++ #define SENSOR_A3_CTRL1_DR100 (0x00) // sample data rate = 100 Hz ++ #define SENSOR_A3_CTRL1_DR400 (0x80) // sample data rate = 400 Hz ++ #define SENSOR_A3_CTRL1_PD (0x00) // power down ++ #define SENSOR_A3_CTRL1_PU (0x40) // power up ++ #define SENSOR_A3_CTRL1_FS (0x20) // See data sheet ++ #define SENSOR_A3_CTRL1_STP (0x10) // See data sheet ++ #define SENSOR_A3_CTRL1_STM (0x08) // See data sheet ++ #define SENSOR_A3_CTRL1_XYZEN (0x07) // X,Y,Z axis enable ++ #define SENSOR_A3_CTRL1_ZEN (0x04) // Z axis enable ++ #define SENSOR_A3_CTRL1_YEN (0x02) // Y axis enable ++ #define SENSOR_A3_CTRL1_XEN (0x01) // X axis enable ++#define SENSOR_A3_CTRL2 (0x21) // Control Register ++ #define SENSOR_A3_CTRL2_SIM (0x80) // SPI mode ++ #define SENSOR_A3_CTRL2_BOOT (0x40) // copy calibration from FLASH ++ #define SENSOR_A3_CTRL2_FILT_OFF (0x00) // internal filter bypassed ++ #define SENSOR_A3_CTRL2_FILT_ON (0x10) // internal filter enabled ++ #define SENSOR_A3_CTRL2_F2 (0x08) // WU2 filter enable ++ #define SENSOR_A3_CTRL2_F1 (0x04) // WU1 filter enable ++ #define SENSOR_A3_CTRL2_COEFF(x) (x & 0x3) // See data sheet ++#define SENSOR_A3_CTRL3 (0x22) // Control Register ++ #define SENSOR_A3_CTRL3_IH (0x00) // Interrupt active high ++ #define SENSOR_A3_CTRL3_IL (0x80) // Interrupt active low ++ #define SENSOR_A3_CTRL3_IPP (0x00) // Interrupt push/pull ++ #define SENSOR_A3_CTRL3_IOD (0x40) // Interrupt open drain ++ #define SENSOR_A3_CTRL3_I2C(x) ((x&0x7) << 3) // I2 config - See data sheet ++ #define SENSOR_A3_CTRL3_I1C(x) ((x&0x7)) // I1 config - See data sheet ++#define SENSOR_A3_HPF_RST (0x23) // High Pass Filter Reset - See data sheet ++#define SENSOR_A3_STAT (0x27) // Status ++ #define SENSOR_A3_STAT_ZYXOR (0x80) // ZYX overrun ++ #define SENSOR_A3_STAT_ZOR (0x40) // Z overrun ++ #define SENSOR_A3_STAT_YOR (0x20) // Y overrun ++ #define SENSOR_A3_STAT_XOR (0x10) // X overrun ++ #define SENSOR_A3_STAT_ZYXDA (0x08) // ZYX data available ++ #define SENSOR_A3_STAT_ZDA (0x04) // Z data available ++ #define SENSOR_A3_STAT_YDA (0x02) // Y data available ++ #define SENSOR_A3_STAT_XDA (0x01) // X data available ++#define SENSOR_A3_OUTX (0x29) // X Output ++#define SENSOR_A3_OUTY (0x2B) // Y Output ++#define SENSOR_A3_OUTZ (0x2D) // Z Output ++#define SENSOR_A3_CFG1 (0x30) // Configuration ++#define SENSOR_A3_CFG2 (0x34) // Configuration ++ #define SENSOR_A3_CFG_AOI (0x80) // AND/OR interrupts ++ #define SENSOR_A3_CFG_LIR (0x40) // latch interrupts into SRC ++ #define SENSOR_A3_CFG_ZHIE (0x20) // Z high enable ++ #define SENSOR_A3_CFG_ZLIE (0x10) // Z low enable ++ #define SENSOR_A3_CFG_YHIE (0x08) // Y high enable ++ #define SENSOR_A3_CFG_YLIE (0x04) // Y low enable ++ #define SENSOR_A3_CFG_XHIE (0x02) // X high enable ++ #define SENSOR_A3_CFG_XLIE (0x01) // X low enable ++#define SENSOR_A3_SRC1 (0x31) // Source ++#define SENSOR_A3_SRC2 (0x35) // Source ++ #define SENSOR_A3_SRC_IA (0x40) // interrupt active ++ #define SENSOR_A3_SRC_ZH (0x20) // Z high ++ #define SENSOR_A3_SRC_ZL (0x10) // Z low ++ #define SENSOR_A3_SRC_YH (0x08) // Y high ++ #define SENSOR_A3_SRC_YL (0x04) // Y low ++ #define SENSOR_A3_SRC_XH (0x02) // X high ++ #define SENSOR_A3_SRC_XL (0x01) // X low ++#define SENSOR_A3_THS1 (0x32) // Threshold ++#define SENSOR_A3_THS2 (0x36) // Threshold ++ #define SENSOR_A3_THS_DCRM (0x80) // Resetting mode - See data sheet ++ #define SENSOR_A3_THS_THS(x) (x & 0x7F) // FF/wakeup threshold ++#define SENSOR_A3_DUR1 (0x33) // Duration - See data sheet ++#define SENSOR_A3_DUR2 (0x37) // Duration - See data sheet ++#define SENSOR_A3_CCFG (0x38) // Click Configuration ++#define SENSOR_A3_CSRC (0x39) // Click Source ++ #define SENSOR_A3_CCS_LIR (0x40) // latch interrupt into SRC ++ #define SENSOR_A3_CCS_DZ (0x20) // double Z enable ++ #define SENSOR_A3_CCS_SZ (0x10) // single Z enable ++ #define SENSOR_A3_CCS_DY (0x08) // double Y enable ++ #define SENSOR_A3_CCS_SY (0x04) // single Y enable ++ #define SENSOR_A3_CCS_DX (0x02) // double X enable ++ #define SENSOR_A3_CCS_SX (0x01) // single X enable ++#define SENSOR_A3_CTHXY (0x3B) // Click X, Y Threshold ++ #define SENSOR_A3_CTHYX_Y(x) ((x&0xF) << 4) // Y Threshold ++ #define SENSOR_A3_CTHYX_X(x) (x&0xF) // X Threshold ++#define SENSOR_A3_CTHZ (0x3C) // Click Z Threshold ++ #define SENSOR_A3_CTHYX_Z(x) (x&0xF) // Z Threshold ++#define SENSOR_A3_CTL (0x3D) // Click Time Limit ++#define SENSOR_A3_CLAT (0x3E) // Click Latency ++#define SENSOR_A3_CWIN (0x3F) // Click Window ++ ++// count always = 1 for LIS302DL ++struct sensor_acc_rw { // see the datasheets ++ unsigned char address; ++ unsigned int count; // number of bytes to read (1 or 2) ++ unsigned char data[2]; ++}; ++ ++// digital compass ++#define SENSOR_DCOMP_ST (0xC0) // Status (RO) ++ #define SENSOR_DCOMP_ST_INT (0x01) // Interrupt ++ #define SENSOR_DCOMP_ST_EERW (0x02) // EEPROM R/W ++#define SENSOR_DCOMP_TMPS (0xC1) // Temperature(C) = 35+(120-TMPS)/1.6 ++#define SENSOR_DCOMP_H1X (0xC2) // X Heading ++#define SENSOR_DCOMP_H1Y (0xC3) // Y Heading ++#define SENSOR_DCOMP_H1Z (0xC4) // Z Heading ++#define SENSOR_DCOMP_MS1 (0xE0) // Mode ++ #define SENSOR_DCOMP_MS1_SENSOR (0x0) // sensor mode ++ #define SENSOR_DCOMP_MS1_EEPROM (0x2) // EEPROM R/W ++ #define SENSOR_DCOMP_MS1_PD (0x3) // power down ++ #define SENSOR_DCOMP_MS1_EEWEN (0xA8) // EEPROM Write Enable ++#define SENSOR_DCOMP_HXDA (0xE1) // X DAC offset - see table 3 in datasheet ++#define SENSOR_DCOMP_HYDA (0xE2) // Y DAC offset - see table 3 in datasheet ++#define SENSOR_DCOMP_HZDA (0xE3) // Z DAC offset - see table 3 in datasheet ++#define SENSOR_DCOMP_HXGA (0xE4) // X gain - see table 4 in datasheet ++#define SENSOR_DCOMP_HYGA (0xE5) // Y gain - see table 4 in datasheet ++#define SENSOR_DCOMP_HZGA (0xE6) // Z gain - see table 4 in datasheet ++#define SENSOR_DCOMP_TS1 (0x5D) // FACTORY TEST - DO NOT USE ++#define SENSOR_DCOMP_EE_WRAL1 (0x60) // EE - batch write adress ++#define SENSOR_DCOMP_EE_ETS (0x62) // EE - temperature offset ++#define SENSOR_DCOMP_EE_EVIR (0x63) // EE - VREF/IREF adjustment ++#define SENSOR_DCOMP_EE_EIHE (0x64) // EE - HE drive/OSC ++#define SENSOR_DCOMP_EE_ETST (0x65) // EE - test ++#define SENSOR_DCOMP_EE_EHXGA (0x66) // EE - X gain adjustment ++#define SENSOR_DCOMP_EE_EHYGA (0x67) // EE - Y gain adjustment ++#define SENSOR_DCOMP_EE_EHZGA (0x68) // EE - Z gain adjustment ++ ++// generic address/data byte R/W ++struct sensor_rw { ++ unsigned char address; ++ unsigned char data; ++}; ++ ++// Sensor driver ioctl definitions ++#define BMI_SENSOR_ON (1) ++#define BMI_SENSOR_OFF (0) ++#define BMI_SENSOR_RLEDOFF _IOW(BMI_SENSOR_IOCTL, 0x1, unsigned int) // Turn off red LED ++#define BMI_SENSOR_RLEDON _IOW(BMI_SENSOR_IOCTL, 0x2, unsigned int) // Turn on red LED ++#define BMI_SENSOR_GLEDOFF _IOW(BMI_SENSOR_IOCTL, 0x3, unsigned int) // Turn off green LED ++#define BMI_SENSOR_GLEDON _IOW(BMI_SENSOR_IOCTL, 0x4, unsigned int) // Turn on green LED ++#define BMI_SENSOR_GETSTAT _IOR(BMI_SENSOR_IOCTL, 0x5, unsigned int *) // Read IOX/GPIO (== GPIO<<16 | IOX1<<8 | IOX0) ++#define BMI_SENSOR_ADCWR _IOW(BMI_SENSOR_IOCTL, 0x6, unsigned int) // write ADC ++#define BMI_SENSOR_ADCRD _IOR(BMI_SENSOR_IOCTL, 0x7, unsigned int *) // read ADC ++#define BMI_SENSOR_HUMRD _IOR(BMI_SENSOR_IOCTL, 0x8, unsigned int *) // read ADC - Humidity sensor ++#define BMI_SENSOR_ACOMPRST _IO(BMI_SENSOR_IOCTL, 0x9) // analog Compass reset (toggle off/on) ++#define BMI_SENSOR_ACOMPXRD _IOR(BMI_SENSOR_IOCTL, 0xa, unsigned int *) // read ADC - Compass X axis ++#define BMI_SENSOR_ACOMPYRD _IOR(BMI_SENSOR_IOCTL, 0xb, unsigned int *) // read ADC - Compass Y axis ++#define BMI_SENSOR_ACOMPZRD _IOR(BMI_SENSOR_IOCTL, 0xc, unsigned int *) // read ADC - Compass Z axis ++#define BMI_SENSOR_PLWR _IOW(BMI_SENSOR_IOCTL, 0xd, struct sensor_pl_rw *) // write Proximity/Light sensor ++#define BMI_SENSOR_PLRD _IOR(BMI_SENSOR_IOCTL, 0xe, struct sensor_pl_rw *) // read Proximity/Light sensor ++#define BMI_SENSOR_PL_SYNC _IO(BMI_SENSOR_IOCTL, 0xf) // generate external SYNC for Proximity/Light or Digital Light ++#define BMI_SENSOR_PL_IWAIT _IOR(BMI_SENSOR_IOCTL, 0x10, struct sensor_pl_rw *) // wait for Proximity/Light interrupt - application sets up INT configuration ++#define BMI_SENSOR_SNDARD _IOR(BMI_SENSOR_IOCTL, 0x11, unsigned int *) // read ADC - Sound Average level ++#define BMI_SENSOR_SNDPRD _IOR(BMI_SENSOR_IOCTL, 0x12, unsigned int *) // read ADC - Sound Peak level read/clear ++#define BMI_SENSOR_SNDIRD _IOR(BMI_SENSOR_IOCTL, 0x13, unsigned int *) // read ADC - Instantaneous level read/clear ++#define BMI_SENSOR_TEMPWR _IOW(BMI_SENSOR_IOCTL, 0x14, struct sensor_temp_rw *) // write Temperature sensor ++#define BMI_SENSOR_TEMPRD _IOR(BMI_SENSOR_IOCTL, 0x15, struct sensor_temp_rw *) // read Temperature sensor ++#define BMI_SENSOR_TEMPRD_SL _IOR(BMI_SENSOR_IOCTL, 0x16, unsigned int *) // Read signed local ++#define BMI_SENSOR_TEMPRD_SR _IOR(BMI_SENSOR_IOCTL, 0x17, unsigned int *) // Read signed remote ++#define BMI_SENSOR_TEMPRD_UR _IOR(BMI_SENSOR_IOCTL, 0x18, unsigned int *) // Read unsigned remote ++#define BMI_SENSOR_TEMP_IWAIT _IO(BMI_SENSOR_IOCTL, 0x19) // wait for Temperature interrupt - application sets up INT configuration ++#define BMI_SENSOR_MOTRD _IOR(BMI_SENSOR_IOCTL, 0x1a, unsigned int *) // read real-time Motion state ++#define BMI_SENSOR_MOT_IWAIT _IOR(BMI_SENSOR_IOCTL, 0x1b, unsigned int *) // wait for Motion interrupt ++#define BMI_SENSOR_ACCWR _IOW(BMI_SENSOR_IOCTL, 0x1c, struct sensor_acc_rw *) // write Accelerometer ++#define BMI_SENSOR_ACCRD _IOR(BMI_SENSOR_IOCTL, 0x1d, struct sensor_acc_rw *) // read Accelerometer ++#define BMI_SENSOR_ACCXRD _IOR(BMI_SENSOR_IOCTL, 0x1e, unsigned int *) // read Accelerometer X ++#define BMI_SENSOR_ACCYRD _IOR(BMI_SENSOR_IOCTL, 0x1f, unsigned int *) // read Accelerometer Y ++#define BMI_SENSOR_ACCZRD _IOR(BMI_SENSOR_IOCTL, 0x20, unsigned int *) // read Accelerometer Z ++#define BMI_SENSOR_ACC_I1WAIT _IO(BMI_SENSOR_IOCTL, 0x21) // wait for Accelerometer interrupt 1 - application sets up INT configuration ++#define BMI_SENSOR_ACC_I2WAIT _IO(BMI_SENSOR_IOCTL, 0x22) // wait for Accelerometer interrupt 2 - application sets up INT configuration ++#define BMI_SENSOR_EEWR _IOW(BMI_SENSOR_IOCTL, 0x23, struct sensor_rw *) // write EEPROM ++#define BMI_SENSOR_EERD _IOR(BMI_SENSOR_IOCTL, 0x24, struct sensor_rw *) // read EEPROM ++#define BMI_SENSOR_MOT_IE _IOW(BMI_SENSOR_IOCTL, 0x25, unsigned int) // Motion interrupt enable (on = BMI_SENSOR_ON) ++#define BMI_SENSOR_USB_IWAIT _IO(BMI_SENSOR_IOCTL, 0x26) // wait for USB power flag interrupt ++#define BMI_SENSOR_USB_PWR_EN _IOW(BMI_SENSOR_IOCTL, 0x27, unsigned int) // USB power enable (on = BMI_SENSOR_ON) ++#define BMI_SENSOR_HUM_PWR_EN _IOW(BMI_SENSOR_IOCTL, 0x28, unsigned int) // Humidity power enable (on = BMI_SENSOR_ON) ++#define BMI_SENSOR_DCOM_RST _IOW(BMI_SENSOR_IOCTL, 0x29, unsigned int) // Digital Compass Reset (on = BMI_SENSOR_ON) ++#define BMI_SENSOR_COM_GCAL _IOR(BMI_SENSOR_IOCTL, 0x2a, struct sensor_comp_cal *) // Get compass calibation ++#define BMI_SENSOR_COM_SCAL _IOW(BMI_SENSOR_IOCTL, 0x2b, struct sensor_comp_cal *) // Set compass calibation ++#define BMI_SENSOR_DCWR _IOW(BMI_SENSOR_IOCTL, 0x2c, struct sensor_rw *) // write digital compass ++#define BMI_SENSOR_DCRD _IOR(BMI_SENSOR_IOCTL, 0x2d, struct sensor_rw *) // read digital compass ++#define BMI_SENSOR_DC_GDAC _IOR(BMI_SENSOR_IOCTL, 0x2e, struct sensor_comp_dac *) // Get digital compass DAC settings ++#define BMI_SENSOR_DC_SDAC _IOW(BMI_SENSOR_IOCTL, 0x2f, struct sensor_comp_dac *) // Set digital compass DAC settings ++#define BMI_SENSOR_DC_IWAIT _IO(BMI_SENSOR_IOCTL, 0x30) // wait for digital compass interrupt - application sets up INT configuration ++#define BMI_SENSOR_APROX_DUR _IOW(BMI_SENSOR_IOCTL, 0x31, unsigned int) // Analog Proximity LED burst time (in ms 2 <= arg <= 100) ++#define BMI_SENSOR_APROXRD _IOR(BMI_SENSOR_IOCTL, 0x32, unsigned int *) // read Analog proximity = (PDOUT << 16) | ADC_DATA ++#define BMI_SENSOR_ALIGHTRD _IOR(BMI_SENSOR_IOCTL, 0x33, unsigned int *) // read Analog Light ++#define BMI_SENSOR_DLIGHTWR _IOW(BMI_SENSOR_IOCTL, 0x34, struct sensor_dl_rw *) // write Digital Light sensor ++#define BMI_SENSOR_DLIGHTRD _IOR(BMI_SENSOR_IOCTL, 0x35, unsigned int) // read Digital Light sensor ++#define BMI_SENSOR_DLIGHT_IC _IO(BMI_SENSOR_IOCTL, 0x36) // Digital Light interrupt clear ++#define BMI_SENSOR_DLIGHT_IWAIT _IOR(BMI_SENSOR_IOCTL, 0x37, struct sensor_dl_rw *) // wait for Digital Light interrupt - application sets up INT configuration ++#define BMI_SENSOR_MIC_EN _IOW(BMI_SENSOR_IOCTL, 0x38, unsigned int) // Sound power enable (on = BMI_SENSOR_ON) ++ ++#endif /* BMI_SENSOR_H */ ++ +--- /dev/null ++++ git/include/linux/bmi/bmi_vh.h +@@ -0,0 +1,135 @@ ++/* ++ * File: include/linux/bmi/bmi_vh.h ++ * Author: Peter Giacomini ++ * ++ * This is the application header file for the BMI bus voh Hippel plug-in ++ * module on the MX31 BUG platform. ++ */ ++ ++#ifndef BMI_VH_H ++#define BMI_VH_H ++ ++#include ++ ++// GPIO ++#define VH_GPIO_RED_LED 3 // default to input ++#define VH_GPIO_GREEN_LED 2 // default to input ++#define VH_GPIO_1 1 // default to input ++#define VH_GPIO_0 0 // default to input ++ ++#define VH_GPIO_LED_ON 0 ++#define VH_GPIO_LED_OFF 1 ++ ++// I2C ++// I2C Slave Addresses ++#define BMI_IOX_I2C_ADDRESS 0x71 // 7-bit address ++#define VH_RDAC_I2C_ADDRESS 0x18 // 7-bit address ++#define VH_ADC_I2C_ADDRESS 0x24 // 7-bit address ++#define VH_DAC_I2C_ADDRESS 0x58 // 7-bit address ++ ++// I2C IOX register addresses ++#define IOX_INPUT_REG 0x0 ++#define IOX_OUTPUT_REG 0x1 ++#define IOX_POLARITY_REG 0x2 ++#define IOX_CONTROL 0x3 ++ ++#define VH_IOX_USB_FLG_N 7 // Input - H=normal, L=fault ++#define VH_IOX_USB_VEN 6 // output - H=power on, L=power off ++#define VH_IOX_B5 5 // set to output driven high to prevent interrupts ++#define VH_IOX_B4 4 // set to output driven high to prevent interrupts ++#define VH_IOX_B3 3 // set to output driven high to prevent interrupts ++#define VH_IOX_B2 2 // set to output driven high to prevent interrupts ++#define VH_IOX_B1 1 // set to output driven high to prevent interrupts ++#define VH_IOX_B0 0 // set to output driven high to prevent interrupts ++ ++// programmable LDO digital resistor ++#define VH_RD_CMD_RDAC 0x00 // RDAC interface ++#define VH_RD_CMD_EE 0x20 // EEPROM interface ++ #define VH_TOL_HA 0x1E // Tolerance MSB ++ #define VH_TOL_LA 0x1F // Tolerance LSB ++#define VH_RD_CMD_WP 0x40 // EEPROM write protect ++#define VH_RD_CMD_NOP 0x80 // NOP ++#define VH_RD_CMD_ETOR 0xA0 // EEPROM -> RDAC ++#define VH_RD_CMD_RTOE 0xC0 // RDAC -> EEPROM ++ ++// ADC ++#define VH_ADC_W1_EN 0xA0 // Word 1 Enable ++#define VH_ADC_W1_CH01 0x00 // diff - 0, 1 ++#define VH_ADC_W1_CH23 0x01 // diff - 2, 3 ++#define VH_ADC_W1_CH10 0x08 // diff - 1, 0 ++#define VH_ADC_W1_CH32 0x09 // diff - 3, 2 ++#define VH_ADC_W1_CH0 0x10 // single-ended - 0 ++#define VH_ADC_W1_CH1 0x18 // single-ended - 1 ++#define VH_ADC_W1_CH2 0x11 // single-ended - 2 ++#define VH_ADC_W1_CH3 0x19 // single-ended - 3 ++#define VH_ADC_W2_EN 0x80 // Word 2 Enable ++#define VH_ADC_W2_IM 0x40 // internal temp ++#define VH_ADC_W2_F(x) (((x) % 0x3) << 4) // rejection mode ++#define VH_ADC_W2_SPD 0x08 // speed 2X ++#define VH_ADC_W2_G(x) ((x) % 0x7) // gain ++ ++struct vh_adc_wr { // see the datasheet ++ unsigned char w1; // VH_ADC_W1_* ++ unsigned char w2; // VH_ADC_W2_* ++}; ++ ++// DAC ++#define VH_DAC_W1_UA 0x00 // update DAC A output ++#define VH_DAC_W1_UB 0x10 // update DAC B output ++#define VH_DAC_W1_LA 0x40 // load DAC A input ++#define VH_DAC_W1_LB 0x50 // load DAC B input ++#define VH_DAC_W1_ALLA 0x80 // load DAC A input, update all outputs ++#define VH_DAC_W1_ALLB 0x90 // load DAC B input, update all outputs ++#define VH_DAC_W1_ALL 0xC0 // load all inputs, update all outputs ++#define VH_DAC_W1_ALLI 0xD0 // load all inputs ++#define VH_DAC_W1_UALL 0xE0 // update all - don't send data ++#define VH_DAC_W1_EC 0xF0 // Extended command ++ #define VH_DAC_BCH 0x0C // both channel A & B ++ #define VH_DAC_CHB 0x08 // channel B ++ #define VH_DAC_CHA 0x04 // channel A ++ #define VH_DAC_PD100K 0x03 // power down - 100K pull down ++ #define VH_DAC_PD1K 0x02 // power down - 1K pull down ++ #define VH_DAC_PDF 0x01 // power down - float ++ #define VH_DAC_PU 0x00 // power up ++#define VH_DAC_W1_RDA 0xF1 // Read A ++#define VH_DAC_W1_RDB 0xF2 // Read B ++ ++struct vh_dac_wr { ++ unsigned char w1; // cmd | d[7:3] ++ unsigned char w2; // (d[3:0] << 4) || (VH_DAC_CH* | VH_DAC_P*) ++}; ++ ++// SPI ++#define BUF_MAX_SIZE (20) ++ ++// SPI transfer structure ++struct spi_xfer { ++ unsigned char addr; ++ unsigned char data[2]; ++} spi_xfer; ++ ++// von hippel driver ioctl definitions ++#define BMI_VH_RLEDOFF _IOW(BMI_VH_IOCTL, 0x1, unsigned int) // Turn off red LED ++#define BMI_VH_RLEDON _IOW(BMI_VH_IOCTL, 0x2, unsigned int) // Turn on red LED ++#define BMI_VH_GLEDOFF _IOW(BMI_VH_IOCTL, 0x3, unsigned int) // Turn off green LED ++#define BMI_VH_GLEDON _IOW(BMI_VH_IOCTL, 0x4, unsigned int) // Turn on green LED ++#define BMI_VH_GETSTAT _IOR(BMI_VH_IOCTL, 0x5, unsigned int *) // READ IOX register ++#define BMI_VH_MKGPIO_OUT _IOW(BMI_VH_IOCTL, 0x6, unsigned int) // make a GPIO bit an output ++#define BMI_VH_MKGPIO_IN _IOW(BMI_VH_IOCTL, 0x7, unsigned int) // make a GPIO bit an input ++#define BMI_VH_SETGPIO _IOW(BMI_VH_IOCTL, 0x8, unsigned int) // set a GPIO output to 1 ++#define BMI_VH_CLRGPIO _IOW(BMI_VH_IOCTL, 0x9, unsigned int) // set a GPIO output to 0 ++#define BMI_VH_MKIOX_OUT _IOW(BMI_VH_IOCTL, 0xa, unsigned int) // make a IOX bit an output ++#define BMI_VH_MKIOX_IN _IOW(BMI_VH_IOCTL, 0xb, unsigned int) // make a IOX bit an input ++#define BMI_VH_SETIOX _IOW(BMI_VH_IOCTL, 0xc, unsigned int) // set a IOX output to 1 ++#define BMI_VH_CLRIOX _IOW(BMI_VH_IOCTL, 0xd, unsigned int) // set a IOX output to 0 ++#define BMI_VH_SETRDAC _IOW(BMI_VH_IOCTL, 0xe, unsigned int) // set LDO RDAC resistance ++#define BMI_VH_RDRDAC _IOW(BMI_VH_IOCTL, 0xf, unsigned int *) // read LDO RDAC resistance ++#define BMI_VH_ADCWR _IOW(BMI_VH_IOCTL, 0x10, struct vh_adc_wr *) // write ADC ++#define BMI_VH_ADCRD _IOW(BMI_VH_IOCTL, 0x11, unsigned int *) // read ADC ++#define BMI_VH_DACWR _IOW(BMI_VH_IOCTL, 0x12, struct vh_dac_wr *) // write DAC ++#define BMI_VH_DACRD _IOW(BMI_VH_IOCTL, 0x13, unsigned int *) // read DAC ++#define BMI_VH_READ_SPI _IOR(BMI_VH_IOCTL, 0x14, struct spi_xfer *) // read SPI - requires SPI EEPROM ++#define BMI_VH_WRITE_SPI _IOR(BMI_VH_IOCTL, 0x15, struct spi_xfer *) // write SPI - requires SPI EEPROM ++ ++#endif /* BMI_VH_H */ ++ +--- /dev/null ++++ git/include/linux/bmi/bmi_zb.h +@@ -0,0 +1,83 @@ ++/* ++ * File: include/linux/bmi/bmi_gps.h ++ * Author: V. Thavisri ++#include ++ ++/* IOCTL commands for BMI ZB driver - char device portion */ ++ ++#define BMI_ZB_RLEDOFF _IO(BMI_ZIGBEE_IOCTL, 0x1) ++#define BMI_ZB_RLEDON _IO(BMI_ZIGBEE_IOCTL, 0x2) ++#define BMI_ZB_GLEDOFF _IO(BMI_ZIGBEE_IOCTL, 0x3) ++#define BMI_ZB_GLEDON _IO(BMI_ZIGBEE_IOCTL, 0x4) ++#define BMI_ZB_RESET _IO(BMI_ZIGBEE_IOCTL, 0x5) ++#define BMI_ZB_SPI_SIG _IO(BMI_ZIGBEE_IOCTL, 0x6) ++#define BMI_ZB_LOOPBACK _IO(BMI_ZIGBEE_IOCTL, 0x7) ++#define BMI_ZB_STARTREQ _IO(BMI_ZIGBEE_IOCTL, 0x8) ++#define BMI_ZB_UPDATE_STATE _IO(BMI_ZIGBEE_IOCTL, 0x9) ++ ++ ++/* IOCTL commands for BMI ZB driver - network device portion */ ++ ++#define SIOCSAPPREGISTER (SIOCDEVPRIVATE + 1) ++#define SIOCSALLOWBIND (SIOCDEVPRIVATE + 2) ++#define SIOCSPERMITJOINING (SIOCDEVPRIVATE + 3) ++#define SIOCGDEVICEINFO (SIOCDEVPRIVATE + 4) ++#define SIOCSRESET (SIOCDEVPRIVATE + 5) ++#define SIOCSBIND (SIOCDEVPRIVATE + 6) ++#define SIOCSZCOMMAND (SIOCDEVPRIVATE + 7) ++#define SIOCSSTARTREQ (SIOCDEVPRIVATE + 8) ++#define SIOCSFINDDEVICE (SIOCDEVPRIVATE + 9) ++#define SIOCSAFREGISTER (SIOCDEVPRIVATE + 10) ++#define SIOCSPOWERAMP (SIOCDEVPRIVATE + 11) ++#define SIOCDEBUG (SIOCDEVPRIVATE + 15) ++ ++struct sockaddr_zb ++{ ++ unsigned short z_family; ++ int z_ifindex; ++ unsigned char z_name[15]; ++ unsigned short z_protocol; ++}; ++ ++/* move this #define to include/linux/socket.h */ ++#define SOL_ZACCEL 275 ++ ++#define Z_PACKET_SOCK 0 ++#define Z_CONTROL_SOCK 1 ++#define Z_NUM_SOCK 2 ++#define Z_NO_SOCK 0xFF ++ ++/* Device-Specification Configuration Parameters */ ++#define ZCD_NV_STARTUP_OPTION 0x03 ++#define ZCD_NV_LOGICAL_TYPE 0x87 ++#define ZCD_NV_POLL_RATE 0x24 ++#define ZCD_NV_QUEUED_POLL_RATE 0x25 ++#define ZCD_NV_RESPONSE_POLL_RATE 0x26 ++#define ZCD_NV_POLL_FAILURE_RETRIES 0x29 ++#define ZCD_NV_INDIRECT_MSG_TIMEOUT 0x2B ++#define ZCD_NV_APS_FRAME_RETRIES 0x43 ++#define ZCD_NV_APS_ACK_WAIT_DURATION 0x44 ++#define ZCD_NV_BINDING_TIME 0x46 ++#define ZCD_NV_USERDESC 0x81 ++ ++// Network-Specification Configuration Parameters ++#define ZCD_NV_PANID 0x83 ++#define ZCD_NV_CHANLIST 0x84 ++#define ZCD_NV_PRECFGKEY 0x62 ++#define ZCD_NV_PRECFGKEYS_ENABLE 0x63 ++#define ZCD_NV_SECURITY_MODE 0x64 ++#define ZCD_NV_BCAST_RETRIES 0x2E ++#define ZCD_NV_PASSIVE_ACK_TIMEOUT 0x2F ++#define ZCD_NV_BCAST_DELIVERY_TIME 0x30 ++#define ZCD_NV_ROUTE_EXPIRY_TIME 0x2C ++ ++#endif /* BMI_ZBCNTL_H */ +--- git.orig/include/linux/mod_devicetable.h ++++ git/include/linux/mod_devicetable.h +@@ -341,10 +341,23 @@ struct eisa_device_id { + kernel_ulong_t driver_data; + }; + + #define EISA_DEVICE_MODALIAS_FMT "eisa:s%s" + ++/* Bug Labs BeagleBug */ ++ ++struct bmi_device_id { ++ __u16 match_flags; ++ __u16 vendor; ++ __u16 product; ++ __u16 revision; ++}; ++ ++#define BMI_DEVICE_ID_MATCH_VENDOR (1) ++#define BMI_DEVICE_ID_MATCH_PRODUCT (2) ++#define BMI_DEVICE_ID_MATCH_REVISION (4) ++ + struct parisc_device_id { + __u8 hw_type; /* 5 bits used */ + __u8 hversion_rev; /* 4 bits */ + __u16 hversion; /* 12 bits */ + __u32 sversion; /* 20 bits */ +--- git.orig/scripts/mod/file2alias.c ++++ git/scripts/mod/file2alias.c +@@ -286,10 +286,26 @@ static int do_pci_entry(const char *file + ADD(alias, "i", interface_mask == 0xFF, interface); + add_wildcard(alias); + return 1; + } + ++/* Looks like: bmi:vNpNrN. */ ++static int do_bmi_entry(const char *filename, ++ struct bmi_device_id *id, char *alias) ++{ ++ id->match_flags = TO_NATIVE(id->match_flags); ++ id->vendor = TO_NATIVE(id->vendor); ++ id->product = TO_NATIVE(id->product); ++ id->revision = TO_NATIVE(id->revision); ++ ++ strcpy(alias, "bmi:"); ++ ADD(alias, "v", id->match_flags & BMI_DEVICE_ID_MATCH_VENDOR, id->vendor); ++ ADD(alias, "p", id->match_flags & BMI_DEVICE_ID_MATCH_PRODUCT, id->product); ++ ADD(alias, "r", id->match_flags & BMI_DEVICE_ID_MATCH_REVISION, id->revision); ++ return 1; ++} ++ + /* looks like: "ccw:tNmNdtNdmN" */ + static int do_ccw_entry(const char *filename, + struct ccw_device_id *id, char *alias) + { + id->match_flags = TO_NATIVE(id->match_flags); +@@ -779,10 +795,14 @@ void handle_moddevtable(struct module *m + do_hid_entry, mod); + else if (sym_is(symname, "__mod_ieee1394_device_table")) + do_table(symval, sym->st_size, + sizeof(struct ieee1394_device_id), "ieee1394", + do_ieee1394_entry, mod); ++ else if (sym_is(symname, "__mod_bmi_device_table")) ++ do_table(symval, sym->st_size, ++ sizeof(struct bmi_device_id), "bmi", ++ do_bmi_entry, mod); + else if (sym_is(symname, "__mod_ccw_device_table")) + do_table(symval, sym->st_size, + sizeof(struct ccw_device_id), "ccw", + do_ccw_entry, mod); + else if (sym_is(symname, "__mod_ap_device_table")) diff --git a/recipes/linux/linux-omap_2.6.29.bb b/recipes/linux/linux-omap_2.6.29.bb index 18382b60ef..56e6107a4c 100644 --- a/recipes/linux/linux-omap_2.6.29.bb +++ b/recipes/linux/linux-omap_2.6.29.bb @@ -172,6 +172,7 @@ SRC_URI_append_beagleboard = " file://logo_linux_clut224.ppm \ file://beagle-asoc.patch;patch=1 \ file://tincantools-puppy.diff;patch=1 \ file://tincantools-zippy.diff;patch=1 \ + file://beaglebug/beaglebug-full.patch;patch=1 \ " SRC_URI_append_omap3evm = " \ -- cgit v1.2.3 From 5503c215650838e0e1649421ae540b669991f1b2 Mon Sep 17 00:00:00 2001 From: Graham Gower Date: Wed, 26 Aug 2009 16:48:36 +0930 Subject: enca_1.9.bb: remove unused configure test which is bound to fail. Enca's configure will fail on everything not arm or ix86. Signed-off-by: Graham Gower --- recipes/enca/enca_1.9.bb | 7 ++++++- site/arm-linux | 3 --- site/ix86-common | 3 --- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/recipes/enca/enca_1.9.bb b/recipes/enca/enca_1.9.bb index 548a824523..dbffe1e97b 100644 --- a/recipes/enca/enca_1.9.bb +++ b/recipes/enca/enca_1.9.bb @@ -3,7 +3,7 @@ SECTION = "libs" PRIORITY = "optional" LICENSE = "GPLv2" HOMEPAGE = "http://trific.ath.cx/software/enca/" -PR = "r3" +PR = "r4" SRC_URI = "http://www.sourcefiles.org/Networking/Tools/Miscellanenous/enca-${PV}.tar.bz2 \ file://configure-hack.patch;patch=1 \ @@ -15,6 +15,11 @@ inherit autotools EXTRA_OECONF="--with-libiconv-prefix=${STAGING_DIR_HOST}${layout_exec_prefix}" +do_configure_prepend() { + # remove failing test which checks for something that isn't even used + sed -i -e '/ye_FUNC_SCANF_MODIF_SIZE_T/d' configure.ac +} + do_configure_append() { sed -i s:-I/usr/include::g Makefile sed -i s:-I/usr/include::g */Makefile diff --git a/site/arm-linux b/site/arm-linux index 4212728d72..18dfb38d14 100644 --- a/site/arm-linux +++ b/site/arm-linux @@ -148,9 +148,6 @@ samba_cv_USE_SETREUID=${samba_cv_USE_SETREUID=yes} samba_cv_USE_SETUIDX=${samba_cv_USE_SETUIDX=yes} samba_cv_LINUX_LFS_SUPPORT=${samba_cv_LINUX_LFS_SUPPORT=yes} -# enca -yeti_cv_func_scanf_modif_size_t=yes - # clamav clamav_av_func_working_snprintf_long=${clamav_av_func_working_snprintf_long=yes} clamav_av_have_in_port_t=${clamav_av_have_in_port_t=yes} diff --git a/site/ix86-common b/site/ix86-common index 64106587fc..3995e675ba 100644 --- a/site/ix86-common +++ b/site/ix86-common @@ -90,9 +90,6 @@ ac_cv_func_posix_getpwnam_r=${ac_cv_func_posix_getpwnam_r=yes} dpkg_cv_va_copy=${ac_cv_va_copy=no} dpkg_cv___va_copy=${ac_cv___va_copy=yes} -# enca -yeti_cv_func_scanf_modif_size_t=yes - # ettercap ettercap_cv_type_socklen_t=${ettercap_cv_type_socklen_t=yes} -- cgit v1.2.3 From db852227f1ed420bd850d3fe31392b66b544cf4f Mon Sep 17 00:00:00 2001 From: Graham Gower Date: Wed, 9 Sep 2009 16:25:55 +0930 Subject: Add liblinebreak-1.2 Signed-off-by: Graham Gower --- conf/checksums.ini | 4 ++++ recipes/liblinebreak/liblinebreak_1.2.bb | 9 +++++++++ 2 files changed, 13 insertions(+) create mode 100644 recipes/liblinebreak/liblinebreak_1.2.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index 3c8e48d6f0..6c2924278b 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -14294,6 +14294,10 @@ sha256=e485f36d74f477f3d235a05bb67b502dc744092569842d9ab45e2f785f74f556 md5=6cef76df73f86482fa478ad8252d9055 sha256=d9ca5d502f8a4a6c146d1f0458ac27c95cc59724caa6d845e24946d299463bc5 +[http://downloads.sourceforge.net/project/vimgadgets/liblinebreak/1.2/liblinebreak-1.2.tar.gz] +md5=d18039259001ccb24b5dd4648c49c5ad +sha256=9efcb0cb1afc75ad1e92d2b2dbf4d9c77b072d6656c5f1a150af8b718d0c7b76 + [ftp://ftp.debian.org/debian/pool/main/libl/liblinebreak/liblinebreak_0.9.6.orig.tar.gz] md5=e898200ac89815365e89b7c6cc2f78fd sha256=f23ac7320379d8e950340fe37633c21a56a5f4320d29c34a65819558fe6cdaa1 diff --git a/recipes/liblinebreak/liblinebreak_1.2.bb b/recipes/liblinebreak/liblinebreak_1.2.bb new file mode 100644 index 0000000000..a012c60464 --- /dev/null +++ b/recipes/liblinebreak/liblinebreak_1.2.bb @@ -0,0 +1,9 @@ +DESCRIPTION = "Liblinebreak is an implementation of the line breaking algorithm as described in Unicode 5.1.0 Standard Annex 14, Revision 22" +HOMEPAGE = "http://vimgadgets.sourceforge.net/liblinebreak/" +SECTION = "libs" +PRIORITY = "optional" +LICENSE = "zlib" + +SRC_URI = "${SOURCEFORGE_MIRROR}/project/vimgadgets/liblinebreak/${PV}/liblinebreak-${PV}.tar.gz" + +inherit autotools_stage -- cgit v1.2.3 From 008c8d35e0a65a732a4ea078ffa9adc1d1c93db3 Mon Sep 17 00:00:00 2001 From: Cliff Brake Date: Wed, 9 Sep 2009 09:20:02 -0400 Subject: clearsilver: fix various build issues - fix hardcoded Python 2.4 path in patch - fix missing env variables by inheriting distutils-common-base --- recipes/clearsilver/clearsilver_0.10.3.bb | 6 +++--- recipes/clearsilver/files/crosscompile.patch | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/recipes/clearsilver/clearsilver_0.10.3.bb b/recipes/clearsilver/clearsilver_0.10.3.bb index 6c41497ef4..752223d998 100644 --- a/recipes/clearsilver/clearsilver_0.10.3.bb +++ b/recipes/clearsilver/clearsilver_0.10.3.bb @@ -3,16 +3,16 @@ SECTION = "net" DESCRIPTION = "Clearsilver is a fast, powerful, and language-neutral HTML template system" LICENSE = "Neotonic ClearSilver License" DEPENDS = "python" -PR = "r1" +PR = "r2" SRC_URI = "http://www.clearsilver.net/downloads/${P}.tar.gz \ file://crosscompile.patch;patch=1" EXTRA_OECONF = "--disable-apache --disable-perl --disable-ruby --disable-java --disable-csharp --enable-gettext --with-python=${STAGING_BINDIR_NATIVE}/python" -inherit autotools +inherit autotools distutils-common-base -FILES_${PN} += "/usr/lib/python*" +export PYTHON_DIR do_compile() { BUILD_SYS=${BUILD_SYS} HOST_SYS=${HOST_SYS} oe_runmake diff --git a/recipes/clearsilver/files/crosscompile.patch b/recipes/clearsilver/files/crosscompile.patch index 1b73bd5576..a19506d48c 100644 --- a/recipes/clearsilver/files/crosscompile.patch +++ b/recipes/clearsilver/files/crosscompile.patch @@ -52,7 +52,7 @@ Index: clearsilver-0.10.3/python/Makefile TARGETS = $(NEO_UTIL_SO) endif -+PYTHON_SITE = /usr/lib/python2.4/site-packages/ ++PYTHON_SITE = /usr/lib/${PYTHON_DIR}/site-packages/ + all: $(TARGETS) -- cgit v1.2.3 From 9324048f648da3b5ac3e507ab5fcc1bb8a3721c9 Mon Sep 17 00:00:00 2001 From: Cliff Brake Date: Wed, 9 Sep 2009 09:26:57 -0400 Subject: MAINTAINERS: update my entry --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 2e33203f87..15744b50b8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -44,7 +44,7 @@ Mail: cbrake@bec-systems.com Website: http://bec-systems.com Interests: Support in OE for single board computers, web application support Machines: cm-x270, em-x270, gesbc-9302 -Recipes: mono, argtable, vala, socketcan +Recipes: mono, argtable, vala, socketcan, clearsilver Person: Denys Dmytriyenko Mail: denis@denix.org -- cgit v1.2.3 From 080009c07fea6c60ef5991c2c5794b6520d9b703 Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Mon, 7 Sep 2009 16:23:54 +0200 Subject: pointercal: added at91sam9263ek --- recipes/pointercal/files/at91sam9263ek/pointercal | 1 + recipes/pointercal/pointercal_0.0.bb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 recipes/pointercal/files/at91sam9263ek/pointercal diff --git a/recipes/pointercal/files/at91sam9263ek/pointercal b/recipes/pointercal/files/at91sam9263ek/pointercal new file mode 100644 index 0000000000..7a8596d0b1 --- /dev/null +++ b/recipes/pointercal/files/at91sam9263ek/pointercal @@ -0,0 +1 @@ +-10 4298 -1026530 5663 8 -1123190 65536 diff --git a/recipes/pointercal/pointercal_0.0.bb b/recipes/pointercal/pointercal_0.0.bb index 2850c2d54c..7efe459df9 100644 --- a/recipes/pointercal/pointercal_0.0.bb +++ b/recipes/pointercal/pointercal_0.0.bb @@ -1,6 +1,6 @@ DESCRIPTION = "Touchscreen calibration data" SECTION = "base" -PR = "r15" +PR = "r16" SRC_URI = "file://pointercal" S = "${WORKDIR}" -- cgit v1.2.3 From 33dab639015d787725f9589f534161995aca1fce Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Wed, 9 Sep 2009 16:09:59 +0200 Subject: xserver-common: recommend xtscal (works without it but needs for calibration) --- recipes/xserver-common/xserver-common_1.30.bb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/recipes/xserver-common/xserver-common_1.30.bb b/recipes/xserver-common/xserver-common_1.30.bb index 54a5018212..797b831f7f 100644 --- a/recipes/xserver-common/xserver-common_1.30.bb +++ b/recipes/xserver-common/xserver-common_1.30.bb @@ -2,7 +2,8 @@ DESCRIPTION = "Common X11 scripts and support files" LICENSE = "GPL" SECTION = "x11" RDEPENDS_${PN} = "xmodmap xrandr xdpyinfo" -PR = "r4" +RRECOMMENDS_${PN} = "xtscal" +PR = "r5" PACKAGE_ARCH = "all" DEFAULT_PREFERENCE = "-1" -- cgit v1.2.3 From 35ccef0bc225c7d05c98ebbc63e568aa3856d7ab Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Thu, 14 May 2009 06:11:26 -0700 Subject: i2c-tools: build & install eepromer tools --- recipes/i2c-tools/files/Module.mk | 72 ++++++++++++++++++++++++++++++++++++ recipes/i2c-tools/i2c-tools_3.0.2.bb | 8 +++- 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 recipes/i2c-tools/files/Module.mk diff --git a/recipes/i2c-tools/files/Module.mk b/recipes/i2c-tools/files/Module.mk new file mode 100644 index 0000000000..fcaf72f22a --- /dev/null +++ b/recipes/i2c-tools/files/Module.mk @@ -0,0 +1,72 @@ +# EEPROMER +# +# Licensed under the GNU General Public License. + +EEPROMER_DIR := eepromer + +EEPROMER_CFLAGS := -Wstrict-prototypes -Wshadow -Wpointer-arith -Wcast-qual \ + -Wcast-align -Wwrite-strings -Wnested-externs -Winline \ + -W -Wundef -Wmissing-prototypes -Iinclude + +EEPROMER_TARGETS := eepromer eeprom eeprog + +# +# Programs +# + +$(EEPROMER_DIR)/eepromer: $(EEPROMER_DIR)/eepromer.o + $(CC) $(LDFLAGS) -o $@ $^ + +$(EEPROMER_DIR)/eeprom: $(EEPROMER_DIR)/eeprom.o + $(CC) $(LDFLAGS) -o $@ $^ + +$(EEPROMER_DIR)/eeprog: $(EEPROMER_DIR)/eeprog.o $(EEPROMER_DIR)/24cXX.o + $(CC) $(LDFLAGS) -o $@ $^ + +# +# Objects +# + +$(EEPROMER_DIR)/eepromer.o: $(EEPROMER_DIR)/eepromer.c + $(CC) $(CFLAGS) $(EEPROMER_CFLAGS) -c $< -o $@ + +$(EEPROMER_DIR)/eeprom.o: $(EEPROMER_DIR)/eeprom.c + $(CC) $(CFLAGS) $(EEPROMER_CFLAGS) -c $< -o $@ + +$(EEPROMER_DIR)/eeprog.o: $(EEPROMER_DIR)/eeprog.c + $(CC) $(CFLAGS) $(EEPROMER_CFLAGS) -c $< -o $@ + +$(EEPROMER_DIR)/24cXX.o: $(EEPROMER_DIR)/24cXX.c + $(CC) $(CFLAGS) $(EEPROMER_CFLAGS) -c $< -o $@ + +# +# Commands +# + +all-eepromer: $(addprefix $(EEPROMER_DIR)/,$(EEPROMER_TARGETS)) + +strip-eepromer: $(addprefix $(EEPROMER_DIR)/,$(EEPROMER_TARGETS)) + strip $(addprefix $(EEPROMER_DIR)/,$(EEPROMER_TARGETS)) + +clean-eepromer: + $(RM) $(addprefix $(EEPROMER_DIR)/,*.o $(EEPROMER_TARGETS)) + +install-eepromer: $(addprefix $(EEPROMER_DIR)/,$(EEPROMER_TARGETS)) + $(INSTALL_DIR) $(DESTDIR)$(sbindir) $(DESTDIR)$(man8dir) + for program in $(EEPROMER_TARGETS) ; do \ + $(INSTALL_PROGRAM) $(EEPROMER_DIR)/$$program $(DESTDIR)$(sbindir) ; done + +uninstall-eepromer: + for program in $(EEPROMER_TARGETS) ; do \ + $(RM) $(DESTDIR)$(sbindir)/$$program ; \ + $(RM) $(DESTDIR)$(man8dir)/$$program.8 ; done + +all: all-eepromer + +strip: strip-eepromer + +clean: clean-eepromer + +install: install-eepromer + +uninstall: uninstall-eepromer diff --git a/recipes/i2c-tools/i2c-tools_3.0.2.bb b/recipes/i2c-tools/i2c-tools_3.0.2.bb index c8ea32a5f1..c44af1e3ba 100644 --- a/recipes/i2c-tools/i2c-tools_3.0.2.bb +++ b/recipes/i2c-tools/i2c-tools_3.0.2.bb @@ -2,11 +2,17 @@ DESCRIPTION = "Set of i2c tools for linux" SECTION = "base" LICENSE = "GPL" -SRC_URI = "http://dl.lm-sensors.org/i2c-tools/releases/i2c-tools-${PV}.tar.bz2" +PR = "r1" + +SRC_URI = "http://dl.lm-sensors.org/i2c-tools/releases/i2c-tools-${PV}.tar.bz2 \ + file://Module.mk \ + " inherit autotools do_compile_prepend() { + cp ${WORKDIR}/Module.mk ${S}/eepromer/ sed -i 's_/usr/local_/usr_' Makefile sed -i 's_CC\t:= gcc_CC\t:= ${CC}_' Makefile + echo "include eepromer/Module.mk" >> Makefile } -- cgit v1.2.3 From 430db434a74e863f29396f04455646206f7581cb Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Wed, 9 Sep 2009 16:54:41 +0000 Subject: moko-autorev.inc: Remove no longer used file. This file was only used during the developemnet of the OM2007.x releases which are dead by now. If you have this file in your local.conf it can be safely removed. --- conf/distro/include/moko-autorev.inc | 71 ------------------------------------ conf/distro/openmoko.conf | 1 - 2 files changed, 72 deletions(-) delete mode 100644 conf/distro/include/moko-autorev.inc diff --git a/conf/distro/include/moko-autorev.inc b/conf/distro/include/moko-autorev.inc deleted file mode 100644 index ce9f488e77..0000000000 --- a/conf/distro/include/moko-autorev.inc +++ /dev/null @@ -1,71 +0,0 @@ -SRCREV_pn-assassin ?= "${AUTOREV}" -SRCREV_pn-dfu-util ?= "${AUTOREV}" -SRCREV_pn-dfu-util-native ?= "${AUTOREV}" -SRCREV_pn-diversity-daemon ?= "${AUTOREV}" -SRCREV_pn-diversity-radar ?= "${AUTOREV}" -SRCREV_pn-etk-theme-ninja ?= "${AUTOREV}" -SRCREV_pn-exposure ?= "${AUTOREV}" -SRCREV_pn-illume-theme-asu ?= "${AUTOREV}" -SRCREV_pn-libgsmd ?= "${AUTOREV}" -SRCREV_pn-libjana ?= "${AUTOREV}" -SRCREV_pn-libmokogsmd2 ?= "${AUTOREV}" -SRCREV_pn-libmokojournal2 ?= "${AUTOREV}" -SRCREV_pn-libmokopanelui2 ?= "${AUTOREV}" -SRCREV_pn-libmokoui2 ?= "${AUTOREV}" -SRCREV_pn-linux-openmoko-devel ?= "${AUTOREV}" -SRCREV_pn-moko-gtk-engine ?= "${AUTOREV}" -SRCREV_pn-multitap-pad ?= "${AUTOREV}" -SRCREV_pn-moko-gtk-engine ?= "${AUTOREV}" -SRCREV_pn-neod ?= "${AUTOREV}" -SRCREV_pn-om-locations ?= "${AUTOREV}" -SRCREV_pn-openmoko-agpsui ?= "${AUTOREV}" -SRCREV_pn-openmoko-alsa-scenarios ?= "${AUTOREV}" -SRCREV_pn-openmoko-appearance ?= "${AUTOREV}" -SRCREV_pn-openmoko-appmanager2 ?= "${AUTOREV}" -SRCREV_pn-openmoko-browser2 ?= "${AUTOREV}" -SRCREV_pn-openmoko-calculator2 ?= "${AUTOREV}" -SRCREV_pn-openmoko-common2 ?= "${AUTOREV}" -SRCREV_pn-openmoko-contacts2 ?= "${AUTOREV}" -SRCREV_pn-openmoko-dates2 ?= "${AUTOREV}" -SRCREV_pn-openmoko-dialer2 ?= "${AUTOREV}" -SRCREV_pn-openmoko-feedreader2 ?= "${AUTOREV}" -SRCREV_pn-openmoko-firststart2 ?= "${AUTOREV}" -SRCREV_pn-openmoko-icon-theme-standard2 ?= "${AUTOREV}" -SRCREV_pn-openmoko-icon-theme-standard2-qvga ?= "${AUTOREV}" -SRCREV_pn-openmoko-mediaplayer2 ?= "${AUTOREV}" -SRCREV_pn-openmoko-messages2 ?= "${AUTOREV}" -SRCREV_pn-openmoko-panel-battery ?= "${AUTOREV}" -SRCREV_pn-openmoko-panel-bt ?= "${AUTOREV}" -SRCREV_pn-openmoko-panel-clock ?= "${AUTOREV}" -SRCREV_pn-openmoko-panel-gps ?= "${AUTOREV}" -SRCREV_pn-openmoko-panel-gsm ?= "${AUTOREV}" -SRCREV_pn-openmoko-panel-mainmenu ?= "${AUTOREV}" -SRCREV_pn-openmoko-panel-memory ?= "${AUTOREV}" -SRCREV_pn-openmoko-panel-usb ?= "${AUTOREV}" -SRCREV_pn-openmoko-panel-wifi ?= "${AUTOREV}" -SRCREV_pn-openmoko-sample2 ?= "${AUTOREV}" -SRCREV_pn-openmoko-sound-theme-standard2 ?= "${AUTOREV}" -SRCREV_pn-openmoko-tasks2 ?= "${AUTOREV}" -SRCREV_pn-openmoko-terminal2 ?= "${AUTOREV}" -SRCREV_pn-openmoko-theme-standard2 ?= "${AUTOREV}" -SRCREV_pn-openmoko-theme-standard2-qvga ?= "${AUTOREV}" -SRCREV_pn-openmoko-today2 ?= "${AUTOREV}" -SRCREV_pn-openmoko-today2-folders ?= "${AUTOREV}" -SRCREV_pn-openmoko-toolchain-scripts ?= "${AUTOREV}" -SRCREV_pn-openmoko-worldclock2 ?= "${AUTOREV}" -SRCREV_pn-openocd ?= "${AUTOREV}" -SRCREV_pn-openocd-native ?= "${AUTOREV}" -SRCREV_pn-opkg ?= "${AUTOREV}" -SRCREV_pn-opkg-native ?= "${AUTOREV}" -SRCREV_pn-opkg-sdk ?= "${AUTOREV}" -SRCREV_pn-packagekit ?= "${AUTOREV}" -SRCREV_pn-paroli ?= "${AUTOREV}" -SRCREV_pn-pyefl-sudoku ?= "${AUTOREV}" -SRCREV_pn-qi ?= "${AUTOREV}" -SRCREV_pn-tichy ?= "${AUTOREV}" -SRCREV_pn-u-boot-openmoko ?= "${AUTOREV}" -SRCREV_pn-u-boot-openmoko-devel ?= "${AUTOREV}" -SRCREV_pn-usbpath ?= "${AUTOREV}" -SRCREV_pn-usbpath-native ?= "${AUTOREV}" -SRCREV_pn-wmiconfig ?= "${AUTOREV}" - diff --git a/conf/distro/openmoko.conf b/conf/distro/openmoko.conf index 4d73b8ff84..81d7075fc1 100644 --- a/conf/distro/openmoko.conf +++ b/conf/distro/openmoko.conf @@ -50,7 +50,6 @@ PREFERRED_VERSION_binutils ?= "2.17.50.0.12" PREFERRED_VERSION_binutils-cross ?= "2.17.50.0.12" # Bleeding-edge developers should add the following lines to their local.conf: -# require conf/distro/include/moko-autorev.inc # require conf/distro/include/fso-autorev.inc # override the PACKAGE_ARCH of certain packages for openmoko distro -- cgit v1.2.3 From 48b5a924917292f153ace40ff72bdbcaf420fb3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jeremy=20Lain=C3=A9?= Date: Wed, 9 Sep 2009 20:21:06 +0200 Subject: linux-2.6.29: add devicetree for boc02 --- recipes/linux/linux-2.6.29/boc01/boc02.dts | 344 +++++++++++++++++++++++++++++ 1 file changed, 344 insertions(+) create mode 100644 recipes/linux/linux-2.6.29/boc01/boc02.dts diff --git a/recipes/linux/linux-2.6.29/boc01/boc02.dts b/recipes/linux/linux-2.6.29/boc01/boc02.dts new file mode 100644 index 0000000000..fb0b5fb0a5 --- /dev/null +++ b/recipes/linux/linux-2.6.29/boc01/boc02.dts @@ -0,0 +1,344 @@ +/* + * Bolloré telecom CPE v01 Device Tree Source + * + * Copyright 2005, 2006, 2007 Freescale Semiconductor Inc. + * Copyright 2008, 2009 Bolloré telecom. + * + * 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. + */ + +/dts-v1/; + +/ { + model = "MPC8313ERDB"; + compatible = "MPC8313ERDB", "MPC831xRDB", "MPC83xxRDB"; + #address-cells = <1>; + #size-cells = <1>; + + aliases { + ethernet1 = &enet1; + serial0 = &serial0; + pci0 = &pci0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,8313@0 { + device_type = "cpu"; + reg = <0x0>; + d-cache-line-size = <32>; + i-cache-line-size = <32>; + d-cache-size = <16384>; + i-cache-size = <16384>; + timebase-frequency = <0>; // from bootloader + bus-frequency = <0>; // from bootloader + clock-frequency = <0>; // from bootloader + }; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x08000000>; // 128MB at 0 + }; + + localbus@e0005000 { + #address-cells = <2>; + #size-cells = <1>; + compatible = "fsl,mpc8313-elbc", "fsl,elbc", "simple-bus"; + reg = <0xe0005000 0x1000>; + interrupts = <77 0x8>; + interrupt-parent = <&ipic>; + + // CS0 and CS1 are swapped when + // booting from nand, but the + // addresses are the same. + ranges = <0x0 0x0 0xfe000000 0x00800000 + 0x1 0x0 0xe2800000 0x00008000 + 0x2 0x0 0xf0000000 0x00020000 + 0x3 0x0 0xfa000000 0x00008000>; + + flash@0,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0x0 0x0 0x800000>; + bank-width = <2>; + device-width = <1>; + }; + + nand@1,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc8313-fcm-nand", + "fsl,elbc-fcm-nand"; + reg = <0x1 0x0 0x2000>; + + kernel@0 { + reg = <0x0 0x400000>; + read-only; + }; + + fs@400000 { + reg = <0x400000 0x4000000>; + }; + + appli@4400000 { + reg = <0x4400000 0x3c00000>; + }; + }; + }; + + soc8313@e0000000 { + #address-cells = <1>; + #size-cells = <1>; + device_type = "soc"; + compatible = "simple-bus"; + ranges = <0x0 0xe0000000 0x00100000>; + reg = <0xe0000000 0x00000200>; + bus-frequency = <0>; + + wdt@200 { + device_type = "watchdog"; + compatible = "mpc83xx_wdt"; + reg = <0x200 0x100>; + }; + + sleep-nexus { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + sleep = <&pmc 0x03000000>; + ranges; + + i2c@3000 { + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + compatible = "fsl-i2c"; + reg = <0x3000 0x100>; + interrupts = <14 0x8>; + interrupt-parent = <&ipic>; + dfsrr; + rtc@6f { + compatible = "isl12024"; + reg = <0x6f>; + }; + dtt@49 { + compatible = "national,lm73"; + reg = <0x49>; + }; + at24@50 { + compatible = "at24,24c32"; + reg = <0x50>; + }; + at24@57 { + compatible = "at24,isl12024"; + reg = <0x57>; + }; + }; + + crypto@30000 { + compatible = "fsl,sec2.2", "fsl,sec2.1", + "fsl,sec2.0"; + reg = <0x30000 0x10000>; + interrupts = <11 0x8>; + interrupt-parent = <&ipic>; + fsl,num-channels = <1>; + fsl,channel-fifo-len = <24>; + fsl,exec-units-mask = <0x4c>; + fsl,descriptor-types-mask = <0x0122003f>; + }; + }; + + i2c@3100 { + #address-cells = <1>; + #size-cells = <0>; + cell-index = <1>; + compatible = "fsl-i2c"; + reg = <0x3100 0x100>; + interrupts = <15 0x8>; + interrupt-parent = <&ipic>; + dfsrr; + }; + + spi@7000 { + cell-index = <0>; + compatible = "fsl,spi"; + reg = <0x7000 0x1000>; + interrupts = <16 0x8>; + interrupt-parent = <&ipic>; + mode = "cpu"; + }; + + /* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */ + usb@23000 { + compatible = "fsl-usb2-dr"; + reg = <0x23000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <&ipic>; + interrupts = <38 0x8>; + phy_type = "utmi_wide"; + sleep = <&pmc 0x00300000>; + }; + + enet1: ethernet@25000 { + cell-index = <1>; + device_type = "network"; + model = "eTSEC"; + compatible = "gianfar"; + reg = <0x25000 0x1000>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <35 0x8 36 0x8 37 0x8>; + interrupt-parent = <&ipic>; + fixed-link = <1 1 100 0 0>; + sleep = <&pmc 0x10000000>; + fsl,magic-packet; + }; + + serial0: serial@4600 { + cell-index = <0>; + device_type = "serial"; + compatible = "ns16550"; + reg = <0x4600 0x100>; + clock-frequency = <0>; + interrupts = <10 0x8>; + interrupt-parent = <&ipic>; + }; + + /* IPIC + * interrupts cell = + * sense values match linux IORESOURCE_IRQ_* defines: + * sense == 8: Level, low assertion + * sense == 2: Edge, high-to-low change + */ + ipic: pic@700 { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <2>; + reg = <0x700 0x100>; + device_type = "ipic"; + }; + + pmc: power@b00 { + compatible = "fsl,mpc8313-pmc", "fsl,mpc8349-pmc"; + reg = <0xb00 0x100 0xa00 0x100>; + interrupts = <80 8>; + interrupt-parent = <&ipic>; + fsl,mpc8313-wakeup-timer = <>m1>; + + /* Remove this (or change to "okay") if you have + * a REVA3 or later board, if you apply one of the + * workarounds listed in section 8.5 of the board + * manual, or if you are adapting this device tree + * to a different board. + */ + status = "okay"; + }; + + gtm1: timer@500 { + compatible = "fsl,mpc8313-gtm", "fsl,gtm"; + reg = <0x500 0x100>; + interrupts = <72 8 78 8 84 8 90 8>; + interrupt-parent = <&ipic>; + }; + + timer@600 { + compatible = "fsl,mpc8313-gtm", "fsl,gtm"; + reg = <0x600 0x100>; + interrupts = <91 8 79 8 85 8 73 8>; + interrupt-parent = <&ipic>; + }; + + wakeup@27000 { + compatible = "fsl,wakeup-it", "fsl,gtm"; + reg = <0x27000 0x100>; + interrupts = <17 8 19 8>; + interrupt-parent = <&ipic>; + }; + + }; + + sleep-nexus { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + sleep = <&pmc 0x00010000>; + ranges; + + pci0: pci@e0008500 { + cell-index = <1>; + interrupt-map-mask = <0xf800 0x0 0x0 0x7>; + interrupt-map = < + /* IDSEL 0x0F - PCI slot */ + 0x7800 0x0 0x0 0x1 &ipic 48 0x8 + 0x7800 0x0 0x0 0x2 &ipic 48 0x8 + 0x7800 0x0 0x0 0x3 &ipic 48 0x8 + 0x7800 0x0 0x0 0x4 &ipic 48 0x8>; + interrupt-parent = <&ipic>; + interrupts = <66 0x8>; + bus-range = <0x0 0x0>; + ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000 + 0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000 + 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>; + clock-frequency = <66666666>; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <0xe0008500 0x100>; + compatible = "fsl,mpc8349-pci"; + device_type = "pci"; + }; + + dma@82a8 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc8313-dma", "fsl,elo-dma"; + reg = <0xe00082a8 4>; + ranges = <0 0xe0008100 0x1a8>; + interrupt-parent = <&ipic>; + interrupts = <71 8>; + + dma-channel@0 { + compatible = "fsl,mpc8313-dma-channel", + "fsl,elo-dma-channel"; + reg = <0 0x28>; + interrupt-parent = <&ipic>; + interrupts = <71 8>; + cell-index = <0>; + }; + + dma-channel@80 { + compatible = "fsl,mpc8313-dma-channel", + "fsl,elo-dma-channel"; + reg = <0x80 0x28>; + interrupt-parent = <&ipic>; + interrupts = <71 8>; + cell-index = <1>; + }; + + dma-channel@100 { + compatible = "fsl,mpc8313-dma-channel", + "fsl,elo-dma-channel"; + reg = <0x100 0x28>; + interrupt-parent = <&ipic>; + interrupts = <71 8>; + cell-index = <2>; + }; + + dma-channel@180 { + compatible = "fsl,mpc8313-dma-channel", + "fsl,elo-dma-channel"; + reg = <0x180 0x28>; + interrupt-parent = <&ipic>; + interrupts = <71 8>; + cell-index = <3>; + }; + }; + }; +}; -- cgit v1.2.3 From ec1461ce16b91c008d22000f6a471b2b106669ce Mon Sep 17 00:00:00 2001 From: Graham Gower Date: Tue, 11 Aug 2009 21:32:03 +0000 Subject: glibc: Build glibc 2.9 with glibc-ports 2.9 This combination of glibc-2.9 with glibc-ports-2.7 fails to build on mipsel. The reason we have been using glibc-ports 2.7 was that glibc-ports 2.9 was not tagged or we didn't see it for various reasons. Build glibc 2.9 with glibc-port 2.9 and drop the three ARM patches as they have been applied to the upstream glibc-ports tree: http://sourceware.org/git/?p=glibc-ports.git;a=commitdiff;h=7272ed4e474a398b8ce1e7374cdaa8592b840e2a http://sourceware.org/git/?p=glibc-ports.git;a=commitdiff;h=e6e41f0f4963bfb0c0e32f8263ae028b288b5453 Patchwork: http://patchwork.openembedded.org/patch/933/ Signed-off-By: Graham Gower Signed-off-By: Holger Hans Peter Acked-by: Khem Raj --- conf/checksums.ini | 4 ++++ recipes/glibc/glibc-2.9/glibc-2.9-use-_begin.patch | 28 ++++++++++++++++++++++ recipes/glibc/glibc_2.9.bb | 12 ++++------ 3 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 recipes/glibc/glibc-2.9/glibc-2.9-use-_begin.patch diff --git a/conf/checksums.ini b/conf/checksums.ini index 6c2924278b..7d3bf188bc 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -8274,6 +8274,10 @@ sha256=d094028bc6d6691f56b4efeff7cd7e1c7ca10733e0cb5efc36e8fb08d8324bf1 md5=eaeb8527b8fa286c2d887157214f9998 sha256=3e481996259af87c3581da23481970a27de679e3c87cfa9a5a59751cd20c7b44 +[ftp://ftp.gnu.org/pub/gnu/glibc/glibc-ports-2.9.tar.bz2] +md5=7d5d86031cb15403e4d246658209ee81 +sha256=824c97b83f1ec2894ee0e824db6d542c40b978d2f6c4364c7411777e44b15a64 + [ftp://ftp.gnome.org/pub/GNOME/sources/glibmm/2.16/glibmm-2.16.2.tar.bz2] md5=408054366f0acc01014f4c4af2304da5 sha256=f033f6f39c32fc17ecce63087e41408671a3a43d698c83de2528af3fc7276d28 diff --git a/recipes/glibc/glibc-2.9/glibc-2.9-use-_begin.patch b/recipes/glibc/glibc-2.9/glibc-2.9-use-_begin.patch new file mode 100644 index 0000000000..8d36a0524e --- /dev/null +++ b/recipes/glibc/glibc-2.9/glibc-2.9-use-_begin.patch @@ -0,0 +1,28 @@ +From 7c8a67320e26b8c11108bf0a3410d3aef9cf3486 Mon Sep 17 00:00:00 2001 +From: Ulrich Drepper +Date: Sat, 31 Jan 2009 00:21:15 +0000 +Subject: [PATCH] * elf/Makefile (ld.so): Adjust the sed script to insert _begin in to newer linker scripts. +--- +diff --git a/elf/Makefile b/elf/Makefile +index 8079fe9..e44ff1d 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -1,4 +1,4 @@ +-# Copyright (C) 1995-2007, 2008 Free Software Foundation, Inc. ++# Copyright (C) 1995-2007, 2008, 2009 Free Software Foundation, Inc. + # This file is part of the GNU C Library. + + # The GNU C Library is free software; you can redistribute it and/or +@@ -304,7 +304,7 @@ $(objpfx)ld.so: $(objpfx)librtld.os $(ld-map) + $(LDFLAGS-rtld) -Wl,-z,defs -Wl,--verbose 2>&1 | \ + LC_ALL=C \ + sed -e '/^=========/,/^=========/!d;/^=========/d' \ +- -e 's/\. = 0 + SIZEOF_HEADERS;/& _begin = . - SIZEOF_HEADERS;/' \ ++ -e 's/\. = .* + SIZEOF_HEADERS;/& _begin = . - SIZEOF_HEADERS;/' \ + > $@.lds + $(LINK.o) -nostdlib -nostartfiles -shared -o $@ \ + $(LDFLAGS-rtld) -Wl,-z,defs $(z-now-$(bind-now)) \ +-- +1.6.3.2 + + diff --git a/recipes/glibc/glibc_2.9.bb b/recipes/glibc/glibc_2.9.bb index eb157506c6..c3ebc167aa 100644 --- a/recipes/glibc/glibc_2.9.bb +++ b/recipes/glibc/glibc_2.9.bb @@ -5,7 +5,7 @@ ARM_INSTRUCTION_SET = "arm" PACKAGES_DYNAMIC = "libc6*" RPROVIDES_${PN}-dev = "libc6-dev virtual-libc-dev" -PR = "${INC_PR}.1" +PR = "${INC_PR}.2" # the -isystem in bitbake.conf screws up glibc do_stage BUILD_CPPFLAGS = "-I${STAGING_INCDIR_NATIVE}" @@ -43,7 +43,7 @@ RDEPENDS_${PN}-dev = "linux-libc-headers-dev" # file://arm-ioperm.patch;patch=1;pnum=0 \ # file://ldd.patch;patch=1;pnum=0 \ SRC_URI = "ftp://ftp.gnu.org/pub/gnu/glibc/glibc-${PV}.tar.bz2 \ - ftp://ftp.gnu.org/pub/gnu/glibc/glibc-ports-2.7.tar.bz2 \ + ftp://ftp.gnu.org/pub/gnu/glibc/glibc-ports-${PV}.tar.bz2 \ ftp://ftp.gnu.org/pub/gnu/glibc/glibc-libidn-${PV}.tar.bz2 \ file://nscd-init.patch;patch=1;pnum=0 \ file://arm-memcpy.patch;patch=1 \ @@ -55,9 +55,6 @@ SRC_URI = "ftp://ftp.gnu.org/pub/gnu/glibc/glibc-${PV}.tar.bz2 \ file://glibc-check_pf.patch;patch=1;pnum=0 \ file://ldd-unbash.patch;patch=1 \ file://glibc-arm-IO-acquire-lock-fix.diff;patch=1 \ - file://local-args6.diff;patch=1 \ - file://arm-check-pf.patch;patch=1 \ - file://arm-lowlevellock-include-tls.patch;patch=1 \ file://generic-bits_select.h \ file://generic-bits_types.h \ file://generic-bits_typesizes.h \ @@ -66,10 +63,9 @@ SRC_URI = "ftp://ftp.gnu.org/pub/gnu/glibc/glibc-${PV}.tar.bz2 \ file://generate-supported.mk \ file://march-i686.patch;patch=1;pnum=0 \ file://tls_i486.patch;patch=1 \ - file://glibc-arm-no-asm-page.patch;patch=1 \ + file://glibc-2.9-use-_begin.patch;patch=1 \ " - # Build fails on sh3 and sh4 without additional patches SRC_URI_append_sh3 = " file://no-z-defs.patch;patch=1" SRC_URI_append_sh4 = " file://no-z-defs.patch;patch=1" @@ -92,7 +88,7 @@ EXTRA_OECONF += "${@get_glibc_fpu_setting(bb, d)}" do_munge() { # Integrate ports and libidn into tree - mv ${WORKDIR}/glibc-ports-2.7 ${S}/ports + mv ${WORKDIR}/glibc-ports-${PV} ${S}/ports mv ${WORKDIR}/glibc-libidn-${PV} ${S}/libidn # Ports isn't really working... Fix it -- cgit v1.2.3 From 3a8e482ccc5b6c2912dc9f6cb2a7598423f9152b Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 10 Sep 2009 15:18:48 +0200 Subject: quake2: fix QA errors --- recipes/quake/quake2_svn.bb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/recipes/quake/quake2_svn.bb b/recipes/quake/quake2_svn.bb index 31491ad419..a01def898d 100644 --- a/recipes/quake/quake2_svn.bb +++ b/recipes/quake/quake2_svn.bb @@ -5,6 +5,7 @@ DEPENDS = "libsdl-x11 libxxf86dga" SRCREV = "205" PV = "0.16.1+svnr${SRCREV}" +PR = "r1" SRC_URI = "svn://svn.icculus.org/quake2/;module=trunk \ file://quake2-arm.patch;patch=1" @@ -14,7 +15,7 @@ S = "${WORKDIR}/trunk" export BUILD_SDLQUAKE2=YES export OSTYPE=Linux export ARCH=${TARGET_ARCH} -export BASE_CFLAGS="${TARGET_CC_ARCH} -Wall -pipe -Dstricmp=strcasecmp" +export BASE_CFLAGS="${TARGET_CC_ARCH} ${LDFLAGS} -Wall -pipe -Dstricmp=strcasecmp" export OPT_CFLAGS="-O3 -ffast-math -funroll-loops -fomit-frame-pointer -fexpensive-optimizations" do_compile() { -- cgit v1.2.3 From dd5c666d2182d6d839bde4ba4737bbea65680854 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 10 Sep 2009 18:53:51 +0200 Subject: freeimage: fix QA errors --- recipes/ogre/freeimage_3.11.0.bb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/recipes/ogre/freeimage_3.11.0.bb b/recipes/ogre/freeimage_3.11.0.bb index 2d7f4f0688..49b0848474 100644 --- a/recipes/ogre/freeimage_3.11.0.bb +++ b/recipes/ogre/freeimage_3.11.0.bb @@ -1,10 +1,14 @@ LICENSE = "MIT" do_unpack[depends] += "unzip-native:do_populate_staging" +PR = "r1" + SRC_URI = "${SOURCEFORGE_MIRROR}/freeimage/FreeImage3110.zip" S = "${WORKDIR}/FreeImage/" +TARGET_CC_ARCH += "${LDFLAGS}" + do_configure() { sed -i -e /^CC/d \ -e /^CXX\ /d \ -- cgit v1.2.3 From 5a881d0d782cb69b7754f7438ba66b703f4884ba Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Thu, 10 Sep 2009 12:49:38 -0700 Subject: cherokee: Add new version 0.99.24 * Use INC_PR * Add new recipe for 0.99.24 * Add --with-mysql configure option to point to staging area. Otherwise with build machines having local installation of mysql-dev, cherokee configures itself to use the headers from /usr/include/mysql Signed-off-by: Khem Raj Signed-off-by: Cliff Brake --- conf/checksums.ini | 4 ++++ recipes/cherokee/cherokee.inc | 1 + recipes/cherokee/cherokee_0.4.29.bb | 2 +- recipes/cherokee/cherokee_0.5.3.bb | 3 +-- recipes/cherokee/cherokee_0.5.5.bb | 3 +-- recipes/cherokee/cherokee_0.98.0.bb | 2 +- recipes/cherokee/cherokee_0.99.24.bb | 12 ++++++++++++ 7 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 recipes/cherokee/cherokee_0.99.24.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index 7d3bf188bc..c5ce891f13 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -3682,6 +3682,10 @@ sha256=e9c6feee2a626a38cd69c726ed31ffbbf55d288386f50fe6f90fa63de410d67a md5=9f1876232bdfdfa5b4e02ff0636e7241 sha256=701721a58aa79b93a4f3aaf633f0b842a05b07c73996cd44e78a383a7387226d +[http://www.cherokee-project.com/download/0.99/0.99.24/cherokee-0.99.24.tar.gz] +md5=5afed8bdd6020dc5bf0ba9ec83b947f1 +sha256=0581b5eafba9a993d035467c51bfa85fa76ca46043fab95e6f7592ad8f4f38e1 + [http://www.call-with-current-continuation.org/chicken-2.6.tar.gz] md5=332edae079bb34d815369f4ba5181983 sha256=32385c5393c7376035f911f3e887351b1ce8fb6e56498cc4258815bc6db06326 diff --git a/recipes/cherokee/cherokee.inc b/recipes/cherokee/cherokee.inc index 58ffe1ac94..16ecfbfe1f 100644 --- a/recipes/cherokee/cherokee.inc +++ b/recipes/cherokee/cherokee.inc @@ -4,6 +4,7 @@ HOMEPAGE = "http://www.cherokee-project.com/" SECTION = "network" LICENSE = "GPL" DEPENDS = "libpcre gnutls" +INC_PR = "r7" SRC_URI = "http://www.cherokee-project.com/download/0.5/${PV}/cherokee-${PV}.tar.gz \ file://cherokee.init " diff --git a/recipes/cherokee/cherokee_0.4.29.bb b/recipes/cherokee/cherokee_0.4.29.bb index 42eae684e7..a2c43e3c78 100644 --- a/recipes/cherokee/cherokee_0.4.29.bb +++ b/recipes/cherokee/cherokee_0.4.29.bb @@ -8,7 +8,7 @@ SRC_URI = "http://www.0x50.org/download/0.4/${PV}/${P}.tar.gz \ file://Makefile.in.patch;patch=1 \ file://Makefile.cget.patch;patch=1 \ file://util.patch;patch=1" -PR = "r1" +PR = "${INC_PR}.0" inherit autotools diff --git a/recipes/cherokee/cherokee_0.5.3.bb b/recipes/cherokee/cherokee_0.5.3.bb index 1fe9df46c0..a6e14e75c8 100644 --- a/recipes/cherokee/cherokee_0.5.3.bb +++ b/recipes/cherokee/cherokee_0.5.3.bb @@ -1,11 +1,10 @@ -PR = "r7" - SRC_URI_append = "file://configure.patch;patch=1 \ file://Makefile.in.patch;patch=1 \ file://Makefile.cget.patch;patch=1 \ file://util.patch;patch=1" require cherokee.inc +PR = "${INC_PR}.0" do_configure() { gnu-configize diff --git a/recipes/cherokee/cherokee_0.5.5.bb b/recipes/cherokee/cherokee_0.5.5.bb index 73b4d52418..c12f519622 100644 --- a/recipes/cherokee/cherokee_0.5.5.bb +++ b/recipes/cherokee/cherokee_0.5.5.bb @@ -1,5 +1,3 @@ -PR = "r4" - SRC_URI_append = "file://configure.in.patch;patch=1 \ file://Makefile.am.patch;patch=1" @@ -9,3 +7,4 @@ do_install_prepend () { } require cherokee.inc +PR = "${INC_PR}.0" diff --git a/recipes/cherokee/cherokee_0.98.0.bb b/recipes/cherokee/cherokee_0.98.0.bb index a8ebaa8f72..264e7a54af 100644 --- a/recipes/cherokee/cherokee_0.98.0.bb +++ b/recipes/cherokee/cherokee_0.98.0.bb @@ -1,6 +1,6 @@ require cherokee.inc -PR = "r1" +PR = "${INC_PR}.0" SRC_URI = "http://www.cherokee-project.com/download/0.98/${PV}/cherokee-${PV}.tar.gz \ file://cherokee.init " diff --git a/recipes/cherokee/cherokee_0.99.24.bb b/recipes/cherokee/cherokee_0.99.24.bb new file mode 100644 index 0000000000..b5d016006f --- /dev/null +++ b/recipes/cherokee/cherokee_0.99.24.bb @@ -0,0 +1,12 @@ +require cherokee.inc + +PR = "${INC_PR}.0" + +SRC_URI = "http://www.cherokee-project.com/download/0.99/${PV}/cherokee-${PV}.tar.gz \ + file://cherokee.init " + +CONFFILES_${PN} = " \ +${sysconfdir}/cherokee/cherokee.conf \ +${sysconfdir}/init.d/cherokee \ +" +EXTRA_OECONF += "--with-mysql=${STAGING_INCDIR}/mysql" -- cgit v1.2.3 From b76c22a5c61a06c64c0baefec048690cf0c88806 Mon Sep 17 00:00:00 2001 From: Henning Heinold Date: Fri, 11 Sep 2009 01:12:10 +0200 Subject: directfb: update to version 1.4.2 --- conf/checksums.ini | 4 ++++ .../directfb/directfb-1.4.2/ts_lib_autotools.patch | 22 ++++++++++++++++++ recipes/directfb/directfb_1.4.2.bb | 26 ++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 recipes/directfb/directfb-1.4.2/ts_lib_autotools.patch create mode 100644 recipes/directfb/directfb_1.4.2.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index c5ce891f13..5de82f5366 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -250,6 +250,10 @@ sha256=cbf94eb10e9c305c81b24e298e55c7825df5ab9060d82443f7b9734f760f859d md5=e7df079ff44ec98187c24a00500e597a sha256=aa9d532ec4481a3c9f7b3298b1786a84825a3474b714690b901d0617743d8221 +[http://directfb.org/downloads/Core/DirectFB-1.4/DirectFB-1.4.2.tar.gz] +md5=e4376c6c5b8e27d735edb7f62a7a8e86 +sha256=051847e21e88a9c32ee78f8920014602d8b21928602075c5266433cd58addbc6 + [http://www.directfb.org/downloads/Extras/DirectFB-examples-0.9.25.tar.gz] md5=835e850fddba8d8214d39ddd0646c3e8 sha256=f83af60d53ab4319e5d71a4459cc10464ffd683efabacd6bd773bb807f8771fa diff --git a/recipes/directfb/directfb-1.4.2/ts_lib_autotools.patch b/recipes/directfb/directfb-1.4.2/ts_lib_autotools.patch new file mode 100644 index 0000000000..414d48c2d6 --- /dev/null +++ b/recipes/directfb/directfb-1.4.2/ts_lib_autotools.patch @@ -0,0 +1,22 @@ +--- + configure.in | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +Index: DirectFB-1.4.1/configure.in +=================================================================== +--- DirectFB-1.4.1.orig/configure.in 2009-06-26 23:30:03.000000000 +0200 ++++ DirectFB-1.4.1/configure.in 2009-07-13 00:23:19.558669631 +0200 +@@ -1334,8 +1334,11 @@ + + enable_tslib=no + if test "$checkfor_tslib" = "yes"; then +- PKG_CHECK_MODULES([TSLIB], [tslib-0.0], enable_tslib=yes, enable_tslib=no +- AC_MSG_WARN([*** no tslib -- tslib driver will not be built.])) ++ PKG_CHECK_MODULES([TSLIB], [tslib-1.0 >= 1.0.0], [enable_tslib=yes], [enable_tslib=no]) ++ if test "$enable_tslib" = "no"; then ++ PKG_CHECK_MODULES([TSLIB], [tslib-0.0], [enable_tslib=yes], [enable_tslib=no, ++ AC_MSG_WARN([*** no tslib -- tslib driver will not be built.])]) ++ fi + fi + + enable_ucb1x00_ts=no diff --git a/recipes/directfb/directfb_1.4.2.bb b/recipes/directfb/directfb_1.4.2.bb new file mode 100644 index 0000000000..1e15186cd3 --- /dev/null +++ b/recipes/directfb/directfb_1.4.2.bb @@ -0,0 +1,26 @@ +require directfb.inc + +RV = "1.4-0" + +DEPENDS += "sysfsutils" + +SRC_URI = " \ + http://directfb.org/downloads/Core/DirectFB-1.4/DirectFB-${PV}.tar.gz \ + file://directfb-1.2.x-fix-pkgconfig-cflags.patch;patch=1 \ + file://mkdfiff.patch;patch=1 \ + file://dont-use-linux-config.patch;patch=1 \ + file://ts_lib_autotools.patch;patch=1 \ +" + +EXTRA_OECONF = "\ + --enable-freetype=yes \ + --enable-zlib \ + --with-gfxdrivers=none \ + --disable-sdl \ + --disable-vnc \ + --disable-x11 \ +" + +LDFLAGS_append = "" + +LEAD_SONAME = "libdirectfb-1.4.so.0" -- cgit v1.2.3 From fae7226fa006e8157fd802cd50f6643fa56060bb Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Thu, 10 Sep 2009 17:50:59 -0700 Subject: uclibc-initial: Move the compile stuff to do_compile * Currently all work is done in do_stage. On Henning's suggestion I refactored it. * For 0.9.30 onwards installing pregen and install_dev built almost whole uclibc. We only needed libc headers so replaced with install_headers Signed-off-by: Khem Raj --- recipes/uclibc/uclibc-initial_0.9.28.bb | 16 ++++++++-------- recipes/uclibc/uclibc-initial_0.9.29.bb | 12 ++++++------ recipes/uclibc/uclibc-initial_0.9.30.1.bb | 17 +++++++---------- recipes/uclibc/uclibc-initial_0.9.30.bb | 16 +++++++--------- recipes/uclibc/uclibc-initial_git.bb | 13 ++++++------- recipes/uclibc/uclibc-initial_nptl.bb | 12 ++++++------ 6 files changed, 40 insertions(+), 46 deletions(-) diff --git a/recipes/uclibc/uclibc-initial_0.9.28.bb b/recipes/uclibc/uclibc-initial_0.9.28.bb index dbd90fc862..6e82dcd50a 100644 --- a/recipes/uclibc/uclibc-initial_0.9.28.bb +++ b/recipes/uclibc/uclibc-initial_0.9.28.bb @@ -10,11 +10,6 @@ do_stage() { make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ RUNTIME_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ pregen install_dev - make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ - RUNTIME_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ - libc/sysdeps/linux/${TARGET_ARCH}/crt1.o \ - libc/sysdeps/linux/${TARGET_ARCH}/crti.o \ - libc/sysdeps/linux/${TARGET_ARCH}/crtn.o install -d ${CROSS_DIR}/${TARGET_SYS} ln -sf include ${CROSS_DIR}/${TARGET_SYS}/sys-include @@ -22,8 +17,7 @@ do_stage() { # This conflicts with the c++ version of this header rm -f ${UCLIBC_STAGE_PREFIX}/include/bits/atomicity.h install -m 644 libc/sysdeps/linux/${TARGET_ARCH}/crt[1in].o ${UCLIBC_STAGE_PREFIX}/lib - ${CC} -nostdlib -nostartfiles -shared -x c /dev/null \ - -o ${UCLIBC_STAGE_PREFIX}/lib/libc.so + install -m 644 libc/libc.so ${UCLIBC_STAGE_PREFIX}/lib } @@ -32,5 +26,11 @@ do_install() { } do_compile () { - : + make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ + RUNTIME_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ + libc/sysdeps/linux/${TARGET_ARCH}/crt1.o \ + libc/sysdeps/linux/${TARGET_ARCH}/crti.o \ + libc/sysdeps/linux/${TARGET_ARCH}/crtn.o + ${CC} -nostdlib -nostartfiles -shared -x c /dev/null \ + -o lib/libc.so } diff --git a/recipes/uclibc/uclibc-initial_0.9.29.bb b/recipes/uclibc/uclibc-initial_0.9.29.bb index 98ef7b291a..964f319783 100644 --- a/recipes/uclibc/uclibc-initial_0.9.29.bb +++ b/recipes/uclibc/uclibc-initial_0.9.29.bb @@ -10,9 +10,6 @@ do_stage() { make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ RUNTIME_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ pregen install_dev - make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ - RUNTIME_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ - lib/crt1.o lib/crti.o lib/crtn.o install -d ${CROSS_DIR}/${TARGET_SYS} ln -sf include ${CROSS_DIR}/${TARGET_SYS}/sys-include @@ -20,8 +17,7 @@ do_stage() { # This conflicts with the c++ version of this header rm -f ${UCLIBC_STAGE_PREFIX}/include/bits/atomicity.h install -m 644 lib/crt[1in].o ${UCLIBC_STAGE_PREFIX}/lib - ${CC} -nostdlib -nostartfiles -shared -x c /dev/null \ - -o ${UCLIBC_STAGE_PREFIX}/lib/libc.so + install -m 644 lib/libc.so ${UCLIBC_STAGE_PREFIX}/lib } @@ -30,5 +26,9 @@ do_install() { } do_compile () { - : + make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ + RUNTIME_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ + lib/crt1.o lib/crti.o lib/crtn.o + ${CC} -nostdlib -nostartfiles -shared -x c /dev/null \ + -o lib/libc.so } diff --git a/recipes/uclibc/uclibc-initial_0.9.30.1.bb b/recipes/uclibc/uclibc-initial_0.9.30.1.bb index d0edf93693..5c803b99c6 100644 --- a/recipes/uclibc/uclibc-initial_0.9.30.1.bb +++ b/recipes/uclibc/uclibc-initial_0.9.30.1.bb @@ -9,20 +9,13 @@ do_stage() { # Install initial headers into the cross dir make V=1 CC="${CC}" PREFIX= DEVEL_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ RUNTIME_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ - pregen install_dev - make V=1 CC="${CC}" PREFIX= DEVEL_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ - RUNTIME_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ - lib/crt1.o lib/crti.o lib/crtn.o - - install -d ${CROSS_DIR}/${TARGET_SYS} + install_headers ln -sf include ${CROSS_DIR}/${TARGET_SYS}/sys-include # This conflicts with the c++ version of this header rm -f ${UCLIBC_STAGE_PREFIX}/include/bits/atomicity.h install -m 644 lib/crt[1in].o ${UCLIBC_STAGE_PREFIX}/lib - ${CC} -nostdlib -nostartfiles -shared -x c /dev/null \ - -o ${UCLIBC_STAGE_PREFIX}/lib/libc.so - + install -m 644 lib/libc.so ${UCLIBC_STAGE_PREFIX}/lib } do_install() { @@ -30,5 +23,9 @@ do_install() { } do_compile () { - : + make V=1 CC="${CC}" PREFIX= DEVEL_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ + RUNTIME_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ + lib/crt1.o lib/crti.o lib/crtn.o + ${CC} -nostdlib -nostartfiles -shared -x c /dev/null \ + -o lib/libc.so } diff --git a/recipes/uclibc/uclibc-initial_0.9.30.bb b/recipes/uclibc/uclibc-initial_0.9.30.bb index 98ef7b291a..7cd953605b 100644 --- a/recipes/uclibc/uclibc-initial_0.9.30.bb +++ b/recipes/uclibc/uclibc-initial_0.9.30.bb @@ -9,20 +9,14 @@ do_stage() { # Install initial headers into the cross dir make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ RUNTIME_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ - pregen install_dev - make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ - RUNTIME_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ - lib/crt1.o lib/crti.o lib/crtn.o + install-headers - install -d ${CROSS_DIR}/${TARGET_SYS} ln -sf include ${CROSS_DIR}/${TARGET_SYS}/sys-include # This conflicts with the c++ version of this header rm -f ${UCLIBC_STAGE_PREFIX}/include/bits/atomicity.h install -m 644 lib/crt[1in].o ${UCLIBC_STAGE_PREFIX}/lib - ${CC} -nostdlib -nostartfiles -shared -x c /dev/null \ - -o ${UCLIBC_STAGE_PREFIX}/lib/libc.so - + install -m 644 lib/libc.so ${UCLIBC_STAGE_PREFIX}/lib } do_install() { @@ -30,5 +24,9 @@ do_install() { } do_compile () { - : + make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ + RUNTIME_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ + lib/crt1.o lib/crti.o lib/crtn.o + ${CC} -nostdlib -nostartfiles -shared -x c /dev/null \ + -o lib/libc.so } diff --git a/recipes/uclibc/uclibc-initial_git.bb b/recipes/uclibc/uclibc-initial_git.bb index 38b85ef36f..6c91762723 100644 --- a/recipes/uclibc/uclibc-initial_git.bb +++ b/recipes/uclibc/uclibc-initial_git.bb @@ -10,17 +10,12 @@ do_stage() { make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ RUNTIME_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ install_headers - make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ - RUNTIME_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ - lib/crt1.o lib/crti.o lib/crtn.o - ln -sf include ${CROSS_DIR}/${TARGET_SYS}/sys-include # This conflicts with the c++ version of this header rm -f ${UCLIBC_STAGE_PREFIX}/include/bits/atomicity.h install -m 644 lib/crt[1in].o ${UCLIBC_STAGE_PREFIX}/lib - ${CC} -nostdlib -nostartfiles -shared -x c /dev/null \ - -o ${UCLIBC_STAGE_PREFIX}/lib/libc.so + install -m 644 lib/libc.so ${UCLIBC_STAGE_PREFIX}/lib } do_install() { @@ -28,5 +23,9 @@ do_install() { } do_compile () { - : + make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ + RUNTIME_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ + lib/crt1.o lib/crti.o lib/crtn.o + ${CC} -nostdlib -nostartfiles -shared -x c /dev/null \ + -o lib/libc.so } diff --git a/recipes/uclibc/uclibc-initial_nptl.bb b/recipes/uclibc/uclibc-initial_nptl.bb index 3da8417e52..cca3c1e688 100644 --- a/recipes/uclibc/uclibc-initial_nptl.bb +++ b/recipes/uclibc/uclibc-initial_nptl.bb @@ -14,16 +14,12 @@ do_stage() { ln -sf include ${CROSS_DIR}/${TARGET_SYS}/sys-include # This conflicts with the c++ version of this header - make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ - RUNTIME_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ - lib/crt1.o lib/crti.o lib/crtn.o V=1 rm -f ${UCLIBC_STAGE_PREFIX}/include/bits/atomicity.h install -m 644 lib/crt[1in].o ${UCLIBC_STAGE_PREFIX}/lib + install -m 644 lib/libc.so ${UCLIBC_STAGE_PREFIX}/lib - ${CC} -nostdlib -nostartfiles -shared -x c /dev/null \ - -o ${UCLIBC_STAGE_PREFIX}/lib/libc.so } do_install() { @@ -31,5 +27,9 @@ do_install() { } do_compile () { - : + make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ + RUNTIME_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ + lib/crt1.o lib/crti.o lib/crtn.o V=1 + ${CC} -nostdlib -nostartfiles -shared -x c /dev/null \ + -o lib/libc.so } -- cgit v1.2.3 From bcc5de7935874cb2e5673526398ddf3a08e9812f Mon Sep 17 00:00:00 2001 From: Henning Heinold Date: Fri, 11 Sep 2009 03:22:24 +0200 Subject: eject: inherit gettext to honour USE_NLS --- recipes/eject/eject_2.1.5.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/eject/eject_2.1.5.bb b/recipes/eject/eject_2.1.5.bb index 7cf7188899..6d53aee9a7 100644 --- a/recipes/eject/eject_2.1.5.bb +++ b/recipes/eject/eject_2.1.5.bb @@ -1,7 +1,7 @@ DESCRIPTION = "Eject allows removable media (typically a CD-ROM, floppy disk, tape, or JAZ or ZIP disk) to be ejected under software control." LICENSE = "GPLv2" -inherit autotools +inherit autotools gettext SRC_URI = "http://ca.geocities.com/jefftranter@rogers.com/eject-${PV}.tar.gz" -- cgit v1.2.3 From a74a29fb4084d201f664aa00d7d5f0891d6d4822 Mon Sep 17 00:00:00 2001 From: Henning Heinold Date: Fri, 11 Sep 2009 03:23:54 +0200 Subject: disko: update to newer git rev * stole some input form the disko-oe-git, but rework some stuff --- recipes/disko/disko.inc | 24 ++++++++++++++ recipes/disko/disko_git.bb | 26 +++------------ recipes/disko/files/linkpath.patch | 23 +++++--------- recipes/disko/files/pkgconfig.patch | 63 +++++++++++++++++++------------------ 4 files changed, 69 insertions(+), 67 deletions(-) create mode 100644 recipes/disko/disko.inc diff --git a/recipes/disko/disko.inc b/recipes/disko/disko.inc new file mode 100644 index 0000000000..8f531c5a5a --- /dev/null +++ b/recipes/disko/disko.inc @@ -0,0 +1,24 @@ +DESCRIPTION = "Disko is an application framework, that can be used to develop GUI applications for embedded devices." +LICENSE = "GPL" + +DEPENDS = "sqlite3 libpng jpeg curl alsa-lib freetype libxml2 libsigc++-2.0 openssl" + +inherit scons pkgconfig + +ARM_INSTRUCTION_SET = "arm" +LD = ${CXX} + +#workaround for disko which creates .pc inside install +do_install_append () { + +for i in `find ${S}/ ${D}/${libdir}/pkgconfig -name "*.pc" -type f` ; do \ + sed -i -e 's:${D}::g' $i + done +} + +scons_do_stage_append () { + STAGE_PKG_SEARCHPATH="${S}/ ${@['','${WORKDIR}/staging-pkg/'][bb.data.inherits_class('packaged-staging',d)]}" + for i in `find ${STAGE_PKG_SEARCHPATH} -name "*.pc" -type f` ; do \ + sed -i -e 's:${STAGING_DIR_HOST}::g' $i + done +} diff --git a/recipes/disko/disko_git.bb b/recipes/disko/disko_git.bb index a48ec15d39..9aa378ee5c 100644 --- a/recipes/disko/disko_git.bb +++ b/recipes/disko/disko_git.bb @@ -1,38 +1,22 @@ DESCRIPTION = "Disko is an application framework, that can be used to develop GUI applications for embedded devices. It is closely connected to the DirectFB" LICENSE = "GPL" -PV = "1.1.5+gitr${SRCREV}" +PV = "1.6.0+gitr${SRCREV}" PR = "r0" -DEPENDS = "sqlite3 libpng jpeg curl alsa-lib taglib directfb libxml2 virtual/libx11 libsigc++-2.0 hal \ - libxv libxxf86vm" +require disko.inc + +DEPENDS += "taglib directfb virtual/libx11 hal libxv libxxf86vm" SRC_URI = "git://www.diskohq.org/disko.git;protocol=git \ file://linkpath.patch;patch=1 \ file://pkgconfig.patch;patch=1 \ " -SRCREV = "ed1d2905be5ae4fff37c498847c298fa501bbde1" +SRCREV = "2aa9912fc32fcf24574e5053201e967dd59bceca" S = "${WORKDIR}/git" -inherit scons pkgconfig - do_compile() { ${STAGING_BINDIR_NATIVE}/scons ${PARALLEL_MAKE} graphics=all PREFIX=${prefix} prefix=${prefix} || \ oefatal "scons build execution failed." } - -#workaround for disko which creates .pc inside install -do_install_append () { - -for i in `find ${S}/ ${D}/${libdir}/pkgconfig -name "*.pc" -type f` ; do \ - sed -i -e 's:${D}::g' $i - done -} - -scons_do_stage_append () { - STAGE_PKG_SEARCHPATH="${S}/ ${@['','${WORKDIR}/staging-pkg/'][bb.data.inherits_class('packaged-staging',d)]}" - for i in `find ${STAGE_PKG_SEARCHPATH} -name "*.pc" -type f` ; do \ - sed -i -e 's:${STAGING_DIR_HOST}::g' $i - done -} diff --git a/recipes/disko/files/linkpath.patch b/recipes/disko/files/linkpath.patch index c28540848e..e38b0748c4 100644 --- a/recipes/disko/files/linkpath.patch +++ b/recipes/disko/files/linkpath.patch @@ -1,22 +1,15 @@ Index: git/SConstruct =================================================================== ---- git.orig/SConstruct 2009-07-14 20:45:56.924100368 +0200 -+++ git/SConstruct 2009-07-14 20:46:27.553677127 +0200 -@@ -131,7 +131,7 @@ - if os.environ.has_key('CXXFLAGS'): - env['CCFLAGS'] = [os.environ['CXXFLAGS'].split()] - if os.environ.has_key('LD'): -- env['LINK'] = [os.environ['LD'].split()] -+ env['LINK'] = [os.environ['CXX'].split()] - if os.environ.has_key('LDFLAGS'): - env['LINKFLAGS'] = [os.environ['LDFLAGS'].split()] - -@@ -156,7 +156,7 @@ +--- git.orig/SConstruct 2009-09-11 01:44:37.000000000 +0200 ++++ git/SConstruct 2009-09-11 01:52:26.265319426 +0200 +@@ -161,8 +161,8 @@ + idir_inc = idir_prefix + '/include/disko' idir_data = idir_prefix + '/share/disko' - # link with -rpath --env['LINKFLAGS'].append('-Wl,-rpath=' + env['prefix'] + '/lib/disko') -+env['LINKFLAGS'].append('-Wl,-rpath-link=' + env['prefix'] + '/lib/disko') +-# link with -rpath +-# env['LINKFLAGS'].extend(['-Wl,-rpath=' + env['prefix'] + '/lib/disko']) ++# link with -rpath-link ++# env['LINKFLAGS'].extend(['-Wl,-rpath-link==' + env['prefix'] + '/lib/disko']) # extra flags if env['messages']: diff --git a/recipes/disko/files/pkgconfig.patch b/recipes/disko/files/pkgconfig.patch index 4bf50dcfa4..3e4a84bfe8 100644 --- a/recipes/disko/files/pkgconfig.patch +++ b/recipes/disko/files/pkgconfig.patch @@ -1,60 +1,60 @@ Index: git/SConstruct =================================================================== ---- git.orig/SConstruct 2009-07-14 23:53:04.460889326 +0200 -+++ git/SConstruct 2009-07-14 23:56:23.408030317 +0200 -@@ -542,6 +542,7 @@ +--- git.orig/SConstruct 2009-09-11 01:53:54.000000000 +0200 ++++ git/SConstruct 2009-09-11 02:08:12.789878911 +0200 +@@ -585,6 +585,7 @@ ####################################################################### # TODO: handle disko_pc_libs # if 'install' in BUILD_TARGETS: + PKG_CCFLAGS = '' disko_pc = open('disko.pc', 'w') - disko_pc_requires = 'libxml-2.0 >= 2.6, libcurl, sigc++-2.0, libpng >= 1.2, freetype2' + disko_pc_requires = 'libxml-2.0 >= 2.6, sigc++-2.0, libpng >= 1.2, freetype2' if env['LIBPATH']: -@@ -559,31 +560,43 @@ +@@ -610,30 +611,43 @@ + if env.has_key('libdl'): + disko_pc_libs += ' -ldl' - if env.has_key('libiconv'): - disko_pc_libs += ' -liconv' + if('fbdev' in env['graphics']): -+ PKG_CCFLAGS += '-D__HAVE_FBDEV__ ' - ++ PKG_CCFLAGS += '-D__HAVE_FBDEV__ ' ++ if 'dfb' in env['graphics']: disko_pc_requires += ', directfb' -+ PKG_CCFLAGS += '-D__HAVE_DIRECTFB__ ' ++ PKG_CCFLAGS += '-D__HAVE_DIRECTFB__ ' if 'x11' in env['graphics']: disko_pc_requires += ', x11, xv, xxf86vm' -+ PKG_CCFLAGS += '-D__HAVE_XLIB__ ' -+ PKG_CCFLAGS += '-D__ENABLE_MMSFB_X11_CORE__ ' -+ PKG_CCFLAGS += '-D__ENABLE_MMSFBSURFACE_X11_CORE__ ' ++ PKG_CCFLAGS += '-D__HAVE_XLIB__ ' ++ PKG_CCFLAGS += '-D__ENABLE_MMSFB_X11_CORE__ ' ++ PKG_CCFLAGS += '-D__ENABLE_MMSFBSURFACE_X11_CORE__ ' - if env['media'] != 'none': + if env['media'] and env['media'] != 'none': disko_pc_requires += ', alsa' - if not env['big_lib']: + if not env['big_lib'] and not env['static_lib']: disko_pc_libs += ' -lmmsmedia' -+ PKG_CCFLAGS += '-D__HAVE_MMSMEDIA__ -D__HAVE_MIXER__ ' ++ PKG_CCFLAGS += '-D__HAVE_MMSMEDIA__ -D__HAVE_MIXER__ ' if 'xine' in env['media']: if('x11' in env['graphics']): disko_pc_requires += ', libxine >= 1.1.15' else: disko_pc_requires += ', libxine' -+ PKG_CCFLAGS += '-D__HAVE_XINE__ ' -+ if conf.checkXineBlDvb(): -+ PKG_CCFLAGS += '-D__HAVE_XINE_BLDVB__ ' ++ PKG_CCFLAGS += '-D__HAVE_XINE__ ' ++ if conf.checkXineBlDvb(): ++ PKG_CCFLAGS += '-D__HAVE_XINE_BLDVB__ ' if 'gstreamer' in env['media']: disko_pc_requires += ', gstreamer-0.10' -+ PKG_CCFLAGS += '-D__HAVE_GSTREAMER__ ' ++ PKG_CCFLAGS += '-D__HAVE_GSTREAMER__ ' if env['enable_flash']: - disko_pc_requires += ', swfdec-0.8' - if not env['big_lib']: + disko_pc_requires += ', swfdec-' + swfdecversion + if not env['big_lib'] and not env['static_lib']: disko_pc_libs += ' -lmmsflash' -+ PKG_CCFLAGS += '-D__HAVE_MMSFLASH__ ' ++ PKG_CCFLAGS += '-D__HAVE_MMSFLASH__ ' if env['enable_sip']: disko_pc_requires += ', libpj' -@@ -591,18 +604,32 @@ +@@ -641,18 +655,32 @@ disko_pc_libs += ' -lmmssip' if('uuid' in env['LIBS']): disko_pc_requires += ', uuid' @@ -87,17 +87,18 @@ Index: git/SConstruct disko_pc.write('prefix=' + env['prefix'] + '\n') disko_pc.write('exec_prefix=${prefix}\n') -@@ -614,12 +641,7 @@ +@@ -664,13 +692,7 @@ disko_pc.write('Requires: ' + disko_pc_requires + '\n') disko_pc.write('Libs: -L${libdir} ' + disko_pc_libs + '\n') disko_pc.write('Cflags: -I${includedir}/ ') - for ccflag in env['CCFLAGS']: -- disko_pc.write(' ') -- if(type(ccflag).__name__ == 'str'): -- disko_pc.write(ccflag) -- else: -- disko_pc.write(' '.join(ccflag)) -+ disko_pc.write(PKG_CCFLAGS) +- if type(ccflag).__name__ == 'str' and not ccflag.startswith('-isystem'): +- disko_pc.write(' ') +- if(type(ccflag).__name__ == 'str'): +- disko_pc.write(ccflag) +- else: +- disko_pc.write(' '.join(ccflag)) ++ disko_pc.write(PKG_CCFLAGS) disko_pc.write('\n') disko_pc.close() -- cgit v1.2.3 From 50d8ec53a4424cf9fc80c6f3e80f9ffbe3b19a18 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Tue, 8 Sep 2009 20:41:56 -0700 Subject: images: Rename native-sdk-console-image.bb as native-sdk-image.bb tasks: Rename task-native-sdk.bb as task-sdk-native.bb Signed-off-by: Khem Raj --- recipes/images/native-sdk-console-image.bb | 2 -- recipes/images/native-sdk-image.bb | 2 ++ recipes/tasks/task-native-sdk.bb | 14 -------------- recipes/tasks/task-sdk-native.bb | 14 ++++++++++++++ 4 files changed, 16 insertions(+), 16 deletions(-) delete mode 100644 recipes/images/native-sdk-console-image.bb create mode 100644 recipes/images/native-sdk-image.bb delete mode 100644 recipes/tasks/task-native-sdk.bb create mode 100644 recipes/tasks/task-sdk-native.bb diff --git a/recipes/images/native-sdk-console-image.bb b/recipes/images/native-sdk-console-image.bb deleted file mode 100644 index df05fb4d6b..0000000000 --- a/recipes/images/native-sdk-console-image.bb +++ /dev/null @@ -1,2 +0,0 @@ -require console-image.bb -IMAGE_INSTALL += "task-native-sdk" diff --git a/recipes/images/native-sdk-image.bb b/recipes/images/native-sdk-image.bb new file mode 100644 index 0000000000..df05fb4d6b --- /dev/null +++ b/recipes/images/native-sdk-image.bb @@ -0,0 +1,2 @@ +require console-image.bb +IMAGE_INSTALL += "task-native-sdk" diff --git a/recipes/tasks/task-native-sdk.bb b/recipes/tasks/task-native-sdk.bb deleted file mode 100644 index 387e7b56fe..0000000000 --- a/recipes/tasks/task-native-sdk.bb +++ /dev/null @@ -1,14 +0,0 @@ -DESCRIPTION = "Packages required for native (on-device) SDK" -LICENSE = "MIT" -DEPENDS = "virtual/libc gcc binutils make patch patchutils diffstat diffutils automake flex bison gawk sed grep" -RDEPENDS = "gcc-symlinks g++-symlinks cpp cpp-symlinks binutils-symlinks \ - make virtual-libc-dev \ - task-proper-tools perl-modules flex flex-dev bison gawk sed grep autoconf automake make \ - patch patchutils diffstat diffutils libstdc++-dev" - -RECOMMENDS = " g77-symlinks gfortran-symlinks " - -PR = "r6" - -ALLOW_EMPTY = "1" -PACKAGES = "${PN}" diff --git a/recipes/tasks/task-sdk-native.bb b/recipes/tasks/task-sdk-native.bb new file mode 100644 index 0000000000..387e7b56fe --- /dev/null +++ b/recipes/tasks/task-sdk-native.bb @@ -0,0 +1,14 @@ +DESCRIPTION = "Packages required for native (on-device) SDK" +LICENSE = "MIT" +DEPENDS = "virtual/libc gcc binutils make patch patchutils diffstat diffutils automake flex bison gawk sed grep" +RDEPENDS = "gcc-symlinks g++-symlinks cpp cpp-symlinks binutils-symlinks \ + make virtual-libc-dev \ + task-proper-tools perl-modules flex flex-dev bison gawk sed grep autoconf automake make \ + patch patchutils diffstat diffutils libstdc++-dev" + +RECOMMENDS = " g77-symlinks gfortran-symlinks " + +PR = "r6" + +ALLOW_EMPTY = "1" +PACKAGES = "${PN}" -- cgit v1.2.3 From d3fc551eb32ff334fcea7cfe20a6f76b20c65c21 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Tue, 8 Sep 2009 20:43:46 -0700 Subject: console-image.bb: Require console-base-image * Get rid of code duplication. Signed-off-by: Khem Raj --- recipes/images/console-image.bb | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/recipes/images/console-image.bb b/recipes/images/console-image.bb index 9707881402..c3d3f17c39 100644 --- a/recipes/images/console-image.bb +++ b/recipes/images/console-image.bb @@ -1,24 +1,10 @@ #Angstrom bootstrap image +require console-base-image.bb -IMAGE_PREPROCESS_COMMAND = "create_etc_timestamp" - -ANGSTROM_EXTRA_INSTALL ?= "" - -SPLASH ?= "" -ZZAPSPLASH = ' ${@base_contains("MACHINE_FEATURES", "screen", "psplash-zap", "",d)}' - -DEPENDS = "task-base-extended \ - ${SPLASH} \ - ${ZZAPSPLASH} \ +DEPENDS += "task-base-extended \ " -IMAGE_INSTALL = "task-base-extended \ - ${ANGSTROM_EXTRA_INSTALL} \ - ${SPLASH} \ - ${ZZAPSPLASH} \ +IMAGE_INSTALL += "task-base-extended \ " export IMAGE_BASENAME = "console-image" -IMAGE_LINGUAS = "" - -inherit image -- cgit v1.2.3 From ad856cde593366bcd0d6cf4c6dfec12ec58c0b20 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Tue, 8 Sep 2009 20:45:43 -0700 Subject: binutils-cross: Do not install libibery.a in wrong place * This interferes with canadian cross build of binutils because it finds cross libiberty.a where as it needs the target one. Signed-off-by: Khem Raj --- recipes/binutils/binutils-cross.inc | 7 ------- recipes/binutils/binutils_cvs.bb | 28 +++++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/recipes/binutils/binutils-cross.inc b/recipes/binutils/binutils-cross.inc index 384d18cfa7..5808c1fbda 100644 --- a/recipes/binutils/binutils-cross.inc +++ b/recipes/binutils/binutils-cross.inc @@ -22,13 +22,6 @@ do_stage () { rmdir ${CROSS_DIR}/${libdir} || : rmdir ${CROSS_DIR}/${libdir}64 || : rmdir ${CROSS_DIR}/${prefix} || : - - # We want to move this into the target specific location - mkdir -p ${STAGING_DIR_TARGET}/lib - mv -f ${CROSS_DIR}/lib/libiberty.a ${STAGING_DIR_TARGET}/lib || \ - mv -f ${CROSS_DIR}/lib64/libiberty.a ${STAGING_DIR_TARGET}/lib - rmdir ${CROSS_DIR}/lib || : - rmdir ${CROSS_DIR}/lib64 || : } do_install () { diff --git a/recipes/binutils/binutils_cvs.bb b/recipes/binutils/binutils_cvs.bb index ad4dd2b474..88dcd78c90 100644 --- a/recipes/binutils/binutils_cvs.bb +++ b/recipes/binutils/binutils_cvs.bb @@ -21,8 +21,34 @@ do_compile () { oe_runmake all-ld all-binutils all-gas } do_install () { - oe_runmake install-ld install-binutils install-gas + autotools_do_install install-ld install-binutils install-gas + + # We don't really need these, so we'll remove them... + rm -rf ${D}${libdir}/ldscripts + + # Fix the /usr/${TARGET_SYS}/bin/* links + for l in ${D}${prefix}/${TARGET_SYS}/bin/*; do + rm -f $l + ln -sf `echo ${prefix}/${TARGET_SYS}/bin \ + | tr -s / \ + | sed -e 's,^/,,' -e 's,[^/]*,..,g'`${bindir}/${TARGET_PREFIX}`basename $l` $l + done + + # Install the libiberty header + install -d ${D}${includedir} + install -m 644 ${S}/include/ansidecl.h ${D}${includedir} + install -m 644 ${S}/include/libiberty.h ${D}${includedir} + + cd ${D}${bindir} + + # Symlinks for ease of running these on the native target + for p in ${TARGET_SYS}-* ; do + ln -sf $p `echo $p | sed -e s,${TARGET_SYS}-,,` + done + + rm ${D}${bindir}/ar ${D}${bindir}/strings } + do_stage () { oe_libinstall -so -a -C opcodes libopcodes ${STAGING_LIBDIR}/ oe_libinstall -a -C libiberty libiberty ${STAGING_LIBDIR}/ -- cgit v1.2.3 From 2aaa2e297f98a239a628706124615a7816a6b662 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Tue, 8 Sep 2009 20:49:09 -0700 Subject: gcc-configure-common: Dont fiddle with NATIVE_SYSTEM_HEADER_DIR * This does not work on canadian cross build of target gcc. Signed-off-by: Khem Raj --- recipes/gcc/gcc-4.4.1.inc | 43 ------------------------------------ recipes/gcc/gcc-configure-common.inc | 7 ------ 2 files changed, 50 deletions(-) diff --git a/recipes/gcc/gcc-4.4.1.inc b/recipes/gcc/gcc-4.4.1.inc index 9bc4d17dd6..f32f749ce6 100644 --- a/recipes/gcc/gcc-4.4.1.inc +++ b/recipes/gcc/gcc-4.4.1.inc @@ -30,46 +30,3 @@ EXTRA_OECONF_BASE = " --enable-libssp \ --disable-libmudflap" EXTRA_OECONF_append_linux-uclibc = " ${@base_contains('TARGET_ARCH', 'powerpc', '--disable-decimal-float --without-long-double-128', '',d)}" -do_configure () { - # Setup these vars for cross building only - # ... because foo_FOR_TARGET apparently gets misinterpreted inside the - # gcc build stuff when the build is producing a cross compiler - i.e. - # when the 'current' target is the 'host' system, and the host is not - # the target (because the build is actually making a cross compiler!) - if [ "${BUILD_SYS}" != "${HOST_SYS}" ]; then - export CC_FOR_TARGET="${CC}" - export GCC_FOR_TARGET="${CC}" - export CXX_FOR_TARGET="${CXX}" - export AS_FOR_TARGET="${HOST_PREFIX}as" - export LD_FOR_TARGET="${HOST_PREFIX}ld" - export NM_FOR_TARGET="${HOST_PREFIX}nm" - export AR_FOR_TARGET="${HOST_PREFIX}ar" - export GFORTRAN_FOR_TARGET="gfortran" - export RANLIB_FOR_TARGET="${HOST_PREFIX}ranlib" - fi - export CC_FOR_BUILD="${BUILD_CC}" - export CXX_FOR_BUILD="${BUILD_CXX}" - export CFLAGS_FOR_BUILD="${BUILD_CFLAGS}" - export CPPFLAGS_FOR_BUILD="${BUILD_CPPFLAGS}" - export CXXFLAGS_FOR_BUILD="${BUILD_CXXFLAGS}" - export LDFLAGS_FOR_BUILD="${BUILD_LDFLAGS}" - export ARCH_FLAGS_FOR_TARGET="${ARCH_FLAGS_FOR_TARGET}" - - # Make sure LDFLAGS are honored. - sed -i 's/^LDFLAGS = $/LDFLAGS = @LDFLAGS@/' ${S}/Makefile.in - sed -i 's/^LDFLAGS = $/LDFLAGS = @LDFLAGS@/' ${S}/Makefile.tpl - - (cd ${S} && gnu-configize) || die "failure running gnu-configize" - - # splice our idea of where the headers live into gcc's world - #echo "NATIVE_SYSTEM_HEADER_DIR = ${layout_includedir}" > ${T}/t-oe - #sed 's%^tmake_file=.*$%& ${T}/t-oe%' < ${S}/gcc/Makefile.in >${S}/gcc/Makefile.in.new - #mv ${S}/gcc/Makefile.in.new ${S}/gcc/Makefile.in - - #echo "#define STANDARD_INCLUDE_DIR \"${layout_includedir}\"" >> ${S}/gcc/defaults.h - - oe_runconf - - # make sure that no @LDFLAG@ is left in the generated Makefile - sed -i "s/@LDFLAGS@//g" ${B}/Makefile -} diff --git a/recipes/gcc/gcc-configure-common.inc b/recipes/gcc/gcc-configure-common.inc index 1c605a132d..7315a20cf9 100644 --- a/recipes/gcc/gcc-configure-common.inc +++ b/recipes/gcc/gcc-configure-common.inc @@ -81,13 +81,6 @@ do_configure () { (cd ${S} && gnu-configize) || die "failure running gnu-configize" - # splice our idea of where the headers live into gcc's world - echo "NATIVE_SYSTEM_HEADER_DIR = ${layout_includedir}" > ${T}/t-oe - sed 's%^tmake_file=.*$%& ${T}/t-oe%' < ${S}/gcc/Makefile.in >${S}/gcc/Makefile.in.new - mv ${S}/gcc/Makefile.in.new ${S}/gcc/Makefile.in - - echo "#define STANDARD_INCLUDE_DIR \"${layout_includedir}\"" >> ${S}/gcc/defaults.h - oe_runconf # make sure that no @LDFLAG@ is left in the generated Makefile -- cgit v1.2.3 From 045f4e9106384b27d1ebc28e9bc9c5dc6bff7a94 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Thu, 10 Sep 2009 19:16:53 -0700 Subject: sane-toolchain.inc: Default to gcc 4.4.1 * ppc405 has also got tested using 4.4.1 so bump this too. * ARMv7 is also switched to use 4.4.1. Signed-off-by: Khem Raj Acked-by: Michael 'Mickey' Lauer Acked-by: Phil Blundell --- conf/distro/include/sane-toolchain.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/conf/distro/include/sane-toolchain.inc b/conf/distro/include/sane-toolchain.inc index 65cb7763d1..e2c6740e52 100644 --- a/conf/distro/include/sane-toolchain.inc +++ b/conf/distro/include/sane-toolchain.inc @@ -5,7 +5,7 @@ ############################################################################# # Base line versions, good for most things -PREFERRED_GCC_VERSION ?= "4.2.4" +PREFERRED_GCC_VERSION ?= "4.4.1" PREFERRED_BINUTILS ?= "2.18" # Prefer glibc 2.6 and uclibc 0.9.30, these have had the most testing. @@ -19,9 +19,9 @@ PREFERRED_VERSION_uclibc-initial ?= "0.9.30.1" # Some systems need a special gcc version PREFERRED_GCC_VERSION_486sx ?= "4.3.2" PREFERRED_GCC_VERSION_avr32 ?= "4.2.2" -PREFERRED_GCC_VERSION_armv7a ?= "4.3.1" +PREFERRED_GCC_VERSION_armv7a ?= "4.4.1" PREFERRED_GCC_VERSION_bfin ?= "4.1.2" -PREFERRED_GCC_VERSION_ppc405 ?= "4.1.1" +PREFERRED_GCC_VERSION_ppc405 ?= "4.4.1" PREFERRED_GCC_VERSION_xilinx-ml403 ?= "4.1.1" PREFERRED_GCC_VERSION_xilinx-ml403 ?= "4.1.1" -- cgit v1.2.3 From 8050c52cb58da79cb2849f34905fbcfa64fbf58b Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Thu, 10 Sep 2009 19:21:33 -0700 Subject: native-sdk-image.bb: Use IMAGE_BASENAME = "native-sdk-image" Signed-off-by: Khem Raj --- recipes/images/native-sdk-image.bb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/recipes/images/native-sdk-image.bb b/recipes/images/native-sdk-image.bb index df05fb4d6b..5d7968fc4a 100644 --- a/recipes/images/native-sdk-image.bb +++ b/recipes/images/native-sdk-image.bb @@ -1,2 +1,3 @@ -require console-image.bb -IMAGE_INSTALL += "task-native-sdk" +require console-image.bb +IMAGE_INSTALL += "task-sdk-native" +export IMAGE_BASENAME = "native-sdk-image" -- cgit v1.2.3 From 01407868c7671f8f5afdf8e29ee0315e16bef059 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Thu, 10 Sep 2009 19:22:46 -0700 Subject: gcc-configure-cross.inc: Export more binutils * Export AS_FOR_TARGET OBJDUMP_FOR_TARGET OBJCOPY_FOR_TARGET STRIP_FOR_TARGET Signed-off-by: Khem Raj --- recipes/gcc/gcc-configure-cross.inc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/recipes/gcc/gcc-configure-cross.inc b/recipes/gcc/gcc-configure-cross.inc index aa4174edc4..b526ff3cc4 100644 --- a/recipes/gcc/gcc-configure-cross.inc +++ b/recipes/gcc/gcc-configure-cross.inc @@ -7,12 +7,16 @@ EXTRA_OECONF_PATHS = "--with-local-prefix=${STAGING_DIR_TARGET}${layout_prefix} --with-sysroot=${STAGING_DIR_TARGET} \ --with-build-sysroot=${STAGING_DIR_TARGET}" -do_compile_prepend () { +do_configure_prepend () { export CC="${BUILD_CC}" export AR_FOR_TARGET="${TARGET_SYS}-ar" + export AS_FOR_TARGET="${TARGET_SYS}-as" export RANLIB_FOR_TARGET="${TARGET_SYS}-ranlib" export LD_FOR_TARGET="${TARGET_SYS}-ld" export NM_FOR_TARGET="${TARGET_SYS}-nm" + export OBJDUMP_FOR_TARGET="${TARGET_SYS}-objdump" + export OBJCOPY_FOR_TARGET="${TARGET_SYS}-objcopy" + export STRIP_FOR_TARGET="${TARGET_SYS}-strip" export CC_FOR_TARGET="${CCACHE} ${TARGET_SYS}-gcc ${TARGET_CC_ARCH}" } -- cgit v1.2.3 From 2b1928ff76811b5f4e734ddbf21aacdfcd54e68c Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 11 Sep 2009 08:41:51 +0200 Subject: task-native-sdk: fix upgrade paths after task renaming --- recipes/tasks/task-sdk-native.bb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/recipes/tasks/task-sdk-native.bb b/recipes/tasks/task-sdk-native.bb index 387e7b56fe..35ddf788fd 100644 --- a/recipes/tasks/task-sdk-native.bb +++ b/recipes/tasks/task-sdk-native.bb @@ -7,8 +7,9 @@ RDEPENDS = "gcc-symlinks g++-symlinks cpp cpp-symlinks binutils-symlinks \ patch patchutils diffstat diffutils libstdc++-dev" RECOMMENDS = " g77-symlinks gfortran-symlinks " +RPROVIDES_${PN} = "task-native-sdk" -PR = "r6" +PR = "r7" ALLOW_EMPTY = "1" PACKAGES = "${PN}" -- cgit v1.2.3 From d13e15663fb6ccd34dd7214178e3d1caf645179f Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 11 Sep 2009 09:05:21 +0200 Subject: linux-omap: add 2.6.31 --- ...0001-OMAP3-Enable-DSS2-for-OMAP3EVM-board.patch | 42 ++++++++-------- .../dss2/0004-OMAP-Add-VRAM-manager.patch | 34 ++++--------- recipes/linux/linux-omap_2.6.31.bb | 58 ++++++++++++++++++++++ recipes/linux/linux-omap_git.bb | 6 +-- 4 files changed, 91 insertions(+), 49 deletions(-) create mode 100644 recipes/linux/linux-omap_2.6.31.bb diff --git a/recipes/linux/linux-omap-2.6.31/dss2/0001-OMAP3-Enable-DSS2-for-OMAP3EVM-board.patch b/recipes/linux/linux-omap-2.6.31/dss2/0001-OMAP3-Enable-DSS2-for-OMAP3EVM-board.patch index 9a4ea8b9ad..0167fe2a55 100644 --- a/recipes/linux/linux-omap-2.6.31/dss2/0001-OMAP3-Enable-DSS2-for-OMAP3EVM-board.patch +++ b/recipes/linux/linux-omap-2.6.31/dss2/0001-OMAP3-Enable-DSS2-for-OMAP3EVM-board.patch @@ -1,20 +1,17 @@ -From 798f9b1bc478c7ded724fc190c65e413c2401314 Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath -Date: Tue, 11 Aug 2009 15:52:04 +0530 -Subject: [PATCH 1/5] OMAP3: Enable DSS2 for OMAP3EVM board +Date: Thu, 10 Sep 2009 15:11:34 +0000 (+0530) +Subject: OMAP3: Enable DSS2 for OMAP3EVM board +X-Git-Url: http://arago-project.org/git/people/?p=vaibhav%2Fti-psp-omap-video.git;a=commitdiff_plain;h=1022536cf655419eac21299eac837f57f8f72eef + +OMAP3: Enable DSS2 for OMAP3EVM board Tested - - Validated all three outut interfaces (LCD, DVI and TV) + TODO: - - Support for Backlight control range (0 - 100) - Enable selection for both S-Video and Composite TV out - DVI color (VPLL2_DEV_GRP should be equal to 0x7) - -Signed-off-by: Vaibhav Hiremath --- - arch/arm/configs/omap3_evm_defconfig | 51 +++++++- - arch/arm/mach-omap2/board-omap3evm.c | 234 ++++++++++++++++++++++++++++++++-- - 2 files changed, 273 insertions(+), 12 deletions(-) diff --git a/arch/arm/configs/omap3_evm_defconfig b/arch/arm/configs/omap3_evm_defconfig index d5ff477..ba395a2 100644 @@ -79,7 +76,7 @@ index d5ff477..ba395a2 100644 # diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c -index c0cb29d..0bc26b3 100644 +index 35f6075..5bc4bfe 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c @@ -22,6 +22,7 @@ @@ -271,9 +268,9 @@ index c0cb29d..0bc26b3 100644 + }, +}; - static struct omap_uart_platform_data omap3_evm_uart_config __initdata = { - .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), -@@ -143,6 +313,14 @@ static int omap3evm_twl_gpio_setup(struct device *dev, + static struct twl4030_hsmmc_info mmc[] = { + { +@@ -139,6 +309,14 @@ static int omap3evm_twl_gpio_setup(struct device *dev, * the P2 connector; notably LEDA for the LCD backlight. */ @@ -288,7 +285,7 @@ index c0cb29d..0bc26b3 100644 /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; -@@ -194,6 +372,47 @@ static struct twl4030_madc_platform_data omap3evm_madc_data = { +@@ -190,6 +368,47 @@ static struct twl4030_madc_platform_data omap3evm_madc_data = { .irq_line = 1, }; @@ -336,7 +333,7 @@ index c0cb29d..0bc26b3 100644 static struct twl4030_platform_data omap3evm_twldata = { .irq_base = TWL4030_IRQ_BASE, .irq_end = TWL4030_IRQ_END, -@@ -203,6 +422,8 @@ static struct twl4030_platform_data omap3evm_twldata = { +@@ -199,6 +418,8 @@ static struct twl4030_platform_data omap3evm_twldata = { .madc = &omap3evm_madc_data, .usb = &omap3evm_usb_data, .gpio = &omap3evm_gpio_data, @@ -345,7 +342,7 @@ index c0cb29d..0bc26b3 100644 }; static struct i2c_board_info __initdata omap3evm_i2c_boardinfo[] = { -@@ -223,15 +444,6 @@ static int __init omap3_evm_i2c_init(void) +@@ -219,15 +440,6 @@ static int __init omap3_evm_i2c_init(void) return 0; } @@ -361,20 +358,24 @@ index c0cb29d..0bc26b3 100644 static void ads7846_dev_init(void) { if (gpio_request(OMAP3_EVM_TS_GPIO, "ADS7846 pendown") < 0) -@@ -287,11 +499,10 @@ static void __init omap3_evm_init_irq(void) - } +@@ -275,7 +487,6 @@ struct spi_board_info omap3evm_spi_board_info[] = { + }; static struct omap_board_config_kernel omap3_evm_config[] __initdata = { - { OMAP_TAG_LCD, &omap3_evm_lcd_config }, }; + static void __init omap3_evm_init_irq(void) +@@ -289,7 +500,7 @@ static void __init omap3_evm_init_irq(void) + } + static struct platform_device *omap3_evm_devices[] __initdata = { - &omap3_evm_lcd_device, + &omap3_evm_dss_device, &omap3evm_smc911x_device, }; -@@ -314,6 +525,7 @@ static void __init omap3_evm_init(void) +@@ -310,6 +521,7 @@ static void __init omap3_evm_init(void) usb_musb_init(); usb_ehci_init(EHCI_HCD_OMAP_MODE_PHY, true, true, 57, 61); ads7846_dev_init(); @@ -382,6 +383,3 @@ index c0cb29d..0bc26b3 100644 } static void __init omap3_evm_map_io(void) --- -1.6.2.4 - diff --git a/recipes/linux/linux-omap-2.6.31/dss2/0004-OMAP-Add-VRAM-manager.patch b/recipes/linux/linux-omap-2.6.31/dss2/0004-OMAP-Add-VRAM-manager.patch index 13fe0b0234..47eab0fa7d 100644 --- a/recipes/linux/linux-omap-2.6.31/dss2/0004-OMAP-Add-VRAM-manager.patch +++ b/recipes/linux/linux-omap-2.6.31/dss2/0004-OMAP-Add-VRAM-manager.patch @@ -1,7 +1,9 @@ -From cb8ce54283e64bd30636b7bcd2d7bb4e200825d2 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen -Date: Fri, 7 Aug 2009 12:01:55 +0300 -Subject: [PATCH 04/18] OMAP: Add VRAM manager +Date: Fri, 7 Aug 2009 09:01:55 +0000 (+0300) +Subject: OMAP: Add VRAM manager +X-Git-Url: http://arago-project.org/git/people/?p=vaibhav%2Fti-psp-omap-video.git;a=commitdiff_plain;h=9e5a02f69fe2261ac928aa956add6f1c9f48386d + +OMAP: Add VRAM manager Add a Video RAM manager for OMAP 2 and 3 platforms. VRAM manager is used to allocate large continuous blocks of SDRAM or SRAM. The features VRAM @@ -20,33 +22,20 @@ and boot parameter overrides kernel config and board file. Signed-off-by: Tomi Valkeinen --- - arch/arm/mach-omap2/io.c | 2 + - arch/arm/plat-omap/include/mach/vram.h | 63 +++ - arch/arm/plat-omap/sram.c | 8 + - drivers/video/Kconfig | 1 + - drivers/video/Makefile | 1 + - drivers/video/omap2/Kconfig | 2 + - drivers/video/omap2/Makefile | 1 + - drivers/video/omap2/vram.c | 655 ++++++++++++++++++++++++++++++++ - 8 files changed, 733 insertions(+), 0 deletions(-) - create mode 100644 arch/arm/plat-omap/include/mach/vram.h - create mode 100644 drivers/video/omap2/Kconfig - create mode 100644 drivers/video/omap2/Makefile - create mode 100644 drivers/video/omap2/vram.c diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c -index 49199a3..f837063 100644 +index 4a08ad3..e5dd736 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c -@@ -32,6 +32,7 @@ - #include +@@ -33,6 +33,7 @@ #include #include + #include +#include #ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdev is ready */ #include "clock.h" -@@ -240,6 +241,7 @@ void __init omap2_map_common_io(void) +@@ -246,6 +247,7 @@ void __init omap2_map_common_io(void) omap2_check_revision(); omap_sram_init(); omapfb_reserve_sdram(); @@ -124,7 +113,7 @@ index 0000000..fe72f81 + +#endif diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c -index 5eae787..c9b89cd 100644 +index 925f647..cda311b 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -28,6 +28,7 @@ @@ -849,6 +838,3 @@ index 0000000..634ce23 + omap_vram_sram_start = start; + omap_vram_sram_size = size; +} --- -1.6.2.4 - diff --git a/recipes/linux/linux-omap_2.6.31.bb b/recipes/linux/linux-omap_2.6.31.bb new file mode 100644 index 0000000000..cf7f69318f --- /dev/null +++ b/recipes/linux/linux-omap_2.6.31.bb @@ -0,0 +1,58 @@ +require linux.inc + +DESCRIPTION = "Linux kernel for OMAP processors" +KERNEL_IMAGETYPE = "uImage" + +COMPATIBLE_MACHINE = "omap5912osk|omap1710h3|omap2430sdp|omap2420h4|beagleboard|omap3evm|omap3-pandora|overo|omapzoom" + +DEFAULT_PREFERENCE = "-1" +DEFAULT_PREFERENCE_omapzoom2 = "1" + +SRCREV = "52a962f09ab2306a2ac6e22c2d3bac1a76ac" + +# The main PR is now using MACHINE_KERNEL_PR, for omap3 see conf/machine/include/omap3.inc +#PV = "2.6.30+2.6.31-rc8+gitr${SRCREV}" +PV = "2.6.31" + +SRC_URI = "git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git;protocol=git \ + file://defconfig" + +SRC_URI_append = " \ + file://ehci-phy-reset.patch;patch=1 \ + file://ehci.patch;patch=1 \ + file://0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch;patch=1 \ + file://cache/l1cache-shift.patch;patch=1 \ + file://cache/copy-page-tweak.patch;patch=1 \ + file://dss2/0001-OMAP2-Add-funcs-for-writing-SMS_ROT_-registers.patch;patch=1 \ + file://dss2/0002-OMAP-OMAPFB-split-omapfb.h.patch;patch=1 \ + file://dss2/0003-OMAP-OMAPFB-add-omapdss-device.patch;patch=1 \ + file://dss2/0004-OMAP-Add-VRAM-manager.patch;patch=1 \ + file://dss2/0005-OMAP-Add-support-for-VRFB-rotation-engine.patch;patch=1 \ + file://dss2/0006-OMAP-DSS2-Documentation-for-DSS2.patch;patch=1 \ + file://dss2/0007-OMAP-DSS2-Display-Subsystem-Driver-core.patch;patch=1 \ + file://dss2/0008-OMAP-DSS2-Add-more-core-files.patch;patch=1 \ + file://dss2/0009-OMAP-DSS2-DISPC.patch;patch=1 \ + file://dss2/0010-OMAP-DSS2-DPI-driver.patch;patch=1 \ + file://dss2/0011-OMAP-DSS2-Video-encoder-driver.patch;patch=1 \ + file://dss2/0012-OMAP-DSS2-RFBI-driver.patch;patch=1 \ + file://dss2/0013-OMAP-DSS2-SDI-driver.patch;patch=1 \ + file://dss2/0014-OMAP-DSS2-DSI-driver.patch;patch=1 \ + file://dss2/0015-OMAP-DSS2-omapfb-driver.patch;patch=1 \ + file://dss2/0016-OMAP-DSS2-Add-DPI-panel-drivers.patch;patch=1 \ + file://dss2/0017-OMAP-DSS2-Taal-DSI-command-mode-panel-driver.patch;patch=1 \ + file://dss2/0001-OMAP3-Enable-DSS2-for-OMAP3EVM-board.patch;patch=1 \ + file://dss2/0002-V4L2-Added-New-V4L2-CIDs-for-omap-devices-V4L2-IOCT.patch;patch=1 \ + file://dss2/0003-V4L2-Updated-v4l2_common-for-new-V4L2-CIDs.patch;patch=1 \ + file://dss2/0004-OMAP2-3-V4L2-Add-support-for-OMAP2-3-V4L2-driver-on.patch;patch=1 \ + file://expansion-boards/tincantools-zippy.patch;patch=1 \ + file://madc/madc-driver.patch;patch=1 \ + file://madc/madc.patch;patch=1 \ +" + +SRC_URI_append_beagleboard = " file://logo_linux_clut224.ppm \ +" + +S = "${WORKDIR}/git" + +module_autoload_ohci-hcd_omap5912osk = "ohci-hcd" + diff --git a/recipes/linux/linux-omap_git.bb b/recipes/linux/linux-omap_git.bb index f19840d4f4..65aa1187db 100644 --- a/recipes/linux/linux-omap_git.bb +++ b/recipes/linux/linux-omap_git.bb @@ -8,13 +8,13 @@ COMPATIBLE_MACHINE = "omap5912osk|omap1710h3|omap2430sdp|omap2420h4|beagleboard| DEFAULT_PREFERENCE = "-1" DEFAULT_PREFERENCE_omapzoom2 = "1" -SRCREV = "3777b1e9ffb6e0901be93cbe201ae8e96003179b" +SRCREV = "52a962f09ab2306a2ac6e22c2d3bac1a76ac" FILESPATHPKG_prepend = "linux-omap-2.6.31:" # The main PR is now using MACHINE_KERNEL_PR, for omap3 see conf/machine/include/omap3.inc -PV = "2.6.30+2.6.31-rc8+gitr${SRCREV}" -PR = "r0" +#PV = "2.6.30+2.6.31-rc8+gitr${SRCREV}" +PV = "2.6.31" SRC_URI = "git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git;protocol=git \ file://defconfig" -- cgit v1.2.3 From d0585b86dd918ba67546ce93cbefca846c7f3715 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Mon, 7 Sep 2009 17:36:14 +0200 Subject: omap3517-evm: add machine file --- conf/machine/omap3517-evm.conf | 49 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 conf/machine/omap3517-evm.conf diff --git a/conf/machine/omap3517-evm.conf b/conf/machine/omap3517-evm.conf new file mode 100644 index 0000000000..5552681d12 --- /dev/null +++ b/conf/machine/omap3517-evm.conf @@ -0,0 +1,49 @@ +#@TYPE: Machine +#@NAME: omap3 EVM +#@DESCRIPTION: Machine configuration for the TI omap3517 EVM +TARGET_ARCH = "arm" + +PREFERRED_PROVIDER_virtual/xserver = "xserver-xorg" +XSERVER = "xserver-xorg \ + xf86-input-evdev \ + xf86-input-mouse \ + xf86-input-tslib \ + xf86-video-omapfb \ + xf86-input-keyboard" + +GUI_MACHINE_CLASS = "smallscreen" + +require conf/machine/include/omap3.inc + +# Ship all kernel modules +MACHINE_EXTRA_RRECOMMENDS = " omap3-sgx-modules kernel-modules" + +IMAGE_FSTYPES ?= "jffs2 tar.bz2" +EXTRA_IMAGECMD_jffs2 = "-lnp " + +SERIAL_CONSOLE = "115200 ttyS0" + +PREFERRED_PROVIDER_virtual/kernel = "linux-omap-psp" + +UBOOT_ARCH = "arm" +UBOOT_MACHINE = "omap3_evm_config" + +MACHINE_FEATURES = "kernel26 apm usbgadget usbhost vfat ext2 screen touchscreen ethernet" + +# NOTE: there are NAND and OneNAND versions of this board... + +# do ubiattach /dev/ubi_ctrl -m 4 +# From dmesg: +# UBI: smallest flash I/O unit: 2048 +# UBI: logical eraseblock size: 129024 bytes +# from ubiattach stdout: +# UBI device number 0, total 1996 LEBs +MKUBIFS_ARGS = "-m 2048 -e 129024 -c 1996" + +# do ubiattach /dev/ubi_ctrl -m 4 +# from dmesg: +# UBI: smallest flash I/O unit: 2048 +# UBI: physical eraseblock size: 131072 bytes (128 KiB) +# UBI: sub-page size: 512 +UBINIZE_ARGS = "-m 2048 -p 128KiB -s 512" + -- cgit v1.2.3 From 4c014833555dcd14ccdd9fd3f0f864fb4b62631e Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Mon, 7 Sep 2009 17:36:29 +0200 Subject: linux-omap-psp 2.6.29: add shiva support --- .../linux-omap-psp-2.6.29/omap3517-evm/defconfig | 1493 ++++++++++++++++++++ .../linux/linux-omap-psp-2.6.29/shiva-bits.diff | 11 + recipes/linux/linux-omap-psp_2.6.29.bb | 11 +- 3 files changed, 1512 insertions(+), 3 deletions(-) create mode 100644 recipes/linux/linux-omap-psp-2.6.29/omap3517-evm/defconfig create mode 100644 recipes/linux/linux-omap-psp-2.6.29/shiva-bits.diff diff --git a/recipes/linux/linux-omap-psp-2.6.29/omap3517-evm/defconfig b/recipes/linux/linux-omap-psp-2.6.29/omap3517-evm/defconfig new file mode 100644 index 0000000000..3092f7b098 --- /dev/null +++ b/recipes/linux/linux-omap-psp-2.6.29/omap3517-evm/defconfig @@ -0,0 +1,1493 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.29-omap1 +# Mon Sep 7 19:18:57 2009 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +# CONFIG_FREEZER is not set + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +CONFIG_ARCH_OMAP=y +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_W90X900 is not set + +# +# TI OMAP Implementations +# +CONFIG_ARCH_OMAP_OTG=y +# CONFIG_ARCH_OMAP1 is not set +# CONFIG_ARCH_OMAP2 is not set +CONFIG_ARCH_OMAP3=y + +# +# OMAP Feature Selections +# +# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set +# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set +# CONFIG_OMAP_RESET_CLOCKS is not set +CONFIG_OMAP_BOOT_TAG=y +CONFIG_OMAP_BOOT_REASON=y +# CONFIG_OMAP_COMPONENT_VERSION is not set +# CONFIG_OMAP_GPIO_SWITCH is not set +CONFIG_OMAP_MUX=y +# CONFIG_OMAP_MUX_DEBUG is not set +CONFIG_OMAP_MUX_WARNINGS=y +# CONFIG_OMAP_MCBSP is not set +# CONFIG_OMAP_MBOX_FWK is not set +# CONFIG_OMAP_MPU_TIMER is not set +CONFIG_OMAP_32K_TIMER=y +CONFIG_OMAP_32K_TIMER_HZ=128 +CONFIG_OMAP_TICK_GPTIMER=1 +CONFIG_OMAP_DM_TIMER=y +# CONFIG_OMAP_LL_DEBUG_UART1 is not set +# CONFIG_OMAP_LL_DEBUG_UART2 is not set +CONFIG_OMAP_LL_DEBUG_UART3=y +CONFIG_OMAP_SERIAL_WAKE=y +CONFIG_ARCH_OMAP34XX=y +CONFIG_ARCH_OMAP3430=y +CONFIG_ARCH_OMAP35XX=y + +# +# OMAP Board Type +# +# CONFIG_MACH_NOKIA_RX51 is not set +# CONFIG_MACH_OMAP_LDP is not set +# CONFIG_MACH_OMAP_3430SDP is not set +# CONFIG_MACH_OMAP3EVM is not set +CONFIG_MACH_OMAP3517EVM=y + +# +# OMAP3 EVM Power Modules +# +# CONFIG_OMAP3EVM_TWL4030 is not set +# CONFIG_OMAP3EVM_TPS65023 is not set +# CONFIG_OMAP3EVM_TPS65073 is not set +# CONFIG_MACH_OMAP3_BEAGLE is not set +# CONFIG_MACH_OVERO is not set +# CONFIG_MACH_OMAP3_PANDORA is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_V7=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_IFAR=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_ARM_THUMBEE is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_HAS_TLS_REG=y +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PREEMPT is not set +CONFIG_HZ=128 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +CONFIG_ARCH_FLATMEM_HAS_HOLES=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_UNEVICTABLE_LRU=y +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE=" debug " +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +# CONFIG_CPU_FREQ is not set +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_COMPAT_NET_DEV_OPS=y +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_PHONET is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_OMAP_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_OMAP2=y +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=32768 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_LIBFC is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +CONFIG_SMSC_PHY=y +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +CONFIG_TI_DAVINCI_EMAC=y +# CONFIG_DM9000 is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=32 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_OMAP_WATCHDOG=y + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +# CONFIG_MEDIA_ATTACH is not set +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEOBUF_GEN=y +CONFIG_VIDEOBUF_DMA_SG=y +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +CONFIG_VIDEO_OMAP3=y +CONFIG_VIDEO_OMAP_VIDEOOUT=y +CONFIG_NTSC_M=y +# CONFIG_PAL_BDGHI is not set +# CONFIG_SOC_CAMERA is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_USB_VICAM=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_ET61X251=m +CONFIG_USB_OV511=m +CONFIG_USB_SE401=m +CONFIG_USB_SN9C102=m +# CONFIG_USB_STV680 is not set +CONFIG_USB_ZC0301=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_ZR364XX=m +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_S2255=m +CONFIG_RADIO_ADAPTERS=y +# CONFIG_USB_DSBR is not set +# CONFIG_USB_SI470X is not set +# CONFIG_USB_MR800 is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set +CONFIG_OMAP2_DSS=y +CONFIG_OMAP2_DSS_VRAM_SIZE=14 +CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y +# CONFIG_OMAP2_DSS_RFBI is not set +CONFIG_OMAP2_DSS_VENC=y +# CONFIG_OMAP2_DSS_SDI is not set +CONFIG_OMAP2_DSS_DSI=y +CONFIG_OMAP2_DSS_USE_DSI_PLL=y +# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set +CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0 + +# +# OMAP2/3 Display Device Drivers +# +CONFIG_PANEL_GENERIC=y +# CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C is not set +# CONFIG_PANEL_SHARP_LS037V7DW01 is not set +CONFIG_PANEL_SHARP_LQ043T1DG01=y +# CONFIG_PANEL_N800 is not set +# CONFIG_CTRL_BLIZZARD is not set +CONFIG_FB_OMAP2=y +CONFIG_FB_OMAP2_DEBUG_SUPPORT=y +# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set +CONFIG_FB_OMAP2_NUM_FBS=3 +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=y + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set +# CONFIG_LOGO is not set +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# Special HID drivers +# +CONFIG_HID_COMPAT=y +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_GREENASIA_FF is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_THRUSTMASTER_FF is not set +# CONFIG_ZEROPLUS_FF is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_SOC=y + +# +# OMAP 343x high speed USB support +# +CONFIG_USB_MUSB_HOST=y +# CONFIG_USB_MUSB_PERIPHERAL is not set +# CONFIG_USB_MUSB_OTG is not set +CONFIG_USB_MUSB_HDRC_HCD=y +# CONFIG_MUSB_PIO_ONLY is not set +# CONFIG_USB_TI_CPPI_DMA is not set +CONFIG_USB_TI_CPPI41_DMA=y +CONFIG_USB_MUSB_DEBUG=y + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; +# + +# +# see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +# CONFIG_USB_GPIO_VBUS is not set +CONFIG_NOP_USB_XCEIV=y +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +CONFIG_MMC_OMAP_HS=y +# CONFIG_MEMSTICK is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_REGULATOR is not set +# CONFIG_UIO is not set +# CONFIG_STAGING is not set + +# +# CBUS support +# +# CONFIG_CBUS is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +CONFIG_FILE_LOCKING=y +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_QUOTA_TREE=y +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=y +CONFIG_QUOTACTL=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +# CONFIG_JFFS2_CMODE_FAVOURLZO is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_REGISTER_V4 is not set +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +CONFIG_HAVE_FUNCTION_TRACER=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_HW is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/recipes/linux/linux-omap-psp-2.6.29/shiva-bits.diff b/recipes/linux/linux-omap-psp-2.6.29/shiva-bits.diff new file mode 100644 index 0000000000..45d817a146 --- /dev/null +++ b/recipes/linux/linux-omap-psp-2.6.29/shiva-bits.diff @@ -0,0 +1,11 @@ +--- /tmp/board-omap3517evm.c 2009-09-07 17:34:48.000000000 +0200 ++++ git/arch/arm/mach-omap2/board-omap3517evm.c 2009-09-07 17:35:00.000000000 +0200 +@@ -297,7 +297,7 @@ + .type = OMAP_DISPLAY_TYPE_DPI, + .name = "dvi", + .panel_name = "panel-generic", +- .u.dpi.data_lines = 24, ++ .u.dpi.data_lines = 16, + .panel_enable = omap3517_evm_panel_enable_dvi, + .panel_disable = omap3517_evm_panel_disable_dvi, + }; diff --git a/recipes/linux/linux-omap-psp_2.6.29.bb b/recipes/linux/linux-omap-psp_2.6.29.bb index d64786c18c..a336622583 100644 --- a/recipes/linux/linux-omap-psp_2.6.29.bb +++ b/recipes/linux/linux-omap-psp_2.6.29.bb @@ -3,7 +3,7 @@ require linux.inc DESCRIPTION = "Linux kernel for OMAP processors" KERNEL_IMAGETYPE = "uImage" -COMPATIBLE_MACHINE = "omap3evm" +COMPATIBLE_MACHINE = "omap3evm|omap3517-evm" SRCREV = "9abb6eb717acbca192ab251a056e3a66b2b47884" @@ -11,11 +11,16 @@ SRCREV = "9abb6eb717acbca192ab251a056e3a66b2b47884" PR_append = "+gitr${SRCREV}" SRC_URI = "git://arago-project.org/git/people/sriram/ti-psp-omap.git;protocol=git;branch=int_030000_build3 \ - file://defconfig" + file://0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch;patch=1 \ + file://defconfig" S = "${WORKDIR}/git" -SRC_URI_append = " \ +SRC_URI_append_omap3517-evm = " \ + file://shiva-bits.diff;patch=1 \ +" + +SRC_URI_append_omap3evm = " \ file://fix-twl-merge-damage.diff;patch=1 \ file://fix-section-mismatch.diff;patch=1 \ file://no-3517-hack.diff;patch=1 \ -- cgit v1.2.3 From 7286737587f0097d033db3d91ba0e4570ea17b0b Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 8 Sep 2009 12:10:01 +0200 Subject: u-boot git: add support for omap3517-evm --- conf/machine/omap3517-evm.conf | 2 +- .../0001-Changes-for-making-a-NAND-build.patch | 50 + .../0002-Fix-for-NFS-boot-for-OMAP3-EVM.patch | 55 + ...-handling-to-1ms-tick-and-CONFIG_SYS_HZ-t.patch | 277 +++ ...tch-for-NFS-boot-to-fix-comments-provided.patch | 53 + .../0005-SMC911x-driver-fixed-for-NFS-boot.patch | 61 + .../0006-Added-OMAP3517-3505-support.patch | 2501 ++++++++++++++++++++ ...MAP3517TEB-validated-on-OMAP3517TEB-board.patch | 403 ++++ ...E-ALPHA-validated-on-OMAP3517PRE_ALPHA-bo.patch | 126 + ...09-OMAP3517PRE-ALPHA-DDR-size-issue-fixed.patch | 125 + ...RE-ALPHA-Mux-configuration-for-MMC-CD-and.patch | 34 + ...-driver-functional-no-need-for-time-delay.patch | 488 ++++ ...AC-driver-Implement-GPIO-driven-PHY-reset.patch | 319 +++ .../0013-Cleaned-up-during-EVM-hang-issue.patch | 45 + ...-EMAC-driver-cleanup-removed-debug-prints.patch | 419 ++++ ...r-Check-for-link-status-in-packet-send-lo.patch | 42 + ...g-option-and-name-changed-to-omap3517_evm.patch | 750 ++++++ recipes/u-boot/u-boot_git.bb | 22 + 18 files changed, 5771 insertions(+), 1 deletion(-) create mode 100644 recipes/u-boot/u-boot-git/omap3evm/0001-Changes-for-making-a-NAND-build.patch create mode 100644 recipes/u-boot/u-boot-git/omap3evm/0002-Fix-for-NFS-boot-for-OMAP3-EVM.patch create mode 100644 recipes/u-boot/u-boot-git/omap3evm/0003-OMAP3-timer-handling-to-1ms-tick-and-CONFIG_SYS_HZ-t.patch create mode 100644 recipes/u-boot/u-boot-git/omap3evm/0004-Reverse-patch-for-NFS-boot-to-fix-comments-provided.patch create mode 100644 recipes/u-boot/u-boot-git/omap3evm/0005-SMC911x-driver-fixed-for-NFS-boot.patch create mode 100644 recipes/u-boot/u-boot-git/omap3evm/0006-Added-OMAP3517-3505-support.patch create mode 100644 recipes/u-boot/u-boot-git/omap3evm/0007-OMAP3517TEB-validated-on-OMAP3517TEB-board.patch create mode 100644 recipes/u-boot/u-boot-git/omap3evm/0008-OMAP3517PRE-ALPHA-validated-on-OMAP3517PRE_ALPHA-bo.patch create mode 100644 recipes/u-boot/u-boot-git/omap3evm/0009-OMAP3517PRE-ALPHA-DDR-size-issue-fixed.patch create mode 100644 recipes/u-boot/u-boot-git/omap3evm/0010-OMAP3517PRE-ALPHA-Mux-configuration-for-MMC-CD-and.patch create mode 100644 recipes/u-boot/u-boot-git/omap3evm/0011-Ethernet-driver-functional-no-need-for-time-delay.patch create mode 100644 recipes/u-boot/u-boot-git/omap3evm/0012-EMAC-driver-Implement-GPIO-driven-PHY-reset.patch create mode 100644 recipes/u-boot/u-boot-git/omap3evm/0013-Cleaned-up-during-EVM-hang-issue.patch create mode 100644 recipes/u-boot/u-boot-git/omap3evm/0014-EMAC-driver-cleanup-removed-debug-prints.patch create mode 100644 recipes/u-boot/u-boot-git/omap3evm/0015-EMAC-driver-Check-for-link-status-in-packet-send-lo.patch create mode 100644 recipes/u-boot/u-boot-git/omap3evm/0016-Config-option-and-name-changed-to-omap3517_evm.patch diff --git a/conf/machine/omap3517-evm.conf b/conf/machine/omap3517-evm.conf index 5552681d12..a7ef4be0fd 100644 --- a/conf/machine/omap3517-evm.conf +++ b/conf/machine/omap3517-evm.conf @@ -26,7 +26,7 @@ SERIAL_CONSOLE = "115200 ttyS0" PREFERRED_PROVIDER_virtual/kernel = "linux-omap-psp" UBOOT_ARCH = "arm" -UBOOT_MACHINE = "omap3_evm_config" +UBOOT_MACHINE = "omap3517_evm_config" MACHINE_FEATURES = "kernel26 apm usbgadget usbhost vfat ext2 screen touchscreen ethernet" diff --git a/recipes/u-boot/u-boot-git/omap3evm/0001-Changes-for-making-a-NAND-build.patch b/recipes/u-boot/u-boot-git/omap3evm/0001-Changes-for-making-a-NAND-build.patch new file mode 100644 index 0000000000..b762ac0f1e --- /dev/null +++ b/recipes/u-boot/u-boot-git/omap3evm/0001-Changes-for-making-a-NAND-build.patch @@ -0,0 +1,50 @@ +From d58014b0e26652eac04f9799e14640854f7885a8 Mon Sep 17 00:00:00 2001 +From: Manikandan Pillai +Date: Tue, 7 Apr 2009 14:26:41 +0530 +Subject: [PATCH 01/16] Changes for making a NAND build. + +--- + include/configs/omap3_evm.h | 7 +++++-- + 1 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/include/configs/omap3_evm.h b/include/configs/omap3_evm.h +index f4498a9..6283d59 100644 +--- a/include/configs/omap3_evm.h ++++ b/include/configs/omap3_evm.h +@@ -106,7 +106,7 @@ + + #define CONFIG_CMD_I2C /* I2C serial bus support */ + #define CONFIG_CMD_MMC /* MMC support */ +-#define CONFIG_CMD_ONENAND /* ONENAND support */ ++#define CONFIG_CMD_NAND /* NAND support */ + #define CONFIG_CMD_DHCP + #define CONFIG_CMD_PING + +@@ -125,12 +125,15 @@ + /* + * Board NAND Info. + */ ++#define CONFIG_NAND_OMAP_GPMC + #define CONFIG_SYS_NAND_ADDR NAND_BASE /* physical address */ + /* to access nand */ + #define CONFIG_SYS_NAND_BASE NAND_BASE /* physical address */ + /* to access */ + /* nand at CS0 */ + ++#define GPMC_NAND_ECC_LP_x16_LAYOUT 1 ++ + #define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of */ + /* NAND devices */ + #define SECTORSIZE 512 +@@ -271,7 +274,7 @@ + #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE + #define CONFIG_SYS_ONENAND_BASE ONENAND_MAP + +-#define CONFIG_ENV_IS_IN_ONENAND 1 ++#define CONFIG_ENV_IS_IN_NAND 1 + #define ONENAND_ENV_OFFSET 0x260000 /* environment starts here */ + #define SMNAND_ENV_OFFSET 0x260000 /* environment starts here */ + +-- +1.6.2.4 + diff --git a/recipes/u-boot/u-boot-git/omap3evm/0002-Fix-for-NFS-boot-for-OMAP3-EVM.patch b/recipes/u-boot/u-boot-git/omap3evm/0002-Fix-for-NFS-boot-for-OMAP3-EVM.patch new file mode 100644 index 0000000000..243f175728 --- /dev/null +++ b/recipes/u-boot/u-boot-git/omap3evm/0002-Fix-for-NFS-boot-for-OMAP3-EVM.patch @@ -0,0 +1,55 @@ +From 57a0438b9f70bb3e98a20773134b17ef33e266b9 Mon Sep 17 00:00:00 2001 +From: Manikandan Pillai +Date: Tue, 7 Apr 2009 14:27:31 +0530 +Subject: [PATCH 02/16] Fix for NFS boot for OMAP3 EVM + +The eth_halt() function has been modified to remove the +chip reset and instead stop the transmit/receive from the device. +--- + drivers/net/smc911x.c | 23 ++++++++++++++++++++++- + 1 files changed, 22 insertions(+), 1 deletions(-) + +diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c +index 1ded8f0..2f0852e 100644 +--- a/drivers/net/smc911x.c ++++ b/drivers/net/smc911x.c +@@ -116,6 +116,27 @@ static int smc911x_phy_reset(void) + return 0; + } + ++static void smc911x_shutdown(void) ++{ ++ unsigned cr; ++ ++ /* Turn of Rx and TX */ ++ cr = smc911x_get_mac_csr(MAC_CR); ++ cr &= ~(MAC_CR_TXEN | MAC_CR_RXEN | MAC_CR_HBDIS); ++ smc911x_set_mac_csr(MAC_CR, cr); ++ ++ /* Stop Transmission */ ++ cr = smc911x_get_mac_csr(TX_CFG); ++ cr &= ~(TX_CFG_STOP_TX); ++ smc911x_set_mac_csr(TX_CFG, cr); ++ /* Stop receiving packets */ ++ cr = smc911x_get_mac_csr(RX_CFG); ++ cr &= ~(RX_CFG_RXDOFF); ++ smc911x_set_mac_csr(RX_CFG, cr); ++ ++} ++ ++ + static void smc911x_phy_configure(void) + { + int timeout; +@@ -224,7 +245,7 @@ int eth_send(volatile void *packet, int length) + + void eth_halt(void) + { +- smc911x_reset(); ++ smc911x_shutdown(); + } + + int eth_rx(void) +-- +1.6.2.4 + diff --git a/recipes/u-boot/u-boot-git/omap3evm/0003-OMAP3-timer-handling-to-1ms-tick-and-CONFIG_SYS_HZ-t.patch b/recipes/u-boot/u-boot-git/omap3evm/0003-OMAP3-timer-handling-to-1ms-tick-and-CONFIG_SYS_HZ-t.patch new file mode 100644 index 0000000000..75f7ef230a --- /dev/null +++ b/recipes/u-boot/u-boot-git/omap3evm/0003-OMAP3-timer-handling-to-1ms-tick-and-CONFIG_SYS_HZ-t.patch @@ -0,0 +1,277 @@ +From 13fc02c66aa4cc1c5653a4987fdddce63810a7e9 Mon Sep 17 00:00:00 2001 +From: Manikandan Pillai +Date: Tue, 7 Apr 2009 14:28:05 +0530 +Subject: [PATCH 03/16] OMAP3 timer handling to 1ms tick and CONFIG_SYS_HZ to 1000. + +Clean up macros and comments. +--- + cpu/arm_cortexa8/omap3/interrupts.c | 81 ++++++++++------------------------ + examples/Makefile | 2 +- + include/configs/omap3_beagle.h | 11 +++-- + include/configs/omap3_evm.h | 13 +++--- + include/configs/omap3_overo.h | 10 ++-- + include/configs/omap3_pandora.h | 11 ++--- + include/configs/omap3_zoom1.h | 11 ++--- + 7 files changed, 52 insertions(+), 87 deletions(-) + +diff --git a/cpu/arm_cortexa8/omap3/interrupts.c b/cpu/arm_cortexa8/omap3/interrupts.c +index 9e9817d..b99e284 100644 +--- a/cpu/arm_cortexa8/omap3/interrupts.c ++++ b/cpu/arm_cortexa8/omap3/interrupts.c +@@ -169,7 +169,16 @@ static ulong timestamp; + static ulong lastinc; + static gptimer_t *timer_base = (gptimer_t *)CONFIG_SYS_TIMERBASE; + +-/* nothing really to do with interrupts, just starts up a counter. */ ++/* ++ * Nothing really to do with interrupts, just starts up a counter. ++ * We run the counter with 13MHz, divided by 8, resulting in timer ++ * frequency of 1.625MHz. With 32bit counter register, counter ++ * overflows in ~44min ++ */ ++ ++/* 13MHz / 8 = 1.625MHz */ ++#define TIMER_CLOCK (V_SCLK / (2 << CONFIG_SYS_PVT)) ++ + int interrupt_init(void) + { + /* start the counter ticking up, reload value on overflow */ +@@ -204,78 +213,38 @@ void set_timer(ulong t) + /* delay x useconds AND perserve advance timstamp value */ + void udelay(unsigned long usec) + { +- ulong tmo, tmp; +- +- /* if "big" number, spread normalization to seconds */ +- if (usec >= 1000) { +- /* if "big" number, spread normalization to seconds */ +- tmo = usec / 1000; +- /* find number of "ticks" to wait to achieve target */ +- tmo *= CONFIG_SYS_HZ; +- tmo /= 1000; /* finish normalize. */ +- } else {/* else small number, don't kill it prior to HZ multiply */ +- tmo = usec * CONFIG_SYS_HZ; +- tmo /= (1000 * 1000); +- } +- +- tmp = get_timer(0); /* get current timestamp */ +- /* if setting this forward will roll time stamp */ +- if ((tmo + tmp + 1) < tmp) +- /* reset "advancing" timestamp to 0, set lastinc value */ +- reset_timer_masked(); +- else +- tmo += tmp; /* else, set advancing stamp wake up time */ +- while (get_timer_masked() < tmo) /* loop till event */ +- /*NOP*/; ++ ulong tmo, endtime; ++ ++ tmo = usec * (TIMER_CLOCK / CONFIG_SYS_HZ); ++ tmo /= 1000; ++ ++ endtime = readl(&timer_base->tcrr) + tmo; ++ ++ while (readl(&timer_base->tcrr) < endtime); + } + + void reset_timer_masked(void) + { + /* reset time, capture current incrementer value time */ +- lastinc = readl(&timer_base->tcrr); ++ lastinc = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ); + timestamp = 0; /* start "advancing" time stamp from 0 */ + } + + ulong get_timer_masked(void) + { +- ulong now = readl(&timer_base->tcrr); /* current tick value */ ++ /* current tick value */ ++ ulong now = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ); + + if (now >= lastinc) /* normal mode (non roll) */ + /* move stamp fordward with absoulte diff ticks */ + timestamp += (now - lastinc); + else /* we have rollover of incrementer */ +- timestamp += (0xFFFFFFFF - lastinc) + now; ++ timestamp += ((0xFFFFFFFF / (TIMER_CLOCK / CONFIG_SYS_HZ)) ++ - lastinc) + now; + lastinc = now; + return timestamp; + } + +-/* waits specified delay value and resets timestamp */ +-void udelay_masked(unsigned long usec) +-{ +- ulong tmo; +- ulong endtime; +- signed long diff; +- +- /* if "big" number, spread normalization to seconds */ +- if (usec >= 1000) { +- /* start to normalize for usec to ticks per sec */ +- tmo = usec / 1000; +- /* find number of "ticks" to wait to achieve target */ +- tmo *= CONFIG_SYS_HZ; +- tmo /= 1000; /* finish normalize. */ +- } else { /* else small number, */ +- /* don't kill it prior to HZ multiply */ +- tmo = usec * CONFIG_SYS_HZ; +- tmo /= (1000 * 1000); +- } +- endtime = get_timer_masked() + tmo; +- +- do { +- ulong now = get_timer_masked(); +- diff = endtime - now; +- } while (diff >= 0); +-} +- + /* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. +@@ -291,7 +260,5 @@ unsigned long long get_ticks(void) + */ + ulong get_tbclk(void) + { +- ulong tbclk; +- tbclk = CONFIG_SYS_HZ; +- return tbclk; ++ return CONFIG_SYS_HZ; + } +diff --git a/examples/Makefile b/examples/Makefile +index dbcfa92..d2e811a 100644 +--- a/examples/Makefile ++++ b/examples/Makefile +@@ -33,7 +33,7 @@ ifeq ($(ARCH),arm) + ifeq ($(BOARD),omap2420h4) + LOAD_ADDR = 0x80300000 + else +-ifeq ($(CPU),omap3) ++ifeq ($(SOC),omap3) + LOAD_ADDR = 0x80300000 + else + LOAD_ADDR = 0xc100000 +diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h +index 9057606..2f30783 100644 +--- a/include/configs/omap3_beagle.h ++++ b/include/configs/omap3_beagle.h +@@ -220,14 +220,15 @@ + /* load address */ + + /* +- * 2430 has 12 GP timers, they can be driven by the SysClk (12/13/19.2) or by +- * 32KHz clk, or from external sig. This rate is divided by a local divisor. ++ * OMAP3 has 12 GP timers, they can be driven by the system clock ++ * (12/13/16.8/19.2/38.4MHz) or by 32KHz clock. We use 13MHz (V_SCLK). ++ * This rate is divided by a local divisor. + */ +-#define V_PVT 7 + + #define CONFIG_SYS_TIMERBASE (OMAP34XX_GPT2) +-#define CONFIG_SYS_PVT V_PVT /* 2^(pvt+1) */ +-#define CONFIG_SYS_HZ ((V_SCLK) / (2 << CONFIG_SYS_PVT)) ++#define CONFIG_SYS_PVT 2 /* Divisor: 2^(PVT+1) => 8 */ ++#define CONFIG_SYS_HZ 1000 ++ + + /*----------------------------------------------------------------------- + * Stack sizes +diff --git a/include/configs/omap3_evm.h b/include/configs/omap3_evm.h +index 6283d59..fb8a424 100644 +--- a/include/configs/omap3_evm.h ++++ b/include/configs/omap3_evm.h +@@ -222,14 +222,13 @@ + /* address */ + + /* +- * 2430 has 12 GP timers, they can be driven by the SysClk (12/13/19.2) or by +- * 32KHz clk, or from external sig. This rate is divided by a local divisor. ++ * OMAP3 has 12 GP timers, they can be driven by the system clock ++ * (12/13/16.8/19.2/38.4MHz) or by 32KHz clock. We use 13MHz (V_SCLK). ++ * This rate is divided by a local divisor. + */ +-#define V_PVT 7 +- +-#define CONFIG_SYS_TIMERBASE OMAP34XX_GPT2 +-#define CONFIG_SYS_PVT V_PVT /* 2^(pvt+1) */ +-#define CONFIG_SYS_HZ ((V_SCLK) / (2 << CONFIG_SYS_PVT)) ++#define CONFIG_SYS_TIMERBASE (OMAP34XX_GPT2) ++#define CONFIG_SYS_PVT 2 /* Divisor: 2^(PVT+1) => 8 */ ++#define CONFIG_SYS_HZ 1000 + + /*----------------------------------------------------------------------- + * Stack sizes +diff --git a/include/configs/omap3_overo.h b/include/configs/omap3_overo.h +index dee0417..45e5478 100644 +--- a/include/configs/omap3_overo.h ++++ b/include/configs/omap3_overo.h +@@ -213,14 +213,14 @@ + /* address */ + + /* +- * 2430 has 12 GP timers, they can be driven by the SysClk (12/13/19.2) or by +- * 32KHz clk, or from external sig. This rate is divided by a local divisor. ++ * OMAP3 has 12 GP timers, they can be driven by the system clock ++ * (12/13/16.8/19.2/38.4MHz) or by 32KHz clock. We use 13MHz (V_SCLK). ++ * This rate is divided by a local divisor. + */ +-#define V_PVT 7 + + #define CONFIG_SYS_TIMERBASE (OMAP34XX_GPT2) +-#define CONFIG_SYS_PVT V_PVT /* 2^(pvt+1) */ +-#define CONFIG_SYS_HZ ((V_SCLK) / (2 << CONFIG_SYS_PVT)) ++#define CONFIG_SYS_PVT 2 /* Divisor: 2^(PVT+1) => 8 */ ++#define CONFIG_SYS_HZ 1000 + + /*----------------------------------------------------------------------- + * Stack sizes +diff --git a/include/configs/omap3_pandora.h b/include/configs/omap3_pandora.h +index 00c0374..4ed8373 100644 +--- a/include/configs/omap3_pandora.h ++++ b/include/configs/omap3_pandora.h +@@ -215,14 +215,13 @@ + /* address */ + + /* +- * 2430 has 12 GP timers, they can be driven by the SysClk (12/13/19.2) or by +- * 32KHz clk, or from external sig. This rate is divided by a local divisor. ++ * OMAP3 has 12 GP timers, they can be driven by the system clock ++ * (12/13/16.8/19.2/38.4MHz) or by 32KHz clock. We use 13MHz (V_SCLK). ++ * This rate is divided by a local divisor. + */ +-#define V_PVT 7 +- + #define CONFIG_SYS_TIMERBASE (OMAP34XX_GPT2) +-#define CONFIG_SYS_PVT V_PVT /* 2^(pvt+1) */ +-#define CONFIG_SYS_HZ ((V_SCLK) / (2 << CONFIG_SYS_PVT)) ++#define CONFIG_SYS_PVT 2 /* Divisor: 2^(PVT+1) => 8 */ ++#define CONFIG_SYS_HZ 1000 + + /*----------------------------------------------------------------------- + * Stack sizes +diff --git a/include/configs/omap3_zoom1.h b/include/configs/omap3_zoom1.h +index f8ae163..0185fa6 100644 +--- a/include/configs/omap3_zoom1.h ++++ b/include/configs/omap3_zoom1.h +@@ -222,14 +222,13 @@ + /* load address */ + + /* +- * 2430 has 12 GP timers, they can be driven by the SysClk (12/13/19.2) or by +- * 32KHz clk, or from external sig. This rate is divided by a local divisor. ++ * OMAP3 has 12 GP timers, they can be driven by the system clock ++ * (12/13/16.8/19.2/38.4MHz) or by 32KHz clock. We use 13MHz (V_SCLK). ++ * This rate is divided by a local divisor. + */ +-#define V_PVT 7 +- + #define CONFIG_SYS_TIMERBASE (OMAP34XX_GPT2) +-#define CONFIG_SYS_PVT V_PVT /* 2^(pvt+1) */ +-#define CONFIG_SYS_HZ ((V_SCLK) / (2 << CONFIG_SYS_PVT)) ++#define CONFIG_SYS_PVT 2 /* Divisor: 2^(PVT+1) => 8 */ ++#define CONFIG_SYS_HZ 1000 + + /*----------------------------------------------------------------------- + * Stack sizes +-- +1.6.2.4 + diff --git a/recipes/u-boot/u-boot-git/omap3evm/0004-Reverse-patch-for-NFS-boot-to-fix-comments-provided.patch b/recipes/u-boot/u-boot-git/omap3evm/0004-Reverse-patch-for-NFS-boot-to-fix-comments-provided.patch new file mode 100644 index 0000000000..8ce6ac9602 --- /dev/null +++ b/recipes/u-boot/u-boot-git/omap3evm/0004-Reverse-patch-for-NFS-boot-to-fix-comments-provided.patch @@ -0,0 +1,53 @@ +From 515c1e71f21e6666d8f8da7a539d6edd122a0fc3 Mon Sep 17 00:00:00 2001 +From: Manikandan Pillai +Date: Wed, 8 Apr 2009 09:03:10 +0530 +Subject: [PATCH 04/16] Reverse patch for NFS boot to fix comments provided by community + +--- + drivers/net/smc911x.c | 23 +---------------------- + 1 files changed, 1 insertions(+), 22 deletions(-) + +diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c +index 2f0852e..1ded8f0 100644 +--- a/drivers/net/smc911x.c ++++ b/drivers/net/smc911x.c +@@ -116,27 +116,6 @@ static int smc911x_phy_reset(void) + return 0; + } + +-static void smc911x_shutdown(void) +-{ +- unsigned cr; +- +- /* Turn of Rx and TX */ +- cr = smc911x_get_mac_csr(MAC_CR); +- cr &= ~(MAC_CR_TXEN | MAC_CR_RXEN | MAC_CR_HBDIS); +- smc911x_set_mac_csr(MAC_CR, cr); +- +- /* Stop Transmission */ +- cr = smc911x_get_mac_csr(TX_CFG); +- cr &= ~(TX_CFG_STOP_TX); +- smc911x_set_mac_csr(TX_CFG, cr); +- /* Stop receiving packets */ +- cr = smc911x_get_mac_csr(RX_CFG); +- cr &= ~(RX_CFG_RXDOFF); +- smc911x_set_mac_csr(RX_CFG, cr); +- +-} +- +- + static void smc911x_phy_configure(void) + { + int timeout; +@@ -245,7 +224,7 @@ int eth_send(volatile void *packet, int length) + + void eth_halt(void) + { +- smc911x_shutdown(); ++ smc911x_reset(); + } + + int eth_rx(void) +-- +1.6.2.4 + diff --git a/recipes/u-boot/u-boot-git/omap3evm/0005-SMC911x-driver-fixed-for-NFS-boot.patch b/recipes/u-boot/u-boot-git/omap3evm/0005-SMC911x-driver-fixed-for-NFS-boot.patch new file mode 100644 index 0000000000..8b3894bc3f --- /dev/null +++ b/recipes/u-boot/u-boot-git/omap3evm/0005-SMC911x-driver-fixed-for-NFS-boot.patch @@ -0,0 +1,61 @@ +From 3ffa2549a4f61053f78c00b8716cda392cf97b93 Mon Sep 17 00:00:00 2001 +From: Manikandan Pillai +Date: Wed, 8 Apr 2009 09:08:00 +0530 +Subject: [PATCH 05/16] SMC911x driver fixed for NFS boot + +eth_halt() function in the smc911x drivers used to call the +smc911x_reset() function. eth_halt() used to be called after +tftp transfers. This used to put the ethernet chip in reset +while the linux boots up resulting in the ethernet driver +not coming up. NFS boot used to fail as a result. + +This patch calls smc911x_shutdown() instead of smc911x_reset(). +Some comments received has also been fixed. +--- + drivers/net/smc911x.c | 23 ++++++++++++++++++++++- + 1 files changed, 22 insertions(+), 1 deletions(-) + +diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c +index 1ded8f0..5bc3914 100644 +--- a/drivers/net/smc911x.c ++++ b/drivers/net/smc911x.c +@@ -116,6 +116,27 @@ static int smc911x_phy_reset(void) + return 0; + } + ++static void smc911x_shutdown(void) ++{ ++ unsigned int cr; ++ ++ /* Turn of Rx and TX */ ++ cr = smc911x_get_mac_csr(MAC_CR); ++ cr &= ~(MAC_CR_TXEN | MAC_CR_RXEN | MAC_CR_HBDIS); ++ smc911x_set_mac_csr(MAC_CR, cr); ++ ++ /* Stop Transmission */ ++ cr = smc911x_get_mac_csr(TX_CFG); ++ cr &= ~(TX_CFG_STOP_TX); ++ smc911x_set_mac_csr(TX_CFG, cr); ++ /* Stop receiving packets */ ++ cr = smc911x_get_mac_csr(RX_CFG); ++ cr &= ~(RX_CFG_RXDOFF); ++ smc911x_set_mac_csr(RX_CFG, cr); ++ ++} ++ ++ + static void smc911x_phy_configure(void) + { + int timeout; +@@ -224,7 +245,7 @@ int eth_send(volatile void *packet, int length) + + void eth_halt(void) + { +- smc911x_reset(); ++ smc911x_shutdown(); + } + + int eth_rx(void) +-- +1.6.2.4 + diff --git a/recipes/u-boot/u-boot-git/omap3evm/0006-Added-OMAP3517-3505-support.patch b/recipes/u-boot/u-boot-git/omap3evm/0006-Added-OMAP3517-3505-support.patch new file mode 100644 index 0000000000..326679af78 --- /dev/null +++ b/recipes/u-boot/u-boot-git/omap3evm/0006-Added-OMAP3517-3505-support.patch @@ -0,0 +1,2501 @@ +From 4144e9f85d1b0e48732c80b05bc380ae6d2af6d8 Mon Sep 17 00:00:00 2001 +From: Vaibhav Hiremath +Date: Sat, 13 Jun 2009 00:47:34 +0530 +Subject: [PATCH 06/16] Added OMAP3517/3505 support + +Added support for OMAP3517/3505 SoC, it includes all the changes +from Mani's commit for OMAP3517 and review comments fix. + +Major features/changes - + - New config file + - New board files + - New ethernet driver + +Major Review comments - + - Added macine ID for OMAP3517 + - Naming conventions used. +--- + Makefile | 3 + + board/omap3/omap3517evm/Makefile | 47 +++ + board/omap3/omap3517evm/config.mk | 33 ++ + board/omap3/omap3517evm/omap3517evm.c | 124 ++++++ + board/omap3/omap3517evm/omap3517evm.h | 392 ++++++++++++++++++ + board/omap3/omap3517evm/u-boot.lds | 63 +++ + cpu/arm_cortexa8/omap3/board.c | 8 + + cpu/arm_cortexa8/omap3/clock.c | 4 + + cpu/arm_cortexa8/omap3/mem.c | 110 +++++ + drivers/net/Makefile | 1 + + drivers/net/ticpgmac.c | 693 ++++++++++++++++++++++++++++++++ + include/asm-arm/arch-omap3/cpu.h | 26 ++ + include/asm-arm/arch-omap3/mux.h | 41 ++ + include/asm-arm/arch-omap3/sys_proto.h | 1 + + include/asm-arm/arch-omap3/ticpgmac.h | 340 ++++++++++++++++ + include/asm-arm/mach-types.h | 1 + + include/configs/omap3517evm.h | 349 ++++++++++++++++ + lib_arm/board.c | 4 +- + net/eth.c | 4 +- + 19 files changed, 2240 insertions(+), 4 deletions(-) + create mode 100644 board/omap3/omap3517evm/Makefile + create mode 100644 board/omap3/omap3517evm/config.mk + create mode 100644 board/omap3/omap3517evm/omap3517evm.c + create mode 100644 board/omap3/omap3517evm/omap3517evm.h + create mode 100644 board/omap3/omap3517evm/u-boot.lds + create mode 100644 drivers/net/ticpgmac.c + create mode 100644 include/asm-arm/arch-omap3/ticpgmac.h + create mode 100644 include/configs/omap3517evm.h + +diff --git a/Makefile b/Makefile +index 61bae6d..df25fb3 100644 +--- a/Makefile ++++ b/Makefile +@@ -2942,6 +2942,9 @@ omap3_pandora_config : unconfig + omap3_zoom1_config : unconfig + @$(MKCONFIG) $(@:_config=) arm arm_cortexa8 zoom1 omap3 omap3 + ++omap3517evm_config : unconfig ++ @$(MKCONFIG) $(@:_config=) arm arm_cortexa8 omap3517evm omap3 omap3 ++ + ######################################################################### + ## XScale Systems + ######################################################################### +diff --git a/board/omap3/omap3517evm/Makefile b/board/omap3/omap3517evm/Makefile +new file mode 100644 +index 0000000..8f6d10e +--- /dev/null ++++ b/board/omap3/omap3517evm/Makefile +@@ -0,0 +1,47 @@ ++# ++# (C) Copyright 2000, 2001, 2002 ++# Wolfgang Denk, DENX Software Engineering, wd@denx.de. ++# ++# See file CREDITS for list of people who contributed to this ++# project. ++# ++# 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., 59 Temple Place, Suite 330, Boston, ++# MA 02111-1307 USA ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = $(obj)lib$(BOARD).a ++ ++COBJS := omap3517evm.o ++ ++SRCS := $(COBJS:.o=.c) ++OBJS := $(addprefix $(obj),$(COBJS)) ++ ++$(LIB): $(obj).depend $(OBJS) ++ $(AR) $(ARFLAGS) $@ $(OBJS) ++ ++clean: ++ rm -f $(OBJS) ++ ++distclean: clean ++ rm -f $(LIB) core *.bak $(obj).depend ++ ++######################################################################### ++ ++# defines $(obj).depend target ++include $(SRCTREE)/rules.mk ++ ++sinclude $(obj).depend +diff --git a/board/omap3/omap3517evm/config.mk b/board/omap3/omap3517evm/config.mk +new file mode 100644 +index 0000000..4d873eb +--- /dev/null ++++ b/board/omap3/omap3517evm/config.mk +@@ -0,0 +1,33 @@ ++# ++# (C) Copyright 2006 - 2008 ++# Texas Instruments, ++# ++# EVM uses OMAP3 (ARM-CortexA8) cpu ++# see http://www.ti.com/ for more information on Texas Instruments ++# ++# See file CREDITS for list of people who contributed to this ++# project. ++# ++# 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., 59 Temple Place, Suite 330, Boston, ++# MA 02111-1307 USA ++# ++# Physical Address: ++# 8000'0000 (bank0) ++# A000/0000 (bank1) ++# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000 ++# (mem base + reserved) ++ ++# For use with external or internal boots. ++TEXT_BASE = 0x80e80000 +diff --git a/board/omap3/omap3517evm/omap3517evm.c b/board/omap3/omap3517evm/omap3517evm.c +new file mode 100644 +index 0000000..2330776 +--- /dev/null ++++ b/board/omap3/omap3517evm/omap3517evm.c +@@ -0,0 +1,124 @@ ++/* ++ * (C) Copyright 2004-2008 ++ * Texas Instruments, ++ * ++ * Author : ++ * Manikandan Pillai ++ * ++ * Derived from Beagle Board and 3430 SDP code by ++ * Richard Woodruff ++ * Syed Mohammed Khasim ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "omap3517evm.h" ++ ++/****************************************************************************** ++ * Routine: board_init ++ * Description: Early hardware init. ++ *****************************************************************************/ ++int board_init(void) ++{ ++ DECLARE_GLOBAL_DATA_PTR; ++ ++ gpmc_init(); /* in SRAM or SDRAM, finish GPMC */ ++ /* board id for Linux */ ++ gd->bd->bi_arch_number = MACH_TYPE_OMAP3517EVM; ++ /* boot param addr */ ++ gd->bd->bi_boot_params = (OMAP34XX_SDRC_CS0 + 0x100); ++ ++ return 0; ++} ++ ++/****************************************************************************** ++ * Routine: misc_init_r ++ * Description: Init ethernet (done here so udelay works) ++ *****************************************************************************/ ++int misc_init_r(void) ++{ ++ ++#ifdef CONFIG_DRIVER_OMAP34XX_I2C ++ i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); ++#endif ++ ++#if defined(CONFIG_CMD_NET) ++ setup_net_chip(); ++#endif ++ ++ dieid_num_r(); ++ ++ return 0; ++} ++ ++/****************************************************************************** ++ * Routine: set_muxconf_regs ++ * Description: Setting up the configuration Mux registers specific to the ++ * hardware. Many pins need to be moved from protect to primary ++ * mode. ++ *****************************************************************************/ ++void set_muxconf_regs(void) ++{ ++ MUX_OMAP3517EVM(); ++} ++ ++/****************************************************************************** ++ * Routine: setup_net_chip ++ * Description: Setting up the configuration GPMC registers specific to the ++ * Ethernet hardware. ++ *****************************************************************************/ ++static void setup_net_chip(void) ++{ ++ gpio_t *gpio3_base = (gpio_t *)OMAP34XX_GPIO3_BASE; ++ gpmc_csx_t *gpmc_cs6_base = (gpmc_csx_t *)GPMC_CONFIG_CS6_BASE; ++ ctrl_t *ctrl_base = (ctrl_t *)OMAP34XX_CTRL_BASE; ++ ++ /* Configure GPMC registers */ ++ writel(NET_GPMC_CONFIG1, &gpmc_cs6_base->config1); ++ writel(NET_GPMC_CONFIG2, &gpmc_cs6_base->config2); ++ writel(NET_GPMC_CONFIG3, &gpmc_cs6_base->config3); ++ writel(NET_GPMC_CONFIG4, &gpmc_cs6_base->config4); ++ writel(NET_GPMC_CONFIG5, &gpmc_cs6_base->config5); ++ writel(NET_GPMC_CONFIG6, &gpmc_cs6_base->config6); ++ writel(NET_GPMC_CONFIG7, &gpmc_cs6_base->config7); ++ ++ /* Enable off mode for NWE in PADCONF_GPMC_NWE register */ ++ writew(readw(&ctrl_base ->gpmc_nwe) | 0x0E00, &ctrl_base->gpmc_nwe); ++ /* Enable off mode for NOE in PADCONF_GPMC_NADV_ALE register */ ++ writew(readw(&ctrl_base->gpmc_noe) | 0x0E00, &ctrl_base->gpmc_noe); ++ /* Enable off mode for ALE in PADCONF_GPMC_NADV_ALE register */ ++ writew(readw(&ctrl_base->gpmc_nadv_ale) | 0x0E00, ++ &ctrl_base->gpmc_nadv_ale); ++ ++ /* Make GPIO 64 as output pin */ ++ writel(readl(&gpio3_base->oe) & ~(GPIO0), &gpio3_base->oe); ++ ++ /* Now send a pulse on the GPIO pin */ ++ writel(GPIO0, &gpio3_base->setdataout); ++ udelay(1); ++ writel(GPIO0, &gpio3_base->cleardataout); ++ udelay(1); ++ writel(GPIO0, &gpio3_base->setdataout); ++} +diff --git a/board/omap3/omap3517evm/omap3517evm.h b/board/omap3/omap3517evm/omap3517evm.h +new file mode 100644 +index 0000000..aba53bf +--- /dev/null ++++ b/board/omap3/omap3517evm/omap3517evm.h +@@ -0,0 +1,392 @@ ++/* ++ * (C) Copyright 2008 ++ * Nishanth Menon ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++#ifndef _OMAP3517EVM_H_ ++#define _OMAP3517EVM_H_ ++ ++const omap3_sysinfo sysinfo = { ++ OMAP3EVM_V1, ++ OMAP3EVM_V2, ++ DDR_DISCRETE, ++ "OMAP3 omap3517evm board", ++ "NAND", ++}; ++ ++static void setup_net_chip(void); ++ ++/* ++ * IEN - Input Enable ++ * IDIS - Input Disable ++ * PTD - Pull type Down ++ * PTU - Pull type Up ++ * DIS - Pull type selection is inactive ++ * EN - Pull type selection is active ++ * M0 - Mode 0 ++ * The commented string gives the final mux configuration for that pin ++ */ ++#define MUX_OMAP3517EVM() \ ++ /*SDRC*/\ ++ MUX_VAL(CP(SDRC_D0), (IEN | PTD | DIS | M0)) /*SDRC_D0*/\ ++ MUX_VAL(CP(SDRC_D1), (IEN | PTD | DIS | M0)) /*SDRC_D1*/\ ++ MUX_VAL(CP(SDRC_D2), (IEN | PTD | DIS | M0)) /*SDRC_D2*/\ ++ MUX_VAL(CP(SDRC_D3), (IEN | PTD | DIS | M0)) /*SDRC_D3*/\ ++ MUX_VAL(CP(SDRC_D4), (IEN | PTD | DIS | M0)) /*SDRC_D4*/\ ++ MUX_VAL(CP(SDRC_D5), (IEN | PTD | DIS | M0)) /*SDRC_D5*/\ ++ MUX_VAL(CP(SDRC_D6), (IEN | PTD | DIS | M0)) /*SDRC_D6*/\ ++ MUX_VAL(CP(SDRC_D7), (IEN | PTD | DIS | M0)) /*SDRC_D7*/\ ++ MUX_VAL(CP(SDRC_D8), (IEN | PTD | DIS | M0)) /*SDRC_D8*/\ ++ MUX_VAL(CP(SDRC_D9), (IEN | PTD | DIS | M0)) /*SDRC_D9*/\ ++ MUX_VAL(CP(SDRC_D10), (IEN | PTD | DIS | M0)) /*SDRC_D10*/\ ++ MUX_VAL(CP(SDRC_D11), (IEN | PTD | DIS | M0)) /*SDRC_D11*/\ ++ MUX_VAL(CP(SDRC_D12), (IEN | PTD | DIS | M0)) /*SDRC_D12*/\ ++ MUX_VAL(CP(SDRC_D13), (IEN | PTD | DIS | M0)) /*SDRC_D13*/\ ++ MUX_VAL(CP(SDRC_D14), (IEN | PTD | DIS | M0)) /*SDRC_D14*/\ ++ MUX_VAL(CP(SDRC_D15), (IEN | PTD | DIS | M0)) /*SDRC_D15*/\ ++ MUX_VAL(CP(SDRC_D16), (IEN | PTD | DIS | M0)) /*SDRC_D16*/\ ++ MUX_VAL(CP(SDRC_D17), (IEN | PTD | DIS | M0)) /*SDRC_D17*/\ ++ MUX_VAL(CP(SDRC_D18), (IEN | PTD | DIS | M0)) /*SDRC_D18*/\ ++ MUX_VAL(CP(SDRC_D19), (IEN | PTD | DIS | M0)) /*SDRC_D19*/\ ++ MUX_VAL(CP(SDRC_D20), (IEN | PTD | DIS | M0)) /*SDRC_D20*/\ ++ MUX_VAL(CP(SDRC_D21), (IEN | PTD | DIS | M0)) /*SDRC_D21*/\ ++ MUX_VAL(CP(SDRC_D22), (IEN | PTD | DIS | M0)) /*SDRC_D22*/\ ++ MUX_VAL(CP(SDRC_D23), (IEN | PTD | DIS | M0)) /*SDRC_D23*/\ ++ MUX_VAL(CP(SDRC_D24), (IEN | PTD | DIS | M0)) /*SDRC_D24*/\ ++ MUX_VAL(CP(SDRC_D25), (IEN | PTD | DIS | M0)) /*SDRC_D25*/\ ++ MUX_VAL(CP(SDRC_D26), (IEN | PTD | DIS | M0)) /*SDRC_D26*/\ ++ MUX_VAL(CP(SDRC_D27), (IEN | PTD | DIS | M0)) /*SDRC_D27*/\ ++ MUX_VAL(CP(SDRC_D28), (IEN | PTD | DIS | M0)) /*SDRC_D28*/\ ++ MUX_VAL(CP(SDRC_D29), (IEN | PTD | DIS | M0)) /*SDRC_D29*/\ ++ MUX_VAL(CP(SDRC_D30), (IEN | PTD | DIS | M0)) /*SDRC_D30*/\ ++ MUX_VAL(CP(SDRC_D31), (IEN | PTD | DIS | M0)) /*SDRC_D31*/\ ++ MUX_VAL(CP(SDRC_CLK), (IEN | PTD | DIS | M0)) /*SDRC_CLK*/\ ++ MUX_VAL(CP(SDRC_DQS0), (IEN | PTD | DIS | M0)) /*SDRC_DQS0*/\ ++ MUX_VAL(CP(SDRC_DQS1), (IEN | PTD | DIS | M0)) /*SDRC_DQS1*/\ ++ MUX_VAL(CP(SDRC_DQS2), (IEN | PTD | DIS | M0)) /*SDRC_DQS2*/\ ++ MUX_VAL(CP(SDRC_DQS3), (IEN | PTD | DIS | M0)) /*SDRC_DQS3*/\ ++ /*GPMC*/\ ++ MUX_VAL(CP(GPMC_A1), (IDIS | PTU | EN | M0)) /*GPMC_A1*/\ ++ MUX_VAL(CP(GPMC_A2), (IDIS | PTU | EN | M0)) /*GPMC_A2*/\ ++ MUX_VAL(CP(GPMC_A3), (IDIS | PTU | EN | M0)) /*GPMC_A3*/\ ++ MUX_VAL(CP(GPMC_A4), (IDIS | PTU | EN | M0)) /*GPMC_A4*/\ ++ MUX_VAL(CP(GPMC_A5), (IDIS | PTU | EN | M0)) /*GPMC_A5*/\ ++ MUX_VAL(CP(GPMC_A6), (IDIS | PTU | EN | M0)) /*GPMC_A6*/\ ++ MUX_VAL(CP(GPMC_A7), (IDIS | PTU | EN | M0)) /*GPMC_A7*/\ ++ MUX_VAL(CP(GPMC_A8), (IDIS | PTU | EN | M0)) /*GPMC_A8*/\ ++ MUX_VAL(CP(GPMC_A9), (IDIS | PTU | EN | M0)) /*GPMC_A9*/\ ++ MUX_VAL(CP(GPMC_A10), (IDIS | PTU | EN | M0)) /*GPMC_A10*/\ ++ MUX_VAL(CP(GPMC_D0), (IEN | PTU | EN | M0)) /*GPMC_D0*/\ ++ MUX_VAL(CP(GPMC_D1), (IEN | PTU | EN | M0)) /*GPMC_D1*/\ ++ MUX_VAL(CP(GPMC_D2), (IEN | PTU | EN | M0)) /*GPMC_D2*/\ ++ MUX_VAL(CP(GPMC_D3), (IEN | PTU | EN | M0)) /*GPMC_D3*/\ ++ MUX_VAL(CP(GPMC_D4), (IEN | PTU | EN | M0)) /*GPMC_D4*/\ ++ MUX_VAL(CP(GPMC_D5), (IEN | PTU | EN | M0)) /*GPMC_D5*/\ ++ MUX_VAL(CP(GPMC_D6), (IEN | PTU | EN | M0)) /*GPMC_D6*/\ ++ MUX_VAL(CP(GPMC_D7), (IEN | PTU | EN | M0)) /*GPMC_D7*/\ ++ MUX_VAL(CP(GPMC_D8), (IEN | PTU | EN | M0)) /*GPMC_D8*/\ ++ MUX_VAL(CP(GPMC_D9), (IEN | PTU | EN | M0)) /*GPMC_D9*/\ ++ MUX_VAL(CP(GPMC_D10), (IEN | PTU | EN | M0)) /*GPMC_D10*/\ ++ MUX_VAL(CP(GPMC_D11), (IEN | PTU | EN | M0)) /*GPMC_D11*/\ ++ MUX_VAL(CP(GPMC_D12), (IEN | PTU | EN | M0)) /*GPMC_D12*/\ ++ MUX_VAL(CP(GPMC_D13), (IEN | PTU | EN | M0)) /*GPMC_D13*/\ ++ MUX_VAL(CP(GPMC_D14), (IEN | PTU | EN | M0)) /*GPMC_D14*/\ ++ MUX_VAL(CP(GPMC_D15), (IEN | PTU | EN | M0)) /*GPMC_D15*/\ ++ MUX_VAL(CP(GPMC_NCS0), (IDIS | PTU | EN | M0)) /*GPMC_nCS0*/\ ++ MUX_VAL(CP(GPMC_NCS1), (IDIS | PTU | EN | M0)) /*GPMC_nCS1*/\ ++ MUX_VAL(CP(GPMC_NCS2), (IDIS | PTU | EN | M0)) /*GPMC_nCS2*/\ ++ MUX_VAL(CP(GPMC_NCS3), (IDIS | PTU | EN | M0)) /*GPMC_nCS3*/\ ++ MUX_VAL(CP(GPMC_NCS4), (IEN | PTU | EN | M0)) /*GPMC_nCS4*/\ ++ MUX_VAL(CP(GPMC_NCS5), (IDIS | PTU | EN | M0)) /*GPMC_nCS5*/\ ++ MUX_VAL(CP(GPMC_NCS6), (IEN | PTD | DIS | M0)) /*GPMC_nCS6*/\ ++ MUX_VAL(CP(GPMC_NCS7), (IEN | PTU | EN | M0)) /*GPMC_nCS7*/\ ++ MUX_VAL(CP(GPMC_CLK), (IDIS | PTU | EN | M0)) /*GPMC_CLK*/\ ++ MUX_VAL(CP(GPMC_NADV_ALE), (IDIS | PTD | DIS | M0)) /*GPMC_nADV_ALE*/\ ++ MUX_VAL(CP(GPMC_NOE), (IDIS | PTD | DIS | M0)) /*GPMC_nOE*/\ ++ MUX_VAL(CP(GPMC_NWE), (IDIS | PTD | DIS | M0)) /*GPMC_nWE*/\ ++ MUX_VAL(CP(GPMC_NBE0_CLE), (IDIS | PTU | EN | M0)) /*GPMC_nBE0_CLE*/\ ++ MUX_VAL(CP(GPMC_NBE1), (IEN | PTU | EN | M0)) /*GPMC_nBE1*/\ ++ MUX_VAL(CP(GPMC_NWP), (IEN | PTD | DIS | M0)) /*GPMC_nWP*/\ ++ MUX_VAL(CP(GPMC_WAIT0), (IEN | PTU | EN | M0)) /*GPMC_WAIT0*/\ ++ MUX_VAL(CP(GPMC_WAIT1), (IEN | PTU | EN | M0)) /*GPMC_WAIT1*/\ ++ MUX_VAL(CP(GPMC_WAIT2), (IEN | PTU | EN | M4)) /*GPIO_64*/\ ++ /* - ETH_nRESET*/\ ++ MUX_VAL(CP(GPMC_WAIT3), (IEN | PTU | EN | M0)) /*GPMC_WAIT3*/\ ++ /*DSS*/\ ++ MUX_VAL(CP(DSS_PCLK), (IDIS | PTD | DIS | M0)) /*DSS_PCLK*/\ ++ MUX_VAL(CP(DSS_HSYNC), (IDIS | PTD | DIS | M0)) /*DSS_HSYNC*/\ ++ MUX_VAL(CP(DSS_VSYNC), (IDIS | PTD | DIS | M0)) /*DSS_VSYNC*/\ ++ MUX_VAL(CP(DSS_ACBIAS), (IDIS | PTD | DIS | M0)) /*DSS_ACBIAS*/\ ++ MUX_VAL(CP(DSS_DATA0), (IDIS | PTD | DIS | M0)) /*DSS_DATA0*/\ ++ MUX_VAL(CP(DSS_DATA1), (IDIS | PTD | DIS | M0)) /*DSS_DATA1*/\ ++ MUX_VAL(CP(DSS_DATA2), (IDIS | PTD | DIS | M0)) /*DSS_DATA2*/\ ++ MUX_VAL(CP(DSS_DATA3), (IDIS | PTD | DIS | M0)) /*DSS_DATA3*/\ ++ MUX_VAL(CP(DSS_DATA4), (IDIS | PTD | DIS | M0)) /*DSS_DATA4*/\ ++ MUX_VAL(CP(DSS_DATA5), (IDIS | PTD | DIS | M0)) /*DSS_DATA5*/\ ++ MUX_VAL(CP(DSS_DATA6), (IDIS | PTD | DIS | M0)) /*DSS_DATA6*/\ ++ MUX_VAL(CP(DSS_DATA7), (IDIS | PTD | DIS | M0)) /*DSS_DATA7*/\ ++ MUX_VAL(CP(DSS_DATA8), (IDIS | PTD | DIS | M0)) /*DSS_DATA8*/\ ++ MUX_VAL(CP(DSS_DATA9), (IDIS | PTD | DIS | M0)) /*DSS_DATA9*/\ ++ MUX_VAL(CP(DSS_DATA10), (IDIS | PTD | DIS | M0)) /*DSS_DATA10*/\ ++ MUX_VAL(CP(DSS_DATA11), (IDIS | PTD | DIS | M0)) /*DSS_DATA11*/\ ++ MUX_VAL(CP(DSS_DATA12), (IDIS | PTD | DIS | M0)) /*DSS_DATA12*/\ ++ MUX_VAL(CP(DSS_DATA13), (IDIS | PTD | DIS | M0)) /*DSS_DATA13*/\ ++ MUX_VAL(CP(DSS_DATA14), (IDIS | PTD | DIS | M0)) /*DSS_DATA14*/\ ++ MUX_VAL(CP(DSS_DATA15), (IDIS | PTD | DIS | M0)) /*DSS_DATA15*/\ ++ MUX_VAL(CP(DSS_DATA16), (IDIS | PTD | DIS | M0)) /*DSS_DATA16*/\ ++ MUX_VAL(CP(DSS_DATA17), (IDIS | PTD | DIS | M0)) /*DSS_DATA17*/\ ++ MUX_VAL(CP(DSS_DATA18), (IDIS | PTD | DIS | M0)) /*DSS_DATA18*/\ ++ MUX_VAL(CP(DSS_DATA19), (IDIS | PTD | DIS | M0)) /*DSS_DATA19*/\ ++ MUX_VAL(CP(DSS_DATA20), (IDIS | PTD | DIS | M0)) /*DSS_DATA20*/\ ++ MUX_VAL(CP(DSS_DATA21), (IDIS | PTD | DIS | M0)) /*DSS_DATA21*/\ ++ MUX_VAL(CP(DSS_DATA22), (IDIS | PTD | DIS | M0)) /*DSS_DATA22*/\ ++ MUX_VAL(CP(DSS_DATA23), (IDIS | PTD | DIS | M0)) /*DSS_DATA23*/\ ++ /*CAMERA*/\ ++ MUX_VAL(CP(CAM_HS), (IEN | PTU | EN | M0)) /*CAM_HS */\ ++ MUX_VAL(CP(CAM_VS), (IEN | PTU | EN | M0)) /*CAM_VS */\ ++ MUX_VAL(CP(CAM_XCLKA), (IDIS | PTD | DIS | M0)) /*CAM_XCLKA*/\ ++ MUX_VAL(CP(CAM_PCLK), (IEN | PTU | EN | M0)) /*CAM_PCLK*/\ ++ MUX_VAL(CP(CAM_FLD), (IDIS | PTD | DIS | M4)) /*GPIO_98*/\ ++ /* - CAM_RESET*/\ ++ MUX_VAL(CP(CAM_D0), (IEN | PTD | DIS | M0)) /*CAM_D0*/\ ++ MUX_VAL(CP(CAM_D1), (IEN | PTD | DIS | M0)) /*CAM_D1*/\ ++ MUX_VAL(CP(CAM_D2), (IEN | PTD | DIS | M0)) /*CAM_D2*/\ ++ MUX_VAL(CP(CAM_D3), (IEN | PTD | DIS | M0)) /*CAM_D3*/\ ++ MUX_VAL(CP(CAM_D4), (IEN | PTD | DIS | M0)) /*CAM_D4*/\ ++ MUX_VAL(CP(CAM_D5), (IEN | PTD | DIS | M0)) /*CAM_D5*/\ ++ MUX_VAL(CP(CAM_D6), (IEN | PTD | DIS | M0)) /*CAM_D6*/\ ++ MUX_VAL(CP(CAM_D7), (IEN | PTD | DIS | M0)) /*CAM_D7*/\ ++ MUX_VAL(CP(CAM_D8), (IEN | PTD | DIS | M0)) /*CAM_D8*/\ ++ MUX_VAL(CP(CAM_D9), (IEN | PTD | DIS | M0)) /*CAM_D9*/\ ++ MUX_VAL(CP(CAM_D10), (IEN | PTD | DIS | M0)) /*CAM_D10*/\ ++ MUX_VAL(CP(CAM_D11), (IEN | PTD | DIS | M0)) /*CAM_D11*/\ ++ MUX_VAL(CP(CAM_XCLKB), (IDIS | PTD | DIS | M0)) /*CAM_XCLKB*/\ ++ MUX_VAL(CP(CAM_WEN), (IEN | PTD | DIS | M4)) /*GPIO_167*/\ ++ MUX_VAL(CP(CAM_STROBE), (IDIS | PTD | DIS | M0)) /*CAM_STROBE*/\ ++ MUX_VAL(CP(CSI2_DX0), (IEN | PTD | DIS | M0)) /*CSI2_DX0*/\ ++ MUX_VAL(CP(CSI2_DY0), (IEN | PTD | DIS | M0)) /*CSI2_DY0*/\ ++ MUX_VAL(CP(CSI2_DX1), (IEN | PTD | DIS | M0)) /*CSI2_DX1*/\ ++ MUX_VAL(CP(CSI2_DY1), (IEN | PTD | DIS | M0)) /*CSI2_DY1*/\ ++ /*Audio Interface */\ ++ MUX_VAL(CP(MCBSP2_FSX), (IEN | PTD | DIS | M0)) /*McBSP2_FSX*/\ ++ MUX_VAL(CP(MCBSP2_CLKX), (IEN | PTD | DIS | M0)) /*McBSP2_CLKX*/\ ++ MUX_VAL(CP(MCBSP2_DR), (IEN | PTD | DIS | M0)) /*McBSP2_DR*/\ ++ MUX_VAL(CP(MCBSP2_DX), (IDIS | PTD | DIS | M0)) /*McBSP2_DX*/\ ++ /*Expansion card */\ ++ MUX_VAL(CP(MMC1_CLK), (IDIS | PTU | EN | M0)) /*MMC1_CLK*/\ ++ MUX_VAL(CP(MMC1_CMD), (IEN | PTU | EN | M0)) /*MMC1_CMD*/\ ++ MUX_VAL(CP(MMC1_DAT0), (IEN | PTU | EN | M0)) /*MMC1_DAT0*/\ ++ MUX_VAL(CP(MMC1_DAT1), (IEN | PTU | EN | M0)) /*MMC1_DAT1*/\ ++ MUX_VAL(CP(MMC1_DAT2), (IEN | PTU | EN | M0)) /*MMC1_DAT2*/\ ++ MUX_VAL(CP(MMC1_DAT3), (IEN | PTU | EN | M0)) /*MMC1_DAT3*/\ ++ MUX_VAL(CP(MMC1_DAT4), (IEN | PTU | EN | M0)) /*MMC1_DAT4*/\ ++ MUX_VAL(CP(MMC1_DAT5), (IEN | PTU | EN | M0)) /*MMC1_DAT5*/\ ++ MUX_VAL(CP(MMC1_DAT6), (IEN | PTU | EN | M0)) /*MMC1_DAT6*/\ ++ MUX_VAL(CP(MMC1_DAT7), (IEN | PTU | EN | M0)) /*MMC1_DAT7*/\ ++ /*Wireless LAN */\ ++ MUX_VAL(CP(MMC2_CLK), (IEN | PTD | DIS | M0)) /*MMC2_CLK*/\ ++ MUX_VAL(CP(MMC2_CMD), (IEN | PTU | EN | M0)) /*MMC2_CMD*/\ ++ MUX_VAL(CP(MMC2_DAT0), (IEN | PTU | EN | M0)) /*MMC2_DAT0*/\ ++ MUX_VAL(CP(MMC2_DAT1), (IEN | PTU | EN | M0)) /*MMC2_DAT1*/\ ++ MUX_VAL(CP(MMC2_DAT2), (IEN | PTU | EN | M0)) /*MMC2_DAT2*/\ ++ MUX_VAL(CP(MMC2_DAT3), (IEN | PTU | EN | M0)) /*MMC2_DAT3*/\ ++ MUX_VAL(CP(MMC2_DAT4), (IDIS | PTD | DIS | M0)) /*MMC2_DAT4*/\ ++ MUX_VAL(CP(MMC2_DAT5), (IDIS | PTD | DIS | M0)) /*MMC2_DAT5*/\ ++ MUX_VAL(CP(MMC2_DAT6), (IDIS | PTD | DIS | M0)) /*MMC2_DAT6 */\ ++ MUX_VAL(CP(MMC2_DAT7), (IEN | PTU | EN | M0)) /*MMC2_DAT7*/\ ++ /*Bluetooth*/\ ++ MUX_VAL(CP(MCBSP3_DX), (IDIS | PTD | DIS | M0)) /*McBSP3_DX*/\ ++ MUX_VAL(CP(MCBSP3_DR), (IEN | PTD | DIS | M0)) /*McBSP3_DR*/\ ++ MUX_VAL(CP(MCBSP3_CLKX), (IEN | PTD | DIS | M0)) /*McBSP3_CLKX */\ ++ MUX_VAL(CP(MCBSP3_FSX), (IEN | PTD | DIS | M0)) /*McBSP3_FSX*/\ ++ MUX_VAL(CP(UART2_CTS), (IEN | PTU | EN | M0)) /*UART2_CTS*/\ ++ MUX_VAL(CP(UART2_RTS), (IDIS | PTD | DIS | M0)) /*UART2_RTS*/\ ++ MUX_VAL(CP(UART2_TX), (IDIS | PTD | DIS | M0)) /*UART2_TX*/\ ++ MUX_VAL(CP(UART2_RX), (IEN | PTD | DIS | M0)) /*UART2_RX*/\ ++ /*Modem Interface */\ ++ MUX_VAL(CP(UART1_TX), (IDIS | PTD | DIS | M0)) /*UART1_TX*/\ ++ MUX_VAL(CP(UART1_RTS), (IDIS | PTD | DIS | M0)) /*UART1_RTS*/\ ++ MUX_VAL(CP(UART1_CTS), (IEN | PTU | DIS | M0)) /*UART1_CTS*/\ ++ MUX_VAL(CP(UART1_RX), (IEN | PTD | DIS | M0)) /*UART1_RX*/\ ++ MUX_VAL(CP(MCBSP4_CLKX), (IDIS | PTD | DIS | M4)) /*GPIO_152*/\ ++ /* - LCD_INI*/\ ++ MUX_VAL(CP(MCBSP4_DR), (IDIS | PTD | DIS | M4)) /*GPIO_153*/\ ++ /* - LCD_ENVDD */\ ++ MUX_VAL(CP(MCBSP4_DX), (IDIS | PTD | DIS | M4)) /*GPIO_154*/\ ++ /* - LCD_QVGA/nVGA */\ ++ MUX_VAL(CP(MCBSP4_FSX), (IDIS | PTD | DIS | M4)) /*GPIO_155*/\ ++ /* - LCD_RESB */\ ++ MUX_VAL(CP(MCBSP1_CLKR), (IEN | PTD | DIS | M0)) /*MCBSP1_CLKR */\ ++ MUX_VAL(CP(MCBSP1_FSR), (IDIS | PTU | EN | M0)) /*MCBSP1_FSR*/\ ++ MUX_VAL(CP(MCBSP1_DX), (IDIS | PTD | DIS | M0)) /*MCBSP1_DX*/\ ++ MUX_VAL(CP(MCBSP1_DR), (IEN | PTD | DIS | M0)) /*MCBSP1_DR*/\ ++ MUX_VAL(CP(MCBSP_CLKS), (IEN | PTU | DIS | M0)) /*MCBSP_CLKS */\ ++ MUX_VAL(CP(MCBSP1_FSX), (IEN | PTD | DIS | M0)) /*MCBSP1_FSX*/\ ++ MUX_VAL(CP(MCBSP1_CLKX), (IEN | PTD | DIS | M0)) /*MCBSP1_CLKX */\ ++ /*Serial Interface*/\ ++ MUX_VAL(CP(UART3_CTS_RCTX), (IEN | PTD | EN | M0)) /*UART3_CTS_*/\ ++ /* RCTX*/\ ++ MUX_VAL(CP(UART3_RTS_SD), (IDIS | PTD | DIS | M0)) /*UART3_RTS_SD */\ ++ MUX_VAL(CP(UART3_RX_IRRX), (IEN | PTD | DIS | M0)) /*UART3_RX_IRRX*/\ ++ MUX_VAL(CP(UART3_TX_IRTX), (IDIS | PTD | DIS | M0)) /*UART3_TX_IRTX*/\ ++ MUX_VAL(CP(HSUSB0_CLK), (IEN | PTD | DIS | M0)) /*HSUSB0_CLK*/\ ++ MUX_VAL(CP(HSUSB0_STP), (IDIS | PTU | EN | M0)) /*HSUSB0_STP*/\ ++ MUX_VAL(CP(HSUSB0_DIR), (IEN | PTD | DIS | M0)) /*HSUSB0_DIR*/\ ++ MUX_VAL(CP(HSUSB0_NXT), (IEN | PTD | DIS | M0)) /*HSUSB0_NXT*/\ ++ MUX_VAL(CP(HSUSB0_DATA0), (IEN | PTD | DIS | M0)) /*HSUSB0_DATA0*/\ ++ MUX_VAL(CP(HSUSB0_DATA1), (IEN | PTD | DIS | M0)) /*HSUSB0_DATA1*/\ ++ MUX_VAL(CP(HSUSB0_DATA2), (IEN | PTD | DIS | M0)) /*HSUSB0_DATA2*/\ ++ MUX_VAL(CP(HSUSB0_DATA3), (IEN | PTD | DIS | M0)) /*HSUSB0_DATA3*/\ ++ MUX_VAL(CP(HSUSB0_DATA4), (IEN | PTD | DIS | M0)) /*HSUSB0_DATA4*/\ ++ MUX_VAL(CP(HSUSB0_DATA5), (IEN | PTD | DIS | M0)) /*HSUSB0_DATA5*/\ ++ MUX_VAL(CP(HSUSB0_DATA6), (IEN | PTD | DIS | M0)) /*HSUSB0_DATA6*/\ ++ MUX_VAL(CP(HSUSB0_DATA7), (IEN | PTD | DIS | M0)) /*HSUSB0_DATA7*/\ ++ MUX_VAL(CP(I2C1_SCL), (IEN | PTU | EN | M0)) /*I2C1_SCL*/\ ++ MUX_VAL(CP(I2C1_SDA), (IEN | PTU | EN | M0)) /*I2C1_SDA*/\ ++ MUX_VAL(CP(I2C2_SCL), (IEN | PTU | EN | M0)) /*I2C2_SCL*/\ ++ MUX_VAL(CP(I2C2_SDA), (IEN | PTU | EN | M0)) /*I2C2_SDA*/\ ++ MUX_VAL(CP(I2C3_SCL), (IEN | PTU | EN | M0)) /*I2C3_SCL*/\ ++ MUX_VAL(CP(I2C3_SDA), (IEN | PTU | EN | M0)) /*I2C3_SDA*/\ ++ MUX_VAL(CP(I2C4_SCL), (IEN | PTU | EN | M0)) /*I2C4_SCL*/\ ++ MUX_VAL(CP(I2C4_SDA), (IEN | PTU | EN | M0)) /*I2C4_SDA*/\ ++ MUX_VAL(CP(HDQ_SIO), (IEN | PTU | EN | M0)) /*HDQ_SIO*/\ ++ MUX_VAL(CP(MCSPI1_CLK), (IEN | PTD | DIS | M0)) /*McSPI1_CLK*/\ ++ MUX_VAL(CP(MCSPI1_SIMO), (IEN | PTD | DIS | M0)) /*McSPI1_SIMO */\ ++ MUX_VAL(CP(MCSPI1_SOMI), (IEN | PTD | DIS | M0)) /*McSPI1_SOMI */\ ++ MUX_VAL(CP(MCSPI1_CS0), (IEN | PTD | EN | M0)) /*McSPI1_CS0*/\ ++ MUX_VAL(CP(MCSPI1_CS1), (IEN | PTD | EN | M4)) /*GPIO_175*/\ ++ /* TS_PEN_IRQ */\ ++ MUX_VAL(CP(MCSPI1_CS2), (IEN | PTU | DIS | M4)) /*GPIO_176*/\ ++ /* - LAN_INTR*/\ ++ MUX_VAL(CP(MCSPI1_CS3), (IEN | PTD | EN | M0)) /*McSPI1_CS3*/\ ++ MUX_VAL(CP(MCSPI2_CLK), (IEN | PTD | DIS | M0)) /*McSPI2_CLK*/\ ++ MUX_VAL(CP(MCSPI2_SIMO), (IEN | PTD | DIS | M0)) /*McSPI2_SIMO*/\ ++ MUX_VAL(CP(MCSPI2_SOMI), (IEN | PTD | DIS | M0)) /*McSPI2_SOMI*/\ ++ MUX_VAL(CP(MCSPI2_CS0), (IEN | PTD | EN | M0)) /*McSPI2_CS0*/\ ++ MUX_VAL(CP(MCSPI2_CS1), (IEN | PTD | EN | M0)) /*McSPI2_CS1*/\ ++ /*Control and debug */\ ++ MUX_VAL(CP(SYS_32K), (IEN | PTD | DIS | M0)) /*SYS_32K*/\ ++ MUX_VAL(CP(SYS_CLKREQ), (IEN | PTD | DIS | M0)) /*SYS_CLKREQ*/\ ++ MUX_VAL(CP(SYS_NIRQ), (IEN | PTU | EN | M0)) /*SYS_nIRQ*/\ ++ MUX_VAL(CP(SYS_BOOT0), (IEN | PTD | DIS | M4)) /*GPIO_2*/\ ++ /* - PEN_IRQ */\ ++ MUX_VAL(CP(SYS_BOOT1), (IEN | PTD | DIS | M4)) /*GPIO_3 */\ ++ MUX_VAL(CP(SYS_BOOT2), (IEN | PTD | DIS | M4)) /*GPIO_4*/\ ++ MUX_VAL(CP(SYS_BOOT3), (IEN | PTD | DIS | M4)) /*GPIO_5*/\ ++ MUX_VAL(CP(SYS_BOOT4), (IEN | PTD | DIS | M4)) /*GPIO_6*/\ ++ MUX_VAL(CP(SYS_BOOT5), (IEN | PTD | DIS | M4)) /*GPIO_7*/\ ++ MUX_VAL(CP(SYS_BOOT6), (IDIS | PTD | DIS | M4)) /*GPIO_8*/\ ++ /* - VIO_1V8*/\ ++ MUX_VAL(CP(SYS_OFF_MODE), (IEN | PTD | DIS | M0)) /*SYS_OFF_MODE*/\ ++ MUX_VAL(CP(SYS_CLKOUT1), (IEN | PTD | DIS | M0)) /*SYS_CLKOUT1*/\ ++ MUX_VAL(CP(SYS_CLKOUT2), (IEN | PTU | EN | M0)) /*SYS_CLKOUT2*/\ ++ MUX_VAL(CP(JTAG_nTRST), (IEN | PTD | DIS | M0)) /*JTAG_nTRST*/\ ++ MUX_VAL(CP(JTAG_TCK), (IEN | PTD | DIS | M0)) /*JTAG_TCK*/\ ++ MUX_VAL(CP(JTAG_TMS), (IEN | PTD | DIS | M0)) /*JTAG_TMS*/\ ++ MUX_VAL(CP(JTAG_TDI), (IEN | PTD | DIS | M0)) /*JTAG_TDI*/\ ++ MUX_VAL(CP(JTAG_EMU0), (IEN | PTD | DIS | M0)) /*JTAG_EMU0*/\ ++ MUX_VAL(CP(JTAG_EMU1), (IEN | PTD | DIS | M0)) /*JTAG_EMU1*/\ ++ MUX_VAL(CP(ETK_CLK_ES2), (IDIS | PTU | EN | M0)) /*ETK_CLK*/\ ++ MUX_VAL(CP(ETK_CTL_ES2), (IDIS | PTD | DIS | M0)) /*ETK_CTL*/\ ++ MUX_VAL(CP(ETK_D0_ES2 ), (IEN | PTD | DIS | M0)) /*ETK_D0*/\ ++ MUX_VAL(CP(ETK_D1_ES2 ), (IEN | PTD | DIS | M0)) /*ETK_D1*/\ ++ MUX_VAL(CP(ETK_D2_ES2 ), (IEN | PTD | EN | M0)) /*ETK_D2*/\ ++ MUX_VAL(CP(ETK_D3_ES2 ), (IEN | PTD | DIS | M0)) /*ETK_D3*/\ ++ MUX_VAL(CP(ETK_D4_ES2 ), (IEN | PTD | DIS | M0)) /*ETK_D4*/\ ++ MUX_VAL(CP(ETK_D5_ES2 ), (IEN | PTD | DIS | M0)) /*ETK_D5*/\ ++ MUX_VAL(CP(ETK_D6_ES2 ), (IEN | PTD | DIS | M0)) /*ETK_D6*/\ ++ MUX_VAL(CP(ETK_D7_ES2 ), (IEN | PTD | DIS | M0)) /*ETK_D7*/\ ++ MUX_VAL(CP(ETK_D8_ES2 ), (IEN | PTD | DIS | M0)) /*ETK_D8*/\ ++ MUX_VAL(CP(ETK_D9_ES2 ), (IEN | PTD | DIS | M0)) /*ETK_D9*/\ ++ MUX_VAL(CP(ETK_D10_ES2), (IEN | PTD | DIS | M0)) /*ETK_D10*/\ ++ MUX_VAL(CP(ETK_D11_ES2), (IEN | PTD | DIS | M0)) /*ETK_D11*/\ ++ MUX_VAL(CP(ETK_D12_ES2), (IEN | PTD | DIS | M0)) /*ETK_D12*/\ ++ MUX_VAL(CP(ETK_D13_ES2), (IEN | PTD | DIS | M0)) /*ETK_D13*/\ ++ MUX_VAL(CP(ETK_D14_ES2), (IEN | PTD | DIS | M0)) /*ETK_D14*/\ ++ MUX_VAL(CP(ETK_D15_ES2), (IEN | PTD | DIS | M0)) /*ETK_D15*/\ ++ /*Die to Die */\ ++ MUX_VAL(CP(CCDC_PCLK), (IEN | PTD | EN | M0)) /*ccdc_pclk*/\ ++ MUX_VAL(CP(CCDC_FIELD), (IEN | PTD | EN | M0)) /*ccdc_field*/\ ++ MUX_VAL(CP(CCDC_HD), (IEN | PTD | EN | M0)) /*ccdc_hd*/\ ++ MUX_VAL(CP(CCDC_VD), (IEN | PTD | EN | M0)) /*ccdc_vd*/\ ++ MUX_VAL(CP(CCDC_WEN), (IEN | PTD | EN | M0)) /*ccdc_wen*/\ ++ MUX_VAL(CP(CCDC_DATA0), (IEN | PTD | EN | M0)) /*ccdc_data0*/\ ++ MUX_VAL(CP(CCDC_DATA1), (IEN | PTD | EN | M0)) /*ccdc_data1*/\ ++ MUX_VAL(CP(CCDC_DATA2), (IEN | PTD | EN | M0)) /*ccdc_data2*/\ ++ MUX_VAL(CP(CCDC_DATA3), (IEN | PTD | EN | M0)) /*ccdc_data3*/\ ++ MUX_VAL(CP(CCDC_DATA4), (IEN | PTD | EN | M0)) /*ccdc_data4*/\ ++ MUX_VAL(CP(CCDC_DATA5), (IEN | PTD | EN | M0)) /*ccdc_data5*/\ ++ MUX_VAL(CP(CCDC_DATA6), (IEN | PTD | EN | M0)) /*ccdc_data6*/\ ++ MUX_VAL(CP(CCDC_DATA7), (IEN | PTD | EN | M0)) /*ccdc_data7*/\ ++ MUX_VAL(CP(RMII_MDIO_DATA), (IEN | PTD | EN | M0)) /*rmii_mdio_data*/\ ++ MUX_VAL(CP(RMII_MDIO_CLK), (IEN | PTD | EN | M0)) /*rmii_mdio_clk*/\ ++ MUX_VAL(CP(RMII_RXD0) , (IEN | PTD | EN | M0)) /*rmii_rxd0*/\ ++ MUX_VAL(CP(RMII_RXD1), (IEN | PTD | EN | M0)) /*rmii_rxd1*/\ ++ MUX_VAL(CP(RMII_CRS_DV), (IEN | PTD | EN | M0)) /*rmii_crs_dv*/\ ++ MUX_VAL(CP(RMII_RXER), (IEN | PTD | EN | M0)) /*rmii_rxer*/\ ++ MUX_VAL(CP(RMII_TXD0), (IEN | PTD | EN | M0)) /*rmii_txd0*/\ ++ MUX_VAL(CP(RMII_TXD1), (IEN | PTD | EN | M0)) /*rmii_txd1*/\ ++ MUX_VAL(CP(RMII_TXEN), (IEN | PTD | EN | M0)) /*rmii_txen*/\ ++ MUX_VAL(CP(RMII_50MHZ_CLK), (IEN | PTD | EN | M0)) /*rmii_50mhz_clk*/\ ++ MUX_VAL(CP(USB0_DRVBUS), (IEN | PTD | EN | M0)) /*usb0_drvbus*/\ ++ MUX_VAL(CP(HECCL_TXD), (IEN | PTD | EN | M0)) /*heccl_txd*/\ ++ MUX_VAL(CP(HECCL_RXD), (IEN | PTD | EN | M0)) /*heccl_rxd*/\ ++ MUX_VAL(CP(SYS_BOOT7), (IEN | PTD | EN | M0)) /*sys_boot7*/\ ++ MUX_VAL(CP(SDRC_DQS0N), (IEN | PTD | EN | M0)) /*sdrc_dqs0n*/\ ++ MUX_VAL(CP(SDRC_DQS1N), (IEN | PTD | EN | M0)) /*sdrc_dqs1n*/\ ++ MUX_VAL(CP(SDRC_DQS2N), (IEN | PTD | EN | M0)) /*sdrc_dqs2n*/\ ++ MUX_VAL(CP(SDRC_DQS3N), (IEN | PTD | EN | M0)) /*sdrc_dqs3n*/\ ++ MUX_VAL(CP(STRBEN_DLY0), (IEN | PTD | EN | M0)) /*sdrc_strben_dly0*/\ ++ MUX_VAL(CP(STRBEN_DLY1), (IEN | PTD | EN | M0)) /*sdrc_strben_dly1*/\ ++ MUX_VAL(CP(SYS_BOOT8), (IEN | PTD | EN | M0)) /*sys_boot8*/\ ++ MUX_VAL(CP(D2D_MCAD34), (IEN | PTD | EN | M0)) /*d2d_mcad34*/\ ++ MUX_VAL(CP(D2D_MCAD35), (IEN | PTD | EN | M0)) /*d2d_mcad35*/\ ++ MUX_VAL(CP(D2D_MCAD36), (IEN | PTD | EN | M0)) /*d2d_mcad36*/\ ++ MUX_VAL(CP(D2D_CLK26MI), (IEN | PTD | DIS | M0)) /*d2d_clk26mi*/\ ++ MUX_VAL(CP(D2D_NRESPWRON), (IEN | PTD | EN | M0)) /*d2d_nrespwron*/\ ++ MUX_VAL(CP(D2D_NRESWARM), (IEN | PTU | EN | M0)) /*d2d_nreswarm */\ ++ MUX_VAL(CP(D2D_ARM9NIRQ), (IEN | PTD | DIS | M0)) /*d2d_arm9nirq */\ ++ MUX_VAL(CP(D2D_UMA2P6FIQ), (IEN | PTD | DIS | M0)) /*d2d_uma2p6fiq*/\ ++ MUX_VAL(CP(D2D_SPINT), (IEN | PTD | EN | M0)) /*d2d_spint*/\ ++ MUX_VAL(CP(D2D_FRINT), (IEN | PTD | EN | M0)) /*d2d_frint*/\ ++ MUX_VAL(CP(D2D_DMAREQ0), (IEN | PTD | DIS | M0)) /*d2d_dmareq0*/\ ++ MUX_VAL(CP(D2D_DMAREQ1), (IEN | PTD | DIS | M0)) /*d2d_dmareq1*/\ ++ MUX_VAL(CP(D2D_DMAREQ2), (IEN | PTD | DIS | M0)) /*d2d_dmareq2*/\ ++ MUX_VAL(CP(D2D_DMAREQ3), (IEN | PTD | DIS | M0)) /*d2d_dmareq3*/\ ++ MUX_VAL(CP(D2D_N3GTRST), (IEN | PTD | DIS | M0)) /*d2d_n3gtrst*/\ ++ MUX_VAL(CP(D2D_N3GTDI), (IEN | PTD | DIS | M0)) /*d2d_n3gtdi*/\ ++ MUX_VAL(CP(D2D_N3GTDO), (IEN | PTD | DIS | M0)) /*d2d_n3gtdo*/\ ++ MUX_VAL(CP(D2D_N3GTMS), (IEN | PTD | DIS | M0)) /*d2d_n3gtms*/\ ++ MUX_VAL(CP(D2D_N3GTCK), (IEN | PTD | DIS | M0)) /*d2d_n3gtck*/\ ++ MUX_VAL(CP(D2D_N3GRTCK), (IEN | PTD | DIS | M0)) /*d2d_n3grtck*/\ ++ MUX_VAL(CP(D2D_MSTDBY), (IEN | PTU | EN | M0)) /*d2d_mstdby*/\ ++ MUX_VAL(CP(D2D_SWAKEUP), (IEN | PTD | EN | M0)) /*d2d_swakeup*/\ ++ MUX_VAL(CP(D2D_IDLEREQ), (IEN | PTD | DIS | M0)) /*d2d_idlereq*/\ ++ MUX_VAL(CP(D2D_IDLEACK), (IEN | PTU | EN | M0)) /*d2d_idleack*/\ ++ MUX_VAL(CP(D2D_MWRITE), (IEN | PTD | DIS | M0)) /*d2d_mwrite*/\ ++ MUX_VAL(CP(D2D_SWRITE), (IEN | PTD | DIS | M0)) /*d2d_swrite*/\ ++ MUX_VAL(CP(D2D_MREAD), (IEN | PTD | DIS | M0)) /*d2d_mread*/\ ++ MUX_VAL(CP(D2D_SREAD), (IEN | PTD | DIS | M0)) /*d2d_sread*/\ ++ MUX_VAL(CP(D2D_MBUSFLAG), (IEN | PTD | DIS | M0)) /*d2d_mbusflag*/\ ++ MUX_VAL(CP(D2D_SBUSFLAG), (IEN | PTD | DIS | M0)) /*d2d_sbusflag*/\ ++ MUX_VAL(CP(SDRC_CKE0), (IDIS | PTU | EN | M0)) /*sdrc_cke0*/\ ++ MUX_VAL(CP(SDRC_CKE1), (IDIS | PTD | DIS | M7)) /*sdrc_cke1*/\ ++ ++#endif +diff --git a/board/omap3/omap3517evm/u-boot.lds b/board/omap3/omap3517evm/u-boot.lds +new file mode 100644 +index 0000000..69d8ac9 +--- /dev/null ++++ b/board/omap3/omap3517evm/u-boot.lds +@@ -0,0 +1,63 @@ ++/* ++ * January 2004 - Changed to support H4 device ++ * Copyright (c) 2004 Texas Instruments ++ * ++ * (C) Copyright 2002 ++ * Gary Jennejohn, DENX Software Engineering, ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") ++OUTPUT_ARCH(arm) ++ENTRY(_start) ++SECTIONS ++{ ++ . = 0x00000000; ++ ++ . = ALIGN(4); ++ .text : ++ { ++ cpu/arm_cortexa8/start.o (.text) ++ *(.text) ++ } ++ ++ . = ALIGN(4); ++ .rodata : { *(.rodata) } ++ ++ .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } ++ __exidx_start = .; ++ .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } ++ __exidx_end = .; ++ ++ . = ALIGN(4); ++ .data : { *(.data) } ++ ++ . = ALIGN(4); ++ .got : { *(.got) } ++ ++ __u_boot_cmd_start = .; ++ .u_boot_cmd : { *(.u_boot_cmd) } ++ __u_boot_cmd_end = .; ++ ++ . = ALIGN(4); ++ __bss_start = .; ++ .bss : { *(.bss) } ++ _end = .; ++} +diff --git a/cpu/arm_cortexa8/omap3/board.c b/cpu/arm_cortexa8/omap3/board.c +index 7bb3e28..a0c2d05 100644 +--- a/cpu/arm_cortexa8/omap3/board.c ++++ b/cpu/arm_cortexa8/omap3/board.c +@@ -224,7 +224,11 @@ void s_init(void) + per_clocks_enable(); + + if (!in_sdram) ++#ifdef CONFIG_OMAP3_OMAP3517EVM ++ emif4_init(); ++#else + sdrc_init(); ++#endif + } + + /****************************************************************************** +@@ -284,8 +288,12 @@ int dram_init(void) + * memory on CS0. + */ + if ((sysinfo.mtype == DDR_COMBO) || (sysinfo.mtype == DDR_STACKED)) { ++#ifdef CONFIG_OMAP3_OMAP3517EVM ++ emif4_init(); ++#else + do_sdrc_init(CS1, NOT_EARLY); + make_cs1_contiguous(); ++#endif + } + + size0 = get_sdr_cs_size(CS0); +diff --git a/cpu/arm_cortexa8/omap3/clock.c b/cpu/arm_cortexa8/omap3/clock.c +index 8ac31be..a706cd4 100644 +--- a/cpu/arm_cortexa8/omap3/clock.c ++++ b/cpu/arm_cortexa8/omap3/clock.c +@@ -352,6 +352,10 @@ void per_clocks_enable(void) + sr32(&prcm_base->fclken1_core, 13, 1, 0x1); + sr32(&prcm_base->iclken1_core, 13, 1, 0x1); + ++ /* Enable UART2 clocks */ ++ sr32(&prcm_base->fclken1_core, 14, 1, 0x1); ++ sr32(&prcm_base->iclken1_core, 14, 1, 0x1); ++ + /* UART 3 Clocks */ + sr32(&prcm_base->fclken_per, 11, 1, 0x1); + sr32(&prcm_base->iclken_per, 11, 1, 0x1); +diff --git a/cpu/arm_cortexa8/omap3/mem.c b/cpu/arm_cortexa8/omap3/mem.c +index 3cc22c4..1badb34 100644 +--- a/cpu/arm_cortexa8/omap3/mem.c ++++ b/cpu/arm_cortexa8/omap3/mem.c +@@ -31,6 +31,53 @@ + #include + #include + ++/* Definitions for EMIF4 configuration values */ ++#define EMIF4_TIM1_T_RP 0x4 ++#define EMIF4_TIM1_T_RCD 0x4 ++#define EMIF4_TIM1_T_WR 0x2 ++#define EMIF4_TIM1_T_RAS 0x8 ++#define EMIF4_TIM1_T_RC 13 ++#define EMIF4_TIM1_T_RRD 0x2 ++#define EMIF4_TIM1_T_WTR 0x2 ++ ++#define EMIF4_TIM2_T_XP 0x2 ++#define EMIF4_TIM2_T_ODT 0x0 ++#define EMIF4_TIM2_T_XSNR 28 ++#define EMIF4_TIM2_T_XSRD 200 ++#define EMIF4_TIM2_T_RTP 0x2 ++#define EMIF4_TIM2_T_CKE 0x3 ++ ++#define EMIF4_TIM3_T_TDQSCKMAX 0x0 ++#define EMIF4_TIM3_T_RFC 33 ++#define EMIF4_TIM3_T_RAS_MAX 0x7 ++ ++#define EMIF4_PWR_IDLE 0x2 ++#define EMIF4_PWR_DPD_EN 0x0 ++#define EMIF4_PWR_PM_EN 0x0 ++#define EMIF4_PWR_PM_TIM 0x0 ++ ++#define EMIF4_INITREF_DIS 0x0 ++#define EMIF4_PASR 0x0 ++#define EMIF4_REFRESH_RATE 1295 ++ ++#define EMIF4_CFG_SDRAM_TYP 0x2 ++#define EMIF4_CFG_IBANK_POS 0x0 ++#define EMIF4_CFG_DDR_TERM 0x0 ++#define EMIF4_CFG_DDR2_DDQS 0x1 ++#define EMIF4_CFG_DYN_ODT 0x0 ++#define EMIF4_CFG_DDR_DIS_DLL 0x0 ++#define EMIF4_CFG_SDR_DRV 0x0 ++#define EMIF4_CFG_CWL 0x0 ++#define EMIF4_CFG_NARROW_MD 0x0 ++#define EMIF4_CFG_CL 0x3 ++#define EMIF4_CFG_ROWSIZE 0x3 ++#define EMIF4_CFG_IBANK 0x3 ++#define EMIF4_CFG_EBANK 0x0 ++#define EMIF4_CFG_PGSIZE 0x2 ++ ++#define EMIF4_DDR1_READ_LAT 0x3 ++#define EMIF4_DDR1_VTP_DYN 0x1 ++ + /* + * Only One NAND allowed on board at a time. + * The GPMC CS Base for the same +@@ -83,6 +130,7 @@ gpmc_csx_t *onenand_cs_base; + #endif + + static sdrc_t *sdrc_base = (sdrc_t *)OMAP34XX_SDRC_BASE; ++static emif4_t *emif4_base = (emif4_t *)OMAP34XX_SDRC_BASE; + + /************************************************************************** + * make_cs1_contiguous() - for es2 and above remap cs1 behind cs0 to allow +@@ -195,6 +243,68 @@ void do_sdrc_init(u32 cs, u32 early) + writel(0, &sdrc_base->cs[cs].mcfg); + } + ++/******************************************************** ++ * emif4 _init() - init the emif4 module for DDR access ++ * - early init routines, called from flash or ++ * SRAM. ++ *******************************************************/ ++void emif4_init(void) ++{ ++ unsigned int regval; ++ /* Set the DDR PHY parameters in PHY ctrl registers */ ++ regval = (EMIF4_DDR1_READ_LAT | (EMIF4_DDR1_VTP_DYN << 15)); ++ writel(regval, &emif4_base->ddr_phyctrl1); ++ writel(regval, &emif4_base->ddr_phyctrl1_shdw); ++ writel(0, &emif4_base->ddr_phyctrl2); ++ ++ /* Reset the DDR PHY and wait till completed */ ++ regval = readl(&emif4_base->sdram_iodft_tlgc); ++ regval |= (1<<10); ++ writel(regval, &emif4_base->sdram_iodft_tlgc); ++ while ((readl(&emif4_base->sdram_sts) & (1<<10)) == 0x0); ++ ++ /* Set SDR timing registers */ ++ regval = (EMIF4_TIM1_T_WTR | (EMIF4_TIM1_T_RRD << 3) | ++ (EMIF4_TIM1_T_RC << 6) | (EMIF4_TIM1_T_RAS << 12) | ++ (EMIF4_TIM1_T_WR << 17) | (EMIF4_TIM1_T_RCD << 21) | ++ (EMIF4_TIM1_T_RP << 25)); ++ writel(regval, &emif4_base->sdram_time1); ++ writel(regval, &emif4_base->sdram_time1_shdw); ++ ++ regval = (EMIF4_TIM2_T_CKE | (EMIF4_TIM2_T_RTP << 3) | ++ (EMIF4_TIM2_T_XSRD << 6) | (EMIF4_TIM2_T_XSNR << 16) | ++ (EMIF4_TIM2_T_ODT << 25) | (EMIF4_TIM2_T_XP << 28)); ++ writel(regval, &emif4_base->sdram_time2); ++ writel(regval, &emif4_base->sdram_time2_shdw); ++ ++ regval = (EMIF4_TIM3_T_RAS_MAX | (EMIF4_TIM3_T_RFC << 4) | ++ (EMIF4_TIM3_T_TDQSCKMAX << 13)); ++ writel(regval, &emif4_base->sdram_time3); ++ writel(regval, &emif4_base->sdram_time3_shdw); ++ ++ /* Set the PWR control register */ ++ regval = (EMIF4_PWR_PM_TIM | (EMIF4_PWR_PM_EN << 8) | ++ (EMIF4_PWR_DPD_EN << 10) | (EMIF4_PWR_IDLE << 30)); ++ writel(regval, &emif4_base->sdram_pwr_mgmt); ++ writel(regval, &emif4_base->sdram_pwr_mgmt_shdw); ++ ++ /* Set the DDR refresh rate control register */ ++ regval = (EMIF4_REFRESH_RATE | (EMIF4_PASR << 24) | ++ (EMIF4_INITREF_DIS << 31)); ++ writel(regval, &emif4_base->sdram_refresh_ctrl); ++ writel(regval, &emif4_base->sdram_refresh_ctrl_shdw); ++ ++ /* set the SDRAM configuration register */ ++ regval = (EMIF4_CFG_PGSIZE | (EMIF4_CFG_EBANK << 3) | ++ (EMIF4_CFG_IBANK << 4) | (EMIF4_CFG_ROWSIZE << 7) | ++ (EMIF4_CFG_CL << 10) | (EMIF4_CFG_NARROW_MD << 14) | ++ (EMIF4_CFG_CWL << 16) | (EMIF4_CFG_SDR_DRV << 18) | ++ (EMIF4_CFG_DDR_DIS_DLL << 20) | (EMIF4_CFG_DYN_ODT << 21) | ++ (EMIF4_CFG_DDR2_DDQS << 23) | (EMIF4_CFG_DDR_TERM << 24) | ++ (EMIF4_CFG_IBANK_POS << 27) | (EMIF4_CFG_SDRAM_TYP << 29)); ++ writel(regval, &emif4_base->sdram_config); ++} ++ + void enable_gpmc_config(u32 *gpmc_config, gpmc_csx_t *gpmc_cs_base, u32 base, + u32 size) + { +diff --git a/drivers/net/Makefile b/drivers/net/Makefile +index a360a50..3d803f4 100644 +--- a/drivers/net/Makefile ++++ b/drivers/net/Makefile +@@ -70,6 +70,7 @@ COBJS-$(CONFIG_ULI526X) += uli526x.o + COBJS-$(CONFIG_VSC7385_ENET) += vsc7385.o + COBJS-$(CONFIG_XILINX_EMAC) += xilinx_emac.o + COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o ++COBJS-$(CONFIG_TICPGMAC) += ticpgmac.o + + COBJS := $(COBJS-y) + SRCS := $(COBJS:.o=.c) +diff --git a/drivers/net/ticpgmac.c b/drivers/net/ticpgmac.c +new file mode 100644 +index 0000000..e83b951 +--- /dev/null ++++ b/drivers/net/ticpgmac.c +@@ -0,0 +1,693 @@ ++/* ++ * Ethernet driver for OMAP3 OMAP3517EVM chip. ++ * ++ * Copyright (C) 2007 Sergey Kubushyn ++ * ++ * Parts shamelessly stolen from TI's dm644x_emac.c. Original copyright ++ * follows: ++ * ++ * ---------------------------------------------------------------------------- ++ * Derived from - ++ * dm644x_emac.c ++ * ++ * TI DaVinci (DM644X) EMAC peripheral driver source for DV-EVM ++ * ++ * Copyright (C) 2005 Texas Instruments. ++ * ++ * ---------------------------------------------------------------------------- ++ * ++ * 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. ++ * ---------------------------------------------------------------------------- ++ ++ * Modifications: ++ * ver. 1.0: Sep 2005, Anant Gole - Created EMAC version for uBoot. ++ * ver 1.1: Nov 2005, Anant Gole - Extended the RX logic for multiple descriptors ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_DRIVER_TI_EMAC ++ ++#ifdef CONFIG_CMD_NET ++ ++unsigned int emac_dbg = 0; ++#define debug_emac(fmt,args...) if (emac_dbg) printf(fmt,##args) ++ ++/* Internal static functions */ ++static int cpgmac_eth_hw_init (void); ++static int cpgmac_eth_open (void); ++static int cpgmac_eth_close (void); ++static int cpgmac_eth_send_packet (volatile void *packet, int length); ++static int cpgmac_eth_rcv_packet (void); ++static void cpgmac_eth_mdio_enable(void); ++ ++static int gen_init_phy(int phy_addr); ++static int gen_is_phy_connected(int phy_addr); ++static int gen_get_link_status(int phy_addr); ++static int gen_auto_negotiate(int phy_addr); ++ ++/* Wrappers exported to the U-Boot proper */ ++int eth_hw_init(void) ++{ ++ return(cpgmac_eth_hw_init()); ++} ++ ++int eth_init(bd_t * bd) ++{ ++ return(cpgmac_eth_open()); ++} ++ ++void eth_halt(void) ++{ ++ cpgmac_eth_close(); ++} ++ ++int eth_send(volatile void *packet, int length) ++{ ++ return(cpgmac_eth_send_packet(packet, length)); ++} ++ ++int eth_rx(void) ++{ ++ return(cpgmac_eth_rcv_packet()); ++} ++ ++void eth_mdio_enable(void) ++{ ++ cpgmac_eth_mdio_enable(); ++} ++/* End of wrappers */ ++ ++/* cpgmac_eth_mac_addr[0] goes out on the wire first */ ++ ++static u_int8_t cpgmac_eth_mac_addr[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0x00 }; ++ ++/* ++ * This function must be called before emac_open() if you want to override ++ * the default mac address. ++ */ ++void cpgmac_eth_set_mac_addr(const u_int8_t *addr) ++{ ++ int i; ++ ++ for (i = 0; i < sizeof (cpgmac_eth_mac_addr); i++) { ++ cpgmac_eth_mac_addr[i] = addr[i]; ++ } ++} ++ ++/* EMAC Addresses */ ++static volatile emac_regs *adap_emac = (emac_regs *)EMAC_BASE_ADDR; ++static volatile ewrap_regs *adap_ewrap = (ewrap_regs *)EMAC_WRAPPER_BASE_ADDR; ++static volatile mdio_regs *adap_mdio = (mdio_regs *)EMAC_MDIO_BASE_ADDR; ++ ++/* EMAC descriptors */ ++static volatile emac_desc *emac_rx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE); ++static volatile emac_desc *emac_tx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE); ++static volatile emac_desc *emac_rx_active_head = 0; ++static volatile emac_desc *emac_rx_active_tail = 0; ++static int emac_rx_queue_active = 0; ++ ++/* Receive packet buffers */ ++static unsigned char emac_rx_buffers[EMAC_MAX_RX_BUFFERS * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)]; ++ ++/* PHY address for a discovered PHY (0xff - not found) */ ++static volatile u_int8_t active_phy_addr = 0xff; ++ ++static int no_phy_init (int phy_addr) { return(1); } ++static int no_phy_is_connected (int phy_addr) { return(1); } ++static int no_phy_get_link_status (int phy_addr) ++{ ++ adap_emac->MACCONTROL = (EMAC_MACCONTROL_MIIEN_ENABLE ++ | EMAC_MACCONTROL_FULLDUPLEX_ENABLE); ++#ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII ++ adap_emac->MACCONTROL |= EMAC_MACCONTROL_RMIISPEED_100; ++#endif ++ return 1; ++} ++static int no_phy_auto_negotiate (int phy_addr) { return(1); } ++phy_t phy = { ++ .init = no_phy_init, ++ .is_phy_connected = no_phy_is_connected, ++ .get_link_status = no_phy_get_link_status, ++ .auto_negotiate = no_phy_auto_negotiate ++}; ++ ++static void cpgmac_eth_mdio_enable(void) ++{ ++ u_int32_t clkdiv; ++ ++ clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1; ++ ++ adap_mdio->CONTROL = (clkdiv & 0xff) | ++ MDIO_CONTROL_ENABLE | ++ MDIO_CONTROL_FAULT | ++ MDIO_CONTROL_FAULT_ENABLE; ++ ++ while (adap_mdio->CONTROL & MDIO_CONTROL_IDLE) {;} ++} ++ ++/* ++ * Tries to find an active connected PHY. Returns 1 if address if found. ++ * If no active PHY found returns 0. If more than one active PHY (switch) ++ * returns 2 ++ * Sets active_phy_addr variable when returns 1. ++ */ ++static int cpgmac_eth_phy_detect(void) ++{ ++ u_int32_t phy_act_state; ++ int i; ++ ++ active_phy_addr = 0xff; ++ ++ if ((phy_act_state = adap_mdio->ALIVE) == 0) ++ return(0); /* No active PHYs */ ++ ++ debug_emac("cpgmac_eth_phy_detect(), ALIVE = 0x%08x\n", phy_act_state); ++ ++ for (i = 0; i < 32; i++) { ++ if (phy_act_state & (1 << i)) { ++ if (phy_act_state & ~(1 << i)) ++ return(2); /* More than one PHY */ ++ else { ++ active_phy_addr = i; ++ return(1); ++ } ++ } ++ } ++ ++ return(0); /* Just to make GCC happy */ ++} ++ ++ ++/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */ ++int cpgmac_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data) ++{ ++ int tmp; ++ ++ while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;} ++ ++ adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO | ++ MDIO_USERACCESS0_WRITE_READ | ++ ((reg_num & 0x1f) << 21) | ++ ((phy_addr & 0x1f) << 16); ++ ++ /* Wait for command to complete */ ++ while ((tmp = adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO) {;} ++ ++ if (tmp & MDIO_USERACCESS0_ACK) { ++ *data = tmp & 0xffff; ++ return(1); ++ } ++ ++ *data = -1; ++ return(0); ++} ++ ++/* Write to a PHY register via MDIO inteface. Blocks until operation is complete. */ ++int cpgmac_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data) ++{ ++ ++ while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;} ++ ++ adap_mdio->USERACCESS0 = MDIO_USERACCESS0_GO | ++ MDIO_USERACCESS0_WRITE_WRITE | ++ ((reg_num & 0x1f) << 21) | ++ ((phy_addr & 0x1f) << 16) | ++ (data & 0xffff); ++ ++ /* Wait for command to complete */ ++ while (adap_mdio->USERACCESS0 & MDIO_USERACCESS0_GO) {;} ++ ++ return(1); ++} ++ ++/* PHY functions for a generic PHY */ ++static int gen_init_phy(int phy_addr) ++{ ++ int ret = 1; ++ ++ if (gen_get_link_status(phy_addr)) { ++ /* Try another time */ ++ ret = gen_get_link_status(phy_addr); ++ } ++ ++ return(ret); ++} ++ ++static int gen_is_phy_connected(int phy_addr) ++{ ++ u_int16_t dummy; ++ ++ return(cpgmac_eth_phy_read(phy_addr, PHY_PHYIDR1, &dummy)); ++} ++ ++static int gen_get_link_status(int phy_addr) ++{ ++ u_int16_t tmp; ++ ++ if (cpgmac_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp) ++ && (tmp & 0x04)) { ++ ++ /* Speed doesn't matter, there is no setting for it in EMAC. */ ++ if (tmp & GEN_PHY_STATUS_FD_MASK) { ++ /* set EMAC for Full Duplex */ ++ adap_emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | ++ EMAC_MACCONTROL_FULLDUPLEX_ENABLE; ++ } else { ++ /*set EMAC for Half Duplex */ ++ adap_emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE; ++ } ++ ++#ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII ++ if(tmp & GEN_PHY_STATUS_SPEED100_MASK) { ++ adap_emac->MACCONTROL |= EMAC_MACCONTROL_RMIISPEED_100; ++ } else { ++ adap_emac->MACCONTROL &= ~EMAC_MACCONTROL_RMIISPEED_100; ++ } ++#endif ++ ++ return(1); ++ } ++ ++ return(0); ++} ++ ++static int gen_auto_negotiate(int phy_addr) ++{ ++ u_int16_t tmp; ++ ++ if (!cpgmac_eth_phy_read(phy_addr, PHY_BMCR, &tmp)) ++ return(0); ++ ++ /* Restart Auto_negotiation */ ++ tmp |= PHY_BMCR_AUTON; ++ cpgmac_eth_phy_write(phy_addr, PHY_BMCR, tmp); ++ ++ /*check AutoNegotiate complete */ ++ udelay (10000); ++ if (!cpgmac_eth_phy_read(phy_addr, PHY_BMSR, &tmp)) ++ return(0); ++ ++ if (!(tmp & PHY_BMSR_AUTN_COMP)) ++ return(0); ++ ++ return(gen_get_link_status(phy_addr)); ++} ++/* End of generic PHY functions */ ++ ++ ++#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) ++static int cpgmac_mii_phy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value) ++{ ++ return(cpgmac_eth_phy_read(addr, reg, value) ? 0 : 1); ++} ++ ++static int cpgmac_mii_phy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value) ++{ ++ return(cpgmac_eth_phy_write(addr, reg, value) ? 0 : 1); ++} ++ ++int cpgmac_eth_miiphy_initialize(bd_t *bis) ++{ ++ miiphy_register(phy.name, cpgmac_mii_phy_read, cpgmac_mii_phy_write); ++ ++ return(1); ++} ++#endif ++ ++/* ++ * This function initializes the emac hardware. It does NOT initialize ++ * EMAC modules power or pin multiplexors, that is done by board_init() ++ * much earlier in bootup process. Returns 1 on success, 0 otherwise. ++ */ ++static int cpgmac_eth_hw_init(void) ++{ ++ u_int32_t phy_id; ++ u_int16_t tmp; ++ int i, ret; ++ ++ cpgmac_eth_mdio_enable(); ++ ++ for (i = 0; i < 256; i++) { ++ if (adap_mdio->ALIVE) ++ break; ++ udelay(1000); ++ } ++ ++ if (i >= 256) { ++ printf("No ETH PHY detected!!!\n"); ++ return(0); ++ } ++ ++ /* Find if a PHY is connected and get it's address */ ++ ret = cpgmac_eth_phy_detect(); ++ ++ if (ret == 2) { ++ printf("More than one PHY detected.\n"); ++ return(1); ++ } else if(ret == 0) ++ return(0); ++ ++ /* Get PHY ID and initialize phy_ops for a detected PHY */ ++ if (!cpgmac_eth_phy_read(active_phy_addr, PHY_PHYIDR1, &tmp)) { ++ active_phy_addr = 0xff; ++ return(0); ++ } ++ ++ phy_id = (tmp << 16) & 0xffff0000; ++ ++ if (!cpgmac_eth_phy_read(active_phy_addr, PHY_PHYIDR2, &tmp)) { ++ active_phy_addr = 0xff; ++ return(0); ++ } ++ ++ phy_id |= tmp & 0x0000ffff; ++ ++ switch (phy_id) { ++ default: ++ sprintf(phy.name, "GENERIC @ 0x%02x", active_phy_addr); ++ phy.init = gen_init_phy; ++ phy.is_phy_connected = gen_is_phy_connected; ++ phy.get_link_status = gen_get_link_status; ++ phy.auto_negotiate = gen_auto_negotiate; ++ } ++ ++ printf("Ethernet PHY: %s\n", phy.name); ++ ++ return(1); ++} ++ ++ ++/* Eth device open */ ++static int cpgmac_eth_open(void) ++{ ++ dv_reg_p addr; ++ u_int32_t clkdiv, cnt; ++ volatile emac_desc *rx_desc; ++ int i; ++ ++ debug_emac("+ emac_open\n"); ++ ++ /* Reset EMAC module and disable interrupts in wrapper */ ++ adap_emac->EMACSOFTRESET = 1; ++ while (adap_emac->EMACSOFTRESET != 0) {;} ++ adap_ewrap->EMACSOFTRESET = 1; ++ while (adap_ewrap->EMACSOFTRESET != 0) {;} ++ ++ adap_ewrap->C0RXEN = adap_ewrap->C1RXEN = adap_ewrap->C2RXEN = 0; ++ adap_ewrap->C0TXEN = adap_ewrap->C1TXEN = adap_ewrap->C2TXEN = 0; ++ adap_ewrap->C0MISCEN = adap_ewrap->C1MISCEN = adap_ewrap->C2MISCEN = 0; ++ ++ rx_desc = emac_rx_desc; ++ ++ adap_emac->TXCONTROL = 0x01; ++ adap_emac->RXCONTROL = 0x01; ++ ++ /* Set MAC Addresses & Init multicast Hash to 0 (disable any multicast receive) */ ++ /* Using channel 0 only - other channels are disabled */ ++ for (i = 0; i < 8; i++) { ++ adap_emac->MACINDEX = i; ++ adap_emac->MACADDRHI = ++ (cpgmac_eth_mac_addr[3] << 24) | /* bits 23-16 */ ++ (cpgmac_eth_mac_addr[2] << 16) | /* bits 31-24 */ ++ (cpgmac_eth_mac_addr[1] << 8) | /* bits 39-32 */ ++ (cpgmac_eth_mac_addr[0]); /* bits 47-40 */ ++ adap_emac->MACADDRLO = ++ (cpgmac_eth_mac_addr[5] << 8) | /* bits 8-0*/ ++ (cpgmac_eth_mac_addr[4]) | (1 << 19) | (1 << 20); /* bits 8-0 */ ++ } ++ ++ adap_emac->MACHASH1 = 0; ++ adap_emac->MACHASH2 = 0; ++ ++ /* Set source MAC address - REQUIRED for pause frames */ ++ adap_emac->MACSRCADDRHI = ++ (cpgmac_eth_mac_addr[3] << 24) | /* bits 23-16 */ ++ (cpgmac_eth_mac_addr[2] << 16) | /* bits 31-24 */ ++ (cpgmac_eth_mac_addr[1] << 8) | /* bits 39-32 */ ++ (cpgmac_eth_mac_addr[0]); /* bits 47-40 */ ++ adap_emac->MACSRCADDRLO = ++ (cpgmac_eth_mac_addr[5] << 8) | /* bits 8-0 */ ++ (cpgmac_eth_mac_addr[4]); /* bits 15-8 */ ++ ++ /* Set DMA 8 TX / 8 RX Head pointers to 0 */ ++ addr = &adap_emac->TX0HDP; ++ for(cnt = 0; cnt < 16; cnt++) ++ *addr++ = 0; ++ ++ addr = &adap_emac->RX0HDP; ++ for(cnt = 0; cnt < 16; cnt++) ++ *addr++ = 0; ++ ++ /* Clear Statistics (do this before setting MacControl register) */ ++ addr = &adap_emac->RXGOODFRAMES; ++ for(cnt = 0; cnt < EMAC_NUM_STATS; cnt++) ++ *addr++ = 0; ++ ++ /* No multicast addressing */ ++ adap_emac->MACHASH1 = 0; ++ adap_emac->MACHASH2 = 0; ++ ++ /* Create RX queue and set receive process in place */ ++ emac_rx_active_head = emac_rx_desc; ++ for (cnt = 0; cnt < EMAC_MAX_RX_BUFFERS; cnt++) { ++ rx_desc->next = (u_int32_t)(rx_desc + 1); ++ rx_desc->buffer = &emac_rx_buffers[cnt * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)]; ++ rx_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE; ++ rx_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT; ++ rx_desc++; ++ } ++ ++ /* Set the last descriptor's "next" parameter to 0 to end the RX desc list */ ++ rx_desc--; ++ rx_desc->next = 0; ++ emac_rx_active_tail = rx_desc; ++ emac_rx_queue_active = 1; ++ ++ /* Enable TX/RX */ ++ adap_emac->RXMAXLEN = EMAC_MAX_ETHERNET_PKT_SIZE; ++ adap_emac->RXBUFFEROFFSET = 0; ++ ++ /* No fancy configs - Use this for promiscous for debug - EMAC_RXMBPENABLE_RXCAFEN_ENABLE */ ++ adap_emac->RXMBPENABLE = EMAC_RXMBPENABLE_RXBROADEN; ++ ++ /* Enable ch 0 only */ ++ adap_emac->RXUNICASTSET = 0x01; ++ ++ /* Enable MII interface and Full duplex mode */ ++ ++ /* Init MDIO & get link state */ ++ clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1; ++ adap_mdio->CONTROL = ((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT); ++ ++ if (!phy.get_link_status(active_phy_addr)) ++ return(0); ++ ++ /* Start receive process */ ++ adap_emac->RX0HDP = (u_int32_t)emac_rx_desc; ++ ++ debug_emac("- emac_open\n"); ++ ++ return(1); ++} ++ ++/* EMAC Channel Teardown */ ++static void cpgmac_eth_ch_teardown(int ch) ++{ ++ dv_reg dly = 0xff; ++ dv_reg cnt; ++ ++ debug_emac("+ emac_ch_teardown\n"); ++ ++ if (ch == EMAC_CH_TX) { ++ /* Init TX channel teardown */ ++ adap_emac->TXTEARDOWN = 1; ++ for(cnt = 0; cnt != 0xfffffffc; cnt = adap_emac->TX0CP) { ++ /* Wait here for Tx teardown completion interrupt to occur ++ * Note: A task delay can be called here to pend rather than ++ * occupying CPU cycles - anyway it has been found that teardown ++ * takes very few cpu cycles and does not affect functionality */ ++ dly--; ++ udelay(1); ++ if (dly == 0) ++ break; ++ } ++ adap_emac->TX0CP = cnt; ++ adap_emac->TX0HDP = 0; ++ } else { ++ /* Init RX channel teardown */ ++ adap_emac->RXTEARDOWN = 1; ++ for(cnt = 0; cnt != 0xfffffffc; cnt = adap_emac->RX0CP) { ++ /* Wait here for Rx teardown completion interrupt to occur ++ * Note: A task delay can be called here to pend rather than ++ * occupying CPU cycles - anyway it has been found that teardown ++ * takes very few cpu cycles and does not affect functionality */ ++ dly--; ++ udelay(1); ++ if (dly == 0) ++ break; ++ } ++ adap_emac->RX0CP = cnt; ++ adap_emac->RX0HDP = 0; ++ } ++ ++ debug_emac("- emac_ch_teardown\n"); ++} ++ ++/* Eth device close */ ++static int cpgmac_eth_close(void) ++{ ++ debug_emac("+ emac_close\n"); ++ ++ cpgmac_eth_ch_teardown(EMAC_CH_TX); /* TX Channel teardown */ ++ cpgmac_eth_ch_teardown(EMAC_CH_RX); /* RX Channel teardown */ ++ ++ /* Reset EMAC module and disable interrupts in wrapper */ ++ adap_emac->EMACSOFTRESET = 1; ++ adap_ewrap->EMACSOFTRESET = 1; ++ ++ adap_ewrap->C0RXEN = adap_ewrap->C1RXEN = adap_ewrap->C2RXEN = 0; ++ adap_ewrap->C0TXEN = adap_ewrap->C1TXEN = adap_ewrap->C2TXEN = 0; ++ adap_ewrap->C0MISCEN = adap_ewrap->C1MISCEN = adap_ewrap->C2MISCEN = 0; ++ ++ debug_emac("- emac_close\n"); ++ return(1); ++} ++ ++static int tx_send_loop = 0; ++ ++/* ++ * This function sends a single packet on the network and returns ++ * positive number (number of bytes transmitted) or negative for error ++ */ ++static int cpgmac_eth_send_packet (volatile void *packet, int length) ++{ ++ int ret_status = -1; ++ tx_send_loop = 0; ++ ++ /* Return error if no link */ ++ if (!phy.get_link_status (active_phy_addr)) { ++ printf ("WARN: emac_send_packet: No link\n"); ++ return (ret_status); ++ } ++ ++ /* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */ ++ if (length < EMAC_MIN_ETHERNET_PKT_SIZE) { ++ length = EMAC_MIN_ETHERNET_PKT_SIZE; ++ } ++ ++ /* Populate the TX descriptor */ ++ emac_tx_desc->next = 0; ++ emac_tx_desc->buffer = (u_int8_t *) packet; ++ emac_tx_desc->buff_off_len = (length & 0xffff); ++ emac_tx_desc->pkt_flag_len = ((length & 0xffff) | ++ EMAC_CPPI_SOP_BIT | ++ EMAC_CPPI_OWNERSHIP_BIT | ++ EMAC_CPPI_EOP_BIT); ++ /* Send the packet */ ++ adap_emac->TX0HDP = (unsigned int) emac_tx_desc; ++ ++ /* Wait for packet to complete or link down */ ++ while (1) { ++ if (!phy.get_link_status (active_phy_addr)) { ++ cpgmac_eth_ch_teardown (EMAC_CH_TX); ++ return (ret_status); ++ } ++ if (adap_emac->TXINTSTATRAW & 0x01) { ++ ret_status = length; ++ break; ++ } ++ tx_send_loop++; ++ } ++ ++ return (ret_status); ++} ++ ++/* ++ * This function handles receipt of a packet from the network ++ */ ++static int cpgmac_eth_rcv_packet (void) ++{ ++ volatile emac_desc *rx_curr_desc; ++ volatile emac_desc *curr_desc; ++ volatile emac_desc *tail_desc; ++ int status, ret = -1; ++ ++ rx_curr_desc = emac_rx_active_head; ++ status = rx_curr_desc->pkt_flag_len; ++ if ((rx_curr_desc) && ((status & EMAC_CPPI_OWNERSHIP_BIT) == 0)) { ++ if (status & EMAC_CPPI_RX_ERROR_FRAME) { ++ /* Error in packet - discard it and requeue desc */ ++ printf ("WARN: emac_rcv_pkt: Error in packet\n"); ++ } else { ++ NetReceive (rx_curr_desc->buffer, ++ (rx_curr_desc->buff_off_len & 0xffff)); ++ ret = rx_curr_desc->buff_off_len & 0xffff; ++ } ++ ++ /* Ack received packet descriptor */ ++ adap_emac->RX0CP = (unsigned int) rx_curr_desc; ++ curr_desc = rx_curr_desc; ++ emac_rx_active_head = ++ (volatile emac_desc *) rx_curr_desc->next; ++ ++ if (status & EMAC_CPPI_EOQ_BIT) { ++ if (emac_rx_active_head) { ++ adap_emac->RX0HDP = ++ (unsigned int) emac_rx_active_head; ++ } else { ++ emac_rx_queue_active = 0; ++ printf ("INFO:emac_rcv_packet: RX Queue not active\n"); ++ } ++ } ++ ++ /* Recycle RX descriptor */ ++ rx_curr_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE; ++ rx_curr_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT; ++ rx_curr_desc->next = 0; ++ ++ if (emac_rx_active_head == 0) { ++ printf ("INFO: emac_rcv_pkt: active queue head = 0\n"); ++ emac_rx_active_head = curr_desc; ++ emac_rx_active_tail = curr_desc; ++ if (emac_rx_queue_active != 0) { ++ adap_emac->RX0HDP = ++ (unsigned int) emac_rx_active_head; ++ printf ("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n"); ++ emac_rx_queue_active = 1; ++ } ++ } else { ++ tail_desc = emac_rx_active_tail; ++ emac_rx_active_tail = curr_desc; ++ tail_desc->next = (unsigned int) curr_desc; ++ status = tail_desc->pkt_flag_len; ++ if (status & EMAC_CPPI_EOQ_BIT) { ++ adap_emac->RX0HDP = (unsigned int) curr_desc; ++ status &= ~EMAC_CPPI_EOQ_BIT; ++ tail_desc->pkt_flag_len = status; ++ } ++ } ++ return (ret); ++ } ++ return (0); ++} ++ ++#endif /* CONFIG_CMD_NET */ ++ ++#endif /* CONFIG_DRIVER_TI_EMAC */ +diff --git a/include/asm-arm/arch-omap3/cpu.h b/include/asm-arm/arch-omap3/cpu.h +index c544e0c..989b1c3 100644 +--- a/include/asm-arm/arch-omap3/cpu.h ++++ b/include/asm-arm/arch-omap3/cpu.h +@@ -203,6 +203,32 @@ typedef struct sdrc { + } sdrc_t; + #endif /* __ASSEMBLY__ */ + ++/* EMIF4 */ ++#ifndef __ASSEMBLY__ ++typedef struct emif4 { ++ unsigned int sdram_sts; ++ unsigned int sdram_config; ++ unsigned int res1; ++ unsigned int sdram_refresh_ctrl; ++ unsigned int sdram_refresh_ctrl_shdw; ++ unsigned int sdram_time1; ++ unsigned int sdram_time1_shdw; ++ unsigned int sdram_time2; ++ unsigned int sdram_time2_shdw; ++ unsigned int sdram_time3; ++ unsigned int sdram_time3_shdw; ++ unsigned char res2[8]; ++ unsigned int sdram_pwr_mgmt; ++ unsigned int sdram_pwr_mgmt_shdw; ++ unsigned char res3[32]; ++ unsigned int sdram_iodft_tlgc; ++ unsigned char res4[128]; ++ unsigned int ddr_phyctrl1; ++ unsigned int ddr_phyctrl1_shdw; ++ unsigned int ddr_phyctrl2; ++} emif4_t; ++#endif /* __ASSEMBLY__ */ ++ + #define DLLPHASE_90 (0x1 << 1) + #define LOADDLL (0x1 << 2) + #define ENADLL (0x1 << 3) +diff --git a/include/asm-arm/arch-omap3/mux.h b/include/asm-arm/arch-omap3/mux.h +index 0c01c73..5a241cb 100644 +--- a/include/asm-arm/arch-omap3/mux.h ++++ b/include/asm-arm/arch-omap3/mux.h +@@ -337,6 +337,8 @@ + #define CONTROL_PADCONF_ETK_D14_ES2 0x05F8 + #define CONTROL_PADCONF_ETK_D15_ES2 0x05FA + /*Die to Die */ ++#ifndef CONFIG_OMAP3_OMAP3517EVM ++ + #define CONTROL_PADCONF_D2D_MCAD0 0x01E4 + #define CONTROL_PADCONF_D2D_MCAD1 0x01E6 + #define CONTROL_PADCONF_D2D_MCAD2 0x01E8 +@@ -371,6 +373,45 @@ + #define CONTROL_PADCONF_D2D_MCAD31 0x0222 + #define CONTROL_PADCONF_D2D_MCAD32 0x0224 + #define CONTROL_PADCONF_D2D_MCAD33 0x0226 ++ ++#else ++ ++#define CONTROL_PADCONF_CCDC_PCLK 0x01E4 ++#define CONTROL_PADCONF_CCDC_FIELD 0x01E6 ++#define CONTROL_PADCONF_CCDC_HD 0x01E8 ++#define CONTROL_PADCONF_CCDC_VD 0x01EA ++#define CONTROL_PADCONF_CCDC_WEN 0x01EC ++#define CONTROL_PADCONF_CCDC_DATA0 0x01EE ++#define CONTROL_PADCONF_CCDC_DATA1 0x01F0 ++#define CONTROL_PADCONF_CCDC_DATA2 0x01F2 ++#define CONTROL_PADCONF_CCDC_DATA3 0x01F4 ++#define CONTROL_PADCONF_CCDC_DATA4 0x01F6 ++#define CONTROL_PADCONF_CCDC_DATA5 0x01F8 ++#define CONTROL_PADCONF_CCDC_DATA6 0x01FA ++#define CONTROL_PADCONF_CCDC_DATA7 0x01FC ++#define CONTROL_PADCONF_RMII_MDIO_DATA 0x01FE ++#define CONTROL_PADCONF_RMII_MDIO_CLK 0x0200 ++#define CONTROL_PADCONF_RMII_RXD0 0x0202 ++#define CONTROL_PADCONF_RMII_RXD1 0x0204 ++#define CONTROL_PADCONF_RMII_CRS_DV 0x0206 ++#define CONTROL_PADCONF_RMII_RXER 0x0208 ++#define CONTROL_PADCONF_RMII_TXD0 0x020A ++#define CONTROL_PADCONF_RMII_TXD1 0x020C ++#define CONTROL_PADCONF_RMII_TXEN 0x020E ++#define CONTROL_PADCONF_RMII_50MHZ_CLK 0x0210 ++#define CONTROL_PADCONF_USB0_DRVBUS 0x0212 ++#define CONTROL_PADCONF_HECCL_TXD 0x0214 ++#define CONTROL_PADCONF_HECCL_RXD 0x0216 ++#define CONTROL_PADCONF_SYS_BOOT7 0x0218 ++#define CONTROL_PADCONF_SDRC_DQS0N 0x021A ++#define CONTROL_PADCONF_SDRC_DQS1N 0x021C ++#define CONTROL_PADCONF_SDRC_DQS2N 0x021E ++#define CONTROL_PADCONF_SDRC_DQS3N 0x0220 ++#define CONTROL_PADCONF_STRBEN_DLY0 0x0222 ++#define CONTROL_PADCONF_STRBEN_DLY1 0x0224 ++#define CONTROL_PADCONF_SYS_BOOT8 0x0226 ++#endif ++ + #define CONTROL_PADCONF_D2D_MCAD34 0x0228 + #define CONTROL_PADCONF_D2D_MCAD35 0x022A + #define CONTROL_PADCONF_D2D_MCAD36 0x022C +diff --git a/include/asm-arm/arch-omap3/sys_proto.h b/include/asm-arm/arch-omap3/sys_proto.h +index 8b554bb..3efff62 100644 +--- a/include/asm-arm/arch-omap3/sys_proto.h ++++ b/include/asm-arm/arch-omap3/sys_proto.h +@@ -36,6 +36,7 @@ void memif_init(void); + void sdrc_init(void); + void do_sdrc_init(u32, u32); + void gpmc_init(void); ++void emif4_init(void); + + void watchdog_init(void); + void set_muxconf_regs(void); +diff --git a/include/asm-arm/arch-omap3/ticpgmac.h b/include/asm-arm/arch-omap3/ticpgmac.h +new file mode 100644 +index 0000000..d7d77c9 +--- /dev/null ++++ b/include/asm-arm/arch-omap3/ticpgmac.h +@@ -0,0 +1,340 @@ ++/* ++ * Copyright (C) 2007 Sergey Kubushyn ++ * ++ * Based on: ++ * ++ * ---------------------------------------------------------------------------- ++ * ++ * dm644x_emac.h ++ * ++ * TI DaVinci (DM644X) EMAC peripheral driver header for DV-EVM ++ * ++ * Copyright (C) 2005 Texas Instruments. ++ * ++ * ---------------------------------------------------------------------------- ++ * ++ * 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. ++ * ---------------------------------------------------------------------------- ++ ++ * Modifications: ++ * ver. 1.0: Sep 2005, TI PSP Team - Created EMAC version for uBoot. ++ * ++ */ ++ ++#ifndef _TI_CPGMAC_H_ ++#define _TI_CPGMAC_H_ ++ ++#define DAVINCI_EMAC_CNTRL_REGS_BASE 0 ++#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE 0 ++#define DAVINCI_EMAC_WRAPPER_RAM_BASE 0 ++ ++#define EMAC_BASE_ADDR DAVINCI_EMAC_CNTRL_REGS_BASE ++#define EMAC_WRAPPER_BASE_ADDR DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE ++#define EMAC_WRAPPER_RAM_ADDR DAVINCI_EMAC_WRAPPER_RAM_BASE ++#define EMAC_MDIO_BASE_ADDR 0x5C030000 ++ ++/* MDIO module input frequency */ ++#define EMAC_MDIO_BUS_FREQ 26000000 /* 26 MHZ check */ ++ ++/* MDIO clock output frequency */ ++#define EMAC_MDIO_CLOCK_FREQ 2000000 /* 2.0 MHz */ ++ ++/* Ethernet Min/Max packet size */ ++#define EMAC_MIN_ETHERNET_PKT_SIZE 60 ++#define EMAC_MAX_ETHERNET_PKT_SIZE 1518 ++#define EMAC_PKT_ALIGN 18 /* 1518 + 18 = 1536 (packet aligned on 32 byte boundry) */ ++ ++/* Number of RX packet buffers ++ * NOTE: Only 1 buffer supported as of now ++ */ ++#define EMAC_MAX_RX_BUFFERS 10 ++ ++ ++/*********************************************** ++ ******** Internally used macros *************** ++ ***********************************************/ ++ ++#define EMAC_CH_TX 1 ++#define EMAC_CH_RX 0 ++ ++/* Each descriptor occupies 4 words, lets start RX desc's at 0 and ++ * reserve space for 64 descriptors max ++ */ ++#define EMAC_RX_DESC_BASE 0x0 ++#define EMAC_TX_DESC_BASE 0x1000 ++ ++/* EMAC Teardown value */ ++#define EMAC_TEARDOWN_VALUE 0xfffffffc ++ ++/* MII Status Register */ ++#define MII_STATUS_REG 1 ++ ++/* Number of statistics registers */ ++#define EMAC_NUM_STATS 36 ++ ++ ++/* EMAC Descriptor */ ++typedef volatile struct _emac_desc ++{ ++ u_int32_t next; /* Pointer to next descriptor in chain */ ++ u_int8_t *buffer; /* Pointer to data buffer */ ++ u_int32_t buff_off_len; /* Buffer Offset(MSW) and Length(LSW) */ ++ u_int32_t pkt_flag_len; /* Packet Flags(MSW) and Length(LSW) */ ++} emac_desc; ++ ++typedef volatile unsigned int dv_reg; ++typedef volatile unsigned int *dv_reg_p; ++ ++/* CPPI bit positions */ ++#define EMAC_CPPI_SOP_BIT (0x80000000) ++#define EMAC_CPPI_EOP_BIT (0x40000000) ++#define EMAC_CPPI_OWNERSHIP_BIT (0x20000000) ++#define EMAC_CPPI_EOQ_BIT (0x10000000) ++#define EMAC_CPPI_TEARDOWN_COMPLETE_BIT (0x08000000) ++#define EMAC_CPPI_PASS_CRC_BIT (0x04000000) ++ ++#define EMAC_CPPI_RX_ERROR_FRAME (0x03fc0000) ++ ++#define EMAC_MACCONTROL_RMIISPEED_100 (1 << 15) ++#define EMAC_MACCONTROL_MIIEN_ENABLE (0x20) ++#define EMAC_MACCONTROL_FULLDUPLEX_ENABLE (0x1) ++ ++#define EMAC_RXMBPENABLE_RXCAFEN_ENABLE (0x200000) ++#define EMAC_RXMBPENABLE_RXBROADEN (0x2000) ++ ++ ++#define MDIO_CONTROL_IDLE (0x80000000) ++#define MDIO_CONTROL_ENABLE (0x40000000) ++#define MDIO_CONTROL_FAULT_ENABLE (0x40000) ++#define MDIO_CONTROL_FAULT (0x80000) ++#define MDIO_USERACCESS0_GO (0x80000000) ++#define MDIO_USERACCESS0_WRITE_READ (0x0) ++#define MDIO_USERACCESS0_WRITE_WRITE (0x40000000) ++#define MDIO_USERACCESS0_ACK (0x20000000) ++ ++/* Ethernet MAC Registers Structure */ ++typedef struct { ++ dv_reg TXIDVER; ++ dv_reg TXCONTROL; ++ dv_reg TXTEARDOWN; ++ u_int8_t RSVD0[4]; ++ dv_reg RXIDVER; ++ dv_reg RXCONTROL; ++ dv_reg RXTEARDOWN; ++ u_int8_t RSVD1[100]; ++ dv_reg TXINTSTATRAW; ++ dv_reg TXINTSTATMASKED; ++ dv_reg TXINTMASKSET; ++ dv_reg TXINTMASKCLEAR; ++ dv_reg MACINVECTOR; ++ u_int8_t RSVD2[12]; ++ dv_reg RXINTSTATRAW; ++ dv_reg RXINTSTATMASKED; ++ dv_reg RXINTMASKSET; ++ dv_reg RXINTMASKCLEAR; ++ dv_reg MACINTSTATRAW; ++ dv_reg MACINTSTATMASKED; ++ dv_reg MACINTMASKSET; ++ dv_reg MACINTMASKCLEAR; ++ u_int8_t RSVD3[64]; ++ dv_reg RXMBPENABLE; ++ dv_reg RXUNICASTSET; ++ dv_reg RXUNICASTCLEAR; ++ dv_reg RXMAXLEN; ++ dv_reg RXBUFFEROFFSET; ++ dv_reg RXFILTERLOWTHRESH; ++ u_int8_t RSVD4[8]; ++ dv_reg RX0FLOWTHRESH; ++ dv_reg RX1FLOWTHRESH; ++ dv_reg RX2FLOWTHRESH; ++ dv_reg RX3FLOWTHRESH; ++ dv_reg RX4FLOWTHRESH; ++ dv_reg RX5FLOWTHRESH; ++ dv_reg RX6FLOWTHRESH; ++ dv_reg RX7FLOWTHRESH; ++ dv_reg RX0FREEBUFFER; ++ dv_reg RX1FREEBUFFER; ++ dv_reg RX2FREEBUFFER; ++ dv_reg RX3FREEBUFFER; ++ dv_reg RX4FREEBUFFER; ++ dv_reg RX5FREEBUFFER; ++ dv_reg RX6FREEBUFFER; ++ dv_reg RX7FREEBUFFER; ++ dv_reg MACCONTROL; ++ dv_reg MACSTATUS; ++ dv_reg EMCONTROL; ++ dv_reg FIFOCONTROL; ++ dv_reg MACCONFIG; ++ dv_reg EMACSOFTRESET; ++ u_int8_t RSVD5[88]; ++ dv_reg MACSRCADDRLO; ++ dv_reg MACSRCADDRHI; ++ dv_reg MACHASH1; ++ dv_reg MACHASH2; ++ dv_reg BOFFTEST; ++ dv_reg TPACETEST; ++ dv_reg RXPAUSE; ++ dv_reg TXPAUSE; ++ u_int8_t RSVD6[16]; ++ dv_reg RXGOODFRAMES; ++ dv_reg RXBCASTFRAMES; ++ dv_reg RXMCASTFRAMES; ++ dv_reg RXPAUSEFRAMES; ++ dv_reg RXCRCERRORS; ++ dv_reg RXALIGNCODEERRORS; ++ dv_reg RXOVERSIZED; ++ dv_reg RXJABBER; ++ dv_reg RXUNDERSIZED; ++ dv_reg RXFRAGMENTS; ++ dv_reg RXFILTERED; ++ dv_reg RXQOSFILTERED; ++ dv_reg RXOCTETS; ++ dv_reg TXGOODFRAMES; ++ dv_reg TXBCASTFRAMES; ++ dv_reg TXMCASTFRAMES; ++ dv_reg TXPAUSEFRAMES; ++ dv_reg TXDEFERRED; ++ dv_reg TXCOLLISION; ++ dv_reg TXSINGLECOLL; ++ dv_reg TXMULTICOLL; ++ dv_reg TXEXCESSIVECOLL; ++ dv_reg TXLATECOLL; ++ dv_reg TXUNDERRUN; ++ dv_reg TXCARRIERSENSE; ++ dv_reg TXOCTETS; ++ dv_reg FRAME64; ++ dv_reg FRAME65T127; ++ dv_reg FRAME128T255; ++ dv_reg FRAME256T511; ++ dv_reg FRAME512T1023; ++ dv_reg FRAME1024TUP; ++ dv_reg NETOCTETS; ++ dv_reg RXSOFOVERRUNS; ++ dv_reg RXMOFOVERRUNS; ++ dv_reg RXDMAOVERRUNS; ++ u_int8_t RSVD7[624]; ++ dv_reg MACADDRLO; ++ dv_reg MACADDRHI; ++ dv_reg MACINDEX; ++ u_int8_t RSVD8[244]; ++ dv_reg TX0HDP; ++ dv_reg TX1HDP; ++ dv_reg TX2HDP; ++ dv_reg TX3HDP; ++ dv_reg TX4HDP; ++ dv_reg TX5HDP; ++ dv_reg TX6HDP; ++ dv_reg TX7HDP; ++ dv_reg RX0HDP; ++ dv_reg RX1HDP; ++ dv_reg RX2HDP; ++ dv_reg RX3HDP; ++ dv_reg RX4HDP; ++ dv_reg RX5HDP; ++ dv_reg RX6HDP; ++ dv_reg RX7HDP; ++ dv_reg TX0CP; ++ dv_reg TX1CP; ++ dv_reg TX2CP; ++ dv_reg TX3CP; ++ dv_reg TX4CP; ++ dv_reg TX5CP; ++ dv_reg TX6CP; ++ dv_reg TX7CP; ++ dv_reg RX0CP; ++ dv_reg RX1CP; ++ dv_reg RX2CP; ++ dv_reg RX3CP; ++ dv_reg RX4CP; ++ dv_reg RX5CP; ++ dv_reg RX6CP; ++ dv_reg RX7CP; ++} emac_regs; ++ ++/* EMAC Wrapper Registers Structure */ ++typedef struct { ++ dv_reg REV; ++ dv_reg EMACSOFTRESET; ++ dv_reg INTCONTROL; ++ dv_reg C0RXTHRESHEN; ++ dv_reg C0RXEN; ++ dv_reg C0TXEN; ++ dv_reg C0MISCEN; ++ dv_reg C1RXTHRESHEN; ++ dv_reg C1RXEN; ++ dv_reg C1TXEN; ++ dv_reg C1MISCEN; ++ dv_reg C2RXTHRESHEN; ++ dv_reg C2RXEN; ++ dv_reg C2TXEN; ++ dv_reg C2MISCEN; ++ dv_reg C0RXTHRESHSTAT; ++ dv_reg C0RXSTAT; ++ dv_reg C0TXSTAT; ++ dv_reg C0MISCSTAT; ++ dv_reg C1RXTHRESHSTAT; ++ dv_reg C1RXSTAT; ++ dv_reg C1TXSTAT; ++ dv_reg C1MISCSTAT; ++ dv_reg C2RXTHRESHSTAT; ++ dv_reg C2RXSTAT; ++ dv_reg C2TXSTAT; ++ dv_reg C2MISCSTAT; ++ dv_reg C0RXIMAX; ++ dv_reg C0TXIMAX; ++ dv_reg C1RXIMAX; ++ dv_reg C1TXIMAX; ++ dv_reg C2RXIMAX; ++ dv_reg C2TXIMAX; ++} ewrap_regs; ++ ++ ++/* EMAC MDIO Registers Structure */ ++typedef struct { ++ dv_reg VERSION; ++ dv_reg CONTROL; ++ dv_reg ALIVE; ++ dv_reg LINK; ++ dv_reg LINKINTRAW; ++ dv_reg LINKINTMASKED; ++ u_int8_t RSVD0[8]; ++ dv_reg USERINTRAW; ++ dv_reg USERINTMASKED; ++ dv_reg USERINTMASKSET; ++ dv_reg USERINTMASKCLEAR; ++ u_int8_t RSVD1[80]; ++ dv_reg USERACCESS0; ++ dv_reg USERPHYSEL0; ++ dv_reg USERACCESS1; ++ dv_reg USERPHYSEL1; ++} mdio_regs; ++ ++int dm644x_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data); ++int dm644x_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data); ++ ++typedef struct ++{ ++ char name[64]; ++ int (*init)(int phy_addr); ++ int (*is_phy_connected)(int phy_addr); ++ int (*get_link_status)(int phy_addr); ++ int (*auto_negotiate)(int phy_addr); ++} phy_t; ++ ++/* Generic phy definitions */ ++#define GEN_PHY_STATUS_SPEED100_MASK ((1 << 13) | (1 << 14)) ++#define GEN_PHY_STATUS_FD_MASK ((1 << 11) | (1 << 13)) ++ ++#endif /* _TI_CPGMAC_H_ */ +diff --git a/include/asm-arm/mach-types.h b/include/asm-arm/mach-types.h +index 2c1e69b..c7e498e 100644 +--- a/include/asm-arm/mach-types.h ++++ b/include/asm-arm/mach-types.h +@@ -1990,6 +1990,7 @@ extern unsigned int __machine_arch_type; + #define MACH_TYPE_BLAZE 2004 + #define MACH_TYPE_LINKSTATION_LS_HGL 2005 + #define MACH_TYPE_HTCVENUS 2006 ++#define MACH_TYPE_OMAP3517EVM 2200 + + #ifdef CONFIG_ARCH_EBSA110 + # ifdef machine_arch_type +diff --git a/include/configs/omap3517evm.h b/include/configs/omap3517evm.h +new file mode 100644 +index 0000000..28e3d15 +--- /dev/null ++++ b/include/configs/omap3517evm.h +@@ -0,0 +1,349 @@ ++/* ++ * (C) Copyright 2006-2008 ++ * Texas Instruments. ++ * Author : ++ * Manikandan Pillai ++ * ++ * Derived from EVM, Beagle Board and 3430 SDP code by ++ * Richard Woodruff ++ * Syed Mohammed Khasim ++ * ++ * Configuration settings for the TI OMAP3 EVM board. ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++#include ++ ++/* ++ * High Level Configuration Options ++ */ ++#define CONFIG_ARMCORTEXA8 1 /* This is an ARM V7 CPU core */ ++#define CONFIG_OMAP 1 /* in a TI OMAP core */ ++#define CONFIG_OMAP34XX 1 /* which is a 34XX */ ++#define CONFIG_OMAP3430 1 /* which is in a 3430 */ ++#define CONFIG_OMAP3_OMAP3517EVM 1 /* working with EVM */ ++ ++#include /* get chip and board defs */ ++#include ++ ++/* Clock Defines */ ++#define V_OSCK 26000000 /* Clock output from T2 */ ++#define V_SCLK (V_OSCK >> 1) ++ ++#undef CONFIG_USE_IRQ /* no support for IRQs */ ++#define CONFIG_MISC_INIT_R ++ ++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ ++#define CONFIG_SETUP_MEMORY_TAGS 1 ++#define CONFIG_INITRD_TAG 1 ++#define CONFIG_REVISION_TAG 1 ++ ++/* ++ * Size of malloc() pool ++ */ ++#define CONFIG_ENV_SIZE SZ_128K /* Total Size Environment */ ++ /* Sector */ ++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + SZ_128K) ++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* bytes reserved for */ ++ /* initial data */ ++ ++/* ++ * Hardware drivers ++ */ ++ ++/* ++ * NS16550 Configuration ++ */ ++#define V_NS16550_CLK 48000000 /* 48MHz (APLL96/2) */ ++ ++#define CONFIG_SYS_NS16550 ++#define CONFIG_SYS_NS16550_SERIAL ++#define CONFIG_SYS_NS16550_REG_SIZE (-4) ++#define CONFIG_SYS_NS16550_CLK V_NS16550_CLK ++ ++/* ++ * select serial console configuration ++ */ ++#define CONFIG_CONS_INDEX 1 ++#define CONFIG_SYS_NS16550_COM1 OMAP34XX_UART1 ++#define CONFIG_SERIAL1 1 /* UART1 on OMAP3 EVM */ ++ ++/* allow to overwrite serial and ethaddr */ ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\ ++ 115200} ++#define CONFIG_MMC 1 ++#define CONFIG_OMAP3_MMC 1 ++#define CONFIG_DOS_PARTITION 1 ++ ++/* commands to include */ ++#include ++ ++#define CONFIG_CMD_EXT2 /* EXT2 Support */ ++#define CONFIG_CMD_FAT /* FAT support */ ++#define CONFIG_CMD_JFFS2 /* JFFS2 Support */ ++ ++#define CONFIG_CMD_I2C /* I2C serial bus support */ ++#define CONFIG_CMD_MMC /* MMC support */ ++#define CONFIG_CMD_NAND /* NAND support */ ++#define CONFIG_CMD_DHCP ++#define CONFIG_CMD_PING ++ ++#undef CONFIG_CMD_FLASH /* flinfo, erase, protect */ ++#undef CONFIG_CMD_FPGA /* FPGA configuration Support */ ++#undef CONFIG_CMD_IMI /* iminfo */ ++#undef CONFIG_CMD_IMLS /* List all found images */ ++ ++#define CONFIG_SYS_NO_FLASH ++#define CONFIG_SYS_I2C_SPEED 100000 ++#define CONFIG_SYS_I2C_SLAVE 1 ++#define CONFIG_SYS_I2C_BUS 0 ++#define CONFIG_SYS_I2C_BUS_SELECT 1 ++#define CONFIG_DRIVER_OMAP34XX_I2C 1 ++ ++/* ++ * Board NAND Info. ++ */ ++#define CONFIG_NAND_OMAP_GPMC ++#define CONFIG_SYS_NAND_ADDR NAND_BASE /* physical address */ ++ /* to access nand */ ++#define CONFIG_SYS_NAND_BASE NAND_BASE /* physical address */ ++ /* to access */ ++ /* nand at CS0 */ ++ ++#define GPMC_NAND_ECC_LP_x16_LAYOUT 1 ++ ++#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of */ ++ /* NAND devices */ ++#define SECTORSIZE 512 ++ ++#define NAND_ALLOW_ERASE_ALL ++#define ADDR_COLUMN 1 ++#define ADDR_PAGE 2 ++#define ADDR_COLUMN_PAGE 3 ++ ++#define NAND_ChipID_UNKNOWN 0x00 ++#define NAND_MAX_FLOORS 1 ++#define NAND_MAX_CHIPS 1 ++#define NAND_NO_RB 1 ++#define CONFIG_SYS_NAND_WP ++ ++#define CONFIG_JFFS2_NAND ++/* nand device jffs2 lives on */ ++#define CONFIG_JFFS2_DEV "nand0" ++/* start of jffs2 partition */ ++#define CONFIG_JFFS2_PART_OFFSET 0x680000 ++#define CONFIG_JFFS2_PART_SIZE 0xf980000 /* sz of jffs2 part */ ++ ++/* Environment information */ ++#define CONFIG_BOOTDELAY 10 ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ "loadaddr=0x82000000\0" \ ++ "console=ttyS2,115200n8\0" \ ++ "mmcargs=setenv bootargs console=${console} " \ ++ "root=/dev/mmcblk0p2 rw " \ ++ "rootfstype=ext3 rootwait\0" \ ++ "nandargs=setenv bootargs console=${console} " \ ++ "root=/dev/mtdblock4 rw " \ ++ "rootfstype=jffs2\0" \ ++ "loadbootscript=fatload mmc 0 ${loadaddr} boot.scr\0" \ ++ "bootscript=echo Running bootscript from mmc ...; " \ ++ "autoscr ${loadaddr}\0" \ ++ "loaduimage=fatload mmc 0 ${loadaddr} uImage\0" \ ++ "mmcboot=echo Booting from mmc ...; " \ ++ "run mmcargs; " \ ++ "bootm ${loadaddr}\0" \ ++ "nandboot=echo Booting from nand ...; " \ ++ "run nandargs; " \ ++ "onenand read ${loadaddr} 280000 400000; " \ ++ "bootm ${loadaddr}\0" \ ++ ++#define CONFIG_BOOTCOMMAND \ ++ "if mmcinit; then " \ ++ "if run loadbootscript; then " \ ++ "run bootscript; " \ ++ "else " \ ++ "if run loaduimage; then " \ ++ "run mmcboot; " \ ++ "else run nandboot; " \ ++ "fi; " \ ++ "fi; " \ ++ "else run nandboot; fi" ++ ++#define CONFIG_AUTO_COMPLETE 1 ++/* ++ * Miscellaneous configurable options ++ */ ++#define V_PROMPT "OMAP3517EVM # " ++ ++#define CONFIG_SYS_LONGHELP /* undef to save memory */ ++#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ ++#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " ++#define CONFIG_SYS_PROMPT V_PROMPT ++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ ++/* Print Buffer Size */ ++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ ++ sizeof(CONFIG_SYS_PROMPT) + 16) ++#define CONFIG_SYS_MAXARGS 16 /* max number of command */ ++ /* args */ ++/* Boot Argument Buffer Size */ ++#define CONFIG_SYS_BARGSIZE (CONFIG_SYS_CBSIZE) ++/* memtest works on */ ++#define CONFIG_SYS_MEMTEST_START (OMAP34XX_SDRC_CS0) ++#define CONFIG_SYS_MEMTEST_END (OMAP34XX_SDRC_CS0 + \ ++ 0x01F00000) /* 31MB */ ++ ++#undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, */ ++ /* in Hz */ ++ ++#define CONFIG_SYS_LOAD_ADDR (OMAP34XX_SDRC_CS0) /* default load */ ++ /* address */ ++ ++/* ++ * OMAP3 has 12 GP timers, they can be driven by the system clock ++ * (12/13/16.8/19.2/38.4MHz) or by 32KHz clock. We use 13MHz (V_SCLK). ++ * This rate is divided by a local divisor. ++ */ ++#define CONFIG_SYS_TIMERBASE (OMAP34XX_GPT2) ++#define CONFIG_SYS_PVT 2 /* Divisor: 2^(PVT+1) => 8 */ ++#define CONFIG_SYS_HZ 1000 ++ ++/*----------------------------------------------------------------------- ++ * Stack sizes ++ * ++ * The stack sizes are set up in start.S using the settings below ++ */ ++#define CONFIG_STACKSIZE SZ_128K /* regular stack */ ++#ifdef CONFIG_USE_IRQ ++#define CONFIG_STACKSIZE_IRQ SZ_4K /* IRQ stack */ ++#define CONFIG_STACKSIZE_FIQ SZ_4K /* FIQ stack */ ++#endif ++ ++/*----------------------------------------------------------------------- ++ * Physical Memory Map ++ */ ++#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */ ++#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0 ++#define PHYS_SDRAM_1_SIZE SZ_32M /* at least 32 meg */ ++#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1 ++ ++/* SDRAM Bank Allocation method */ ++#define SDRC_R_B_C 1 ++ ++/*----------------------------------------------------------------------- ++ * FLASH and environment organization ++ */ ++ ++/* **** PISMO SUPPORT *** */ ++ ++/* Configure the PISMO */ ++#define PISMO1_NAND_SIZE GPMC_SIZE_128M ++#define PISMO1_ONEN_SIZE GPMC_SIZE_128M ++ ++#define CONFIG_SYS_MAX_FLASH_SECT 520 /* max number of sectors */ ++ /* on one chip */ ++#define CONFIG_SYS_MAX_FLASH_BANKS 2 /* max number of flash banks */ ++#define CONFIG_SYS_MONITOR_LEN SZ_256K /* Reserve 2 sectors */ ++ ++#define CONFIG_SYS_FLASH_BASE boot_flash_base ++ ++/* Monitor at start of flash */ ++#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE ++#define CONFIG_SYS_ONENAND_BASE ONENAND_MAP ++ ++#define CONFIG_ENV_IS_IN_NAND 1 ++#define ONENAND_ENV_OFFSET 0x260000 /* environment starts here */ ++#define SMNAND_ENV_OFFSET 0x260000 /* environment starts here */ ++ ++#define CONFIG_SYS_ENV_SECT_SIZE boot_flash_sec ++#define CONFIG_ENV_OFFSET boot_flash_off ++#define CONFIG_ENV_ADDR boot_flash_env_addr ++ ++/*----------------------------------------------------------------------- ++ * CFI FLASH driver setup ++ */ ++/* timeout values are in ticks */ ++#define CONFIG_SYS_FLASH_ERASE_TOUT (100 * CONFIG_SYS_HZ) ++#define CONFIG_SYS_FLASH_WRITE_TOUT (100 * CONFIG_SYS_HZ) ++ ++/* Flash banks JFFS2 should use */ ++#define CONFIG_SYS_MAX_MTD_BANKS (CONFIG_SYS_MAX_FLASH_BANKS + \ ++ CONFIG_SYS_MAX_NAND_DEVICE) ++#define CONFIG_SYS_JFFS2_MEM_NAND ++/* use flash_info[2] */ ++#define CONFIG_SYS_JFFS2_FIRST_BANK CONFIG_SYS_MAX_FLASH_BANKS ++#define CONFIG_SYS_JFFS2_NUM_BANKS 1 ++ ++#ifndef __ASSEMBLY__ ++extern gpmc_csx_t *nand_cs_base; ++extern gpmc_t *gpmc_cfg_base; ++extern unsigned int boot_flash_base; ++extern volatile unsigned int boot_flash_env_addr; ++extern unsigned int boot_flash_off; ++extern unsigned int boot_flash_sec; ++extern unsigned int boot_flash_type; ++#endif ++ ++ ++#define WRITE_NAND_COMMAND(d, adr)\ ++ writel(d, &nand_cs_base->nand_cmd) ++#define WRITE_NAND_ADDRESS(d, adr)\ ++ writel(d, &nand_cs_base->nand_adr) ++#define WRITE_NAND(d, adr) writew(d, &nand_cs_base->nand_dat) ++#define READ_NAND(adr) readl(&nand_cs_base->nand_dat) ++ ++/* Other NAND Access APIs */ ++#define NAND_WP_OFF() do {readl(&gpmc_cfg_base->config) |= GPMC_CONFIG_WP; } \ ++ while (0) ++#define NAND_WP_ON() do {readl(&gpmc_cfg_base->config) &= ~GPMC_CONFIG_WP; } \ ++ while (0) ++#define NAND_DISABLE_CE(nand) ++#define NAND_ENABLE_CE(nand) ++#define NAND_WAIT_READY(nand) udelay(10) ++ ++/*---------------------------------------------------------------------------- ++ * Ethernet support for OMAP3517EVM ++ *---------------------------------------------------------------------------- ++ */ ++#if defined(CONFIG_CMD_NET) ++#define CONFIG_TICPGMAC ++#define CONFIG_DRIVER_TI_EMAC ++#define CONFIG_MII ++#define CONFIG_NET_RETRY_COUNT 10 ++#endif /* (CONFIG_CMD_NET) */ ++ ++/* ++ * BOOTP fields ++ */ ++#define CONFIG_BOOTP_DEFAULT ++#define CONFIG_BOOTP_DNS ++#define CONFIG_BOOTP_DNS2 ++#define CONFIG_BOOTP_SEND_HOSTNAME ++ ++#define CONFIG_BOOTP_SUBNETMASK 0x00000001 ++#define CONFIG_BOOTP_GATEWAY 0x00000002 ++#define CONFIG_BOOTP_HOSTNAME 0x00000004 ++#define CONFIG_BOOTP_BOOTPATH 0x00000010 ++ ++#endif /* __CONFIG_H */ +diff --git a/lib_arm/board.c b/lib_arm/board.c +index 09eaaf2..4ed200d 100644 +--- a/lib_arm/board.c ++++ b/lib_arm/board.c +@@ -432,9 +432,9 @@ void start_armboot (void) + + /* Perform network card initialisation if necessary */ + #ifdef CONFIG_DRIVER_TI_EMAC +-extern void davinci_eth_set_mac_addr (const u_int8_t *addr); ++extern void cpgmac_eth_set_mac_addr (const u_int8_t *addr); + if (getenv ("ethaddr")) { +- davinci_eth_set_mac_addr(gd->bd->bi_enetaddr); ++ cpgmac_eth_set_mac_addr(gd->bd->bi_enetaddr); + } + #endif + +diff --git a/net/eth.c b/net/eth.c +index 217e885..2e261da 100644 +--- a/net/eth.c ++++ b/net/eth.c +@@ -498,7 +498,7 @@ extern int at91rm9200_miiphy_initialize(bd_t *bis); + extern int emac4xx_miiphy_initialize(bd_t *bis); + extern int mcf52x2_miiphy_initialize(bd_t *bis); + extern int ns7520_miiphy_initialize(bd_t *bis); +-extern int davinci_eth_miiphy_initialize(bd_t *bis); ++extern int cpgmac_eth_miiphy_initialize(bd_t *bis); + + + int eth_initialize(bd_t *bis) +@@ -520,7 +520,7 @@ int eth_initialize(bd_t *bis) + ns7520_miiphy_initialize(bis); + #endif + #if defined(CONFIG_DRIVER_TI_EMAC) +- davinci_eth_miiphy_initialize(bis); ++ cpgmac_eth_miiphy_initialize(bis); + #endif + return 0; + } +-- +1.6.2.4 + diff --git a/recipes/u-boot/u-boot-git/omap3evm/0007-OMAP3517TEB-validated-on-OMAP3517TEB-board.patch b/recipes/u-boot/u-boot-git/omap3evm/0007-OMAP3517TEB-validated-on-OMAP3517TEB-board.patch new file mode 100644 index 0000000000..3c79755d42 --- /dev/null +++ b/recipes/u-boot/u-boot-git/omap3evm/0007-OMAP3517TEB-validated-on-OMAP3517TEB-board.patch @@ -0,0 +1,403 @@ +From ba560965c5fc7671545cd4eed5d57be69958941d Mon Sep 17 00:00:00 2001 +From: Vaibhav Hiremath +Date: Sat, 13 Jun 2009 00:58:06 +0530 +Subject: [PATCH 07/16] OMAP3517TEB: validated on OMAP3517TEB board + +OMAP3517TEB board is being used as a pre-silicon development +platform, below are the details - + +Validation - + - PLL conifguration + - NAND 8-bit micron part (x-loader, u-boot) + - USB Host* (Linux) + - MMC1 (x-loader, u-boot, Linux) + - Video (TV out, LCD (Toshiba part)) + - MMC boot from x-loader + +Changes - + - GPMC timing parameters for NAND interface + - omap3517evm.h config file cleanup + - commented out "smi" instruction + +Issues - + - USB host support has been validated by commenting the + mux configuration in u-boot. Was not able to conclude on + muxing part of it. + - NAND 16-bit is not working, found out to be daughter card issue + Daughter card is not designed for 16bit micron part. + - LCD is validated based on AVV panel initialization, since it was SPI + based LCD panel. +--- + board/omap3/omap3517evm/omap3517evm.h | 20 +++++++------- + cpu/arm_cortexa8/omap3/board.c | 19 ++++++++----- + cpu/arm_cortexa8/omap3/mem.c | 48 ++++++++++++++++++++++---------- + cpu/arm_cortexa8/start.S | 2 +- + drivers/i2c/omap24xx_i2c.c | 9 ++++-- + drivers/mmc/omap3_mmc.c | 6 +++- + include/asm-arm/arch-omap3/mem.h | 18 ++++++++++++ + include/asm-arm/arch-omap3/mux.h | 4 +- + include/configs/omap3517evm.h | 10 +++---- + 9 files changed, 90 insertions(+), 46 deletions(-) + +diff --git a/board/omap3/omap3517evm/omap3517evm.h b/board/omap3/omap3517evm/omap3517evm.h +index aba53bf..d817e93 100644 +--- a/board/omap3/omap3517evm/omap3517evm.h ++++ b/board/omap3/omap3517evm/omap3517evm.h +@@ -190,16 +190,16 @@ static void setup_net_chip(void); + MUX_VAL(CP(MCBSP2_DR), (IEN | PTD | DIS | M0)) /*McBSP2_DR*/\ + MUX_VAL(CP(MCBSP2_DX), (IDIS | PTD | DIS | M0)) /*McBSP2_DX*/\ + /*Expansion card */\ +- MUX_VAL(CP(MMC1_CLK), (IDIS | PTU | EN | M0)) /*MMC1_CLK*/\ +- MUX_VAL(CP(MMC1_CMD), (IEN | PTU | EN | M0)) /*MMC1_CMD*/\ +- MUX_VAL(CP(MMC1_DAT0), (IEN | PTU | EN | M0)) /*MMC1_DAT0*/\ +- MUX_VAL(CP(MMC1_DAT1), (IEN | PTU | EN | M0)) /*MMC1_DAT1*/\ +- MUX_VAL(CP(MMC1_DAT2), (IEN | PTU | EN | M0)) /*MMC1_DAT2*/\ +- MUX_VAL(CP(MMC1_DAT3), (IEN | PTU | EN | M0)) /*MMC1_DAT3*/\ +- MUX_VAL(CP(MMC1_DAT4), (IEN | PTU | EN | M0)) /*MMC1_DAT4*/\ +- MUX_VAL(CP(MMC1_DAT5), (IEN | PTU | EN | M0)) /*MMC1_DAT5*/\ +- MUX_VAL(CP(MMC1_DAT6), (IEN | PTU | EN | M0)) /*MMC1_DAT6*/\ +- MUX_VAL(CP(MMC1_DAT7), (IEN | PTU | EN | M0)) /*MMC1_DAT7*/\ ++ MUX_VAL(CP(MMC1_CLK), (IEN | PTU | EN | M0)) /*MMC1_CLK*/\ ++ MUX_VAL(CP(MMC1_CMD), (IEN | PTU | DIS | M0)) /*MMC1_CMD*/\ ++ MUX_VAL(CP(MMC1_DAT0), (IEN | PTU | DIS | M0)) /*MMC1_DAT0*/\ ++ MUX_VAL(CP(MMC1_DAT1), (IEN | PTU | DIS | M0)) /*MMC1_DAT1*/\ ++ MUX_VAL(CP(MMC1_DAT2), (IEN | PTU | DIS | M0)) /*MMC1_DAT2*/\ ++ MUX_VAL(CP(MMC1_DAT3), (IEN | PTU | DIS | M0)) /*MMC1_DAT3*/\ ++ MUX_VAL(CP(MMC1_DAT4), (IEN | PTU | DIS | M0)) /*MMC1_DAT4*/\ ++ MUX_VAL(CP(MMC1_DAT5), (IEN | PTU | DIS | M0)) /*MMC1_DAT5*/\ ++ MUX_VAL(CP(MMC1_DAT6), (IEN | PTU | DIS | M0)) /*MMC1_DAT6*/\ ++ MUX_VAL(CP(MMC1_DAT7), (IEN | PTU | DIS | M0)) /*MMC1_DAT7*/\ + /*Wireless LAN */\ + MUX_VAL(CP(MMC2_CLK), (IEN | PTD | DIS | M0)) /*MMC2_CLK*/\ + MUX_VAL(CP(MMC2_CMD), (IEN | PTU | EN | M0)) /*MMC2_CMD*/\ +diff --git a/cpu/arm_cortexa8/omap3/board.c b/cpu/arm_cortexa8/omap3/board.c +index a0c2d05..15834fd 100644 +--- a/cpu/arm_cortexa8/omap3/board.c ++++ b/cpu/arm_cortexa8/omap3/board.c +@@ -224,9 +224,9 @@ void s_init(void) + per_clocks_enable(); + + if (!in_sdram) +-#ifdef CONFIG_OMAP3_OMAP3517EVM ++#if defined (CONFIG_OMAP35XX) + emif4_init(); +-#else ++#elif defined (CONFIG_OMAP34XX) + sdrc_init(); + #endif + } +@@ -288,17 +288,22 @@ int dram_init(void) + * memory on CS0. + */ + if ((sysinfo.mtype == DDR_COMBO) || (sysinfo.mtype == DDR_STACKED)) { +-#ifdef CONFIG_OMAP3_OMAP3517EVM ++#if defined (CONFIG_OMAP35XX) + emif4_init(); +-#else ++ /* ++ * TODO: Need to implement function to calculate ++ * DDR size depending on row and coloum size ++ */ ++ size0 = 128 * 1024 * 1024; ++#elif defined (CONFIG_OMAP34XX) + do_sdrc_init(CS1, NOT_EARLY); + make_cs1_contiguous(); ++ ++ size0 = get_sdr_cs_size(CS0); ++ size1 = get_sdr_cs_size(CS1); + #endif + } + +- size0 = get_sdr_cs_size(CS0); +- size1 = get_sdr_cs_size(CS1); +- + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = size0; + gd->bd->bi_dram[1].start = PHYS_SDRAM_1 + get_sdr_cs_offset(CS1); +diff --git a/cpu/arm_cortexa8/omap3/mem.c b/cpu/arm_cortexa8/omap3/mem.c +index 1badb34..7fb05eb 100644 +--- a/cpu/arm_cortexa8/omap3/mem.c ++++ b/cpu/arm_cortexa8/omap3/mem.c +@@ -32,23 +32,23 @@ + #include + + /* Definitions for EMIF4 configuration values */ +-#define EMIF4_TIM1_T_RP 0x4 +-#define EMIF4_TIM1_T_RCD 0x4 +-#define EMIF4_TIM1_T_WR 0x2 ++#define EMIF4_TIM1_T_RP 0x3 ++#define EMIF4_TIM1_T_RCD 0x3 ++#define EMIF4_TIM1_T_WR 0x3 + #define EMIF4_TIM1_T_RAS 0x8 +-#define EMIF4_TIM1_T_RC 13 ++#define EMIF4_TIM1_T_RC 0xA + #define EMIF4_TIM1_T_RRD 0x2 + #define EMIF4_TIM1_T_WTR 0x2 + + #define EMIF4_TIM2_T_XP 0x2 + #define EMIF4_TIM2_T_ODT 0x0 +-#define EMIF4_TIM2_T_XSNR 28 +-#define EMIF4_TIM2_T_XSRD 200 +-#define EMIF4_TIM2_T_RTP 0x2 +-#define EMIF4_TIM2_T_CKE 0x3 ++#define EMIF4_TIM2_T_XSNR 0x1C ++#define EMIF4_TIM2_T_XSRD 0xC8 ++#define EMIF4_TIM2_T_RTP 0x1 ++#define EMIF4_TIM2_T_CKE 0x2 + + #define EMIF4_TIM3_T_TDQSCKMAX 0x0 +-#define EMIF4_TIM3_T_RFC 33 ++#define EMIF4_TIM3_T_RFC 0x25 + #define EMIF4_TIM3_T_RAS_MAX 0x7 + + #define EMIF4_PWR_IDLE 0x2 +@@ -58,7 +58,7 @@ + + #define EMIF4_INITREF_DIS 0x0 + #define EMIF4_PASR 0x0 +-#define EMIF4_REFRESH_RATE 1295 ++#define EMIF4_REFRESH_RATE 0x50F + + #define EMIF4_CFG_SDRAM_TYP 0x2 + #define EMIF4_CFG_IBANK_POS 0x0 +@@ -69,14 +69,21 @@ + #define EMIF4_CFG_SDR_DRV 0x0 + #define EMIF4_CFG_CWL 0x0 + #define EMIF4_CFG_NARROW_MD 0x0 +-#define EMIF4_CFG_CL 0x3 +-#define EMIF4_CFG_ROWSIZE 0x3 ++#define EMIF4_CFG_CL 0x5 ++#define EMIF4_CFG_ROWSIZE 0x0 + #define EMIF4_CFG_IBANK 0x3 + #define EMIF4_CFG_EBANK 0x0 + #define EMIF4_CFG_PGSIZE 0x2 + +-#define EMIF4_DDR1_READ_LAT 0x3 ++/* ++ * EMIF4 PHY Control 1 register configuration ++ */ ++#define EMIF4_DDR1_READ_LAT 0x6 ++#define EMIF4_DDR1_PWRDN_DIS 0x1 ++#define EMIF4_DDR1_STRBEN_EXT 0x1 ++#define EMIF4_DDR1_DLL_MODE 0x0 + #define EMIF4_DDR1_VTP_DYN 0x1 ++#define EMIF4_DDR1_LB_CK_SEL 0x0 + + /* + * Only One NAND allowed on board at a time. +@@ -101,11 +108,15 @@ static u32 gpmc_m_nand[GPMC_MAX_REG] = { + gpmc_csx_t *nand_cs_base; + gpmc_t *gpmc_cfg_base; + ++#if !defined (CONFIG_OMAP3_OMAP3517TEB) + #if defined(CONFIG_ENV_IS_IN_NAND) + #define GPMC_CS 0 + #else + #define GPMC_CS 1 + #endif ++#else ++#define GPMC_CS 2 ++#endif + + #endif + +@@ -252,7 +263,9 @@ void emif4_init(void) + { + unsigned int regval; + /* Set the DDR PHY parameters in PHY ctrl registers */ +- regval = (EMIF4_DDR1_READ_LAT | (EMIF4_DDR1_VTP_DYN << 15)); ++ regval = (EMIF4_DDR1_READ_LAT | (EMIF4_DDR1_VTP_DYN << 15) | ++ (EMIF4_DDR1_STRBEN_EXT << 7) | (EMIF4_DDR1_DLL_MODE << 12) | ++ (EMIF4_DDR1_VTP_DYN << 15) | (EMIF4_DDR1_LB_CK_SEL << 23)); + writel(regval, &emif4_base->ddr_phyctrl1); + writel(regval, &emif4_base->ddr_phyctrl1_shdw); + writel(0, &emif4_base->ddr_phyctrl2); +@@ -261,8 +274,13 @@ void emif4_init(void) + regval = readl(&emif4_base->sdram_iodft_tlgc); + regval |= (1<<10); + writel(regval, &emif4_base->sdram_iodft_tlgc); +- while ((readl(&emif4_base->sdram_sts) & (1<<10)) == 0x0); ++ /*Wait till that bit clears*/ ++ while ((readl(&emif4_base->sdram_iodft_tlgc) & (1<<10)) == 0x1); ++ /*Re-verify the DDR PHY status*/ ++ while ((readl(&emif4_base->sdram_sts) & (1<<2)) == 0x0); + ++ regval |= (1<<0); ++ writel(regval, &emif4_base->sdram_iodft_tlgc); + /* Set SDR timing registers */ + regval = (EMIF4_TIM1_T_WTR | (EMIF4_TIM1_T_RRD << 3) | + (EMIF4_TIM1_T_RC << 6) | (EMIF4_TIM1_T_RAS << 12) | +diff --git a/cpu/arm_cortexa8/start.S b/cpu/arm_cortexa8/start.S +index 07acdbd..81961ad 100644 +--- a/cpu/arm_cortexa8/start.S ++++ b/cpu/arm_cortexa8/start.S +@@ -108,7 +108,7 @@ reset: + orr r0, r0, #0xd3 + msr cpsr,r0 + +-#if (CONFIG_OMAP34XX) ++#if defined (CONFIG_OMAP34XX) || (CONFIG_OMAP35XX) + /* Copy vectors to mask ROM indirect addr */ + adr r0, _start @ r0 <- current position of code + add r0, r0, #4 @ skip reset vector +diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c +index 6784603..9f7d3e8 100644 +--- a/drivers/i2c/omap24xx_i2c.c ++++ b/drivers/i2c/omap24xx_i2c.c +@@ -109,7 +109,8 @@ static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value) + + status = wait_for_pin (); + if (status & I2C_STAT_RRDY) { +-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) ++#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) \ ++ || defined(CONFIG_OMAP35XX) + *value = readb (I2C_DATA); + #else + *value = readw (I2C_DATA); +@@ -154,7 +155,8 @@ static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value) + status = wait_for_pin (); + + if (status & I2C_STAT_XRDY) { +-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) ++#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) \ ++ || defined(CONFIG_OMAP35XX) + /* send out 1 byte */ + writeb (regoffset, I2C_DATA); + writew (I2C_STAT_XRDY, I2C_STAT); +@@ -207,7 +209,8 @@ static void flush_fifo(void) + while(1){ + stat = readw(I2C_STAT); + if(stat == I2C_STAT_RRDY){ +-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) ++#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) \ ++ || defined(CONFIG_OMAP35XX) + readb(I2C_DATA); + #else + readw(I2C_DATA); +diff --git a/drivers/mmc/omap3_mmc.c b/drivers/mmc/omap3_mmc.c +index e90db7e..2d9ec5e 100644 +--- a/drivers/mmc/omap3_mmc.c ++++ b/drivers/mmc/omap3_mmc.c +@@ -57,7 +57,7 @@ block_dev_desc_t *mmc_get_dev(int dev) + { + return (block_dev_desc_t *) &mmc_blk_dev; + } +- ++#if defined (CONFIG_OMAP3_EVM) + void twl4030_mmc_config(void) + { + unsigned char data; +@@ -67,12 +67,14 @@ void twl4030_mmc_config(void) + data = VMMC1_VSEL_30; + i2c_write(PWRMGT_ADDR_ID4, VMMC1_DEDICATED, 1, &data, 1); + } +- ++#endif + unsigned char mmc_board_init(void) + { + t2_t *t2_base = (t2_t *)T2_BASE; + ++#if defined (CONFIG_OMAP3_EVM) + twl4030_mmc_config(); ++#endif + + writel(readl(&t2_base->pbias_lite) | PBIASLITEPWRDNZ1 | + PBIASSPEEDCTRL0 | PBIASLITEPWRDNZ0, +diff --git a/include/asm-arm/arch-omap3/mem.h b/include/asm-arm/arch-omap3/mem.h +index 6f0f90b..261f246 100644 +--- a/include/asm-arm/arch-omap3/mem.h ++++ b/include/asm-arm/arch-omap3/mem.h +@@ -145,6 +145,22 @@ typedef enum { + #define SMNAND_GPMC_CONFIG6 0x1F0F0A80 + #define SMNAND_GPMC_CONFIG7 0x00000C44 + ++#if defined (CONFIG_OMAP3_OMAP3517TEB) || defined (CONFIG_OMAP3_OMAP3517EVM) ++ ++#ifdef GPMC_NAND_ECC_LP_x16_LAYOUT ++#define M_NAND_GPMC_CONFIG1 0x00001800 ++#else ++#define M_NAND_GPMC_CONFIG1 0x00000800 ++#endif ++#define M_NAND_GPMC_CONFIG2 0x00061000 ++#define M_NAND_GPMC_CONFIG3 0x00060600 ++#define M_NAND_GPMC_CONFIG4 0x03000602 ++#define M_NAND_GPMC_CONFIG5 0x00080610 ++#define M_NAND_GPMC_CONFIG6 0x04000D80 ++#define M_NAND_GPMC_CONFIG7 0x00000C48 ++ ++#else ++ + #define M_NAND_GPMC_CONFIG1 0x00001800 + #define M_NAND_GPMC_CONFIG2 0x00141400 + #define M_NAND_GPMC_CONFIG3 0x00141400 +@@ -153,6 +169,8 @@ typedef enum { + #define M_NAND_GPMC_CONFIG6 0x1f0f0A80 + #define M_NAND_GPMC_CONFIG7 0x00000C44 + ++#endif ++ + #define STNOR_GPMC_CONFIG1 0x3 + #define STNOR_GPMC_CONFIG2 0x00151501 + #define STNOR_GPMC_CONFIG3 0x00060602 +diff --git a/include/asm-arm/arch-omap3/mux.h b/include/asm-arm/arch-omap3/mux.h +index 5a241cb..d94eb2d 100644 +--- a/include/asm-arm/arch-omap3/mux.h ++++ b/include/asm-arm/arch-omap3/mux.h +@@ -337,7 +337,7 @@ + #define CONTROL_PADCONF_ETK_D14_ES2 0x05F8 + #define CONTROL_PADCONF_ETK_D15_ES2 0x05FA + /*Die to Die */ +-#ifndef CONFIG_OMAP3_OMAP3517EVM ++#if defined (CONFIG_OMAP34XX) + + #define CONTROL_PADCONF_D2D_MCAD0 0x01E4 + #define CONTROL_PADCONF_D2D_MCAD1 0x01E6 +@@ -374,7 +374,7 @@ + #define CONTROL_PADCONF_D2D_MCAD32 0x0224 + #define CONTROL_PADCONF_D2D_MCAD33 0x0226 + +-#else ++#elif defined (CONFIG_OMAP35XX) + + #define CONTROL_PADCONF_CCDC_PCLK 0x01E4 + #define CONTROL_PADCONF_CCDC_FIELD 0x01E6 +diff --git a/include/configs/omap3517evm.h b/include/configs/omap3517evm.h +index 28e3d15..f6f4be1 100644 +--- a/include/configs/omap3517evm.h ++++ b/include/configs/omap3517evm.h +@@ -38,9 +38,9 @@ + */ + #define CONFIG_ARMCORTEXA8 1 /* This is an ARM V7 CPU core */ + #define CONFIG_OMAP 1 /* in a TI OMAP core */ +-#define CONFIG_OMAP34XX 1 /* which is a 34XX */ +-#define CONFIG_OMAP3430 1 /* which is in a 3430 */ +-#define CONFIG_OMAP3_OMAP3517EVM 1 /* working with EVM */ ++#define CONFIG_OMAP35XX 1 /* which is a 34XX */ ++//#define CONFIG_OMAP3_OMAP3517EVM 1 /* working with EVM */ ++#define CONFIG_OMAP3_OMAP3517TEB 1 /* working with TEB */ + + #include /* get chip and board defs */ + #include +@@ -176,7 +176,7 @@ + "bootm ${loadaddr}\0" \ + "nandboot=echo Booting from nand ...; " \ + "run nandargs; " \ +- "onenand read ${loadaddr} 280000 400000; " \ ++ "nand read ${loadaddr} 80000 40000; " \ + "bootm ${loadaddr}\0" \ + + #define CONFIG_BOOTCOMMAND \ +@@ -270,10 +270,8 @@ + + /* Monitor at start of flash */ + #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE +-#define CONFIG_SYS_ONENAND_BASE ONENAND_MAP + + #define CONFIG_ENV_IS_IN_NAND 1 +-#define ONENAND_ENV_OFFSET 0x260000 /* environment starts here */ + #define SMNAND_ENV_OFFSET 0x260000 /* environment starts here */ + + #define CONFIG_SYS_ENV_SECT_SIZE boot_flash_sec +-- +1.6.2.4 + diff --git a/recipes/u-boot/u-boot-git/omap3evm/0008-OMAP3517PRE-ALPHA-validated-on-OMAP3517PRE_ALPHA-bo.patch b/recipes/u-boot/u-boot-git/omap3evm/0008-OMAP3517PRE-ALPHA-validated-on-OMAP3517PRE_ALPHA-bo.patch new file mode 100644 index 0000000000..0971a411e2 --- /dev/null +++ b/recipes/u-boot/u-boot-git/omap3evm/0008-OMAP3517PRE-ALPHA-validated-on-OMAP3517PRE_ALPHA-bo.patch @@ -0,0 +1,126 @@ +From 1f9233e69952afbf9c116f69ff6ab1fa840f4116 Mon Sep 17 00:00:00 2001 +From: Vaibhav Hiremath +Date: Sat, 13 Jun 2009 01:14:53 +0530 +Subject: [PATCH 08/16] OMAP3517PRE-ALPHA: validated on OMAP3517PRE_ALPHA board + +OMAP3517 Pre-Alpha board is a development platform +used before actual OMAP3517EVM board, below are the details - + +Validation - + - PLL conifguration + - NAND 16-bit micron part (x-loader, u-boot, Linux) + - MMC1 (x-loader, u-boot, Linux) + - Video (LCD (4.3" Sharp part)) + - Complete NAND boot mode + - Complete MMC boot mode + +Changes - + - GPMC Timing parameters for NAND interface + - UART3 made as serial console + +Issues - + - Clock init code still need to be cleaned up. + - boot config code needs to changed for supporting both mmc and nand + boot +--- + board/omap3/omap3517evm/omap3517evm.h | 6 +++--- + cpu/arm_cortexa8/omap3/clock.c | 6 ++++++ + include/asm-arm/arch-omap3/mem.h | 12 ++++++------ + include/configs/omap3517evm.h | 10 +++++----- + 4 files changed, 20 insertions(+), 14 deletions(-) + +diff --git a/board/omap3/omap3517evm/omap3517evm.h b/board/omap3/omap3517evm/omap3517evm.h +index d817e93..000fde6 100644 +--- a/board/omap3/omap3517evm/omap3517evm.h ++++ b/board/omap3/omap3517evm/omap3517evm.h +@@ -241,7 +241,7 @@ static void setup_net_chip(void); + MUX_VAL(CP(MCBSP1_FSX), (IEN | PTD | DIS | M0)) /*MCBSP1_FSX*/\ + MUX_VAL(CP(MCBSP1_CLKX), (IEN | PTD | DIS | M0)) /*MCBSP1_CLKX */\ + /*Serial Interface*/\ +- MUX_VAL(CP(UART3_CTS_RCTX), (IEN | PTD | EN | M0)) /*UART3_CTS_*/\ ++ MUX_VAL(CP(UART3_CTS_RCTX), (IEN | PTU | DIS | M0)) /*UART3_CTS_*/\ + /* RCTX*/\ + MUX_VAL(CP(UART3_RTS_SD), (IDIS | PTD | DIS | M0)) /*UART3_RTS_SD */\ + MUX_VAL(CP(UART3_RX_IRRX), (IEN | PTD | DIS | M0)) /*UART3_RX_IRRX*/\ +@@ -279,8 +279,8 @@ static void setup_net_chip(void); + MUX_VAL(CP(MCSPI2_CLK), (IEN | PTD | DIS | M0)) /*McSPI2_CLK*/\ + MUX_VAL(CP(MCSPI2_SIMO), (IEN | PTD | DIS | M0)) /*McSPI2_SIMO*/\ + MUX_VAL(CP(MCSPI2_SOMI), (IEN | PTD | DIS | M0)) /*McSPI2_SOMI*/\ +- MUX_VAL(CP(MCSPI2_CS0), (IEN | PTD | EN | M0)) /*McSPI2_CS0*/\ +- MUX_VAL(CP(MCSPI2_CS1), (IEN | PTD | EN | M0)) /*McSPI2_CS1*/\ ++ MUX_VAL(CP(MCSPI2_CS0), (IEN | PTD | EN | M4)) /*McSPI2_CS0*/\ ++ MUX_VAL(CP(MCSPI2_CS1), (IEN | PTD | EN | M4)) /*McSPI2_CS1*/\ + /*Control and debug */\ + MUX_VAL(CP(SYS_32K), (IEN | PTD | DIS | M0)) /*SYS_32K*/\ + MUX_VAL(CP(SYS_CLKREQ), (IEN | PTD | DIS | M0)) /*SYS_CLKREQ*/\ +diff --git a/cpu/arm_cortexa8/omap3/clock.c b/cpu/arm_cortexa8/omap3/clock.c +index a706cd4..d023765 100644 +--- a/cpu/arm_cortexa8/omap3/clock.c ++++ b/cpu/arm_cortexa8/omap3/clock.c +@@ -368,6 +368,12 @@ void per_clocks_enable(void) + /* Enable the ICLK for 32K Sync Timer as its used in udelay */ + sr32(&prcm_base->iclken_wkup, 2, 1, 0x1); + ++ sr32(&prcm_base->fclken1_core, 24, 1, 1); ++ sr32(&prcm_base->iclken_wkup, 24, 1, 1); ++ ++ sr32(&prcm_base->fclken1_core, 25, 1, 1); ++ sr32(&prcm_base->iclken_wkup, 25, 1, 1); ++ + sr32(&prcm_base->fclken_iva2, 0, 32, FCK_IVA2_ON); + sr32(&prcm_base->fclken1_core, 0, 32, FCK_CORE1_ON); + sr32(&prcm_base->iclken1_core, 0, 32, ICK_CORE1_ON); +diff --git a/include/asm-arm/arch-omap3/mem.h b/include/asm-arm/arch-omap3/mem.h +index 261f246..1323030 100644 +--- a/include/asm-arm/arch-omap3/mem.h ++++ b/include/asm-arm/arch-omap3/mem.h +@@ -152,12 +152,12 @@ typedef enum { + #else + #define M_NAND_GPMC_CONFIG1 0x00000800 + #endif +-#define M_NAND_GPMC_CONFIG2 0x00061000 +-#define M_NAND_GPMC_CONFIG3 0x00060600 +-#define M_NAND_GPMC_CONFIG4 0x03000602 +-#define M_NAND_GPMC_CONFIG5 0x00080610 +-#define M_NAND_GPMC_CONFIG6 0x04000D80 +-#define M_NAND_GPMC_CONFIG7 0x00000C48 ++#define M_NAND_GPMC_CONFIG2 0x00080800 ++#define M_NAND_GPMC_CONFIG3 0x00080800 ++#define M_NAND_GPMC_CONFIG4 0x06000600 ++#define M_NAND_GPMC_CONFIG5 0x00080808 ++#define M_NAND_GPMC_CONFIG6 0x000003cf ++#define M_NAND_GPMC_CONFIG7 0x00000848 + + #else + +diff --git a/include/configs/omap3517evm.h b/include/configs/omap3517evm.h +index f6f4be1..558538b 100644 +--- a/include/configs/omap3517evm.h ++++ b/include/configs/omap3517evm.h +@@ -39,8 +39,8 @@ + #define CONFIG_ARMCORTEXA8 1 /* This is an ARM V7 CPU core */ + #define CONFIG_OMAP 1 /* in a TI OMAP core */ + #define CONFIG_OMAP35XX 1 /* which is a 34XX */ +-//#define CONFIG_OMAP3_OMAP3517EVM 1 /* working with EVM */ +-#define CONFIG_OMAP3_OMAP3517TEB 1 /* working with TEB */ ++#define CONFIG_OMAP3_OMAP3517EVM 1 /* working with EVM */ ++//#define CONFIG_OMAP3_OMAP3517TEB 1 /* working with TEB */ + + #include /* get chip and board defs */ + #include +@@ -83,9 +83,9 @@ + /* + * select serial console configuration + */ +-#define CONFIG_CONS_INDEX 1 +-#define CONFIG_SYS_NS16550_COM1 OMAP34XX_UART1 +-#define CONFIG_SERIAL1 1 /* UART1 on OMAP3 EVM */ ++#define CONFIG_CONS_INDEX 3 ++#define CONFIG_SYS_NS16550_COM3 OMAP34XX_UART3 ++#define CONFIG_SERIAL3 3 /* UART1 on OMAP3 EVM */ + + /* allow to overwrite serial and ethaddr */ + #define CONFIG_ENV_OVERWRITE +-- +1.6.2.4 + diff --git a/recipes/u-boot/u-boot-git/omap3evm/0009-OMAP3517PRE-ALPHA-DDR-size-issue-fixed.patch b/recipes/u-boot/u-boot-git/omap3evm/0009-OMAP3517PRE-ALPHA-DDR-size-issue-fixed.patch new file mode 100644 index 0000000000..20a4bb1ffb --- /dev/null +++ b/recipes/u-boot/u-boot-git/omap3evm/0009-OMAP3517PRE-ALPHA-DDR-size-issue-fixed.patch @@ -0,0 +1,125 @@ +From 930d9fb1e5971e4012ee081c60b578b83d8dc928 Mon Sep 17 00:00:00 2001 +From: Vaibhav Hiremath +Date: Mon, 15 Jun 2009 20:59:26 +0530 +Subject: [PATCH 09/16] OMAP3517PRE-ALPHA: DDR size issue fixed. + +U-Boot was printing DDR size as 0, as of now hard-coded it with +macro (defined in include/configs/omap3517evm.h). + +TODO: + - Ideally it should calculate the size baded on EMIF configuration + made by primary bootloader (x-loader). +--- + cpu/arm_cortexa8/omap3/board.c | 13 ++----------- + cpu/arm_cortexa8/omap3/mem.c | 17 +++++++++++++++++ + cpu/arm_cortexa8/omap3/sys_info.c | 5 +++++ + include/configs/omap3517evm.h | 5 +++++ + 4 files changed, 29 insertions(+), 11 deletions(-) + +diff --git a/cpu/arm_cortexa8/omap3/board.c b/cpu/arm_cortexa8/omap3/board.c +index 15834fd..ea94e59 100644 +--- a/cpu/arm_cortexa8/omap3/board.c ++++ b/cpu/arm_cortexa8/omap3/board.c +@@ -275,33 +275,24 @@ void watchdog_init(void) + int dram_init(void) + { + DECLARE_GLOBAL_DATA_PTR; +- unsigned int size0 = 0, size1 = 0; ++ unsigned long size0 = 0, size1 = 0; + u32 btype; + + btype = get_board_type(); + + display_board_info(btype); + ++ size0 = get_sdr_cs_size(CS0); + /* + * If a second bank of DDR is attached to CS1 this is + * where it can be started. Early init code will init + * memory on CS0. + */ + if ((sysinfo.mtype == DDR_COMBO) || (sysinfo.mtype == DDR_STACKED)) { +-#if defined (CONFIG_OMAP35XX) +- emif4_init(); +- /* +- * TODO: Need to implement function to calculate +- * DDR size depending on row and coloum size +- */ +- size0 = 128 * 1024 * 1024; +-#elif defined (CONFIG_OMAP34XX) + do_sdrc_init(CS1, NOT_EARLY); + make_cs1_contiguous(); + +- size0 = get_sdr_cs_size(CS0); + size1 = get_sdr_cs_size(CS1); +-#endif + } + + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; +diff --git a/cpu/arm_cortexa8/omap3/mem.c b/cpu/arm_cortexa8/omap3/mem.c +index 7fb05eb..49047b4 100644 +--- a/cpu/arm_cortexa8/omap3/mem.c ++++ b/cpu/arm_cortexa8/omap3/mem.c +@@ -254,6 +254,23 @@ void do_sdrc_init(u32 cs, u32 early) + writel(0, &sdrc_base->cs[cs].mcfg); + } + ++unsigned long calc_size_from_emif4(int cs) ++{ ++ unsigned int size; ++#if 0 ++ unsigned int reg_pagesize, reg_ebank, reg_ibank, reg_rowsize; ++ ++ /* ++ * TODO: Calculate the DDR size based on EMIF configuration ++ * done by x-loader. ++ */ ++ size = ++#else ++ size = CONFIG_SYS_CS0_SIZE; ++#endif ++ ++ return size; ++} + /******************************************************** + * emif4 _init() - init the emif4 module for DDR access + * - early init routines, called from flash or +diff --git a/cpu/arm_cortexa8/omap3/sys_info.c b/cpu/arm_cortexa8/omap3/sys_info.c +index b385b91..8077ecf 100644 +--- a/cpu/arm_cortexa8/omap3/sys_info.c ++++ b/cpu/arm_cortexa8/omap3/sys_info.c +@@ -107,10 +107,15 @@ u32 get_sdr_cs_size(u32 cs) + { + u32 size; + ++#if defined (CONFIG_OMAP35XX) ++ size = calc_size_from_emif4(cs); ++#elif defined (CONFIG_OMAP34XX) + /* get ram size field */ + size = readl(&sdrc_base->cs[cs].mcfg) >> 8; + size &= 0x3FF; /* remove unwanted bits */ + size *= SZ_2M; /* find size in MB */ ++#endif ++ + return size; + } + +diff --git a/include/configs/omap3517evm.h b/include/configs/omap3517evm.h +index 558538b..c434b71 100644 +--- a/include/configs/omap3517evm.h ++++ b/include/configs/omap3517evm.h +@@ -67,6 +67,11 @@ + /* initial data */ + + /* ++ * DDR size interfaced ++ */ ++#define CONFIG_SYS_CS0_SIZE SZ_256M ++ ++/* + * Hardware drivers + */ + +-- +1.6.2.4 + diff --git a/recipes/u-boot/u-boot-git/omap3evm/0010-OMAP3517PRE-ALPHA-Mux-configuration-for-MMC-CD-and.patch b/recipes/u-boot/u-boot-git/omap3evm/0010-OMAP3517PRE-ALPHA-Mux-configuration-for-MMC-CD-and.patch new file mode 100644 index 0000000000..22cd35863b --- /dev/null +++ b/recipes/u-boot/u-boot-git/omap3evm/0010-OMAP3517PRE-ALPHA-Mux-configuration-for-MMC-CD-and.patch @@ -0,0 +1,34 @@ +From be213a61e04fe2427c51d3687ec82d2cd8741d8c Mon Sep 17 00:00:00 2001 +From: Vaibhav Hiremath +Date: Tue, 16 Jun 2009 03:54:56 +0530 +Subject: [PATCH 10/16] OMAP3517PRE-ALPHA: Mux configuration for MMC CD and WP pins + +The Mux configuration changed for MMC1 Card Detect and Write Protect +GPIO pins - + +Card Detect --> MMC_DAT5 = GPIO127 +Write Protect --> MMC_DAT4 = GPIO126 +--- + board/omap3/omap3517evm/omap3517evm.h | 6 ++++-- + 1 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/board/omap3/omap3517evm/omap3517evm.h b/board/omap3/omap3517evm/omap3517evm.h +index 000fde6..c3ea037 100644 +--- a/board/omap3/omap3517evm/omap3517evm.h ++++ b/board/omap3/omap3517evm/omap3517evm.h +@@ -196,8 +196,10 @@ static void setup_net_chip(void); + MUX_VAL(CP(MMC1_DAT1), (IEN | PTU | DIS | M0)) /*MMC1_DAT1*/\ + MUX_VAL(CP(MMC1_DAT2), (IEN | PTU | DIS | M0)) /*MMC1_DAT2*/\ + MUX_VAL(CP(MMC1_DAT3), (IEN | PTU | DIS | M0)) /*MMC1_DAT3*/\ +- MUX_VAL(CP(MMC1_DAT4), (IEN | PTU | DIS | M0)) /*MMC1_DAT4*/\ +- MUX_VAL(CP(MMC1_DAT5), (IEN | PTU | DIS | M0)) /*MMC1_DAT5*/\ ++ MUX_VAL(CP(MMC1_DAT4), (IEN | PTU | EN | M4)) /*MMC1_DAT4,\ ++ WriteProtect*/\ ++ MUX_VAL(CP(MMC1_DAT5), (IEN | PTU | EN | M4)) /*MMC1_DAT5,\ ++ CardDetect*/\ + MUX_VAL(CP(MMC1_DAT6), (IEN | PTU | DIS | M0)) /*MMC1_DAT6*/\ + MUX_VAL(CP(MMC1_DAT7), (IEN | PTU | DIS | M0)) /*MMC1_DAT7*/\ + /*Wireless LAN */\ +-- +1.6.2.4 + diff --git a/recipes/u-boot/u-boot-git/omap3evm/0011-Ethernet-driver-functional-no-need-for-time-delay.patch b/recipes/u-boot/u-boot-git/omap3evm/0011-Ethernet-driver-functional-no-need-for-time-delay.patch new file mode 100644 index 0000000000..aff49a47ef --- /dev/null +++ b/recipes/u-boot/u-boot-git/omap3evm/0011-Ethernet-driver-functional-no-need-for-time-delay.patch @@ -0,0 +1,488 @@ +From f6ee297c14693474a28948432d274bc2801b7578 Mon Sep 17 00:00:00 2001 +From: Vaibhav Hiremath +Date: Mon, 22 Jun 2009 23:40:44 +0530 +Subject: [PATCH 11/16] Ethernet driver functional(no need for time delay) + +Pulled up from branch omap-uboot-denx/int_030000_evm_bringup. +--- + board/omap3/omap3517evm/omap3517evm.c | 6 +- + board/omap3/omap3517evm/omap3517evm.h | 18 ++-- + drivers/net/ticpgmac.c | 139 ++++++++++++++++++++------------- + include/asm-arm/arch-omap3/ticpgmac.h | 14 ++-- + include/configs/omap3517evm.h | 1 + + net/tftp.c | 4 +- + 6 files changed, 109 insertions(+), 73 deletions(-) + +diff --git a/board/omap3/omap3517evm/omap3517evm.c b/board/omap3/omap3517evm/omap3517evm.c +index 2330776..bf304e3 100644 +--- a/board/omap3/omap3517evm/omap3517evm.c ++++ b/board/omap3/omap3517evm/omap3517evm.c +@@ -65,7 +65,11 @@ int misc_init_r(void) + #endif + + #if defined(CONFIG_CMD_NET) +- setup_net_chip(); ++ //setup_net_chip(); ++ if (!eth_hw_init()) { ++ printf("error:Ethernet init failed\n"); ++ } ++ + #endif + + dieid_num_r(); +diff --git a/board/omap3/omap3517evm/omap3517evm.h b/board/omap3/omap3517evm/omap3517evm.h +index c3ea037..65276b8 100644 +--- a/board/omap3/omap3517evm/omap3517evm.h ++++ b/board/omap3/omap3517evm/omap3517evm.h +@@ -337,15 +337,15 @@ static void setup_net_chip(void); + MUX_VAL(CP(CCDC_DATA5), (IEN | PTD | EN | M0)) /*ccdc_data5*/\ + MUX_VAL(CP(CCDC_DATA6), (IEN | PTD | EN | M0)) /*ccdc_data6*/\ + MUX_VAL(CP(CCDC_DATA7), (IEN | PTD | EN | M0)) /*ccdc_data7*/\ +- MUX_VAL(CP(RMII_MDIO_DATA), (IEN | PTD | EN | M0)) /*rmii_mdio_data*/\ +- MUX_VAL(CP(RMII_MDIO_CLK), (IEN | PTD | EN | M0)) /*rmii_mdio_clk*/\ +- MUX_VAL(CP(RMII_RXD0) , (IEN | PTD | EN | M0)) /*rmii_rxd0*/\ +- MUX_VAL(CP(RMII_RXD1), (IEN | PTD | EN | M0)) /*rmii_rxd1*/\ +- MUX_VAL(CP(RMII_CRS_DV), (IEN | PTD | EN | M0)) /*rmii_crs_dv*/\ +- MUX_VAL(CP(RMII_RXER), (IEN | PTD | EN | M0)) /*rmii_rxer*/\ +- MUX_VAL(CP(RMII_TXD0), (IEN | PTD | EN | M0)) /*rmii_txd0*/\ +- MUX_VAL(CP(RMII_TXD1), (IEN | PTD | EN | M0)) /*rmii_txd1*/\ +- MUX_VAL(CP(RMII_TXEN), (IEN | PTD | EN | M0)) /*rmii_txen*/\ ++ MUX_VAL(CP(RMII_MDIO_DATA), (PTD | M0)) /*rmii_mdio_data*/\ ++ MUX_VAL(CP(RMII_MDIO_CLK), (PTD | M0)) /*rmii_mdio_clk*/\ ++ MUX_VAL(CP(RMII_RXD0) , (IEN | PTD | M0)) /*rmii_rxd0*/\ ++ MUX_VAL(CP(RMII_RXD1), (IEN | PTD | M0)) /*rmii_rxd1*/\ ++ MUX_VAL(CP(RMII_CRS_DV), (IEN | PTD | M0)) /*rmii_crs_dv*/\ ++ MUX_VAL(CP(RMII_RXER), (PTD | M0)) /*rmii_rxer*/\ ++ MUX_VAL(CP(RMII_TXD0), (PTD | M0)) /*rmii_txd0*/\ ++ MUX_VAL(CP(RMII_TXD1), (PTD | M0)) /*rmii_txd1*/\ ++ MUX_VAL(CP(RMII_TXEN), (PTD | M0)) /*rmii_txen*/\ + MUX_VAL(CP(RMII_50MHZ_CLK), (IEN | PTD | EN | M0)) /*rmii_50mhz_clk*/\ + MUX_VAL(CP(USB0_DRVBUS), (IEN | PTD | EN | M0)) /*usb0_drvbus*/\ + MUX_VAL(CP(HECCL_TXD), (IEN | PTD | EN | M0)) /*heccl_txd*/\ +diff --git a/drivers/net/ticpgmac.c b/drivers/net/ticpgmac.c +index e83b951..350fb9b 100644 +--- a/drivers/net/ticpgmac.c ++++ b/drivers/net/ticpgmac.c +@@ -42,25 +42,34 @@ + #include + #include + ++ ++#define STATIC ++#define PRINTF(args,...) ++ + #ifdef CONFIG_DRIVER_TI_EMAC + + #ifdef CONFIG_CMD_NET + +-unsigned int emac_dbg = 0; ++unsigned int emac_dbg = 1; + #define debug_emac(fmt,args...) if (emac_dbg) printf(fmt,##args) + ++#define BD_TO_HW(x) \ ++ ( ( (x) == 0) ? 0 : ( (x) - EMAC_WRAPPER_RAM_ADDR + EMAC_HW_RAM_ADDR )) ++#define HW_TO_BD(x) \ ++ ( ( (x) == 0) ? 0 : ( (x) - EMAC_HW_RAM_ADDR + EMAC_WRAPPER_RAM_ADDR )) ++ + /* Internal static functions */ +-static int cpgmac_eth_hw_init (void); +-static int cpgmac_eth_open (void); +-static int cpgmac_eth_close (void); +-static int cpgmac_eth_send_packet (volatile void *packet, int length); +-static int cpgmac_eth_rcv_packet (void); +-static void cpgmac_eth_mdio_enable(void); +- +-static int gen_init_phy(int phy_addr); +-static int gen_is_phy_connected(int phy_addr); +-static int gen_get_link_status(int phy_addr); +-static int gen_auto_negotiate(int phy_addr); ++STATIC int cpgmac_eth_hw_init (void); ++STATIC int cpgmac_eth_open (void); ++STATIC int cpgmac_eth_close (void); ++STATIC int cpgmac_eth_send_packet (volatile void *packet, int length); ++STATIC int cpgmac_eth_rcv_packet (void); ++STATIC void cpgmac_eth_mdio_enable(void); ++ ++STATIC int gen_init_phy(int phy_addr); ++STATIC int gen_is_phy_connected(int phy_addr); ++STATIC int gen_get_link_status(int phy_addr); ++STATIC int gen_auto_negotiate(int phy_addr); + + /* Wrappers exported to the U-Boot proper */ + int eth_hw_init(void) +@@ -96,7 +105,7 @@ void eth_mdio_enable(void) + + /* cpgmac_eth_mac_addr[0] goes out on the wire first */ + +-static u_int8_t cpgmac_eth_mac_addr[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0x00 }; ++STATIC u_int8_t cpgmac_eth_mac_addr[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0x00 }; + + /* + * This function must be called before emac_open() if you want to override +@@ -112,26 +121,26 @@ void cpgmac_eth_set_mac_addr(const u_int8_t *addr) + } + + /* EMAC Addresses */ +-static volatile emac_regs *adap_emac = (emac_regs *)EMAC_BASE_ADDR; +-static volatile ewrap_regs *adap_ewrap = (ewrap_regs *)EMAC_WRAPPER_BASE_ADDR; +-static volatile mdio_regs *adap_mdio = (mdio_regs *)EMAC_MDIO_BASE_ADDR; ++STATIC volatile emac_regs *adap_emac = (emac_regs *)EMAC_BASE_ADDR; ++STATIC volatile ewrap_regs *adap_ewrap = (ewrap_regs *)EMAC_WRAPPER_BASE_ADDR; ++STATIC volatile mdio_regs *adap_mdio = (mdio_regs *)EMAC_MDIO_BASE_ADDR; + + /* EMAC descriptors */ +-static volatile emac_desc *emac_rx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE); +-static volatile emac_desc *emac_tx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE); +-static volatile emac_desc *emac_rx_active_head = 0; +-static volatile emac_desc *emac_rx_active_tail = 0; +-static int emac_rx_queue_active = 0; ++STATIC volatile emac_desc *emac_rx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE); ++STATIC volatile emac_desc *emac_tx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE); ++STATIC volatile emac_desc *emac_rx_active_head = 0; ++STATIC volatile emac_desc *emac_rx_active_tail = 0; ++STATIC int emac_rx_queue_active = 0; + + /* Receive packet buffers */ +-static unsigned char emac_rx_buffers[EMAC_MAX_RX_BUFFERS * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)]; ++STATIC unsigned char emac_rx_buffers[EMAC_MAX_RX_BUFFERS * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)]; + + /* PHY address for a discovered PHY (0xff - not found) */ +-static volatile u_int8_t active_phy_addr = 0xff; ++STATIC volatile u_int8_t active_phy_addr = 0xff; + +-static int no_phy_init (int phy_addr) { return(1); } +-static int no_phy_is_connected (int phy_addr) { return(1); } +-static int no_phy_get_link_status (int phy_addr) ++STATIC int no_phy_init (int phy_addr) { return(1); } ++STATIC int no_phy_is_connected (int phy_addr) { return(1); } ++STATIC int no_phy_get_link_status (int phy_addr) + { + adap_emac->MACCONTROL = (EMAC_MACCONTROL_MIIEN_ENABLE + | EMAC_MACCONTROL_FULLDUPLEX_ENABLE); +@@ -140,7 +149,7 @@ static int no_phy_get_link_status (int phy_addr) + #endif + return 1; + } +-static int no_phy_auto_negotiate (int phy_addr) { return(1); } ++STATIC int no_phy_auto_negotiate (int phy_addr) { return(1); } + phy_t phy = { + .init = no_phy_init, + .is_phy_connected = no_phy_is_connected, +@@ -148,7 +157,7 @@ phy_t phy = { + .auto_negotiate = no_phy_auto_negotiate + }; + +-static void cpgmac_eth_mdio_enable(void) ++STATIC void cpgmac_eth_mdio_enable(void) + { + u_int32_t clkdiv; + +@@ -168,7 +177,7 @@ static void cpgmac_eth_mdio_enable(void) + * returns 2 + * Sets active_phy_addr variable when returns 1. + */ +-static int cpgmac_eth_phy_detect(void) ++STATIC int cpgmac_eth_phy_detect(void) + { + u_int32_t phy_act_state; + int i; +@@ -238,7 +247,7 @@ int cpgmac_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data) + } + + /* PHY functions for a generic PHY */ +-static int gen_init_phy(int phy_addr) ++STATIC int gen_init_phy(int phy_addr) + { + int ret = 1; + +@@ -250,14 +259,14 @@ static int gen_init_phy(int phy_addr) + return(ret); + } + +-static int gen_is_phy_connected(int phy_addr) ++STATIC int gen_is_phy_connected(int phy_addr) + { + u_int16_t dummy; + + return(cpgmac_eth_phy_read(phy_addr, PHY_PHYIDR1, &dummy)); + } + +-static int gen_get_link_status(int phy_addr) ++STATIC int gen_get_link_status(int phy_addr) + { + u_int16_t tmp; + +@@ -288,7 +297,7 @@ static int gen_get_link_status(int phy_addr) + return(0); + } + +-static int gen_auto_negotiate(int phy_addr) ++STATIC int gen_auto_negotiate(int phy_addr) + { + u_int16_t tmp; + +@@ -313,12 +322,12 @@ static int gen_auto_negotiate(int phy_addr) + + + #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) +-static int cpgmac_mii_phy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value) ++STATIC int cpgmac_mii_phy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value) + { + return(cpgmac_eth_phy_read(addr, reg, value) ? 0 : 1); + } + +-static int cpgmac_mii_phy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value) ++STATIC int cpgmac_mii_phy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value) + { + return(cpgmac_eth_phy_write(addr, reg, value) ? 0 : 1); + } +@@ -336,7 +345,7 @@ int cpgmac_eth_miiphy_initialize(bd_t *bis) + * EMAC modules power or pin multiplexors, that is done by board_init() + * much earlier in bootup process. Returns 1 on success, 0 otherwise. + */ +-static int cpgmac_eth_hw_init(void) ++STATIC int cpgmac_eth_hw_init(void) + { + u_int32_t phy_id; + u_int16_t tmp; +@@ -395,7 +404,7 @@ static int cpgmac_eth_hw_init(void) + + + /* Eth device open */ +-static int cpgmac_eth_open(void) ++STATIC int cpgmac_eth_open(void) + { + dv_reg_p addr; + u_int32_t clkdiv, cnt; +@@ -467,7 +476,7 @@ static int cpgmac_eth_open(void) + /* Create RX queue and set receive process in place */ + emac_rx_active_head = emac_rx_desc; + for (cnt = 0; cnt < EMAC_MAX_RX_BUFFERS; cnt++) { +- rx_desc->next = (u_int32_t)(rx_desc + 1); ++ rx_desc->next =BD_TO_HW( (u_int32_t)(rx_desc + 1) ); + rx_desc->buffer = &emac_rx_buffers[cnt * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)]; + rx_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE; + rx_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT; +@@ -500,7 +509,7 @@ static int cpgmac_eth_open(void) + return(0); + + /* Start receive process */ +- adap_emac->RX0HDP = (u_int32_t)emac_rx_desc; ++ adap_emac->RX0HDP = BD_TO_HW((u_int32_t)emac_rx_desc); + + debug_emac("- emac_open\n"); + +@@ -508,7 +517,7 @@ static int cpgmac_eth_open(void) + } + + /* EMAC Channel Teardown */ +-static void cpgmac_eth_ch_teardown(int ch) ++STATIC void cpgmac_eth_ch_teardown(int ch) + { + dv_reg dly = 0xff; + dv_reg cnt; +@@ -551,7 +560,7 @@ static void cpgmac_eth_ch_teardown(int ch) + } + + /* Eth device close */ +-static int cpgmac_eth_close(void) ++STATIC int cpgmac_eth_close(void) + { + debug_emac("+ emac_close\n"); + +@@ -570,13 +579,13 @@ static int cpgmac_eth_close(void) + return(1); + } + +-static int tx_send_loop = 0; ++STATIC int tx_send_loop = 0; + + /* + * This function sends a single packet on the network and returns + * positive number (number of bytes transmitted) or negative for error + */ +-static int cpgmac_eth_send_packet (volatile void *packet, int length) ++STATIC int cpgmac_eth_send_packet (volatile void *packet, int length) + { + int ret_status = -1; + tx_send_loop = 0; +@@ -600,17 +609,30 @@ static int cpgmac_eth_send_packet (volatile void *packet, int length) + EMAC_CPPI_SOP_BIT | + EMAC_CPPI_OWNERSHIP_BIT | + EMAC_CPPI_EOP_BIT); ++ ++ if (!phy.get_link_status (active_phy_addr)) { ++ printf("Link down . Abort Tx - pHY %d\n",active_phy_addr); ++ cpgmac_eth_ch_teardown (EMAC_CH_TX); ++ return (ret_status); ++ } ++ + /* Send the packet */ +- adap_emac->TX0HDP = (unsigned int) emac_tx_desc; ++ adap_emac->TX0HDP = BD_TO_HW((unsigned int) emac_tx_desc); ++ PRINTF("Send: BD=0x%X BF=0x%x len=%d \n", emac_tx_desc, emac_tx_desc->buffer, length); ++// udelay(2500); + + /* Wait for packet to complete or link down */ + while (1) { ++ #if 0 + if (!phy.get_link_status (active_phy_addr)) { ++ printf("Link down . Abort Tx - pHY %d\n",active_phy_addr); + cpgmac_eth_ch_teardown (EMAC_CH_TX); + return (ret_status); + } ++ #endif + if (adap_emac->TXINTSTATRAW & 0x01) { + ret_status = length; ++ //PRINTF("Send Complete: BD=0x%X BF=0x%x len=%d \n", emac_tx_desc, emac_tx_desc->buffer, length); + break; + } + tx_send_loop++; +@@ -622,7 +644,7 @@ static int cpgmac_eth_send_packet (volatile void *packet, int length) + /* + * This function handles receipt of a packet from the network + */ +-static int cpgmac_eth_rcv_packet (void) ++STATIC int cpgmac_eth_rcv_packet (void) + { + volatile emac_desc *rx_curr_desc; + volatile emac_desc *curr_desc; +@@ -642,18 +664,21 @@ static int cpgmac_eth_rcv_packet (void) + } + + /* Ack received packet descriptor */ +- adap_emac->RX0CP = (unsigned int) rx_curr_desc; ++ adap_emac->RX0CP = BD_TO_HW((unsigned int) rx_curr_desc); + curr_desc = rx_curr_desc; + emac_rx_active_head = +- (volatile emac_desc *) rx_curr_desc->next; ++ (volatile emac_desc *) (HW_TO_BD(rx_curr_desc->next)); ++ PRINTF("New Rx Active head 0x%x \n",emac_rx_active_head); ++ + + if (status & EMAC_CPPI_EOQ_BIT) { + if (emac_rx_active_head) { + adap_emac->RX0HDP = +- (unsigned int) emac_rx_active_head; ++ BD_TO_HW((unsigned int) emac_rx_active_head); ++ PRINTF("Rx EOQ reset HDP for misqueued pkt 0x%x \n",emac_rx_active_head); + } else { + emac_rx_queue_active = 0; +- printf ("INFO:emac_rcv_packet: RX Queue not active\n"); ++ PRINTF ("INFO:emac_rcv_packet: RX Queue not active\n"); + } + } + +@@ -663,24 +688,28 @@ static int cpgmac_eth_rcv_packet (void) + rx_curr_desc->next = 0; + + if (emac_rx_active_head == 0) { +- printf ("INFO: emac_rcv_pkt: active queue head = 0\n"); ++ // printf ("INFO: emac_rcv_pkt: active queue head = 0\n"); ++ PRINTF(" Rx active head NULL, set head/tail to 0x%x",curr_desc); + emac_rx_active_head = curr_desc; + emac_rx_active_tail = curr_desc; +- if (emac_rx_queue_active != 0) { ++ if (emac_rx_queue_active == 0) { + adap_emac->RX0HDP = +- (unsigned int) emac_rx_active_head; +- printf ("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n"); ++ BD_TO_HW((unsigned int) emac_rx_active_head); ++ //printf ("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n"); ++ PRINTF("Rx Q inactive , set HDP to 0x%x \n", emac_rx_active_head); + emac_rx_queue_active = 1; + } + } else { ++ PRINTF("Append 0x%x to tail \n", curr_desc); + tail_desc = emac_rx_active_tail; + emac_rx_active_tail = curr_desc; +- tail_desc->next = (unsigned int) curr_desc; ++ tail_desc->next = BD_TO_HW((unsigned int) curr_desc); + status = tail_desc->pkt_flag_len; + if (status & EMAC_CPPI_EOQ_BIT) { +- adap_emac->RX0HDP = (unsigned int) curr_desc; + status &= ~EMAC_CPPI_EOQ_BIT; + tail_desc->pkt_flag_len = status; ++ adap_emac->RX0HDP = BD_TO_HW((unsigned int) curr_desc); ++ PRINTF("Restart the Q in tail append case\n"); + } + } + return (ret); +diff --git a/include/asm-arm/arch-omap3/ticpgmac.h b/include/asm-arm/arch-omap3/ticpgmac.h +index d7d77c9..10ec187 100644 +--- a/include/asm-arm/arch-omap3/ticpgmac.h ++++ b/include/asm-arm/arch-omap3/ticpgmac.h +@@ -36,20 +36,22 @@ + #ifndef _TI_CPGMAC_H_ + #define _TI_CPGMAC_H_ + +-#define DAVINCI_EMAC_CNTRL_REGS_BASE 0 +-#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE 0 +-#define DAVINCI_EMAC_WRAPPER_RAM_BASE 0 ++#define DAVINCI_EMAC_CNTRL_REGS_BASE 0x5C010000 ++#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE 0x5C000000 ++#define DAVINCI_EMAC_WRAPPER_RAM_BASE 0x5C020000 + + #define EMAC_BASE_ADDR DAVINCI_EMAC_CNTRL_REGS_BASE + #define EMAC_WRAPPER_BASE_ADDR DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE + #define EMAC_WRAPPER_RAM_ADDR DAVINCI_EMAC_WRAPPER_RAM_BASE + #define EMAC_MDIO_BASE_ADDR 0x5C030000 + ++#define EMAC_HW_RAM_ADDR 0x01E20000 ++ + /* MDIO module input frequency */ +-#define EMAC_MDIO_BUS_FREQ 26000000 /* 26 MHZ check */ ++#define EMAC_MDIO_BUS_FREQ 166000000 /* 166 MHZ check */ + + /* MDIO clock output frequency */ +-#define EMAC_MDIO_CLOCK_FREQ 2000000 /* 2.0 MHz */ ++#define EMAC_MDIO_CLOCK_FREQ 1000000 /* 2.0 MHz */ + + /* Ethernet Min/Max packet size */ + #define EMAC_MIN_ETHERNET_PKT_SIZE 60 +@@ -59,7 +61,7 @@ + /* Number of RX packet buffers + * NOTE: Only 1 buffer supported as of now + */ +-#define EMAC_MAX_RX_BUFFERS 10 ++#define EMAC_MAX_RX_BUFFERS 8 + + + /*********************************************** +diff --git a/include/configs/omap3517evm.h b/include/configs/omap3517evm.h +index c434b71..9fe3f72 100644 +--- a/include/configs/omap3517evm.h ++++ b/include/configs/omap3517evm.h +@@ -332,6 +332,7 @@ extern unsigned int boot_flash_type; + #if defined(CONFIG_CMD_NET) + #define CONFIG_TICPGMAC + #define CONFIG_DRIVER_TI_EMAC ++#define CONFIG_DRIVER_TI_EMAC_USE_RMII + #define CONFIG_MII + #define CONFIG_NET_RETRY_COUNT 10 + #endif /* (CONFIG_CMD_NET) */ +diff --git a/net/tftp.c b/net/tftp.c +index 3dac3d8..c779b88 100644 +--- a/net/tftp.c ++++ b/net/tftp.c +@@ -65,7 +65,7 @@ static int TftpState; + #define STATE_BAD_MAGIC 4 + #define STATE_OACK 5 + +-#define TFTP_BLOCK_SIZE 512 /* default TFTP block size */ ++#define TFTP_BLOCK_SIZE 512 /* default TFTP block size */ + #define TFTP_SEQUENCE_SIZE ((ulong)(1<<16)) /* sequence number is 16 bit */ + + #define DEFAULT_NAME_LEN (8 + 4 + 1) +@@ -87,7 +87,7 @@ extern flash_info_t flash_info[]; + * Minus eth.hdrs thats 1468. Can get 2x better throughput with + * almost-MTU block sizes. At least try... fall back to 512 if need be. + */ +-#define TFTP_MTU_BLOCKSIZE 1468 ++#define TFTP_MTU_BLOCKSIZE 512 + static unsigned short TftpBlkSize=TFTP_BLOCK_SIZE; + static unsigned short TftpBlkSizeOption=TFTP_MTU_BLOCKSIZE; + +-- +1.6.2.4 + diff --git a/recipes/u-boot/u-boot-git/omap3evm/0012-EMAC-driver-Implement-GPIO-driven-PHY-reset.patch b/recipes/u-boot/u-boot-git/omap3evm/0012-EMAC-driver-Implement-GPIO-driven-PHY-reset.patch new file mode 100644 index 0000000000..4650ecba16 --- /dev/null +++ b/recipes/u-boot/u-boot-git/omap3evm/0012-EMAC-driver-Implement-GPIO-driven-PHY-reset.patch @@ -0,0 +1,319 @@ +From 2cd2cbb5b87695b85471ceecf314146de0dba77e Mon Sep 17 00:00:00 2001 +From: Sriram +Date: Thu, 18 Jun 2009 01:53:03 +0530 +Subject: [PATCH 12/16] EMAC driver: Implement GPIO driven PHY reset. + +--- + board/omap3/omap3517evm/omap3517evm.c | 33 ++++++++++- + board/omap3/omap3517evm/omap3517evm.h | 6 +- + drivers/net/ticpgmac.c | 104 ++++++++++++++++++++++++++++++--- + include/asm-arm/arch-omap3/mux.h | 1 + + include/asm-arm/arch-omap3/ticpgmac.h | 17 +++++ + 5 files changed, 149 insertions(+), 12 deletions(-) + +diff --git a/board/omap3/omap3517evm/omap3517evm.c b/board/omap3/omap3517evm/omap3517evm.c +index bf304e3..0f8dc74 100644 +--- a/board/omap3/omap3517evm/omap3517evm.c ++++ b/board/omap3/omap3517evm/omap3517evm.c +@@ -65,7 +65,8 @@ int misc_init_r(void) + #endif + + #if defined(CONFIG_CMD_NET) +- //setup_net_chip(); ++ /* Drive the PHY reset thru GPIO 30 */ ++ setup_net_chip(); + if (!eth_hw_init()) { + printf("error:Ethernet init failed\n"); + } +@@ -95,6 +96,7 @@ void set_muxconf_regs(void) + *****************************************************************************/ + static void setup_net_chip(void) + { ++ #if 0 + gpio_t *gpio3_base = (gpio_t *)OMAP34XX_GPIO3_BASE; + gpmc_csx_t *gpmc_cs6_base = (gpmc_csx_t *)GPMC_CONFIG_CS6_BASE; + ctrl_t *ctrl_base = (ctrl_t *)OMAP34XX_CTRL_BASE; +@@ -125,4 +127,33 @@ static void setup_net_chip(void) + writel(GPIO0, &gpio3_base->cleardataout); + udelay(1); + writel(GPIO0, &gpio3_base->setdataout); ++ #else ++ volatile unsigned int ctr; ++ ++ gpio_t *gpio1_base = (gpio_t *)OMAP34XX_GPIO1_BASE; ++ ctrl_t *ctrl_base = (ctrl_t *)OMAP34XX_CTRL_BASE; ++ ++ ++ /* Make GPIO 30 as output pin */ ++ writel(readl(&gpio1_base->oe) & ~(GPIO30), &gpio1_base->oe); ++ ++ /* Now send a pulse on the GPIO pin */ ++ printf("Driving GPIO 30 low \n"); ++ writel(GPIO30, &gpio1_base->cleardataout); ++ ctr = 0; ++ do{ ++ udelay(1000); ++ ctr++; ++ }while (ctr <300); ++ ++ printf("Driving GPIO 30 high \n"); ++ writel(GPIO30, &gpio1_base->setdataout); ++ ctr =0; ++ /* allow the PHY to stabilize and settle down */ ++ do{ ++ udelay(1000); ++ ctr++; ++ }while (ctr <300); ++ ++ #endif + } +diff --git a/board/omap3/omap3517evm/omap3517evm.h b/board/omap3/omap3517evm/omap3517evm.h +index 65276b8..074d4ff 100644 +--- a/board/omap3/omap3517evm/omap3517evm.h ++++ b/board/omap3/omap3517evm/omap3517evm.h +@@ -287,6 +287,8 @@ static void setup_net_chip(void); + MUX_VAL(CP(SYS_32K), (IEN | PTD | DIS | M0)) /*SYS_32K*/\ + MUX_VAL(CP(SYS_CLKREQ), (IEN | PTD | DIS | M0)) /*SYS_CLKREQ*/\ + MUX_VAL(CP(SYS_NIRQ), (IEN | PTU | EN | M0)) /*SYS_nIRQ*/\ ++ MUX_VAL(CP(SYS_NRESWARM), (IDIS | PTU | DIS | M4)) /*SYS_nRESWARM */\ ++ /* GPIO 30 */\ + MUX_VAL(CP(SYS_BOOT0), (IEN | PTD | DIS | M4)) /*GPIO_2*/\ + /* - PEN_IRQ */\ + MUX_VAL(CP(SYS_BOOT1), (IEN | PTD | DIS | M4)) /*GPIO_3 */\ +@@ -337,8 +339,8 @@ static void setup_net_chip(void); + MUX_VAL(CP(CCDC_DATA5), (IEN | PTD | EN | M0)) /*ccdc_data5*/\ + MUX_VAL(CP(CCDC_DATA6), (IEN | PTD | EN | M0)) /*ccdc_data6*/\ + MUX_VAL(CP(CCDC_DATA7), (IEN | PTD | EN | M0)) /*ccdc_data7*/\ +- MUX_VAL(CP(RMII_MDIO_DATA), (PTD | M0)) /*rmii_mdio_data*/\ +- MUX_VAL(CP(RMII_MDIO_CLK), (PTD | M0)) /*rmii_mdio_clk*/\ ++ MUX_VAL(CP(RMII_MDIO_DATA), (IEN | M0)) /*rmii_mdio_data*/\ ++ MUX_VAL(CP(RMII_MDIO_CLK), (M0)) /*rmii_mdio_clk*/\ + MUX_VAL(CP(RMII_RXD0) , (IEN | PTD | M0)) /*rmii_rxd0*/\ + MUX_VAL(CP(RMII_RXD1), (IEN | PTD | M0)) /*rmii_rxd1*/\ + MUX_VAL(CP(RMII_CRS_DV), (IEN | PTD | M0)) /*rmii_crs_dv*/\ +diff --git a/drivers/net/ticpgmac.c b/drivers/net/ticpgmac.c +index 350fb9b..eeff23b 100644 +--- a/drivers/net/ticpgmac.c ++++ b/drivers/net/ticpgmac.c +@@ -268,26 +268,44 @@ STATIC int gen_is_phy_connected(int phy_addr) + + STATIC int gen_get_link_status(int phy_addr) + { +- u_int16_t tmp; ++ u_int16_t tmp,lpa_val,val; + + if (cpgmac_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp) + && (tmp & 0x04)) { ++ //printf("Phy %d MII_Status Reg=0x%x \n",phy_addr,tmp); ++ //printf("MACCTRL 0x%x\n",adap_emac->MACCONTROL); + ++ cpgmac_eth_phy_read(phy_addr,MII_CTRL_REG,&val); ++ //printf("Phy CTRL=0x%x \n",val); ++ ++ cpgmac_eth_phy_read(phy_addr,ANEG_ADVERTISE_REG,&val); ++ // printf("Phy ANEG ADV=0x%x \n",val); ++ ++ cpgmac_eth_phy_read(phy_addr,ANEG_LPA_REG,&lpa_val); ++ //printf("Phy ANEG LPA=0x%x \n",lpa_val); ++ + /* Speed doesn't matter, there is no setting for it in EMAC. */ +- if (tmp & GEN_PHY_STATUS_FD_MASK) { ++ //if (tmp & GEN_PHY_STATUS_FD_MASK) { ++ if (lpa_val & (GEN_PHY_ANEG_100DUP | GEN_PHY_ANEG_10DUP ) ) { + /* set EMAC for Full Duplex */ ++ // printf("Set MACCTRL for full duplex \n"); + adap_emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | + EMAC_MACCONTROL_FULLDUPLEX_ENABLE; + } else { + /*set EMAC for Half Duplex */ + adap_emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE; ++ // printf("Set MACCTRL for HALF duplex \n"); + } + + #ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII +- if(tmp & GEN_PHY_STATUS_SPEED100_MASK) { ++ //if(tmp & GEN_PHY_STATUS_SPEED100_MASK) { ++ if (lpa_val & (GEN_PHY_ANEG_100DUP | GEN_PHY_ANEG_100TX ) ) { + adap_emac->MACCONTROL |= EMAC_MACCONTROL_RMIISPEED_100; ++ // printf("Set maccontrol for RMII 100 - 0x%x\n",adap_emac->MACCONTROL); ++ + } else { + adap_emac->MACCONTROL &= ~EMAC_MACCONTROL_RMIISPEED_100; ++ printf("Set maccontrol for RMII 10 - 0x%x\n",adap_emac->MACCONTROL); + } + #endif + +@@ -299,20 +317,62 @@ STATIC int gen_get_link_status(int phy_addr) + + STATIC int gen_auto_negotiate(int phy_addr) + { +- u_int16_t tmp; ++ u_int16_t tmp,val; ++ unsigned long cntr =0; + + if (!cpgmac_eth_phy_read(phy_addr, PHY_BMCR, &tmp)) + return(0); + ++ printf("read BMCR 0x%x\n",tmp); ++ ++ val = tmp | GEN_PHY_CTRL_DUP | GEN_PHY_CTRL_ENA_ANEG | GEN_PHY_CTRL_SPD_SEL ; ++ cpgmac_eth_phy_write(phy_addr, PHY_BMCR, val); ++ cpgmac_eth_phy_read(phy_addr, PHY_BMCR, &val); ++ printf("BMCR set to 0x%X \n",val); ++ ++ cpgmac_eth_phy_read(phy_addr,ANEG_ADVERTISE_REG, &val); ++ printf("read ANEG 0x%x \n",val); ++ val |= ( GEN_PHY_ANEG_100DUP | GEN_PHY_ANEG_100TX | GEN_PHY_ANEG_10DUP | GEN_PHY_ANEG_10TX ); ++ printf("writing back 0x%x \n",val); ++ cpgmac_eth_phy_write(phy_addr, ANEG_ADVERTISE_REG, val); ++ cpgmac_eth_phy_read(phy_addr,ANEG_ADVERTISE_REG, &val); ++ printf("ANEG ADVT set to 0x%x \n", val); ++ ++ ++ printf("Restart Auto-negn \n"); ++ cpgmac_eth_phy_read(phy_addr, PHY_BMCR, &tmp); ++ + /* Restart Auto_negotiation */ +- tmp |= PHY_BMCR_AUTON; ++ tmp |= PHY_BMCR_RST_NEG; ++ printf("writing bk 0x%x to BMCR for anegn \n",tmp); + cpgmac_eth_phy_write(phy_addr, PHY_BMCR, tmp); + + /*check AutoNegotiate complete */ +- udelay (10000); ++ //udelay (10000); ++ do{ ++ udelay(40000); ++ cntr++; ++ }while(cntr < 150 ); ++ + if (!cpgmac_eth_phy_read(phy_addr, PHY_BMSR, &tmp)) + return(0); ++ printf("BMSR after negn 0x%X\n",tmp); + ++ cpgmac_eth_phy_read(phy_addr,MII_CTRL_REG,&val); ++ printf("Phy CTRL=0x%x \n",val); ++ ++ cpgmac_eth_phy_read(phy_addr,ANEG_ADVERTISE_REG,&val); ++ printf("Phy ANEG ADV=0x%x \n",val); ++ ++ cpgmac_eth_phy_read(phy_addr,ANEG_LPA_REG,&val); ++ printf("Phy ANEG LPA=0x%x \n",val); ++ ++ cpgmac_eth_phy_read(phy_addr,ANEG_EXP_REG,&val); ++ printf("Phy ANEG eXP=0x%x \n",val); ++ ++ cpgmac_eth_phy_read(phy_addr,SPL_VEND_REG,&val); ++ printf("Phy SPL VEND =0x%x \n",val); ++ + if (!(tmp & PHY_BMSR_AUTN_COMP)) + return(0); + +@@ -324,16 +384,20 @@ STATIC int gen_auto_negotiate(int phy_addr) + #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) + STATIC int cpgmac_mii_phy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value) + { ++ printf("MII Phy read \n"); + return(cpgmac_eth_phy_read(addr, reg, value) ? 0 : 1); + } + + STATIC int cpgmac_mii_phy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value) + { ++ ++ printf("MII Phy write \n"); + return(cpgmac_eth_phy_write(addr, reg, value) ? 0 : 1); + } + + int cpgmac_eth_miiphy_initialize(bd_t *bis) + { ++ printf("MIIPHY initialize \n"); + miiphy_register(phy.name, cpgmac_mii_phy_read, cpgmac_mii_phy_write); + + return(1); +@@ -399,6 +463,28 @@ STATIC int cpgmac_eth_hw_init(void) + + printf("Ethernet PHY: %s\n", phy.name); + ++ /* Override HW configuration value that were latched */ ++ cpgmac_eth_phy_read(active_phy_addr, SPL_VEND_REG, &tmp); ++ printf("read HW config for PHY 0x%x\n",tmp); ++// tmp |= (1 << 14) | ( 7 << 5) ; ++ tmp = 0x60e0; ++ printf("Program HW config as 0x%x \n",tmp); ++ cpgmac_eth_phy_write(active_phy_addr,SPL_VEND_REG,tmp); ++ ++ /* Soft reset the PHY */ ++ cpgmac_eth_phy_write(active_phy_addr, PHY_BMCR, (1 << 15)); ++ ++ active_phy_addr = 0; ++ ++ do ++ { ++ cpgmac_eth_phy_read(active_phy_addr, PHY_BMCR , &tmp); ++ ++ }while (tmp & (1 << 15)); ++ ++ ++ ++ + return(1); + } + +@@ -505,7 +591,7 @@ STATIC int cpgmac_eth_open(void) + clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1; + adap_mdio->CONTROL = ((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT); + +- if (!phy.get_link_status(active_phy_addr)) ++ if (!phy.auto_negotiate(active_phy_addr)) + return(0); + + /* Start receive process */ +diff --git a/include/asm-arm/arch-omap3/mux.h b/include/asm-arm/arch-omap3/mux.h +index d94eb2d..3e4a2ee 100644 +--- a/include/asm-arm/arch-omap3/mux.h ++++ b/include/asm-arm/arch-omap3/mux.h +@@ -284,6 +284,7 @@ + #define CONTROL_PADCONF_SYS_32K 0x0A04 + #define CONTROL_PADCONF_SYS_CLKREQ 0x0A06 + #define CONTROL_PADCONF_SYS_NIRQ 0x01E0 ++#define CONTROL_PADCONF_SYS_NRESWARM 0x0A08 + #define CONTROL_PADCONF_SYS_BOOT0 0x0A0A + #define CONTROL_PADCONF_SYS_BOOT1 0x0A0C + #define CONTROL_PADCONF_SYS_BOOT2 0x0A0E +diff --git a/include/asm-arm/arch-omap3/ticpgmac.h b/include/asm-arm/arch-omap3/ticpgmac.h +index 10ec187..2a7c886 100644 +--- a/include/asm-arm/arch-omap3/ticpgmac.h ++++ b/include/asm-arm/arch-omap3/ticpgmac.h +@@ -81,7 +81,12 @@ + #define EMAC_TEARDOWN_VALUE 0xfffffffc + + /* MII Status Register */ ++#define MII_CTRL_REG 0 + #define MII_STATUS_REG 1 ++#define ANEG_ADVERTISE_REG 4 ++#define ANEG_LPA_REG 5 ++#define ANEG_EXP_REG 6 ++#define SPL_VEND_REG 18 + + /* Number of statistics registers */ + #define EMAC_NUM_STATS 36 +@@ -339,4 +344,16 @@ typedef struct + #define GEN_PHY_STATUS_SPEED100_MASK ((1 << 13) | (1 << 14)) + #define GEN_PHY_STATUS_FD_MASK ((1 << 11) | (1 << 13)) + ++#define GEN_PHY_ANEG_100DUP (1 << 8) ++#define GEN_PHY_ANEG_100TX (1 << 7) ++#define GEN_PHY_ANEG_10DUP (1 << 6) ++#define GEN_PHY_ANEG_10TX (1 << 5) ++ ++#define GEN_PHY_CTRL_RST_ANEG (1 << 9) ++#define GEN_PHY_CTRL_DUP (1 << 8) ++#define GEN_PHY_CTRL_ENA_ANEG (1 << 12) ++#define GEN_PHY_CTRL_SPD_SEL (1 << 13) ++ ++ ++ + #endif /* _TI_CPGMAC_H_ */ +-- +1.6.2.4 + diff --git a/recipes/u-boot/u-boot-git/omap3evm/0013-Cleaned-up-during-EVM-hang-issue.patch b/recipes/u-boot/u-boot-git/omap3evm/0013-Cleaned-up-during-EVM-hang-issue.patch new file mode 100644 index 0000000000..4173694e39 --- /dev/null +++ b/recipes/u-boot/u-boot-git/omap3evm/0013-Cleaned-up-during-EVM-hang-issue.patch @@ -0,0 +1,45 @@ +From f45b26a8511db31f1133dd247f75741e326f5aa7 Mon Sep 17 00:00:00 2001 +From: Vaibhav Hiremath +Date: Mon, 22 Jun 2009 23:42:51 +0530 +Subject: [PATCH 13/16] Cleaned up during EVM hang issue + +CKE0/1 pad configuration cleanup done during board hang issue debug. + +Removed PRCM_init function from u-boot, since x-loader is handling +the clock/DPLL configuration. +This need to be enabled, after fixing hang issue. +--- + board/omap3/omap3517evm/omap3517evm.h | 4 ++-- + cpu/arm_cortexa8/omap3/board.c | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/board/omap3/omap3517evm/omap3517evm.h b/board/omap3/omap3517evm/omap3517evm.h +index 074d4ff..5ce18bd 100644 +--- a/board/omap3/omap3517evm/omap3517evm.h ++++ b/board/omap3/omap3517evm/omap3517evm.h +@@ -390,7 +390,7 @@ static void setup_net_chip(void); + MUX_VAL(CP(D2D_SREAD), (IEN | PTD | DIS | M0)) /*d2d_sread*/\ + MUX_VAL(CP(D2D_MBUSFLAG), (IEN | PTD | DIS | M0)) /*d2d_mbusflag*/\ + MUX_VAL(CP(D2D_SBUSFLAG), (IEN | PTD | DIS | M0)) /*d2d_sbusflag*/\ +- MUX_VAL(CP(SDRC_CKE0), (IDIS | PTU | EN | M0)) /*sdrc_cke0*/\ +- MUX_VAL(CP(SDRC_CKE1), (IDIS | PTD | DIS | M7)) /*sdrc_cke1*/\ ++ MUX_VAL(CP(SDRC_CKE0), (M0)) /*sdrc_cke0*/\ ++ MUX_VAL(CP(SDRC_CKE1), (M0)) /*sdrc_cke1*/\ + + #endif +diff --git a/cpu/arm_cortexa8/omap3/board.c b/cpu/arm_cortexa8/omap3/board.c +index ea94e59..ff3603b 100644 +--- a/cpu/arm_cortexa8/omap3/board.c ++++ b/cpu/arm_cortexa8/omap3/board.c +@@ -219,7 +219,7 @@ void s_init(void) + set_muxconf_regs(); + delay(100); + +- prcm_init(); ++// prcm_init(); + + per_clocks_enable(); + +-- +1.6.2.4 + diff --git a/recipes/u-boot/u-boot-git/omap3evm/0014-EMAC-driver-cleanup-removed-debug-prints.patch b/recipes/u-boot/u-boot-git/omap3evm/0014-EMAC-driver-cleanup-removed-debug-prints.patch new file mode 100644 index 0000000000..5630ac6313 --- /dev/null +++ b/recipes/u-boot/u-boot-git/omap3evm/0014-EMAC-driver-cleanup-removed-debug-prints.patch @@ -0,0 +1,419 @@ +From 8ceef1101c96a5357a7ec82084a53e7001456170 Mon Sep 17 00:00:00 2001 +From: Sriram +Date: Mon, 29 Jun 2009 03:35:29 +0530 +Subject: [PATCH 14/16] EMAC driver: cleanup(removed debug prints) + +Cleaned up the EMAC driver : removed debug prints and other +debugging aids +--- + drivers/net/ticpgmac.c | 127 ++++++++++++++++------------------------------- + 1 files changed, 43 insertions(+), 84 deletions(-) + +diff --git a/drivers/net/ticpgmac.c b/drivers/net/ticpgmac.c +index eeff23b..78a54d8 100644 +--- a/drivers/net/ticpgmac.c ++++ b/drivers/net/ticpgmac.c +@@ -43,14 +43,11 @@ + #include + + +-#define STATIC +-#define PRINTF(args,...) +- + #ifdef CONFIG_DRIVER_TI_EMAC + + #ifdef CONFIG_CMD_NET + +-unsigned int emac_dbg = 1; ++unsigned int emac_dbg = 0; + #define debug_emac(fmt,args...) if (emac_dbg) printf(fmt,##args) + + #define BD_TO_HW(x) \ +@@ -59,17 +56,17 @@ unsigned int emac_dbg = 1; + ( ( (x) == 0) ? 0 : ( (x) - EMAC_HW_RAM_ADDR + EMAC_WRAPPER_RAM_ADDR )) + + /* Internal static functions */ +-STATIC int cpgmac_eth_hw_init (void); +-STATIC int cpgmac_eth_open (void); +-STATIC int cpgmac_eth_close (void); +-STATIC int cpgmac_eth_send_packet (volatile void *packet, int length); +-STATIC int cpgmac_eth_rcv_packet (void); +-STATIC void cpgmac_eth_mdio_enable(void); +- +-STATIC int gen_init_phy(int phy_addr); +-STATIC int gen_is_phy_connected(int phy_addr); +-STATIC int gen_get_link_status(int phy_addr); +-STATIC int gen_auto_negotiate(int phy_addr); ++static int cpgmac_eth_hw_init (void); ++static int cpgmac_eth_open (void); ++static int cpgmac_eth_close (void); ++static int cpgmac_eth_send_packet (volatile void *packet, int length); ++static int cpgmac_eth_rcv_packet (void); ++static void cpgmac_eth_mdio_enable(void); ++ ++static int gen_init_phy(int phy_addr); ++static int gen_is_phy_connected(int phy_addr); ++static int gen_get_link_status(int phy_addr); ++static int gen_auto_negotiate(int phy_addr); + + /* Wrappers exported to the U-Boot proper */ + int eth_hw_init(void) +@@ -105,7 +102,7 @@ void eth_mdio_enable(void) + + /* cpgmac_eth_mac_addr[0] goes out on the wire first */ + +-STATIC u_int8_t cpgmac_eth_mac_addr[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0x00 }; ++static u_int8_t cpgmac_eth_mac_addr[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0x00 }; + + /* + * This function must be called before emac_open() if you want to override +@@ -121,26 +118,26 @@ void cpgmac_eth_set_mac_addr(const u_int8_t *addr) + } + + /* EMAC Addresses */ +-STATIC volatile emac_regs *adap_emac = (emac_regs *)EMAC_BASE_ADDR; +-STATIC volatile ewrap_regs *adap_ewrap = (ewrap_regs *)EMAC_WRAPPER_BASE_ADDR; +-STATIC volatile mdio_regs *adap_mdio = (mdio_regs *)EMAC_MDIO_BASE_ADDR; ++static volatile emac_regs *adap_emac = (emac_regs *)EMAC_BASE_ADDR; ++static volatile ewrap_regs *adap_ewrap = (ewrap_regs *)EMAC_WRAPPER_BASE_ADDR; ++static volatile mdio_regs *adap_mdio = (mdio_regs *)EMAC_MDIO_BASE_ADDR; + + /* EMAC descriptors */ +-STATIC volatile emac_desc *emac_rx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE); +-STATIC volatile emac_desc *emac_tx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE); +-STATIC volatile emac_desc *emac_rx_active_head = 0; +-STATIC volatile emac_desc *emac_rx_active_tail = 0; +-STATIC int emac_rx_queue_active = 0; ++static volatile emac_desc *emac_rx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE); ++static volatile emac_desc *emac_tx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE); ++static volatile emac_desc *emac_rx_active_head = 0; ++static volatile emac_desc *emac_rx_active_tail = 0; ++static int emac_rx_queue_active = 0; + + /* Receive packet buffers */ +-STATIC unsigned char emac_rx_buffers[EMAC_MAX_RX_BUFFERS * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)]; ++static unsigned char emac_rx_buffers[EMAC_MAX_RX_BUFFERS * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)]; + + /* PHY address for a discovered PHY (0xff - not found) */ +-STATIC volatile u_int8_t active_phy_addr = 0xff; ++static volatile u_int8_t active_phy_addr = 0xff; + +-STATIC int no_phy_init (int phy_addr) { return(1); } +-STATIC int no_phy_is_connected (int phy_addr) { return(1); } +-STATIC int no_phy_get_link_status (int phy_addr) ++static int no_phy_init (int phy_addr) { return(1); } ++static int no_phy_is_connected (int phy_addr) { return(1); } ++static int no_phy_get_link_status (int phy_addr) + { + adap_emac->MACCONTROL = (EMAC_MACCONTROL_MIIEN_ENABLE + | EMAC_MACCONTROL_FULLDUPLEX_ENABLE); +@@ -149,7 +146,7 @@ STATIC int no_phy_get_link_status (int phy_addr) + #endif + return 1; + } +-STATIC int no_phy_auto_negotiate (int phy_addr) { return(1); } ++static int no_phy_auto_negotiate (int phy_addr) { return(1); } + phy_t phy = { + .init = no_phy_init, + .is_phy_connected = no_phy_is_connected, +@@ -157,7 +154,7 @@ phy_t phy = { + .auto_negotiate = no_phy_auto_negotiate + }; + +-STATIC void cpgmac_eth_mdio_enable(void) ++static void cpgmac_eth_mdio_enable(void) + { + u_int32_t clkdiv; + +@@ -177,7 +174,7 @@ STATIC void cpgmac_eth_mdio_enable(void) + * returns 2 + * Sets active_phy_addr variable when returns 1. + */ +-STATIC int cpgmac_eth_phy_detect(void) ++static int cpgmac_eth_phy_detect(void) + { + u_int32_t phy_act_state; + int i; +@@ -247,7 +244,7 @@ int cpgmac_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data) + } + + /* PHY functions for a generic PHY */ +-STATIC int gen_init_phy(int phy_addr) ++static int gen_init_phy(int phy_addr) + { + int ret = 1; + +@@ -259,53 +256,44 @@ STATIC int gen_init_phy(int phy_addr) + return(ret); + } + +-STATIC int gen_is_phy_connected(int phy_addr) ++static int gen_is_phy_connected(int phy_addr) + { + u_int16_t dummy; + + return(cpgmac_eth_phy_read(phy_addr, PHY_PHYIDR1, &dummy)); + } + +-STATIC int gen_get_link_status(int phy_addr) ++static int gen_get_link_status(int phy_addr) + { + u_int16_t tmp,lpa_val,val; + + if (cpgmac_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp) + && (tmp & 0x04)) { +- //printf("Phy %d MII_Status Reg=0x%x \n",phy_addr,tmp); +- //printf("MACCTRL 0x%x\n",adap_emac->MACCONTROL); + + cpgmac_eth_phy_read(phy_addr,MII_CTRL_REG,&val); +- //printf("Phy CTRL=0x%x \n",val); + + cpgmac_eth_phy_read(phy_addr,ANEG_ADVERTISE_REG,&val); +- // printf("Phy ANEG ADV=0x%x \n",val); + + cpgmac_eth_phy_read(phy_addr,ANEG_LPA_REG,&lpa_val); +- //printf("Phy ANEG LPA=0x%x \n",lpa_val); + + /* Speed doesn't matter, there is no setting for it in EMAC. */ + //if (tmp & GEN_PHY_STATUS_FD_MASK) { + if (lpa_val & (GEN_PHY_ANEG_100DUP | GEN_PHY_ANEG_10DUP ) ) { + /* set EMAC for Full Duplex */ +- // printf("Set MACCTRL for full duplex \n"); + adap_emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | + EMAC_MACCONTROL_FULLDUPLEX_ENABLE; + } else { + /*set EMAC for Half Duplex */ + adap_emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE; +- // printf("Set MACCTRL for HALF duplex \n"); + } + + #ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII + //if(tmp & GEN_PHY_STATUS_SPEED100_MASK) { + if (lpa_val & (GEN_PHY_ANEG_100DUP | GEN_PHY_ANEG_100TX ) ) { + adap_emac->MACCONTROL |= EMAC_MACCONTROL_RMIISPEED_100; +- // printf("Set maccontrol for RMII 100 - 0x%x\n",adap_emac->MACCONTROL); + + } else { + adap_emac->MACCONTROL &= ~EMAC_MACCONTROL_RMIISPEED_100; +- printf("Set maccontrol for RMII 10 - 0x%x\n",adap_emac->MACCONTROL); + } + #endif + +@@ -315,7 +303,7 @@ STATIC int gen_get_link_status(int phy_addr) + return(0); + } + +-STATIC int gen_auto_negotiate(int phy_addr) ++static int gen_auto_negotiate(int phy_addr) + { + u_int16_t tmp,val; + unsigned long cntr =0; +@@ -323,55 +311,41 @@ STATIC int gen_auto_negotiate(int phy_addr) + if (!cpgmac_eth_phy_read(phy_addr, PHY_BMCR, &tmp)) + return(0); + +- printf("read BMCR 0x%x\n",tmp); + + val = tmp | GEN_PHY_CTRL_DUP | GEN_PHY_CTRL_ENA_ANEG | GEN_PHY_CTRL_SPD_SEL ; + cpgmac_eth_phy_write(phy_addr, PHY_BMCR, val); + cpgmac_eth_phy_read(phy_addr, PHY_BMCR, &val); +- printf("BMCR set to 0x%X \n",val); + + cpgmac_eth_phy_read(phy_addr,ANEG_ADVERTISE_REG, &val); +- printf("read ANEG 0x%x \n",val); + val |= ( GEN_PHY_ANEG_100DUP | GEN_PHY_ANEG_100TX | GEN_PHY_ANEG_10DUP | GEN_PHY_ANEG_10TX ); +- printf("writing back 0x%x \n",val); + cpgmac_eth_phy_write(phy_addr, ANEG_ADVERTISE_REG, val); + cpgmac_eth_phy_read(phy_addr,ANEG_ADVERTISE_REG, &val); +- printf("ANEG ADVT set to 0x%x \n", val); + + +- printf("Restart Auto-negn \n"); + cpgmac_eth_phy_read(phy_addr, PHY_BMCR, &tmp); + + /* Restart Auto_negotiation */ + tmp |= PHY_BMCR_RST_NEG; +- printf("writing bk 0x%x to BMCR for anegn \n",tmp); + cpgmac_eth_phy_write(phy_addr, PHY_BMCR, tmp); + + /*check AutoNegotiate complete */ +- //udelay (10000); + do{ + udelay(40000); + cntr++; +- }while(cntr < 150 ); ++ }while(cntr < 50 ); + + if (!cpgmac_eth_phy_read(phy_addr, PHY_BMSR, &tmp)) + return(0); +- printf("BMSR after negn 0x%X\n",tmp); + + cpgmac_eth_phy_read(phy_addr,MII_CTRL_REG,&val); +- printf("Phy CTRL=0x%x \n",val); + + cpgmac_eth_phy_read(phy_addr,ANEG_ADVERTISE_REG,&val); +- printf("Phy ANEG ADV=0x%x \n",val); + + cpgmac_eth_phy_read(phy_addr,ANEG_LPA_REG,&val); +- printf("Phy ANEG LPA=0x%x \n",val); + + cpgmac_eth_phy_read(phy_addr,ANEG_EXP_REG,&val); +- printf("Phy ANEG eXP=0x%x \n",val); + + cpgmac_eth_phy_read(phy_addr,SPL_VEND_REG,&val); +- printf("Phy SPL VEND =0x%x \n",val); + + if (!(tmp & PHY_BMSR_AUTN_COMP)) + return(0); +@@ -382,22 +356,19 @@ STATIC int gen_auto_negotiate(int phy_addr) + + + #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) +-STATIC int cpgmac_mii_phy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value) ++static int cpgmac_mii_phy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value) + { +- printf("MII Phy read \n"); + return(cpgmac_eth_phy_read(addr, reg, value) ? 0 : 1); + } + +-STATIC int cpgmac_mii_phy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value) ++static int cpgmac_mii_phy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value) + { + +- printf("MII Phy write \n"); + return(cpgmac_eth_phy_write(addr, reg, value) ? 0 : 1); + } + + int cpgmac_eth_miiphy_initialize(bd_t *bis) + { +- printf("MIIPHY initialize \n"); + miiphy_register(phy.name, cpgmac_mii_phy_read, cpgmac_mii_phy_write); + + return(1); +@@ -409,7 +380,7 @@ int cpgmac_eth_miiphy_initialize(bd_t *bis) + * EMAC modules power or pin multiplexors, that is done by board_init() + * much earlier in bootup process. Returns 1 on success, 0 otherwise. + */ +-STATIC int cpgmac_eth_hw_init(void) ++static int cpgmac_eth_hw_init(void) + { + u_int32_t phy_id; + u_int16_t tmp; +@@ -490,7 +461,7 @@ STATIC int cpgmac_eth_hw_init(void) + + + /* Eth device open */ +-STATIC int cpgmac_eth_open(void) ++static int cpgmac_eth_open(void) + { + dv_reg_p addr; + u_int32_t clkdiv, cnt; +@@ -603,7 +574,7 @@ STATIC int cpgmac_eth_open(void) + } + + /* EMAC Channel Teardown */ +-STATIC void cpgmac_eth_ch_teardown(int ch) ++static void cpgmac_eth_ch_teardown(int ch) + { + dv_reg dly = 0xff; + dv_reg cnt; +@@ -646,7 +617,7 @@ STATIC void cpgmac_eth_ch_teardown(int ch) + } + + /* Eth device close */ +-STATIC int cpgmac_eth_close(void) ++static int cpgmac_eth_close(void) + { + debug_emac("+ emac_close\n"); + +@@ -665,13 +636,13 @@ STATIC int cpgmac_eth_close(void) + return(1); + } + +-STATIC int tx_send_loop = 0; ++static int tx_send_loop = 0; + + /* + * This function sends a single packet on the network and returns + * positive number (number of bytes transmitted) or negative for error + */ +-STATIC int cpgmac_eth_send_packet (volatile void *packet, int length) ++static int cpgmac_eth_send_packet (volatile void *packet, int length) + { + int ret_status = -1; + tx_send_loop = 0; +@@ -704,8 +675,6 @@ STATIC int cpgmac_eth_send_packet (volatile void *packet, int length) + + /* Send the packet */ + adap_emac->TX0HDP = BD_TO_HW((unsigned int) emac_tx_desc); +- PRINTF("Send: BD=0x%X BF=0x%x len=%d \n", emac_tx_desc, emac_tx_desc->buffer, length); +-// udelay(2500); + + /* Wait for packet to complete or link down */ + while (1) { +@@ -718,7 +687,6 @@ STATIC int cpgmac_eth_send_packet (volatile void *packet, int length) + #endif + if (adap_emac->TXINTSTATRAW & 0x01) { + ret_status = length; +- //PRINTF("Send Complete: BD=0x%X BF=0x%x len=%d \n", emac_tx_desc, emac_tx_desc->buffer, length); + break; + } + tx_send_loop++; +@@ -730,7 +698,7 @@ STATIC int cpgmac_eth_send_packet (volatile void *packet, int length) + /* + * This function handles receipt of a packet from the network + */ +-STATIC int cpgmac_eth_rcv_packet (void) ++static int cpgmac_eth_rcv_packet (void) + { + volatile emac_desc *rx_curr_desc; + volatile emac_desc *curr_desc; +@@ -754,17 +722,14 @@ STATIC int cpgmac_eth_rcv_packet (void) + curr_desc = rx_curr_desc; + emac_rx_active_head = + (volatile emac_desc *) (HW_TO_BD(rx_curr_desc->next)); +- PRINTF("New Rx Active head 0x%x \n",emac_rx_active_head); + + + if (status & EMAC_CPPI_EOQ_BIT) { + if (emac_rx_active_head) { + adap_emac->RX0HDP = + BD_TO_HW((unsigned int) emac_rx_active_head); +- PRINTF("Rx EOQ reset HDP for misqueued pkt 0x%x \n",emac_rx_active_head); + } else { + emac_rx_queue_active = 0; +- PRINTF ("INFO:emac_rcv_packet: RX Queue not active\n"); + } + } + +@@ -774,19 +739,14 @@ STATIC int cpgmac_eth_rcv_packet (void) + rx_curr_desc->next = 0; + + if (emac_rx_active_head == 0) { +- // printf ("INFO: emac_rcv_pkt: active queue head = 0\n"); +- PRINTF(" Rx active head NULL, set head/tail to 0x%x",curr_desc); + emac_rx_active_head = curr_desc; + emac_rx_active_tail = curr_desc; + if (emac_rx_queue_active == 0) { + adap_emac->RX0HDP = + BD_TO_HW((unsigned int) emac_rx_active_head); +- //printf ("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n"); +- PRINTF("Rx Q inactive , set HDP to 0x%x \n", emac_rx_active_head); + emac_rx_queue_active = 1; + } + } else { +- PRINTF("Append 0x%x to tail \n", curr_desc); + tail_desc = emac_rx_active_tail; + emac_rx_active_tail = curr_desc; + tail_desc->next = BD_TO_HW((unsigned int) curr_desc); +@@ -795,7 +755,6 @@ STATIC int cpgmac_eth_rcv_packet (void) + status &= ~EMAC_CPPI_EOQ_BIT; + tail_desc->pkt_flag_len = status; + adap_emac->RX0HDP = BD_TO_HW((unsigned int) curr_desc); +- PRINTF("Restart the Q in tail append case\n"); + } + } + return (ret); +-- +1.6.2.4 + diff --git a/recipes/u-boot/u-boot-git/omap3evm/0015-EMAC-driver-Check-for-link-status-in-packet-send-lo.patch b/recipes/u-boot/u-boot-git/omap3evm/0015-EMAC-driver-Check-for-link-status-in-packet-send-lo.patch new file mode 100644 index 0000000000..cd440e4154 --- /dev/null +++ b/recipes/u-boot/u-boot-git/omap3evm/0015-EMAC-driver-Check-for-link-status-in-packet-send-lo.patch @@ -0,0 +1,42 @@ +From 866d110242fe282f3a65b9035bec2157be098445 Mon Sep 17 00:00:00 2001 +From: Sriram +Date: Mon, 29 Jun 2009 03:50:57 +0530 +Subject: [PATCH 15/16] EMAC driver: Check for link status in packet send loop + +--- + drivers/net/ticpgmac.c | 8 +------- + 1 files changed, 1 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ticpgmac.c b/drivers/net/ticpgmac.c +index 78a54d8..0efd5ed 100644 +--- a/drivers/net/ticpgmac.c ++++ b/drivers/net/ticpgmac.c +@@ -667,24 +667,18 @@ static int cpgmac_eth_send_packet (volatile void *packet, int length) + EMAC_CPPI_OWNERSHIP_BIT | + EMAC_CPPI_EOP_BIT); + +- if (!phy.get_link_status (active_phy_addr)) { +- printf("Link down . Abort Tx - pHY %d\n",active_phy_addr); +- cpgmac_eth_ch_teardown (EMAC_CH_TX); +- return (ret_status); +- } + + /* Send the packet */ + adap_emac->TX0HDP = BD_TO_HW((unsigned int) emac_tx_desc); + + /* Wait for packet to complete or link down */ + while (1) { +- #if 0 + if (!phy.get_link_status (active_phy_addr)) { + printf("Link down . Abort Tx - pHY %d\n",active_phy_addr); + cpgmac_eth_ch_teardown (EMAC_CH_TX); + return (ret_status); + } +- #endif ++ + if (adap_emac->TXINTSTATRAW & 0x01) { + ret_status = length; + break; +-- +1.6.2.4 + diff --git a/recipes/u-boot/u-boot-git/omap3evm/0016-Config-option-and-name-changed-to-omap3517_evm.patch b/recipes/u-boot/u-boot-git/omap3evm/0016-Config-option-and-name-changed-to-omap3517_evm.patch new file mode 100644 index 0000000000..d12e52c4a1 --- /dev/null +++ b/recipes/u-boot/u-boot-git/omap3evm/0016-Config-option-and-name-changed-to-omap3517_evm.patch @@ -0,0 +1,750 @@ +From 1e6117f48938151b750b7b53d8020fb93ce8bb62 Mon Sep 17 00:00:00 2001 +From: Vaibhav Hiremath +Date: Wed, 1 Jul 2009 20:17:26 +0530 +Subject: [PATCH 16/16] Config option and name changed to omap3517_evm + +Changes - + - Makefile : omap3517evm_config => omap3517_evm_config + - omap3517evm.h => omap3517_evm.h +--- + Makefile | 2 +- + include/configs/omap3517_evm.h | 353 ++++++++++++++++++++++++++++++++++++++++ + include/configs/omap3517evm.h | 353 ---------------------------------------- + 3 files changed, 354 insertions(+), 354 deletions(-) + create mode 100644 include/configs/omap3517_evm.h + delete mode 100644 include/configs/omap3517evm.h + +diff --git a/Makefile b/Makefile +index df25fb3..a78910c 100644 +--- a/Makefile ++++ b/Makefile +@@ -2942,7 +2942,7 @@ omap3_pandora_config : unconfig + omap3_zoom1_config : unconfig + @$(MKCONFIG) $(@:_config=) arm arm_cortexa8 zoom1 omap3 omap3 + +-omap3517evm_config : unconfig ++omap3517_evm_config : unconfig + @$(MKCONFIG) $(@:_config=) arm arm_cortexa8 omap3517evm omap3 omap3 + + ######################################################################### +diff --git a/include/configs/omap3517_evm.h b/include/configs/omap3517_evm.h +new file mode 100644 +index 0000000..9fe3f72 +--- /dev/null ++++ b/include/configs/omap3517_evm.h +@@ -0,0 +1,353 @@ ++/* ++ * (C) Copyright 2006-2008 ++ * Texas Instruments. ++ * Author : ++ * Manikandan Pillai ++ * ++ * Derived from EVM, Beagle Board and 3430 SDP code by ++ * Richard Woodruff ++ * Syed Mohammed Khasim ++ * ++ * Configuration settings for the TI OMAP3 EVM board. ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++#include ++ ++/* ++ * High Level Configuration Options ++ */ ++#define CONFIG_ARMCORTEXA8 1 /* This is an ARM V7 CPU core */ ++#define CONFIG_OMAP 1 /* in a TI OMAP core */ ++#define CONFIG_OMAP35XX 1 /* which is a 34XX */ ++#define CONFIG_OMAP3_OMAP3517EVM 1 /* working with EVM */ ++//#define CONFIG_OMAP3_OMAP3517TEB 1 /* working with TEB */ ++ ++#include /* get chip and board defs */ ++#include ++ ++/* Clock Defines */ ++#define V_OSCK 26000000 /* Clock output from T2 */ ++#define V_SCLK (V_OSCK >> 1) ++ ++#undef CONFIG_USE_IRQ /* no support for IRQs */ ++#define CONFIG_MISC_INIT_R ++ ++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ ++#define CONFIG_SETUP_MEMORY_TAGS 1 ++#define CONFIG_INITRD_TAG 1 ++#define CONFIG_REVISION_TAG 1 ++ ++/* ++ * Size of malloc() pool ++ */ ++#define CONFIG_ENV_SIZE SZ_128K /* Total Size Environment */ ++ /* Sector */ ++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + SZ_128K) ++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* bytes reserved for */ ++ /* initial data */ ++ ++/* ++ * DDR size interfaced ++ */ ++#define CONFIG_SYS_CS0_SIZE SZ_256M ++ ++/* ++ * Hardware drivers ++ */ ++ ++/* ++ * NS16550 Configuration ++ */ ++#define V_NS16550_CLK 48000000 /* 48MHz (APLL96/2) */ ++ ++#define CONFIG_SYS_NS16550 ++#define CONFIG_SYS_NS16550_SERIAL ++#define CONFIG_SYS_NS16550_REG_SIZE (-4) ++#define CONFIG_SYS_NS16550_CLK V_NS16550_CLK ++ ++/* ++ * select serial console configuration ++ */ ++#define CONFIG_CONS_INDEX 3 ++#define CONFIG_SYS_NS16550_COM3 OMAP34XX_UART3 ++#define CONFIG_SERIAL3 3 /* UART1 on OMAP3 EVM */ ++ ++/* allow to overwrite serial and ethaddr */ ++#define CONFIG_ENV_OVERWRITE ++#define CONFIG_BAUDRATE 115200 ++#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\ ++ 115200} ++#define CONFIG_MMC 1 ++#define CONFIG_OMAP3_MMC 1 ++#define CONFIG_DOS_PARTITION 1 ++ ++/* commands to include */ ++#include ++ ++#define CONFIG_CMD_EXT2 /* EXT2 Support */ ++#define CONFIG_CMD_FAT /* FAT support */ ++#define CONFIG_CMD_JFFS2 /* JFFS2 Support */ ++ ++#define CONFIG_CMD_I2C /* I2C serial bus support */ ++#define CONFIG_CMD_MMC /* MMC support */ ++#define CONFIG_CMD_NAND /* NAND support */ ++#define CONFIG_CMD_DHCP ++#define CONFIG_CMD_PING ++ ++#undef CONFIG_CMD_FLASH /* flinfo, erase, protect */ ++#undef CONFIG_CMD_FPGA /* FPGA configuration Support */ ++#undef CONFIG_CMD_IMI /* iminfo */ ++#undef CONFIG_CMD_IMLS /* List all found images */ ++ ++#define CONFIG_SYS_NO_FLASH ++#define CONFIG_SYS_I2C_SPEED 100000 ++#define CONFIG_SYS_I2C_SLAVE 1 ++#define CONFIG_SYS_I2C_BUS 0 ++#define CONFIG_SYS_I2C_BUS_SELECT 1 ++#define CONFIG_DRIVER_OMAP34XX_I2C 1 ++ ++/* ++ * Board NAND Info. ++ */ ++#define CONFIG_NAND_OMAP_GPMC ++#define CONFIG_SYS_NAND_ADDR NAND_BASE /* physical address */ ++ /* to access nand */ ++#define CONFIG_SYS_NAND_BASE NAND_BASE /* physical address */ ++ /* to access */ ++ /* nand at CS0 */ ++ ++#define GPMC_NAND_ECC_LP_x16_LAYOUT 1 ++ ++#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of */ ++ /* NAND devices */ ++#define SECTORSIZE 512 ++ ++#define NAND_ALLOW_ERASE_ALL ++#define ADDR_COLUMN 1 ++#define ADDR_PAGE 2 ++#define ADDR_COLUMN_PAGE 3 ++ ++#define NAND_ChipID_UNKNOWN 0x00 ++#define NAND_MAX_FLOORS 1 ++#define NAND_MAX_CHIPS 1 ++#define NAND_NO_RB 1 ++#define CONFIG_SYS_NAND_WP ++ ++#define CONFIG_JFFS2_NAND ++/* nand device jffs2 lives on */ ++#define CONFIG_JFFS2_DEV "nand0" ++/* start of jffs2 partition */ ++#define CONFIG_JFFS2_PART_OFFSET 0x680000 ++#define CONFIG_JFFS2_PART_SIZE 0xf980000 /* sz of jffs2 part */ ++ ++/* Environment information */ ++#define CONFIG_BOOTDELAY 10 ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ "loadaddr=0x82000000\0" \ ++ "console=ttyS2,115200n8\0" \ ++ "mmcargs=setenv bootargs console=${console} " \ ++ "root=/dev/mmcblk0p2 rw " \ ++ "rootfstype=ext3 rootwait\0" \ ++ "nandargs=setenv bootargs console=${console} " \ ++ "root=/dev/mtdblock4 rw " \ ++ "rootfstype=jffs2\0" \ ++ "loadbootscript=fatload mmc 0 ${loadaddr} boot.scr\0" \ ++ "bootscript=echo Running bootscript from mmc ...; " \ ++ "autoscr ${loadaddr}\0" \ ++ "loaduimage=fatload mmc 0 ${loadaddr} uImage\0" \ ++ "mmcboot=echo Booting from mmc ...; " \ ++ "run mmcargs; " \ ++ "bootm ${loadaddr}\0" \ ++ "nandboot=echo Booting from nand ...; " \ ++ "run nandargs; " \ ++ "nand read ${loadaddr} 80000 40000; " \ ++ "bootm ${loadaddr}\0" \ ++ ++#define CONFIG_BOOTCOMMAND \ ++ "if mmcinit; then " \ ++ "if run loadbootscript; then " \ ++ "run bootscript; " \ ++ "else " \ ++ "if run loaduimage; then " \ ++ "run mmcboot; " \ ++ "else run nandboot; " \ ++ "fi; " \ ++ "fi; " \ ++ "else run nandboot; fi" ++ ++#define CONFIG_AUTO_COMPLETE 1 ++/* ++ * Miscellaneous configurable options ++ */ ++#define V_PROMPT "OMAP3517EVM # " ++ ++#define CONFIG_SYS_LONGHELP /* undef to save memory */ ++#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ ++#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " ++#define CONFIG_SYS_PROMPT V_PROMPT ++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ ++/* Print Buffer Size */ ++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ ++ sizeof(CONFIG_SYS_PROMPT) + 16) ++#define CONFIG_SYS_MAXARGS 16 /* max number of command */ ++ /* args */ ++/* Boot Argument Buffer Size */ ++#define CONFIG_SYS_BARGSIZE (CONFIG_SYS_CBSIZE) ++/* memtest works on */ ++#define CONFIG_SYS_MEMTEST_START (OMAP34XX_SDRC_CS0) ++#define CONFIG_SYS_MEMTEST_END (OMAP34XX_SDRC_CS0 + \ ++ 0x01F00000) /* 31MB */ ++ ++#undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, */ ++ /* in Hz */ ++ ++#define CONFIG_SYS_LOAD_ADDR (OMAP34XX_SDRC_CS0) /* default load */ ++ /* address */ ++ ++/* ++ * OMAP3 has 12 GP timers, they can be driven by the system clock ++ * (12/13/16.8/19.2/38.4MHz) or by 32KHz clock. We use 13MHz (V_SCLK). ++ * This rate is divided by a local divisor. ++ */ ++#define CONFIG_SYS_TIMERBASE (OMAP34XX_GPT2) ++#define CONFIG_SYS_PVT 2 /* Divisor: 2^(PVT+1) => 8 */ ++#define CONFIG_SYS_HZ 1000 ++ ++/*----------------------------------------------------------------------- ++ * Stack sizes ++ * ++ * The stack sizes are set up in start.S using the settings below ++ */ ++#define CONFIG_STACKSIZE SZ_128K /* regular stack */ ++#ifdef CONFIG_USE_IRQ ++#define CONFIG_STACKSIZE_IRQ SZ_4K /* IRQ stack */ ++#define CONFIG_STACKSIZE_FIQ SZ_4K /* FIQ stack */ ++#endif ++ ++/*----------------------------------------------------------------------- ++ * Physical Memory Map ++ */ ++#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */ ++#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0 ++#define PHYS_SDRAM_1_SIZE SZ_32M /* at least 32 meg */ ++#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1 ++ ++/* SDRAM Bank Allocation method */ ++#define SDRC_R_B_C 1 ++ ++/*----------------------------------------------------------------------- ++ * FLASH and environment organization ++ */ ++ ++/* **** PISMO SUPPORT *** */ ++ ++/* Configure the PISMO */ ++#define PISMO1_NAND_SIZE GPMC_SIZE_128M ++#define PISMO1_ONEN_SIZE GPMC_SIZE_128M ++ ++#define CONFIG_SYS_MAX_FLASH_SECT 520 /* max number of sectors */ ++ /* on one chip */ ++#define CONFIG_SYS_MAX_FLASH_BANKS 2 /* max number of flash banks */ ++#define CONFIG_SYS_MONITOR_LEN SZ_256K /* Reserve 2 sectors */ ++ ++#define CONFIG_SYS_FLASH_BASE boot_flash_base ++ ++/* Monitor at start of flash */ ++#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE ++ ++#define CONFIG_ENV_IS_IN_NAND 1 ++#define SMNAND_ENV_OFFSET 0x260000 /* environment starts here */ ++ ++#define CONFIG_SYS_ENV_SECT_SIZE boot_flash_sec ++#define CONFIG_ENV_OFFSET boot_flash_off ++#define CONFIG_ENV_ADDR boot_flash_env_addr ++ ++/*----------------------------------------------------------------------- ++ * CFI FLASH driver setup ++ */ ++/* timeout values are in ticks */ ++#define CONFIG_SYS_FLASH_ERASE_TOUT (100 * CONFIG_SYS_HZ) ++#define CONFIG_SYS_FLASH_WRITE_TOUT (100 * CONFIG_SYS_HZ) ++ ++/* Flash banks JFFS2 should use */ ++#define CONFIG_SYS_MAX_MTD_BANKS (CONFIG_SYS_MAX_FLASH_BANKS + \ ++ CONFIG_SYS_MAX_NAND_DEVICE) ++#define CONFIG_SYS_JFFS2_MEM_NAND ++/* use flash_info[2] */ ++#define CONFIG_SYS_JFFS2_FIRST_BANK CONFIG_SYS_MAX_FLASH_BANKS ++#define CONFIG_SYS_JFFS2_NUM_BANKS 1 ++ ++#ifndef __ASSEMBLY__ ++extern gpmc_csx_t *nand_cs_base; ++extern gpmc_t *gpmc_cfg_base; ++extern unsigned int boot_flash_base; ++extern volatile unsigned int boot_flash_env_addr; ++extern unsigned int boot_flash_off; ++extern unsigned int boot_flash_sec; ++extern unsigned int boot_flash_type; ++#endif ++ ++ ++#define WRITE_NAND_COMMAND(d, adr)\ ++ writel(d, &nand_cs_base->nand_cmd) ++#define WRITE_NAND_ADDRESS(d, adr)\ ++ writel(d, &nand_cs_base->nand_adr) ++#define WRITE_NAND(d, adr) writew(d, &nand_cs_base->nand_dat) ++#define READ_NAND(adr) readl(&nand_cs_base->nand_dat) ++ ++/* Other NAND Access APIs */ ++#define NAND_WP_OFF() do {readl(&gpmc_cfg_base->config) |= GPMC_CONFIG_WP; } \ ++ while (0) ++#define NAND_WP_ON() do {readl(&gpmc_cfg_base->config) &= ~GPMC_CONFIG_WP; } \ ++ while (0) ++#define NAND_DISABLE_CE(nand) ++#define NAND_ENABLE_CE(nand) ++#define NAND_WAIT_READY(nand) udelay(10) ++ ++/*---------------------------------------------------------------------------- ++ * Ethernet support for OMAP3517EVM ++ *---------------------------------------------------------------------------- ++ */ ++#if defined(CONFIG_CMD_NET) ++#define CONFIG_TICPGMAC ++#define CONFIG_DRIVER_TI_EMAC ++#define CONFIG_DRIVER_TI_EMAC_USE_RMII ++#define CONFIG_MII ++#define CONFIG_NET_RETRY_COUNT 10 ++#endif /* (CONFIG_CMD_NET) */ ++ ++/* ++ * BOOTP fields ++ */ ++#define CONFIG_BOOTP_DEFAULT ++#define CONFIG_BOOTP_DNS ++#define CONFIG_BOOTP_DNS2 ++#define CONFIG_BOOTP_SEND_HOSTNAME ++ ++#define CONFIG_BOOTP_SUBNETMASK 0x00000001 ++#define CONFIG_BOOTP_GATEWAY 0x00000002 ++#define CONFIG_BOOTP_HOSTNAME 0x00000004 ++#define CONFIG_BOOTP_BOOTPATH 0x00000010 ++ ++#endif /* __CONFIG_H */ +diff --git a/include/configs/omap3517evm.h b/include/configs/omap3517evm.h +deleted file mode 100644 +index 9fe3f72..0000000 +--- a/include/configs/omap3517evm.h ++++ /dev/null +@@ -1,353 +0,0 @@ +-/* +- * (C) Copyright 2006-2008 +- * Texas Instruments. +- * Author : +- * Manikandan Pillai +- * +- * Derived from EVM, Beagle Board and 3430 SDP code by +- * Richard Woodruff +- * Syed Mohammed Khasim +- * +- * Configuration settings for the TI OMAP3 EVM board. +- * +- * See file CREDITS for list of people who contributed to this +- * project. +- * +- * 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., 59 Temple Place, Suite 330, Boston, +- * MA 02111-1307 USA +- */ +- +-#ifndef __CONFIG_H +-#define __CONFIG_H +-#include +- +-/* +- * High Level Configuration Options +- */ +-#define CONFIG_ARMCORTEXA8 1 /* This is an ARM V7 CPU core */ +-#define CONFIG_OMAP 1 /* in a TI OMAP core */ +-#define CONFIG_OMAP35XX 1 /* which is a 34XX */ +-#define CONFIG_OMAP3_OMAP3517EVM 1 /* working with EVM */ +-//#define CONFIG_OMAP3_OMAP3517TEB 1 /* working with TEB */ +- +-#include /* get chip and board defs */ +-#include +- +-/* Clock Defines */ +-#define V_OSCK 26000000 /* Clock output from T2 */ +-#define V_SCLK (V_OSCK >> 1) +- +-#undef CONFIG_USE_IRQ /* no support for IRQs */ +-#define CONFIG_MISC_INIT_R +- +-#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ +-#define CONFIG_SETUP_MEMORY_TAGS 1 +-#define CONFIG_INITRD_TAG 1 +-#define CONFIG_REVISION_TAG 1 +- +-/* +- * Size of malloc() pool +- */ +-#define CONFIG_ENV_SIZE SZ_128K /* Total Size Environment */ +- /* Sector */ +-#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + SZ_128K) +-#define CONFIG_SYS_GBL_DATA_SIZE 128 /* bytes reserved for */ +- /* initial data */ +- +-/* +- * DDR size interfaced +- */ +-#define CONFIG_SYS_CS0_SIZE SZ_256M +- +-/* +- * Hardware drivers +- */ +- +-/* +- * NS16550 Configuration +- */ +-#define V_NS16550_CLK 48000000 /* 48MHz (APLL96/2) */ +- +-#define CONFIG_SYS_NS16550 +-#define CONFIG_SYS_NS16550_SERIAL +-#define CONFIG_SYS_NS16550_REG_SIZE (-4) +-#define CONFIG_SYS_NS16550_CLK V_NS16550_CLK +- +-/* +- * select serial console configuration +- */ +-#define CONFIG_CONS_INDEX 3 +-#define CONFIG_SYS_NS16550_COM3 OMAP34XX_UART3 +-#define CONFIG_SERIAL3 3 /* UART1 on OMAP3 EVM */ +- +-/* allow to overwrite serial and ethaddr */ +-#define CONFIG_ENV_OVERWRITE +-#define CONFIG_BAUDRATE 115200 +-#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\ +- 115200} +-#define CONFIG_MMC 1 +-#define CONFIG_OMAP3_MMC 1 +-#define CONFIG_DOS_PARTITION 1 +- +-/* commands to include */ +-#include +- +-#define CONFIG_CMD_EXT2 /* EXT2 Support */ +-#define CONFIG_CMD_FAT /* FAT support */ +-#define CONFIG_CMD_JFFS2 /* JFFS2 Support */ +- +-#define CONFIG_CMD_I2C /* I2C serial bus support */ +-#define CONFIG_CMD_MMC /* MMC support */ +-#define CONFIG_CMD_NAND /* NAND support */ +-#define CONFIG_CMD_DHCP +-#define CONFIG_CMD_PING +- +-#undef CONFIG_CMD_FLASH /* flinfo, erase, protect */ +-#undef CONFIG_CMD_FPGA /* FPGA configuration Support */ +-#undef CONFIG_CMD_IMI /* iminfo */ +-#undef CONFIG_CMD_IMLS /* List all found images */ +- +-#define CONFIG_SYS_NO_FLASH +-#define CONFIG_SYS_I2C_SPEED 100000 +-#define CONFIG_SYS_I2C_SLAVE 1 +-#define CONFIG_SYS_I2C_BUS 0 +-#define CONFIG_SYS_I2C_BUS_SELECT 1 +-#define CONFIG_DRIVER_OMAP34XX_I2C 1 +- +-/* +- * Board NAND Info. +- */ +-#define CONFIG_NAND_OMAP_GPMC +-#define CONFIG_SYS_NAND_ADDR NAND_BASE /* physical address */ +- /* to access nand */ +-#define CONFIG_SYS_NAND_BASE NAND_BASE /* physical address */ +- /* to access */ +- /* nand at CS0 */ +- +-#define GPMC_NAND_ECC_LP_x16_LAYOUT 1 +- +-#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of */ +- /* NAND devices */ +-#define SECTORSIZE 512 +- +-#define NAND_ALLOW_ERASE_ALL +-#define ADDR_COLUMN 1 +-#define ADDR_PAGE 2 +-#define ADDR_COLUMN_PAGE 3 +- +-#define NAND_ChipID_UNKNOWN 0x00 +-#define NAND_MAX_FLOORS 1 +-#define NAND_MAX_CHIPS 1 +-#define NAND_NO_RB 1 +-#define CONFIG_SYS_NAND_WP +- +-#define CONFIG_JFFS2_NAND +-/* nand device jffs2 lives on */ +-#define CONFIG_JFFS2_DEV "nand0" +-/* start of jffs2 partition */ +-#define CONFIG_JFFS2_PART_OFFSET 0x680000 +-#define CONFIG_JFFS2_PART_SIZE 0xf980000 /* sz of jffs2 part */ +- +-/* Environment information */ +-#define CONFIG_BOOTDELAY 10 +- +-#define CONFIG_EXTRA_ENV_SETTINGS \ +- "loadaddr=0x82000000\0" \ +- "console=ttyS2,115200n8\0" \ +- "mmcargs=setenv bootargs console=${console} " \ +- "root=/dev/mmcblk0p2 rw " \ +- "rootfstype=ext3 rootwait\0" \ +- "nandargs=setenv bootargs console=${console} " \ +- "root=/dev/mtdblock4 rw " \ +- "rootfstype=jffs2\0" \ +- "loadbootscript=fatload mmc 0 ${loadaddr} boot.scr\0" \ +- "bootscript=echo Running bootscript from mmc ...; " \ +- "autoscr ${loadaddr}\0" \ +- "loaduimage=fatload mmc 0 ${loadaddr} uImage\0" \ +- "mmcboot=echo Booting from mmc ...; " \ +- "run mmcargs; " \ +- "bootm ${loadaddr}\0" \ +- "nandboot=echo Booting from nand ...; " \ +- "run nandargs; " \ +- "nand read ${loadaddr} 80000 40000; " \ +- "bootm ${loadaddr}\0" \ +- +-#define CONFIG_BOOTCOMMAND \ +- "if mmcinit; then " \ +- "if run loadbootscript; then " \ +- "run bootscript; " \ +- "else " \ +- "if run loaduimage; then " \ +- "run mmcboot; " \ +- "else run nandboot; " \ +- "fi; " \ +- "fi; " \ +- "else run nandboot; fi" +- +-#define CONFIG_AUTO_COMPLETE 1 +-/* +- * Miscellaneous configurable options +- */ +-#define V_PROMPT "OMAP3517EVM # " +- +-#define CONFIG_SYS_LONGHELP /* undef to save memory */ +-#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +-#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " +-#define CONFIG_SYS_PROMPT V_PROMPT +-#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +-/* Print Buffer Size */ +-#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ +- sizeof(CONFIG_SYS_PROMPT) + 16) +-#define CONFIG_SYS_MAXARGS 16 /* max number of command */ +- /* args */ +-/* Boot Argument Buffer Size */ +-#define CONFIG_SYS_BARGSIZE (CONFIG_SYS_CBSIZE) +-/* memtest works on */ +-#define CONFIG_SYS_MEMTEST_START (OMAP34XX_SDRC_CS0) +-#define CONFIG_SYS_MEMTEST_END (OMAP34XX_SDRC_CS0 + \ +- 0x01F00000) /* 31MB */ +- +-#undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, */ +- /* in Hz */ +- +-#define CONFIG_SYS_LOAD_ADDR (OMAP34XX_SDRC_CS0) /* default load */ +- /* address */ +- +-/* +- * OMAP3 has 12 GP timers, they can be driven by the system clock +- * (12/13/16.8/19.2/38.4MHz) or by 32KHz clock. We use 13MHz (V_SCLK). +- * This rate is divided by a local divisor. +- */ +-#define CONFIG_SYS_TIMERBASE (OMAP34XX_GPT2) +-#define CONFIG_SYS_PVT 2 /* Divisor: 2^(PVT+1) => 8 */ +-#define CONFIG_SYS_HZ 1000 +- +-/*----------------------------------------------------------------------- +- * Stack sizes +- * +- * The stack sizes are set up in start.S using the settings below +- */ +-#define CONFIG_STACKSIZE SZ_128K /* regular stack */ +-#ifdef CONFIG_USE_IRQ +-#define CONFIG_STACKSIZE_IRQ SZ_4K /* IRQ stack */ +-#define CONFIG_STACKSIZE_FIQ SZ_4K /* FIQ stack */ +-#endif +- +-/*----------------------------------------------------------------------- +- * Physical Memory Map +- */ +-#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */ +-#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0 +-#define PHYS_SDRAM_1_SIZE SZ_32M /* at least 32 meg */ +-#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1 +- +-/* SDRAM Bank Allocation method */ +-#define SDRC_R_B_C 1 +- +-/*----------------------------------------------------------------------- +- * FLASH and environment organization +- */ +- +-/* **** PISMO SUPPORT *** */ +- +-/* Configure the PISMO */ +-#define PISMO1_NAND_SIZE GPMC_SIZE_128M +-#define PISMO1_ONEN_SIZE GPMC_SIZE_128M +- +-#define CONFIG_SYS_MAX_FLASH_SECT 520 /* max number of sectors */ +- /* on one chip */ +-#define CONFIG_SYS_MAX_FLASH_BANKS 2 /* max number of flash banks */ +-#define CONFIG_SYS_MONITOR_LEN SZ_256K /* Reserve 2 sectors */ +- +-#define CONFIG_SYS_FLASH_BASE boot_flash_base +- +-/* Monitor at start of flash */ +-#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE +- +-#define CONFIG_ENV_IS_IN_NAND 1 +-#define SMNAND_ENV_OFFSET 0x260000 /* environment starts here */ +- +-#define CONFIG_SYS_ENV_SECT_SIZE boot_flash_sec +-#define CONFIG_ENV_OFFSET boot_flash_off +-#define CONFIG_ENV_ADDR boot_flash_env_addr +- +-/*----------------------------------------------------------------------- +- * CFI FLASH driver setup +- */ +-/* timeout values are in ticks */ +-#define CONFIG_SYS_FLASH_ERASE_TOUT (100 * CONFIG_SYS_HZ) +-#define CONFIG_SYS_FLASH_WRITE_TOUT (100 * CONFIG_SYS_HZ) +- +-/* Flash banks JFFS2 should use */ +-#define CONFIG_SYS_MAX_MTD_BANKS (CONFIG_SYS_MAX_FLASH_BANKS + \ +- CONFIG_SYS_MAX_NAND_DEVICE) +-#define CONFIG_SYS_JFFS2_MEM_NAND +-/* use flash_info[2] */ +-#define CONFIG_SYS_JFFS2_FIRST_BANK CONFIG_SYS_MAX_FLASH_BANKS +-#define CONFIG_SYS_JFFS2_NUM_BANKS 1 +- +-#ifndef __ASSEMBLY__ +-extern gpmc_csx_t *nand_cs_base; +-extern gpmc_t *gpmc_cfg_base; +-extern unsigned int boot_flash_base; +-extern volatile unsigned int boot_flash_env_addr; +-extern unsigned int boot_flash_off; +-extern unsigned int boot_flash_sec; +-extern unsigned int boot_flash_type; +-#endif +- +- +-#define WRITE_NAND_COMMAND(d, adr)\ +- writel(d, &nand_cs_base->nand_cmd) +-#define WRITE_NAND_ADDRESS(d, adr)\ +- writel(d, &nand_cs_base->nand_adr) +-#define WRITE_NAND(d, adr) writew(d, &nand_cs_base->nand_dat) +-#define READ_NAND(adr) readl(&nand_cs_base->nand_dat) +- +-/* Other NAND Access APIs */ +-#define NAND_WP_OFF() do {readl(&gpmc_cfg_base->config) |= GPMC_CONFIG_WP; } \ +- while (0) +-#define NAND_WP_ON() do {readl(&gpmc_cfg_base->config) &= ~GPMC_CONFIG_WP; } \ +- while (0) +-#define NAND_DISABLE_CE(nand) +-#define NAND_ENABLE_CE(nand) +-#define NAND_WAIT_READY(nand) udelay(10) +- +-/*---------------------------------------------------------------------------- +- * Ethernet support for OMAP3517EVM +- *---------------------------------------------------------------------------- +- */ +-#if defined(CONFIG_CMD_NET) +-#define CONFIG_TICPGMAC +-#define CONFIG_DRIVER_TI_EMAC +-#define CONFIG_DRIVER_TI_EMAC_USE_RMII +-#define CONFIG_MII +-#define CONFIG_NET_RETRY_COUNT 10 +-#endif /* (CONFIG_CMD_NET) */ +- +-/* +- * BOOTP fields +- */ +-#define CONFIG_BOOTP_DEFAULT +-#define CONFIG_BOOTP_DNS +-#define CONFIG_BOOTP_DNS2 +-#define CONFIG_BOOTP_SEND_HOSTNAME +- +-#define CONFIG_BOOTP_SUBNETMASK 0x00000001 +-#define CONFIG_BOOTP_GATEWAY 0x00000002 +-#define CONFIG_BOOTP_HOSTNAME 0x00000004 +-#define CONFIG_BOOTP_BOOTPATH 0x00000010 +- +-#endif /* __CONFIG_H */ +-- +1.6.2.4 + diff --git a/recipes/u-boot/u-boot_git.bb b/recipes/u-boot/u-boot_git.bb index d30b0bdbd0..fea52ac27e 100644 --- a/recipes/u-boot/u-boot_git.bb +++ b/recipes/u-boot/u-boot_git.bb @@ -25,6 +25,28 @@ SRC_URI_omap3evm = "git://gitorious.org/u-boot-omap3/mainline.git;branch=omap3-d SRCREV_omap3evm = "2dea1db2a3b7c12ed70bbf8ee50755089c5e5170" PV_omap3evm = "2009.03+${PR}+gitr${SRCREV}" + +SRCREV_omap3517-evm = "e60beb13cf0" +SRC_URI_append_omap3517-evm = " \ +file://omap3evm/0001-Changes-for-making-a-NAND-build.patch;patch=1 \ +file://omap3evm/0002-Fix-for-NFS-boot-for-OMAP3-EVM.patch;patch=1 \ +file://omap3evm/0003-OMAP3-timer-handling-to-1ms-tick-and-CONFIG_SYS_HZ-t.patch;patch=1 \ +file://omap3evm/0004-Reverse-patch-for-NFS-boot-to-fix-comments-provided.patch;patch=1 \ +file://omap3evm/0005-SMC911x-driver-fixed-for-NFS-boot.patch;patch=1 \ +file://omap3evm/0006-Added-OMAP3517-3505-support.patch;patch=1 \ +file://omap3evm/0007-OMAP3517TEB-validated-on-OMAP3517TEB-board.patch;patch=1 \ +file://omap3evm/0008-OMAP3517PRE-ALPHA-validated-on-OMAP3517PRE_ALPHA-bo.patch;patch=1 \ +file://omap3evm/0009-OMAP3517PRE-ALPHA-DDR-size-issue-fixed.patch;patch=1 \ +file://omap3evm/0010-OMAP3517PRE-ALPHA-Mux-configuration-for-MMC-CD-and.patch;patch=1 \ +file://omap3evm/0011-Ethernet-driver-functional-no-need-for-time-delay.patch;patch=1 \ +file://omap3evm/0012-EMAC-driver-Implement-GPIO-driven-PHY-reset.patch;patch=1 \ +file://omap3evm/0013-Cleaned-up-during-EVM-hang-issue.patch;patch=1 \ +file://omap3evm/0014-EMAC-driver-cleanup-removed-debug-prints.patch;patch=1 \ +file://omap3evm/0015-EMAC-driver-Check-for-link-status-in-packet-send-lo.patch;patch=1 \ +file://omap3evm/0016-Config-option-and-name-changed-to-omap3517_evm.patch;patch=1 \ +" +PV_omap3517-evm = "2009.03+${PR}+gitr${SRCREV}" + SRC_URI_omapzoom = "git://www.sakoman.net/git/u-boot-omap3.git;branch=omap3-dev;protocol=git" SRCREV_omapzoom = "d691b424f1f5bf7eea3a4131dfc578d272e8f335" PV_omapzoom = "2009.01+${PR}+gitr${SRCREV}" -- cgit v1.2.3 From 0ec2fb98376f700d4d50d7ffb2dd81ccc93ad648 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 8 Sep 2009 14:23:17 +0200 Subject: angstrom feed sorter: add shiva support --- contrib/angstrom/sort.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/angstrom/sort.sh b/contrib/angstrom/sort.sh index 2aea20ed64..8dd1bdb4dc 100755 --- a/contrib/angstrom/sort.sh +++ b/contrib/angstrom/sort.sh @@ -58,7 +58,7 @@ case "$arch" in "armv7") machines="" ;; "armv7a") - machines="beagleboard omap3evm omap3-pandora omapzoom omapzoom2 overo" ;; + machines="beagleboard omap3evm omap3517-evm omap3-pandora omapzoom omapzoom2 overo" ;; "avr32") machines="atngw100 at32stk1000" ;; "bfin") -- cgit v1.2.3 From ede46c7614fd6baaac513d36abb011c5a63772ff Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 8 Sep 2009 16:02:41 +0200 Subject: linux-omap-psp 2.6.29: add WIP patch for EHCI support --- .../linux-omap-psp-2.6.29/omap3517-evm/defconfig | 9 +++- .../linux/linux-omap-psp-2.6.29/shiva-ehci.diff | 60 ++++++++++++++++++++++ recipes/linux/linux-omap-psp_2.6.29.bb | 1 + 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100755 recipes/linux/linux-omap-psp-2.6.29/shiva-ehci.diff diff --git a/recipes/linux/linux-omap-psp-2.6.29/omap3517-evm/defconfig b/recipes/linux/linux-omap-psp-2.6.29/omap3517-evm/defconfig index 3092f7b098..4fa37bd8ef 100644 --- a/recipes/linux/linux-omap-psp-2.6.29/omap3517-evm/defconfig +++ b/recipes/linux/linux-omap-psp-2.6.29/omap3517-evm/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.29-omap1 -# Mon Sep 7 19:18:57 2009 +# Tue Sep 8 15:41:48 2009 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -1003,7 +1003,11 @@ CONFIG_USB=y # USB Host Controller Drivers # # CONFIG_USB_C67X00_HCD is not set -# CONFIG_USB_EHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_OMAP_EHCI_PHY_MODE=y +# CONFIG_OMAP_EHCI_TLL_MODE is not set +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +CONFIG_USB_EHCI_TT_NEWSCHED=y # CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set # CONFIG_USB_OHCI_HCD is not set @@ -1084,6 +1088,7 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_IDMOUSE is not set # CONFIG_USB_FTDI_ELAN is not set # CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set # CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_IOWARRIOR is not set diff --git a/recipes/linux/linux-omap-psp-2.6.29/shiva-ehci.diff b/recipes/linux/linux-omap-psp-2.6.29/shiva-ehci.diff new file mode 100755 index 0000000000..418dca86b5 --- /dev/null +++ b/recipes/linux/linux-omap-psp-2.6.29/shiva-ehci.diff @@ -0,0 +1,60 @@ +commit b73387d2642df981a4cfacddaa36aab8b1ea604b +Author: Ajay Kumar Gupta +Date: Fri Jul 10 18:01:29 2009 +0530 + + ehci: adding support for EHCI + + Port1 is used and EHCI port on OMAP3517. GPIO57 is + used to reset the EHCI phy. + + - Added usb_ehci_init() + - Added port1 phy reset padconfig + +diff --git a/arch/arm/mach-omap2/board-omap3517evm.c b/arch/arm/mach-omap2/board-omap3517evm.c +index cb5af8f..af2d3a9 100644 +--- a/arch/arm/mach-omap2/board-omap3517evm.c ++++ b/arch/arm/mach-omap2/board-omap3517evm.c +@@ -399,6 +399,9 @@ static void __init omap3517_evm_init(void) + + omap3517evm_flash_init(); + usb_musb_init(); ++ /* GPIO57 as port1 phy reset */ ++ omap_cfg_reg(N5_3517_GPIO57_OUT); ++ usb_ehci_init(); + /* + * MMC init function + */ + +diff --git a/arch/arm/plat-omap/include/mach/mux.h b/arch/arm/plat-omap/include/mach/mux.h +index aa9d5a1..4e5a247 100644 +--- a/arch/arm/plat-omap/include/mach/mux.h ++++ b/arch/arm/plat-omap/include/mach/mux.h +@@ -805,6 +805,7 @@ enum omap34xx_index { + J25_34XX_GPIO170, + #ifdef CONFIG_MACH_OMAP3517EVM + E25_3517_USB0_DRVVBUS, ++ N5_3517_GPIO57_OUT, + #endif + }; + +--- /tmp/mux.c 2009-09-08 15:06:05.000000000 +0200 ++++ git/arch/arm/mach-omap2/mux.c 2009-09-08 15:08:28.000000000 +0200 +@@ -486,16 +486,10 @@ + OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) + MUX_CFG_34XX("J25_34XX_GPIO170", 0x1c6, + OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) +-#ifdef CONFIG_MACH_OMAP3517EVM + MUX_CFG_34XX("E25_3517_USB0_DRVVBUS", 0x212, + OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLDOWN) +-#if 0 +-MUX_CFG_34XX("F24_3517_USB0_DM", 0x212, +- OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLDOWN) +-MUX_CFG_34XX("F25_3517_USB0_DP", 0x212, +- OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLDOWN) +-#endif +-#endif ++MUX_CFG_34XX("N5_3517_GPIO57_OUT", 0x0ba, ++ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) + }; + + #define OMAP34XX_PINS_SZ ARRAY_SIZE(omap34xx_pins) diff --git a/recipes/linux/linux-omap-psp_2.6.29.bb b/recipes/linux/linux-omap-psp_2.6.29.bb index a336622583..4c213b1dd1 100644 --- a/recipes/linux/linux-omap-psp_2.6.29.bb +++ b/recipes/linux/linux-omap-psp_2.6.29.bb @@ -18,6 +18,7 @@ S = "${WORKDIR}/git" SRC_URI_append_omap3517-evm = " \ file://shiva-bits.diff;patch=1 \ + file://shiva-ehci.diff;patch=1 \ " SRC_URI_append_omap3evm = " \ -- cgit v1.2.3 From 7937ed35de6218a955a63d9ce61d992532fdc5e0 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Wed, 9 Sep 2009 12:27:50 +0200 Subject: x-load: add omap3517-evm support * 1.41 still has the volatile bugs when compiled with non CSL stuff --- conf/machine/omap3517-evm.conf | 1 + recipes/x-load/files/x-loader-03.00.00.01.tar.gz | Bin 0 -> 166557 bytes recipes/x-load/files/xload-shiva.diff | 2106 ++++++++++++++++++++ ...oard.c-print-boot-method-mmc-onenand-nand.patch | 52 + ...heck-for-u-boot-on-mmc-on-all-configurati.patch | 95 + .../0015-OMAP3EVM-Build-issue-fixed.patch | 77 + ...-mmc-fix-infinite-loop-in-mmc_init_stream.patch | 41 + ...b-board.c-add-missing-call-to-misc_init_r.patch | 25 + ...-omap3evm-provide-missing-udelay-function.patch | 27 + ...c-Specify-where-u-boot-is-being-loaded-fr.patch | 45 + recipes/x-load/x-load-1.41/streen-fix.diff | 39 + recipes/x-load/x-load_1.41.bb | 18 + recipes/x-load/x-load_git.bb | 6 + 13 files changed, 2532 insertions(+) create mode 100755 recipes/x-load/files/x-loader-03.00.00.01.tar.gz create mode 100644 recipes/x-load/files/xload-shiva.diff create mode 100644 recipes/x-load/x-load-1.41/0013-board.c-print-boot-method-mmc-onenand-nand.patch create mode 100644 recipes/x-load/x-load-1.41/0014-board.c-check-for-u-boot-on-mmc-on-all-configurati.patch create mode 100644 recipes/x-load/x-load-1.41/0015-OMAP3EVM-Build-issue-fixed.patch create mode 100644 recipes/x-load/x-load-1.41/0016-mmc-fix-infinite-loop-in-mmc_init_stream.patch create mode 100644 recipes/x-load/x-load-1.41/0017-lib-board.c-add-missing-call-to-misc_init_r.patch create mode 100644 recipes/x-load/x-load-1.41/0018-omap3evm-provide-missing-udelay-function.patch create mode 100644 recipes/x-load/x-load-1.41/0019-lib-board.c-Specify-where-u-boot-is-being-loaded-fr.patch create mode 100644 recipes/x-load/x-load-1.41/streen-fix.diff create mode 100644 recipes/x-load/x-load_1.41.bb diff --git a/conf/machine/omap3517-evm.conf b/conf/machine/omap3517-evm.conf index a7ef4be0fd..4bbd25c718 100644 --- a/conf/machine/omap3517-evm.conf +++ b/conf/machine/omap3517-evm.conf @@ -27,6 +27,7 @@ PREFERRED_PROVIDER_virtual/kernel = "linux-omap-psp" UBOOT_ARCH = "arm" UBOOT_MACHINE = "omap3517_evm_config" +XLOAD_MACHINE = "omap3517evm_config" MACHINE_FEATURES = "kernel26 apm usbgadget usbhost vfat ext2 screen touchscreen ethernet" diff --git a/recipes/x-load/files/x-loader-03.00.00.01.tar.gz b/recipes/x-load/files/x-loader-03.00.00.01.tar.gz new file mode 100755 index 0000000000..60930c68d2 Binary files /dev/null and b/recipes/x-load/files/x-loader-03.00.00.01.tar.gz differ diff --git a/recipes/x-load/files/xload-shiva.diff b/recipes/x-load/files/xload-shiva.diff new file mode 100644 index 0000000000..d1535b682f --- /dev/null +++ b/recipes/x-load/files/xload-shiva.diff @@ -0,0 +1,2106 @@ +diff -Nurd git/Makefile x-load-shiva/Makefile +--- git/Makefile 2009-09-08 16:43:33.000000000 +0200 ++++ x-load-shiva/Makefile 2009-09-08 16:54:21.000000000 +0200 +@@ -156,6 +156,9 @@ + + @./mkconfig $(@:_config=) arm omap3 omap3530beagle + ++omap3517evm_config : unconfig ++ @./mkconfig $(@:_config=) arm omap3 omap3517evm ++ + ######################################################################### + + clean: +diff -Nurd git/board/omap3517evm/Makefile x-load-shiva/board/omap3517evm/Makefile +--- git/board/omap3517evm/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ x-load-shiva/board/omap3517evm/Makefile 2009-09-08 16:54:35.000000000 +0200 +@@ -0,0 +1,47 @@ ++# ++# (C) Copyright 2000, 2001, 2002 ++# Wolfgang Denk, DENX Software Engineering, wd@denx.de. ++# ++# See file CREDITS for list of people who contributed to this ++# project. ++# ++# 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., 59 Temple Place, Suite 330, Boston, ++# MA 02111-1307 USA ++# ++ ++include $(TOPDIR)/config.mk ++ ++LIB = lib$(BOARD).a ++ ++OBJS := omap3517evm.o ++SOBJS := platform.o ++ ++$(LIB): $(OBJS) $(SOBJS) ++ $(AR) crv $@ $^ ++ ++clean: ++ rm -f $(SOBJS) $(OBJS) ++ ++distclean: clean ++ rm -f $(LIB) core *.bak .depend ++ ++######################################################################### ++ ++.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) ++ $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ ++ ++-include .depend ++ ++######################################################################### +diff -Nurd git/board/omap3517evm/config.mk x-load-shiva/board/omap3517evm/config.mk +--- git/board/omap3517evm/config.mk 1970-01-01 01:00:00.000000000 +0100 ++++ x-load-shiva/board/omap3517evm/config.mk 2009-09-08 16:56:20.000000000 +0200 +@@ -0,0 +1,19 @@ ++# (C) Copyright 2009 ++# Texas Instruments, ++# ++# OMAP3517EVM board uses OMAP3517 'shiva' (ARM-CortexA8) cpu ++# see http://www.ti.com/ for more information on Texas Instruments# ++# ++# OMAP3517EVM has 1 bank of 128MB mPOP-SDRAM on CS0 ++# Physical Address: ++# 8000'0000 (bank0) ++ ++# For use if you want X-Loader to relocate from SRAM to DDR ++#TEXT_BASE = 0x80e80000 ++ ++# For XIP in 64K of SRAM or debug (GP device has it all availabe) ++# SRAM 40200000-4020FFFF base ++# initial stack at 0x4020fffc used in s_init (below xloader). ++# The run time stack is (above xloader, 2k below) ++# If any globals exist there needs to be room for them also ++TEXT_BASE = 0x40200800 +diff -Nurd git/board/omap3517evm/omap3517evm.c x-load-shiva/board/omap3517evm/omap3517evm.c +--- git/board/omap3517evm/omap3517evm.c 1970-01-01 01:00:00.000000000 +0100 ++++ x-load-shiva/board/omap3517evm/omap3517evm.c 2009-09-08 18:25:17.000000000 +0200 +@@ -0,0 +1,943 @@ ++/* ++ * (C) Copyright 2009 ++ * Texas Instruments, ++ * Manikandan Pillai ++ * This file is copied from board/omap3evm/omap3evm.c ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Used to index into DPLL parameter tables */ ++struct dpll_param { ++ unsigned int m; ++ unsigned int n; ++ unsigned int fsel; ++ unsigned int m2; ++}; ++ ++typedef struct dpll_param dpll_param; ++ ++#define MAX_SIL_INDEX 3 ++ ++/* Definitions for EMIF4 configuration values */ ++#define EMIF4_TIM1_T_RP 0x3 ++#define EMIF4_TIM1_T_RCD 0x3 ++#define EMIF4_TIM1_T_WR 0x3 ++#define EMIF4_TIM1_T_RAS 0x8 ++#define EMIF4_TIM1_T_RC 0xA ++#define EMIF4_TIM1_T_RRD 0x2 ++#define EMIF4_TIM1_T_WTR 0x2 ++ ++#define EMIF4_TIM2_T_XP 0x2 ++#define EMIF4_TIM2_T_ODT 0x0 ++#define EMIF4_TIM2_T_XSNR 0x1C ++#define EMIF4_TIM2_T_XSRD 0xC8 ++#define EMIF4_TIM2_T_RTP 0x1 ++#define EMIF4_TIM2_T_CKE 0x2 ++ ++#define EMIF4_TIM3_T_TDQSCKMAX 0x0 ++#define EMIF4_TIM3_T_RFC 0x25 ++#define EMIF4_TIM3_T_RAS_MAX 0x7 ++ ++#define EMIF4_PWR_IDLE 0x2 ++#define EMIF4_PWR_DPD_EN 0x0 ++#define EMIF4_PWR_PM_EN 0x0 ++#define EMIF4_PWR_PM_TIM 0x0 ++ ++#define EMIF4_INITREF_DIS 0x0 ++#define EMIF4_PASR 0x0 ++#define EMIF4_REFRESH_RATE 0x50F ++ ++/* ++ * SDRAM Config register ++ */ ++#define EMIF4_CFG_SDRAM_TYP 0x2 ++#define EMIF4_CFG_IBANK_POS 0x0 ++#define EMIF4_CFG_DDR_TERM 0x0 ++#define EMIF4_CFG_DDR2_DDQS 0x1 ++#define EMIF4_CFG_DYN_ODT 0x0 ++#define EMIF4_CFG_DDR_DIS_DLL 0x0 ++#define EMIF4_CFG_SDR_DRV 0x0 ++#define EMIF4_CFG_CWL 0x0 ++#define EMIF4_CFG_NARROW_MD 0x0 ++#define EMIF4_CFG_CL 0x5 ++#define EMIF4_CFG_ROWSIZE 0x0 ++#define EMIF4_CFG_IBANK 0x3 ++#define EMIF4_CFG_EBANK 0x0 ++#define EMIF4_CFG_PGSIZE 0x2 ++ ++/* ++ * EMIF4 PHY Control 1 register configuration ++ */ ++#define EMIF4_DDR1_RD_LAT 0x6 ++#define EMIF4_DDR1_PWRDN_DIS 0x1 ++#define EMIF4_DDR1_STRBEN_EXT 0x1 ++#define EMIF4_DDR1_DLL_MODE 0x0 ++#define EMIF4_DDR1_VTP_DYN 0x1 ++#define EMIF4_DDR1_LB_CK_SEL 0x0 ++ ++/* ++ * EMIF4 PHY Control 2 register configuration ++ */ ++#define EMIF4_DDR2_TX_DATA_ALIGN 0x0 ++#define EMIF4_DDR2_RX_DLL_BYPASS 0x0 ++ ++/* Following functions are exported from lowlevel_init.S */ ++extern dpll_param *get_mpu_dpll_param(void); ++#if 0 ++extern dpll_param *get_iva_dpll_param(void); ++#endif ++extern dpll_param *get_core_dpll_param(void); ++extern dpll_param *get_per_dpll_param(void); ++ ++extern int mmc_init(int verbose); ++extern block_dev_desc_t *mmc_get_dev(int dev); ++ ++#define __raw_readl(a) (*(volatile unsigned int *)(a)) ++#define __raw_writel(v,a) (*(volatile unsigned int *)(a) = (v)) ++#define __raw_readw(a) (*(volatile unsigned short *)(a)) ++#define __raw_writew(v,a) (*(volatile unsigned short *)(a) = (v)) ++ ++/******************************************************* ++ * Routine: delay ++ * Description: spinning delay to use before udelay works ++ ******************************************************/ ++static inline void delay(unsigned long loops) ++{ ++ __asm__ volatile ("1:\n" "subs %0, %1, #1\n" ++ "bne 1b":"=r" (loops):"0"(loops)); ++} ++ ++void udelay (unsigned long usecs) { ++ delay(usecs); ++} ++ ++/***************************************** ++ * Routine: board_init ++ * Description: Early hardware init. ++ *****************************************/ ++int board_init (void) ++{ ++ return 0; ++} ++ ++/************************************************************* ++ * get_device_type(): tell if GP/HS/EMU/TST ++ *************************************************************/ ++u32 get_device_type(void) ++{ ++ int mode; ++ mode = __raw_readl(CONTROL_STATUS) & (DEVICE_MASK); ++ return(mode >>= 8); ++} ++ ++/************************************************ ++ * get_sysboot_value(void) - return SYS_BOOT[4:0] ++ ************************************************/ ++u32 get_sysboot_value(void) ++{ ++ int mode; ++ mode = __raw_readl(CONTROL_STATUS) & (SYSBOOT_MASK); ++ return mode; ++} ++/************************************************************* ++ * Routine: get_mem_type(void) - returns the kind of memory connected ++ * to GPMC that we are trying to boot form. Uses SYS BOOT settings. ++ *************************************************************/ ++u32 get_mem_type(void) ++{ ++ u32 mem_type = get_sysboot_value(); ++ switch (mem_type){ ++ case 0: ++ case 2: ++ case 4: ++ case 16: ++ case 22: return GPMC_ONENAND; ++ ++ case 1: ++ case 12: ++ case 15: ++ case 21: ++ case 27: return GPMC_NAND; ++ ++ case 3: ++ case 6: return MMC_ONENAND; ++ ++ case 8: ++ case 11: ++ case 14: ++ case 20: ++ case 26: return GPMC_MDOC; ++ ++ case 17: ++ case 18: ++ case 24: return MMC_NAND; ++ ++ case 7: ++ case 10: ++ case 13: ++ case 19: ++ case 25: ++ default: return GPMC_NOR; ++ } ++} ++ ++/****************************************** ++ * get_cpu_rev(void) - extract version info ++ ******************************************/ ++u32 get_cpu_rev(void) ++{ ++ u32 cpuid=0; ++ /* On ES1.0 the IDCODE register is not exposed on L4 ++ * so using CPU ID to differentiate ++ * between ES2.0 and ES1.0. ++ */ ++ __asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r" (cpuid)); ++ if((cpuid & 0xf) == 0x0) ++ return CPU_3430_ES1; ++ else ++ return CPU_3430_ES2; ++ ++} ++ ++/***************************************************************** ++ * sr32 - clear & set a value in a bit range for a 32 bit address ++ *****************************************************************/ ++void sr32(u32 addr, u32 start_bit, u32 num_bits, u32 value) ++{ ++ u32 tmp, msk = 0; ++ msk = 1 << num_bits; ++ --msk; ++ tmp = __raw_readl(addr) & ~(msk << start_bit); ++ tmp |= value << start_bit; ++ __raw_writel(tmp, addr); ++} ++ ++/********************************************************************* ++ * wait_on_value() - common routine to allow waiting for changes in ++ * volatile regs. ++ *********************************************************************/ ++u32 wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound) ++{ ++ u32 i = 0, val; ++ do { ++ ++i; ++ val = __raw_readl(read_addr) & read_bit_mask; ++ if (val == match_value) ++ return (1); ++ if (i == bound) ++ return (0); ++ } while (1); ++} ++ ++/********************************************************************* ++ * config_emif4_ddr() - Init/Configure DDR on OMAP3517 EVM board. ++ *********************************************************************/ ++void config_emif4_ddr(void) ++{ ++ unsigned int regval; ++ ++ /* Set the DDR PHY parameters in PHY ctrl registers */ ++ regval = (EMIF4_DDR1_RD_LAT | (EMIF4_DDR1_PWRDN_DIS << 6) | ++ (EMIF4_DDR1_STRBEN_EXT << 7) | (EMIF4_DDR1_DLL_MODE << 12) | ++ (EMIF4_DDR1_VTP_DYN << 15) | (EMIF4_DDR1_LB_CK_SEL << 23)); ++ __raw_writel(regval, EMIF4_DDR_PHYCTL1); ++ __raw_writel(regval, EMIF4_DDR_PHYCTL1_SHDW); ++ ++ regval = (EMIF4_DDR2_TX_DATA_ALIGN | (EMIF4_DDR2_RX_DLL_BYPASS << 1)); ++ __raw_writel(regval, EMIF4_DDR_PHYCTL2); ++ ++ /* Reset the DDR PHY and wait till completed */ ++ sr32(EMIF4_IODFT_TLGC, 10, 1, 1); ++ /*Wait till that bit clears*/ ++ while ((__raw_readl(EMIF4_IODFT_TLGC) & BIT10) == 0x1); ++ /*Re-verify the DDR PHY status*/ ++ while ((__raw_readl(EMIF4_SDRAM_STS) & BIT2) == 0x0); ++ ++ sr32(EMIF4_IODFT_TLGC, 0, 1, 1); ++ /* Set SDR timing registers */ ++ regval = (EMIF4_TIM1_T_WTR | (EMIF4_TIM1_T_RRD << 3) | ++ (EMIF4_TIM1_T_RC << 6) | (EMIF4_TIM1_T_RAS << 12) | ++ (EMIF4_TIM1_T_WR << 17) | (EMIF4_TIM1_T_RCD << 21) | ++ (EMIF4_TIM1_T_RP << 25)); ++ __raw_writel(regval, EMIF4_SDRAM_TIM1); ++ __raw_writel(regval, EMIF4_SDRAM_TIM1_SHDW); ++ ++ regval = (EMIF4_TIM2_T_CKE | (EMIF4_TIM2_T_RTP << 3) | ++ (EMIF4_TIM2_T_XSRD << 6) | (EMIF4_TIM2_T_XSNR << 16) | ++ (EMIF4_TIM2_T_ODT << 25) | (EMIF4_TIM2_T_XP << 28)); ++ __raw_writel(regval, EMIF4_SDRAM_TIM2); ++ __raw_writel(regval, EMIF4_SDRAM_TIM2_SHDW); ++ ++ regval = (EMIF4_TIM3_T_RAS_MAX | (EMIF4_TIM3_T_RFC << 4) | ++ (EMIF4_TIM3_T_TDQSCKMAX << 13)); ++ __raw_writel(regval, EMIF4_SDRAM_TIM3); ++ __raw_writel(regval, EMIF4_SDRAM_TIM3_SHDW); ++ ++ /* Set the PWR control register */ ++ regval = (EMIF4_PWR_PM_TIM | (EMIF4_PWR_PM_EN << 8) | ++ (EMIF4_PWR_DPD_EN << 10) | (EMIF4_PWR_IDLE << 30)); ++ __raw_writel(regval, EMIF4_PWR_MGT_CTRL); ++ __raw_writel(regval, EMIF4_PWR_MGT_CTRL_SHDW); ++ ++ /* Set the DDR refresh rate control register */ ++ regval = (EMIF4_REFRESH_RATE | (EMIF4_PASR << 24) | ++ (EMIF4_INITREF_DIS << 31)); ++ __raw_writel(regval, EMIF4_SDRAM_RFCR); ++ __raw_writel(regval, EMIF4_SDRAM_RFCR_SHDW); ++ ++ /* set the SDRAM configuration register */ ++ regval = (EMIF4_CFG_PGSIZE | (EMIF4_CFG_EBANK << 3) | ++ (EMIF4_CFG_IBANK << 4) | (EMIF4_CFG_ROWSIZE << 7) | ++ (EMIF4_CFG_CL << 10) | (EMIF4_CFG_NARROW_MD << 14) | ++ (EMIF4_CFG_CWL << 16) | (EMIF4_CFG_SDR_DRV << 18) | ++ (EMIF4_CFG_DDR_DIS_DLL << 20) | (EMIF4_CFG_DYN_ODT << 21) | ++ (EMIF4_CFG_DDR2_DDQS << 23) | (EMIF4_CFG_DDR_TERM << 24) | ++ (EMIF4_CFG_IBANK_POS << 27) | (EMIF4_CFG_SDRAM_TYP << 29)); ++ __raw_writel(regval, EMIF4_SDRAM_CFG); ++} ++ ++/************************************************************* ++ * get_sys_clk_speed - determine reference oscillator speed ++ * based on known 32kHz clock and gptimer. ++ *************************************************************/ ++u32 get_osc_clk_speed(void) ++{ ++ u32 start, cstart, cend, cdiff, val; ++ ++ val = __raw_readl(PRM_CLKSRC_CTRL); ++ /* If SYS_CLK is being divided by 2, remove for now */ ++ val = (val & (~BIT7)) | BIT6; ++ __raw_writel(val, PRM_CLKSRC_CTRL); ++ ++ /* enable timer2 */ ++ val = __raw_readl(CM_CLKSEL_WKUP) | BIT0; ++ __raw_writel(val, CM_CLKSEL_WKUP); /* select sys_clk for GPT1 */ ++ ++ /* Enable I and F Clocks for GPT1 */ ++ val = __raw_readl(CM_ICLKEN_WKUP) | BIT0 | BIT2; ++ __raw_writel(val, CM_ICLKEN_WKUP); ++ val = __raw_readl(CM_FCLKEN_WKUP) | BIT0; ++ __raw_writel(val, CM_FCLKEN_WKUP); ++ ++ __raw_writel(0, OMAP34XX_GPT1 + TLDR); /* start counting at 0 */ ++ __raw_writel(GPT_EN, OMAP34XX_GPT1 + TCLR); /* enable clock */ ++ /* enable 32kHz source *//* enabled out of reset */ ++ /* determine sys_clk via gauging */ ++ ++ start = 20 + __raw_readl(S32K_CR); /* start time in 20 cycles */ ++ while (__raw_readl(S32K_CR) < start); /* dead loop till start time */ ++ cstart = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get start sys_clk count */ ++ while (__raw_readl(S32K_CR) < (start + 20)); /* wait for 40 cycles */ ++ cend = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get end sys_clk count */ ++ cdiff = cend - cstart; /* get elapsed ticks */ ++ ++ /* based on number of ticks assign speed */ ++ if (cdiff > 19000) ++ return (S38_4M); ++ else if (cdiff > 15200) ++ return (S26M); ++ else if (cdiff > 13000) ++ return (S24M); ++ else if (cdiff > 9000) ++ return (S19_2M); ++ else if (cdiff > 7600) ++ return (S13M); ++ else ++ return (S12M); ++} ++ ++/****************************************************************************** ++ * get_sys_clkin_sel() - returns the sys_clkin_sel field value based on ++ * -- input oscillator clock frequency. ++ * ++ *****************************************************************************/ ++void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel) ++{ ++ if(osc_clk == S38_4M) ++ *sys_clkin_sel= 4; ++ else if(osc_clk == S26M) ++ *sys_clkin_sel = 3; ++ else if(osc_clk == S19_2M) ++ *sys_clkin_sel = 2; ++ else if(osc_clk == S13M) ++ *sys_clkin_sel = 1; ++ else if(osc_clk == S12M) ++ *sys_clkin_sel = 0; ++} ++ ++/****************************************************************************** ++ * prcm_init() - inits clocks for PRCM as defined in clocks.h ++ * -- called from SRAM, or Flash (using temp SRAM stack). ++ *****************************************************************************/ ++void prcm_init(void) ++{ ++ u32 osc_clk=0, sys_clkin_sel; ++ dpll_param *dpll_param_p; ++ u32 clk_index, sil_index; ++ ++ /* Gauge the input clock speed and find out the sys_clkin_sel ++ * value corresponding to the input clock. ++ */ ++ osc_clk = get_osc_clk_speed(); ++ get_sys_clkin_sel(osc_clk, &sys_clkin_sel); ++ ++ sr32(PRM_CLKSEL, 0, 3, sys_clkin_sel); /* set input crystal speed */ ++ ++ /* If the input clock is greater than 19.2M always divide/2 */ ++ if(sys_clkin_sel > 2) { ++ sr32(PRM_CLKSRC_CTRL, 6, 2, 2);/* input clock divider */ ++ clk_index = sys_clkin_sel/2; ++ } else { ++ sr32(PRM_CLKSRC_CTRL, 6, 2, 1);/* input clock divider */ ++ clk_index = sys_clkin_sel; ++ } ++ ++ /* The DPLL tables are defined according to sysclk value and ++ * silicon revision. The clk_index value will be used to get ++ * the values for that input sysclk from the DPLL param table ++ * and sil_index will get the values for that SysClk for the ++ * appropriate silicon rev. ++ */ ++ sil_index = get_cpu_rev() - 1; ++ ++ /* Unlock MPU DPLL (slows things down, and needed later) */ ++ sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOW_POWER_BYPASS); ++ wait_on_value(BIT0, 0, CM_IDLEST_PLL_MPU, LDELAY); ++ ++ /* Getting the base address of Core DPLL param table*/ ++ dpll_param_p = (dpll_param *)get_core_dpll_param(); ++ /* Moving it to the right sysclk and ES rev base */ ++ dpll_param_p = dpll_param_p + 2*clk_index + sil_index; ++ /* CORE DPLL */ ++ /* sr32(CM_CLKSEL2_EMU) set override to work when asleep */ ++ sr32(CM_CLKEN_PLL, 0, 3, PLL_FAST_RELOCK_BYPASS); ++ wait_on_value(BIT0, 0, CM_IDLEST_CKGEN, LDELAY); ++ sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2); /* m3x2 */ ++ sr32(CM_CLKSEL1_PLL, 27, 2, dpll_param_p->m2); /* Set M2 */ ++ sr32(CM_CLKSEL1_PLL, 16, 11, dpll_param_p->m); /* Set M */ ++ sr32(CM_CLKSEL1_PLL, 8, 7, dpll_param_p->n); /* Set N */ ++ sr32(CM_CLKSEL1_PLL, 6, 1, 0); /* 96M Src */ ++ sr32(CM_CLKSEL_CORE, 2, 2, CORE_L4_DIV); /* l4 */ ++ sr32(CM_CLKSEL_CORE, 0, 2, CORE_L3_DIV); /* l3 */ ++ sr32(CM_CLKSEL_WKUP, 1, 2, WKUP_RSM); /* reset mgr */ ++ sr32(CM_CLKEN_PLL, 4, 4, dpll_param_p->fsel); /* FREQSEL */ ++ sr32(CM_CLKEN_PLL, 0, 3, PLL_LOCK); /* lock mode */ ++ wait_on_value(BIT0, 1, CM_IDLEST_CKGEN, LDELAY); ++ ++ /* Getting the base address to PER DPLL param table*/ ++ dpll_param_p = (dpll_param *)get_per_dpll_param(); ++ /* Moving it to the right sysclk base */ ++ dpll_param_p = dpll_param_p + clk_index; ++ /* PER DPLL */ ++ sr32(CM_CLKEN_PLL, 16, 3, PLL_STOP); ++ wait_on_value(BIT1, 0, CM_IDLEST_CKGEN, LDELAY); ++ sr32(CM_CLKSEL1_EMU, 24, 5, PER_M6X2); /* set M6 */ ++ sr32(CM_CLKSEL_CAM, 0, 5, PER_M5X2); /* set M5 */ ++ sr32(CM_CLKSEL_DSS, 0, 5, PER_M4X2); /* set M4 */ ++ sr32(CM_CLKSEL_DSS, 8, 5, PER_M3X2); /* set M3 */ ++ sr32(CM_CLKSEL3_PLL, 0, 5, dpll_param_p->m2); /* set M2 */ ++ sr32(CM_CLKSEL2_PLL, 8, 11, dpll_param_p->m); /* set m */ ++ sr32(CM_CLKSEL2_PLL, 0, 7, dpll_param_p->n); /* set n */ ++ sr32(CM_CLKEN_PLL, 20, 4, dpll_param_p->fsel);/* FREQSEL */ ++ sr32(CM_CLKEN_PLL, 16, 3, PLL_LOCK); /* lock mode */ ++ wait_on_value(BIT1, 2, CM_IDLEST_CKGEN, LDELAY); ++ ++ /* Getting the base address to MPU DPLL param table*/ ++ dpll_param_p = (dpll_param *)get_mpu_dpll_param(); ++ /* Moving it to the right sysclk and ES rev base */ ++ dpll_param_p = dpll_param_p + 2*clk_index + sil_index; ++ /* MPU DPLL (unlocked already) */ ++ sr32(CM_CLKSEL2_PLL_MPU, 0, 5, dpll_param_p->m2); /* Set M2 */ ++ sr32(CM_CLKSEL1_PLL_MPU, 8, 11, dpll_param_p->m); /* Set M */ ++ sr32(CM_CLKSEL1_PLL_MPU, 0, 7, dpll_param_p->n); /* Set N */ ++ sr32(CM_CLKEN_PLL_MPU, 4, 4, dpll_param_p->fsel); /* FREQSEL */ ++ sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOCK); /* lock mode */ ++ wait_on_value(BIT0, 1, CM_IDLEST_PLL_MPU, LDELAY); ++ ++ /* Set up GPTimers to sys_clk source only */ ++ sr32(CM_CLKSEL_PER, 0, 8, 0xff); ++ sr32(CM_CLKSEL_WKUP, 0, 1, 1); ++ ++ delay(5000); ++} ++ ++/***************************************** ++ * Routine: secure_unlock ++ * Description: Setup security registers for access ++ * (GP Device only) ++ *****************************************/ ++void secure_unlock(void) ++{ ++ /* Permission values for registers -Full fledged permissions to all */ ++ #define UNLOCK_1 0xFFFFFFFF ++ #define UNLOCK_2 0x00000000 ++ #define UNLOCK_3 0x0000FFFF ++ /* Protection Module Register Target APE (PM_RT)*/ ++ __raw_writel(UNLOCK_1, RT_REQ_INFO_PERMISSION_1); ++ __raw_writel(UNLOCK_1, RT_READ_PERMISSION_0); ++ __raw_writel(UNLOCK_1, RT_WRITE_PERMISSION_0); ++ __raw_writel(UNLOCK_2, RT_ADDR_MATCH_1); ++ ++ __raw_writel(UNLOCK_3, GPMC_REQ_INFO_PERMISSION_0); ++ __raw_writel(UNLOCK_3, GPMC_READ_PERMISSION_0); ++ __raw_writel(UNLOCK_3, GPMC_WRITE_PERMISSION_0); ++ ++ __raw_writel(UNLOCK_3, OCM_REQ_INFO_PERMISSION_0); ++ __raw_writel(UNLOCK_3, OCM_READ_PERMISSION_0); ++ __raw_writel(UNLOCK_3, OCM_WRITE_PERMISSION_0); ++ __raw_writel(UNLOCK_2, OCM_ADDR_MATCH_2); ++ ++ __raw_writel(UNLOCK_1, SMS_RG_ATT0); /* SDRC region 0 public */ ++} ++ ++/********************************************************** ++ * Routine: try_unlock_sram() ++ * Description: If chip is GP type, unlock the SRAM for ++ * general use. ++ ***********************************************************/ ++void try_unlock_memory(void) ++{ ++ int mode; ++ ++ /* if GP device unlock device SRAM for general use */ ++ /* secure code breaks for Secure/Emulation device - HS/E/T*/ ++ mode = get_device_type(); ++ if (mode == GP_DEVICE) { ++ secure_unlock(); ++ } ++ return; ++} ++ ++/********************************************************** ++ * Routine: s_init ++ * Description: Does early system init of muxing and clocks. ++ * - Called at time when only stack is available. ++ **********************************************************/ ++ ++void s_init(void) ++{ ++ watchdog_init(); ++#ifdef CONFIG_3430_AS_3410 ++ /* setup the scalability control register for ++ * 3430 to work in 3410 mode ++ */ ++ __raw_writel(0x5ABF,CONTROL_SCALABLE_OMAP_OCP); ++#endif ++ try_unlock_memory(); ++ set_muxconf_regs(); ++ delay(100); ++ prcm_init(); ++ per_clocks_enable(); ++ ++ /* enable the DDRPHY clk */ ++ sr32((OMAP34XX_CTRL_BASE + 0x588), 15, 15, 0x1); ++ /* enable the EMIF4 clk */ ++ sr32((OMAP34XX_CTRL_BASE + 0x588), 14, 14, 0x1); ++ /* Enable the peripheral clocks */ ++ sr32((OMAP34XX_CTRL_BASE + 0x59C), 0, 4, 0xF); ++ sr32((OMAP34XX_CTRL_BASE + 0x59C), 8, 10, 0x7); ++ ++ /* bring cpgmac out of reset */ ++ sr32((OMAP34XX_CTRL_BASE + 0x598), 1, 1, 0x1); ++ ++ /* Configure the EMIF4 for our DDR */ ++ config_emif4_ddr(); ++} ++ ++/******************************************************* ++ * Routine: misc_init_r ++ * Description: Init ethernet (done here so udelay works) ++ ********************************************************/ ++int misc_init_r (void) ++{ ++ return(0); ++} ++ ++/****************************************************** ++ * Routine: wait_for_command_complete ++ * Description: Wait for posting to finish on watchdog ++ ******************************************************/ ++void wait_for_command_complete(unsigned int wd_base) ++{ ++ int pending = 1; ++ do { ++ pending = __raw_readl(wd_base + WWPS); ++ } while (pending); ++} ++ ++/**************************************** ++ * Routine: watchdog_init ++ * Description: Shut down watch dogs ++ *****************************************/ ++void watchdog_init(void) ++{ ++ /* There are 3 watch dogs WD1=Secure, WD2=MPU, WD3=IVA. WD1 is ++ * either taken care of by ROM (HS/EMU) or not accessible (GP). ++ * We need to take care of WD2-MPU or take a PRCM reset. WD3 ++ * should not be running and does not generate a PRCM reset. ++ */ ++ sr32(CM_FCLKEN_WKUP, 5, 1, 1); ++ sr32(CM_ICLKEN_WKUP, 5, 1, 1); ++ wait_on_value(BIT5, 0x20, CM_IDLEST_WKUP, 5); /* some issue here */ ++ ++ __raw_writel(WD_UNLOCK1, WD2_BASE + WSPR); ++ wait_for_command_complete(WD2_BASE); ++ __raw_writel(WD_UNLOCK2, WD2_BASE + WSPR); ++} ++ ++/********************************************** ++ * Routine: dram_init ++ * Description: sets uboots idea of sdram size ++ **********************************************/ ++int dram_init (void) ++{ ++ return 0; ++} ++ ++/***************************************************************** ++ * Routine: peripheral_enable ++ * Description: Enable the clks & power for perifs (GPT2, UART1,...) ++ ******************************************************************/ ++void per_clocks_enable(void) ++{ ++ /* Enable GP2 timer. */ ++ sr32(CM_CLKSEL_PER, 0, 1, 0x1); /* GPT2 = sys clk */ ++ sr32(CM_ICLKEN_PER, 3, 1, 0x1); /* ICKen GPT2 */ ++ sr32(CM_FCLKEN_PER, 3, 1, 0x1); /* FCKen GPT2 */ ++ ++#ifdef CFG_NS16550 ++ /* Enable UART1 clocks */ ++ sr32(CM_FCLKEN1_CORE, 13, 1, 0x1); ++ sr32(CM_ICLKEN1_CORE, 13, 1, 0x1); ++ ++ /* Enable UART2 clocks */ ++ sr32(CM_FCLKEN1_CORE, 14, 1, 0x1); ++ sr32(CM_ICLKEN1_CORE, 14, 1, 0x1); ++ ++ /* Enable UART2 clocks */ ++ sr32(CM_FCLKEN_PER, 11, 1, 0x1); ++ sr32(CM_ICLKEN_PER, 11, 1, 0x1); ++#endif ++ /* Enable MMC1 clocks */ ++ sr32(CM_FCLKEN1_CORE, 24, 1, 0x1); ++ sr32(CM_ICLKEN1_CORE, 24, 1, 0x1); ++ ++ /* Enable MMC2 clocks */ ++ sr32(CM_FCLKEN1_CORE, 25, 1, 0x1); ++ sr32(CM_ICLKEN1_CORE, 25, 1, 0x1); ++ ++ delay(1000); ++} ++ ++/* Set MUX for UART, GPMC, SDRC, GPIO */ ++ ++#define MUX_VAL(OFFSET,VALUE)\ ++ __raw_writew((VALUE), OMAP34XX_CTRL_BASE + (OFFSET)); ++ ++#define CP(x) (CONTROL_PADCONF_##x) ++/* ++ * IEN - Input Enable ++ * IDIS - Input Disable ++ * PTD - Pull type Down ++ * PTU - Pull type Up ++ * DIS - Pull type selection is inactive ++ * EN - Pull type selection is active ++ * M0 - Mode 0 ++ * The commented string gives the final mux configuration for that pin ++ */ ++#define MUX_DEFAULT()\ ++ MUX_VAL(CP(SDRC_D0), (IEN | PTD | DIS | M0)) /*SDRC_D0*/\ ++ MUX_VAL(CP(SDRC_D1), (IEN | PTD | DIS | M0)) /*SDRC_D1*/\ ++ MUX_VAL(CP(SDRC_D2), (IEN | PTD | DIS | M0)) /*SDRC_D2*/\ ++ MUX_VAL(CP(SDRC_D3), (IEN | PTD | DIS | M0)) /*SDRC_D3*/\ ++ MUX_VAL(CP(SDRC_D4), (IEN | PTD | DIS | M0)) /*SDRC_D4*/\ ++ MUX_VAL(CP(SDRC_D5), (IEN | PTD | DIS | M0)) /*SDRC_D5*/\ ++ MUX_VAL(CP(SDRC_D6), (IEN | PTD | DIS | M0)) /*SDRC_D6*/\ ++ MUX_VAL(CP(SDRC_D7), (IEN | PTD | DIS | M0)) /*SDRC_D7*/\ ++ MUX_VAL(CP(SDRC_D8), (IEN | PTD | DIS | M0)) /*SDRC_D8*/\ ++ MUX_VAL(CP(SDRC_D9), (IEN | PTD | DIS | M0)) /*SDRC_D9*/\ ++ MUX_VAL(CP(SDRC_D10), (IEN | PTD | DIS | M0)) /*SDRC_D10*/\ ++ MUX_VAL(CP(SDRC_D11), (IEN | PTD | DIS | M0)) /*SDRC_D11*/\ ++ MUX_VAL(CP(SDRC_D12), (IEN | PTD | DIS | M0)) /*SDRC_D12*/\ ++ MUX_VAL(CP(SDRC_D13), (IEN | PTD | DIS | M0)) /*SDRC_D13*/\ ++ MUX_VAL(CP(SDRC_D14), (IEN | PTD | DIS | M0)) /*SDRC_D14*/\ ++ MUX_VAL(CP(SDRC_D15), (IEN | PTD | DIS | M0)) /*SDRC_D15*/\ ++ MUX_VAL(CP(SDRC_D16), (IEN | PTD | DIS | M0)) /*SDRC_D16*/\ ++ MUX_VAL(CP(SDRC_D17), (IEN | PTD | DIS | M0)) /*SDRC_D17*/\ ++ MUX_VAL(CP(SDRC_D18), (IEN | PTD | DIS | M0)) /*SDRC_D18*/\ ++ MUX_VAL(CP(SDRC_D19), (IEN | PTD | DIS | M0)) /*SDRC_D19*/\ ++ MUX_VAL(CP(SDRC_D20), (IEN | PTD | DIS | M0)) /*SDRC_D20*/\ ++ MUX_VAL(CP(SDRC_D21), (IEN | PTD | DIS | M0)) /*SDRC_D21*/\ ++ MUX_VAL(CP(SDRC_D22), (IEN | PTD | DIS | M0)) /*SDRC_D22*/\ ++ MUX_VAL(CP(SDRC_D23), (IEN | PTD | DIS | M0)) /*SDRC_D23*/\ ++ MUX_VAL(CP(SDRC_D24), (IEN | PTD | DIS | M0)) /*SDRC_D24*/\ ++ MUX_VAL(CP(SDRC_D25), (IEN | PTD | DIS | M0)) /*SDRC_D25*/\ ++ MUX_VAL(CP(SDRC_D26), (IEN | PTD | DIS | M0)) /*SDRC_D26*/\ ++ MUX_VAL(CP(SDRC_D27), (IEN | PTD | DIS | M0)) /*SDRC_D27*/\ ++ MUX_VAL(CP(SDRC_D28), (IEN | PTD | DIS | M0)) /*SDRC_D28*/\ ++ MUX_VAL(CP(SDRC_D29), (IEN | PTD | DIS | M0)) /*SDRC_D29*/\ ++ MUX_VAL(CP(SDRC_D30), (IEN | PTD | DIS | M0)) /*SDRC_D30*/\ ++ MUX_VAL(CP(SDRC_D31), (IEN | PTD | DIS | M0)) /*SDRC_D31*/\ ++ MUX_VAL(CP(SDRC_CLK), (IEN | PTD | DIS | M0)) /*SDRC_CLK*/\ ++ MUX_VAL(CP(SDRC_DQS0), (IEN | PTD | DIS | M0)) /*SDRC_DQS0*/\ ++ MUX_VAL(CP(SDRC_DQS1), (IEN | PTD | DIS | M0)) /*SDRC_DQS1*/\ ++ MUX_VAL(CP(SDRC_DQS2), (IEN | PTD | DIS | M0)) /*SDRC_DQS2*/\ ++ MUX_VAL(CP(SDRC_DQS3), (IEN | PTD | DIS | M0)) /*SDRC_DQS3*/\ ++ MUX_VAL(CP(sdrc_cke0), (M0)) /*SDRC_CKE0*/\ ++ MUX_VAL(CP(sdrc_cke1), (M0)) /*SDRC_CKE1*/\ ++ MUX_VAL(CP(GPMC_A1), (IDIS | PTD | DIS | M0)) /*GPMC_A1*/\ ++ MUX_VAL(CP(GPMC_A2), (IDIS | PTD | DIS | M0)) /*GPMC_A2*/\ ++ MUX_VAL(CP(GPMC_A3), (IDIS | PTD | DIS | M0)) /*GPMC_A3*/\ ++ MUX_VAL(CP(GPMC_A4), (IDIS | PTD | DIS | M0)) /*GPMC_A4*/\ ++ MUX_VAL(CP(GPMC_A5), (IDIS | PTD | DIS | M0)) /*GPMC_A5*/\ ++ MUX_VAL(CP(GPMC_A6), (IDIS | PTD | DIS | M0)) /*GPMC_A6*/\ ++ MUX_VAL(CP(GPMC_A7), (IDIS | PTD | DIS | M0)) /*GPMC_A7*/\ ++ MUX_VAL(CP(GPMC_A8), (IDIS | PTD | DIS | M0)) /*GPMC_A8*/\ ++ MUX_VAL(CP(GPMC_A9), (IDIS | PTD | DIS | M0)) /*GPMC_A9*/\ ++ MUX_VAL(CP(GPMC_A10), (IDIS | PTD | DIS | M0)) /*GPMC_A10*/\ ++ MUX_VAL(CP(GPMC_D0), (IEN | PTD | DIS | M0)) /*GPMC_D0*/\ ++ MUX_VAL(CP(GPMC_D1), (IEN | PTD | DIS | M0)) /*GPMC_D1*/\ ++ MUX_VAL(CP(GPMC_D2), (IEN | PTD | DIS | M0)) /*GPMC_D2*/\ ++ MUX_VAL(CP(GPMC_D3), (IEN | PTD | DIS | M0)) /*GPMC_D3*/\ ++ MUX_VAL(CP(GPMC_D4), (IEN | PTD | DIS | M0)) /*GPMC_D4*/\ ++ MUX_VAL(CP(GPMC_D5), (IEN | PTD | DIS | M0)) /*GPMC_D5*/\ ++ MUX_VAL(CP(GPMC_D6), (IEN | PTD | DIS | M0)) /*GPMC_D6*/\ ++ MUX_VAL(CP(GPMC_D7), (IEN | PTD | DIS | M0)) /*GPMC_D7*/\ ++ MUX_VAL(CP(GPMC_D8), (IEN | PTD | DIS | M0)) /*GPMC_D8*/\ ++ MUX_VAL(CP(GPMC_D9), (IEN | PTD | DIS | M0)) /*GPMC_D9*/\ ++ MUX_VAL(CP(GPMC_D10), (IEN | PTD | DIS | M0)) /*GPMC_D10*/\ ++ MUX_VAL(CP(GPMC_D11), (IEN | PTD | DIS | M0)) /*GPMC_D11*/\ ++ MUX_VAL(CP(GPMC_D12), (IEN | PTD | DIS | M0)) /*GPMC_D12*/\ ++ MUX_VAL(CP(GPMC_D13), (IEN | PTD | DIS | M0)) /*GPMC_D13*/\ ++ MUX_VAL(CP(GPMC_D14), (IEN | PTD | DIS | M0)) /*GPMC_D14*/\ ++ MUX_VAL(CP(GPMC_D15), (IEN | PTD | DIS | M0)) /*GPMC_D15*/\ ++ MUX_VAL(CP(GPMC_nCS0), (IDIS | PTU | EN | M0)) /*GPMC_nCS0*/\ ++ MUX_VAL(CP(GPMC_nCS1), (IDIS | PTU | EN | M0)) /*GPMC_nCS1*/\ ++ MUX_VAL(CP(GPMC_nCS2), (IDIS | PTU | EN | M0)) /*GPMC_nCS2*/\ ++ MUX_VAL(CP(GPMC_nCS3), (IDIS | PTU | EN | M0)) /*GPMC_nCS3*/\ ++ MUX_VAL(CP(GPMC_nCS4), (IDIS | PTU | EN | M0)) /*GPMC_nCS4*/\ ++ MUX_VAL(CP(GPMC_nCS5), (IDIS | PTU | EN | M0)) /*GPMC_nCS5*/\ ++ MUX_VAL(CP(GPMC_nCS6), (IDIS | PTU | EN | M0)) /*GPMC_nCS6*/\ ++ MUX_VAL(CP(GPMC_nCS7), (IDIS | PTU | EN | M0)) /*GPMC_nCS7*/\ ++ MUX_VAL(CP(GPMC_CLK), (IDIS | PTD | DIS | M0)) /*GPMC_CLK*/\ ++ MUX_VAL(CP(GPMC_nADV_ALE), (IDIS | PTD | DIS | M0)) /*GPMC_nADV_ALE*/\ ++ MUX_VAL(CP(GPMC_nOE), (IDIS | PTD | DIS | M0)) /*GPMC_nOE*/\ ++ MUX_VAL(CP(GPMC_nWE), (IDIS | PTD | DIS | M0)) /*GPMC_nWE*/\ ++ MUX_VAL(CP(GPMC_nBE0_CLE), (IDIS | PTD | DIS | M0)) /*GPMC_nBE0_CLE*/\ ++ MUX_VAL(CP(GPMC_nBE1), (IDIS | PTD | DIS | M4)) /*GPIO_61*/\ ++ MUX_VAL(CP(GPMC_nWP), (IEN | PTD | DIS | M0)) /*GPMC_nWP*/\ ++ MUX_VAL(CP(GPMC_WAIT0), (IEN | PTU | EN | M0)) /*GPMC_WAIT0*/\ ++ MUX_VAL(CP(GPMC_WAIT1), (IEN | PTU | EN | M0)) /*GPMC_WAIT1*/\ ++ MUX_VAL(CP(GPMC_WAIT2), (IEN | PTU | EN | M4)) /*GPIO_64*/\ ++ MUX_VAL(CP(GPMC_WAIT3), (IEN | PTU | EN | M4)) /*GPIO_65*/\ ++ MUX_VAL(CP(DSS_DATA18), (IEN | PTD | DIS | M4)) /*GPIO_88*/\ ++ MUX_VAL(CP(DSS_DATA19), (IEN | PTD | DIS | M4)) /*GPIO_89*/\ ++ MUX_VAL(CP(DSS_DATA20), (IEN | PTD | DIS | M4)) /*GPIO_90*/\ ++ MUX_VAL(CP(DSS_DATA21), (IEN | PTD | DIS | M4)) /*GPIO_91*/\ ++ MUX_VAL(CP(CAM_WEN), (IEN | PTD | DIS | M4)) /*GPIO_167*/\ ++ MUX_VAL(CP(UART3_TX_IRTX), (IDIS | PTD | DIS | M0)) /*UART1_TX*/\ ++ MUX_VAL(CP(UART3_RTS_SD), (IDIS | PTD | DIS | M0)) /*UART1_RTS*/\ ++ MUX_VAL(CP(UART3_CTS_RCTX), (IEN | PTU | DIS | M0)) /*UART1_CTS*/\ ++ MUX_VAL(CP(UART3_RX_IRRX), (IEN | PTD | DIS | M0)) /*UART1_RX*/\ ++ /*Expansion card */\ ++ MUX_VAL(CP(MMC1_CLK), (IEN | PTU | EN | M0)) /*MMC1_CLK*/\ ++ MUX_VAL(CP(MMC1_CMD), (IEN | PTU | DIS | M0)) /*MMC1_CMD*/\ ++ MUX_VAL(CP(MMC1_DAT0), (IEN | PTU | DIS | M0)) /*MMC1_DAT0*/\ ++ MUX_VAL(CP(MMC1_DAT1), (IEN | PTU | DIS | M0)) /*MMC1_DAT1*/\ ++ MUX_VAL(CP(MMC1_DAT2), (IEN | PTU | DIS | M0)) /*MMC1_DAT2*/\ ++ MUX_VAL(CP(MMC1_DAT3), (IEN | PTU | DIS | M0)) /*MMC1_DAT3*/\ ++ MUX_VAL(CP(MMC1_DAT4), (IEN | PTU | DIS | M0)) /*MMC1_DAT4*/\ ++ MUX_VAL(CP(MMC1_DAT5), (IEN | PTU | DIS | M0)) /*MMC1_DAT5*/\ ++ MUX_VAL(CP(MMC1_DAT6), (IEN | PTU | DIS | M0)) /*MMC1_DAT6*/\ ++ MUX_VAL(CP(MMC1_DAT7), (IEN | PTU | DIS | M0)) /*MMC1_DAT7*/\ ++ MUX_VAL(CP(McBSP1_DX), (IEN | PTD | DIS | M4)) /*GPIO_158*/\ ++ MUX_VAL(CP(SYS_32K), (IEN | PTD | DIS | M0)) /*SYS_32K*/\ ++ MUX_VAL(CP(SYS_BOOT0), (IEN | PTD | DIS | M4)) /*GPIO_2 */\ ++ MUX_VAL(CP(SYS_BOOT1), (IEN | PTD | DIS | M4)) /*GPIO_3 */\ ++ MUX_VAL(CP(SYS_BOOT2), (IEN | PTD | DIS | M4)) /*GPIO_4 */\ ++ MUX_VAL(CP(SYS_BOOT3), (IEN | PTD | DIS | M4)) /*GPIO_5 */\ ++ MUX_VAL(CP(SYS_BOOT4), (IEN | PTD | DIS | M4)) /*GPIO_6 */\ ++ MUX_VAL(CP(SYS_BOOT5), (IEN | PTD | DIS | M4)) /*GPIO_7 */\ ++ MUX_VAL(CP(SYS_BOOT6), (IEN | PTD | DIS | M4)) /*GPIO_8 */\ ++ MUX_VAL(CP(SYS_CLKOUT2), (IEN | PTU | EN | M4)) /*GPIO_186*/\ ++ MUX_VAL(CP(JTAG_nTRST), (IEN | PTD | DIS | M0)) /*JTAG_nTRST*/\ ++ MUX_VAL(CP(JTAG_TCK), (IEN | PTD | DIS | M0)) /*JTAG_TCK*/\ ++ MUX_VAL(CP(JTAG_TMS), (IEN | PTD | DIS | M0)) /*JTAG_TMS*/\ ++ MUX_VAL(CP(JTAG_TDI), (IEN | PTD | DIS | M0)) /*JTAG_TDI*/\ ++ MUX_VAL(CP(JTAG_EMU0), (IEN | PTD | DIS | M0)) /*JTAG_EMU0*/\ ++ MUX_VAL(CP(JTAG_EMU1), (IEN | PTD | DIS | M0)) /*JTAG_EMU1*/\ ++ MUX_VAL(CP(ETK_CLK), (IEN | PTD | DIS | M4)) /*GPIO_12*/\ ++ MUX_VAL(CP(ETK_CTL), (IEN | PTD | DIS | M4)) /*GPIO_13*/\ ++ MUX_VAL(CP(ETK_D0 ), (IEN | PTD | DIS | M4)) /*GPIO_14*/\ ++ MUX_VAL(CP(ETK_D1 ), (IEN | PTD | DIS | M4)) /*GPIO_15*/\ ++ MUX_VAL(CP(ETK_D2 ), (IEN | PTD | DIS | M4)) /*GPIO_16*/\ ++ MUX_VAL(CP(ETK_D10), (IEN | PTD | DIS | M4)) /*GPIO_24*/\ ++ MUX_VAL(CP(ETK_D11), (IEN | PTD | DIS | M4)) /*GPIO_25*/\ ++ MUX_VAL(CP(ETK_D12), (IEN | PTD | DIS | M4)) /*GPIO_26*/\ ++ MUX_VAL(CP(ETK_D13), (IEN | PTD | DIS | M4)) /*GPIO_27*/\ ++ MUX_VAL(CP(ETK_D14), (IEN | PTD | DIS | M4)) /*GPIO_28*/\ ++ MUX_VAL(CP(ETK_D15), (IEN | PTD | DIS | M4)) /*GPIO_29*/ ++ ++/********************************************************** ++ * Routine: set_muxconf_regs ++ * Description: Setting up the configuration Mux registers ++ * specific to the hardware. Many pins need ++ * to be moved from protect to primary mode. ++ *********************************************************/ ++void set_muxconf_regs(void) ++{ ++ MUX_DEFAULT(); ++} ++ ++/********************************************************** ++ * Routine: nand+_init ++ * Description: Set up nand for nand and jffs2 commands ++ *********************************************************/ ++ ++int nand_init(void) ++{ ++ /* global settings */ ++ __raw_writel(0x10, GPMC_SYSCONFIG); /* smart idle */ ++ __raw_writel(0x0, GPMC_IRQENABLE); /* isr's sources masked */ ++ __raw_writel(0, GPMC_TIMEOUT_CONTROL);/* timeout disable */ ++ ++ /* Set the GPMC Vals . For NAND boot on 3430SDP, NAND is mapped at CS0 ++ * , NOR at CS1 and MPDB at CS3. And oneNAND boot, we map oneNAND at CS0. ++ * We configure only GPMC CS0 with required values. Configiring other devices ++ * at other CS in done in u-boot anyway. So we don't have to bother doing it here. ++ */ ++ __raw_writel(0 , GPMC_CONFIG7 + GPMC_CONFIG_CS0); ++ delay(1000); ++ ++ if ((get_mem_type() == GPMC_NAND) || (get_mem_type() == MMC_NAND)){ ++ __raw_writel( M_NAND_GPMC_CONFIG1, GPMC_CONFIG1 + GPMC_CONFIG_CS0); ++ __raw_writel( M_NAND_GPMC_CONFIG2, GPMC_CONFIG2 + GPMC_CONFIG_CS0); ++ __raw_writel( M_NAND_GPMC_CONFIG3, GPMC_CONFIG3 + GPMC_CONFIG_CS0); ++ __raw_writel( M_NAND_GPMC_CONFIG4, GPMC_CONFIG4 + GPMC_CONFIG_CS0); ++ __raw_writel( M_NAND_GPMC_CONFIG5, GPMC_CONFIG5 + GPMC_CONFIG_CS0); ++ __raw_writel( M_NAND_GPMC_CONFIG6, GPMC_CONFIG6 + GPMC_CONFIG_CS0); ++ ++ /* Enable the GPMC Mapping */ ++ __raw_writel(( ((OMAP34XX_GPMC_CS0_SIZE & 0xF)<<8) | ++ ((NAND_BASE_ADR>>24) & 0x3F) | ++ (1<<6) ), (GPMC_CONFIG7 + GPMC_CONFIG_CS0)); ++ delay(2000); ++ ++ if (nand_chip()){ ++#ifdef CFG_PRINTF ++ printf("Unsupported NAND Chip!\n"); ++#endif ++ return 1; ++ } ++ ++ } ++ ++ if ((get_mem_type() == GPMC_ONENAND) || (get_mem_type() == MMC_ONENAND)){ ++ __raw_writel( ONENAND_GPMC_CONFIG1, GPMC_CONFIG1 + GPMC_CONFIG_CS0); ++ __raw_writel( ONENAND_GPMC_CONFIG2, GPMC_CONFIG2 + GPMC_CONFIG_CS0); ++ __raw_writel( ONENAND_GPMC_CONFIG3, GPMC_CONFIG3 + GPMC_CONFIG_CS0); ++ __raw_writel( ONENAND_GPMC_CONFIG4, GPMC_CONFIG4 + GPMC_CONFIG_CS0); ++ __raw_writel( ONENAND_GPMC_CONFIG5, GPMC_CONFIG5 + GPMC_CONFIG_CS0); ++ __raw_writel( ONENAND_GPMC_CONFIG6, GPMC_CONFIG6 + GPMC_CONFIG_CS0); ++ ++ /* Enable the GPMC Mapping */ ++ __raw_writel(( ((OMAP34XX_GPMC_CS0_SIZE & 0xF)<<8) | ++ ((ONENAND_BASE>>24) & 0x3F) | ++ (1<<6) ), (GPMC_CONFIG7 + GPMC_CONFIG_CS0)); ++ delay(2000); ++ ++ if (onenand_chip()){ ++#ifdef CFG_PRINTF ++ printf("OneNAND Unsupported !\n"); ++#endif ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++ ++typedef int (mmc_boot_addr) (void); ++int mmc_boot(unsigned char *buf) ++{ ++ ++ long size = 0; ++#ifdef CFG_CMD_FAT ++ block_dev_desc_t *dev_desc = NULL; ++ unsigned char ret = 0; ++ ++ printf("Starting X-loader on MMC \n"); ++ ++ ret = mmc_init(1); ++ if(ret == 0){ ++ printf("\n MMC init failed \n"); ++ return 0; ++ } ++ ++ dev_desc = mmc_get_dev(0); ++ fat_register_device(dev_desc, 1); ++ size = file_fat_read("u-boot.bin", buf, 0); ++ if (size == -1) { ++ return 0; ++ } ++ printf("\n%ld Bytes Read from MMC \n", size); ++ ++ printf("Starting OS Bootloader from MMC...\n"); ++#endif ++ return size; ++} ++ ++/* optionally do something like blinking LED */ ++void board_hang (void) ++{ while (0) {};} ++ ++/****************************************************************************** ++ ++ * Dummy function to handle errors for EABI incompatibility ++ ++ *****************************************************************************/ ++ ++void raise(void) ++{ ++} ++ ++ ++/****************************************************************************** ++ ++ * Dummy function to handle errors for EABI incompatibility ++ ++ *****************************************************************************/ ++ ++void abort(void) ++{ ++} ++ ++ +diff -Nurd git/board/omap3517evm/platform.S x-load-shiva/board/omap3517evm/platform.S +--- git/board/omap3517evm/platform.S 1970-01-01 01:00:00.000000000 +0100 ++++ x-load-shiva/board/omap3517evm/platform.S 2009-09-08 16:54:36.000000000 +0200 +@@ -0,0 +1,435 @@ ++/* ++ * Board specific setup info ++ * ++ * (C) Copyright 2004-2006 ++ * Texas Instruments, ++ * Richard Woodruff ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++#include ++#include ++#include ++#include ++ ++_TEXT_BASE: ++ .word TEXT_BASE /* sdram load addr from config.mk */ ++ ++#if !defined(CFG_NAND_BOOT) && !defined(CFG_NAND_BOOT) ++/************************************************************************** ++ * cpy_clk_code: relocates clock code into SRAM where its safer to execute ++ * R1 = SRAM destination address. ++ *************************************************************************/ ++.global cpy_clk_code ++ cpy_clk_code: ++ /* Copy DPLL code into SRAM */ ++ adr r0, go_to_speed /* get addr of clock setting code */ ++ mov r2, #384 /* r2 size to copy (div by 32 bytes) */ ++ mov r1, r1 /* r1 <- dest address (passed in) */ ++ add r2, r2, r0 /* r2 <- source end address */ ++next2: ++ ldmia r0!, {r3-r10} /* copy from source address [r0] */ ++ stmia r1!, {r3-r10} /* copy to target address [r1] */ ++ cmp r0, r2 /* until source end address [r2] */ ++ bne next2 ++ mov pc, lr /* back to caller */ ++ ++/* **************************************************************************** ++ * NOTE: 3430 X-loader currently does not use this code. ++* It could be removed its is kept for compatabily with u-boot. ++ * ++ * go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed ++ * -executed from SRAM. ++ * R0 = CM_CLKEN_PLL-bypass value ++ * R1 = CM_CLKSEL1_PLL-m, n, and divider values ++ * R2 = CM_CLKSEL_CORE-divider values ++ * R3 = CM_IDLEST_CKGEN - addr dpll lock wait ++ * ++ * Note: If core unlocks/relocks and SDRAM is running fast already it gets ++ * confused. A reset of the controller gets it back. Taking away its ++ * L3 when its not in self refresh seems bad for it. Normally, this code ++ * runs from flash before SDR is init so that should be ok. ++ ******************************************************************************/ ++.global go_to_speed ++ go_to_speed: ++ stmfd sp!, {r4-r6} ++ ++ /* move into fast relock bypass */ ++ ldr r4, pll_ctl_add ++ str r0, [r4] ++wait1: ++ ldr r5, [r3] /* get status */ ++ and r5, r5, #0x1 /* isolate core status */ ++ cmp r5, #0x1 /* still locked? */ ++ beq wait1 /* if lock, loop */ ++ ++ /* set new dpll dividers _after_ in bypass */ ++ ldr r5, pll_div_add1 ++ str r1, [r5] /* set m, n, m2 */ ++ ldr r5, pll_div_add2 ++ str r2, [r5] /* set l3/l4/.. dividers*/ ++ ldr r5, pll_div_add3 /* wkup */ ++ ldr r2, pll_div_val3 /* rsm val */ ++ str r2, [r5] ++ ldr r5, pll_div_add4 /* gfx */ ++ ldr r2, pll_div_val4 ++ str r2, [r5] ++ ldr r5, pll_div_add5 /* emu */ ++ ldr r2, pll_div_val5 ++ str r2, [r5] ++ ++ /* now prepare GPMC (flash) for new dpll speed */ ++ /* flash needs to be stable when we jump back to it */ ++ ldr r5, flash_cfg3_addr ++ ldr r2, flash_cfg3_val ++ str r2, [r5] ++ ldr r5, flash_cfg4_addr ++ ldr r2, flash_cfg4_val ++ str r2, [r5] ++ ldr r5, flash_cfg5_addr ++ ldr r2, flash_cfg5_val ++ str r2, [r5] ++ ldr r5, flash_cfg1_addr ++ ldr r2, [r5] ++ orr r2, r2, #0x3 /* up gpmc divider */ ++ str r2, [r5] ++ ++ /* lock DPLL3 and wait a bit */ ++ orr r0, r0, #0x7 /* set up for lock mode */ ++ str r0, [r4] /* lock */ ++ nop /* ARM slow at this point working at sys_clk */ ++ nop ++ nop ++ nop ++wait2: ++ ldr r5, [r3] /* get status */ ++ and r5, r5, #0x1 /* isolate core status */ ++ cmp r5, #0x1 /* still locked? */ ++ bne wait2 /* if lock, loop */ ++ nop ++ nop ++ nop ++ nop ++ ldmfd sp!, {r4-r6} ++ mov pc, lr /* back to caller, locked */ ++ ++_go_to_speed: .word go_to_speed ++ ++/* these constants need to be close for PIC code */ ++/* The Nor has to be in the Flash Base CS0 for this condition to happen */ ++flash_cfg1_addr: ++ .word (GPMC_CONFIG_CS0 + GPMC_CONFIG1) ++flash_cfg3_addr: ++ .word (GPMC_CONFIG_CS0 + GPMC_CONFIG3) ++flash_cfg3_val: ++ .word STNOR_GPMC_CONFIG3 ++flash_cfg4_addr: ++ .word (GPMC_CONFIG_CS0 + GPMC_CONFIG4) ++flash_cfg4_val: ++ .word STNOR_GPMC_CONFIG4 ++flash_cfg5_val: ++ .word STNOR_GPMC_CONFIG5 ++flash_cfg5_addr: ++ .word (GPMC_CONFIG_CS0 + GPMC_CONFIG5) ++pll_ctl_add: ++ .word CM_CLKEN_PLL ++pll_div_add1: ++ .word CM_CLKSEL1_PLL ++pll_div_add2: ++ .word CM_CLKSEL_CORE ++pll_div_add3: ++ .word CM_CLKSEL_WKUP ++pll_div_val3: ++ .word (WKUP_RSM << 1) ++pll_div_add4: ++ .word CM_CLKSEL_GFX ++pll_div_val4: ++ .word (GFX_DIV << 0) ++pll_div_add5: ++ .word CM_CLKSEL1_EMU ++pll_div_val5: ++ .word CLSEL1_EMU_VAL ++ ++#endif ++ ++.globl lowlevel_init ++lowlevel_init: ++ ldr sp, SRAM_STACK ++ str ip, [sp] /* stash old link register */ ++ mov ip, lr /* save link reg across call */ ++ bl s_init /* go setup pll,mux,memory */ ++ ldr ip, [sp] /* restore save ip */ ++ mov lr, ip /* restore link reg */ ++ ++ /* back to arch calling code */ ++ mov pc, lr ++ ++ /* the literal pools origin */ ++ .ltorg ++ ++REG_CONTROL_STATUS: ++ .word CONTROL_STATUS ++SRAM_STACK: ++ .word LOW_LEVEL_SRAM_STACK ++ ++ ++/* DPLL(1-4) PARAM TABLES */ ++/* Each of the tables has M, N, FREQSEL, M2 values defined for nominal ++ * OPP (1.2V). The fields are defined according to dpll_param struct(clock.c). ++ * The values are defined for all possible sysclk and for ES1 and ES2. ++ */ ++ ++mpu_dpll_param: ++/* 12MHz */ ++/* ES1 */ ++.word 0x0FE ++.word 0x07 ++.word 0x05 ++.word 0x01 ++/* ES2 */ ++.word 0x0FA ++.word 0x05 ++.word 0x07 ++.word 0x01 ++ ++/* 13MHz */ ++/* ES1 */ ++.word 0x17D ++.word 0x0C ++.word 0x03 ++.word 0x01 ++/* ES2 */ ++.word 0x1F4 ++.word 0x0C ++.word 0x03 ++.word 0x01 ++ ++/* 19.2MHz */ ++/* ES1 */ ++.word 0x179 ++.word 0x12 ++.word 0x04 ++.word 0x01 ++/* ES2 */ ++.word 0x271 ++.word 0x17 ++.word 0x03 ++.word 0x01 ++ ++/* 26MHz */ ++/* ES1 */ ++.word 0x17D ++.word 0x19 ++.word 0x03 ++.word 0x01 ++/* ES2 */ ++.word 0x0FA ++.word 0x0C ++.word 0x07 ++.word 0x01 ++ ++/* 38.4MHz */ ++/* ES1 */ ++.word 0x1FA ++.word 0x32 ++.word 0x03 ++.word 0x01 ++/* ES2 */ ++.word 0x271 ++.word 0x2F ++.word 0x03 ++.word 0x01 ++ ++ ++.globl get_mpu_dpll_param ++get_mpu_dpll_param: ++ adr r0, mpu_dpll_param ++ mov pc, lr ++ ++iva_dpll_param: ++/* 12MHz */ ++/* ES1 */ ++.word 0x07D ++.word 0x05 ++.word 0x07 ++.word 0x01 ++/* ES2 */ ++.word 0x0B4 ++.word 0x05 ++.word 0x07 ++.word 0x01 ++ ++/* 13MHz */ ++/* ES1 */ ++.word 0x0FA ++.word 0x0C ++.word 0x03 ++.word 0x01 ++/* ES2 */ ++.word 0x168 ++.word 0x0C ++.word 0x03 ++.word 0x01 ++ ++/* 19.2MHz */ ++/* ES1 */ ++.word 0x082 ++.word 0x09 ++.word 0x07 ++.word 0x01 ++/* ES2 */ ++.word 0x0E1 ++.word 0x0B ++.word 0x06 ++.word 0x01 ++ ++/* 26MHz */ ++/* ES1 */ ++.word 0x07D ++.word 0x0C ++.word 0x07 ++.word 0x01 ++/* ES2 */ ++.word 0x0B4 ++.word 0x0C ++.word 0x07 ++.word 0x01 ++ ++/* 38.4MHz */ ++/* ES1 */ ++.word 0x13F ++.word 0x30 ++.word 0x03 ++.word 0x01 ++/* ES2 */ ++.word 0x0E1 ++.word 0x17 ++.word 0x06 ++.word 0x01 ++ ++ ++.globl get_iva_dpll_param ++get_iva_dpll_param: ++ adr r0, iva_dpll_param ++ mov pc, lr ++ ++core_dpll_param: ++/* 12MHz */ ++/* ES1 */ ++.word 0x19F ++.word 0x0E ++.word 0x03 ++.word 0x01 ++/* ES2 */ ++.word 0x0A6 ++.word 0x05 ++.word 0x07 ++.word 0x01 ++ ++/* 13MHz */ ++/* ES1 */ ++.word 0x1B2 ++.word 0x10 ++.word 0x03 ++.word 0x01 ++/* ES2 */ ++.word 0x14C ++.word 0x0C ++.word 0x03 ++.word 0x01 ++ ++/* 19.2MHz */ ++/* ES1 */ ++.word 0x19F ++.word 0x17 ++.word 0x03 ++.word 0x01 ++/* ES2 */ ++.word 0x19F ++.word 0x17 ++.word 0x03 ++.word 0x01 ++ ++/* 26MHz */ ++/* ES1 */ ++.word 0x1B2 ++.word 0x21 ++.word 0x03 ++.word 0x01 ++/* ES2 */ ++.word 0x0A6 ++.word 0x0C ++.word 0x07 ++.word 0x01 ++ ++/* 38.4MHz */ ++/* ES1 */ ++.word 0x19F ++.word 0x2F ++.word 0x03 ++.word 0x01 ++/* ES2 */ ++.word 0x19F ++.word 0x2F ++.word 0x03 ++.word 0x01 ++ ++.globl get_core_dpll_param ++get_core_dpll_param: ++ adr r0, core_dpll_param ++ mov pc, lr ++ ++/* PER DPLL values are same for both ES1 and ES2 */ ++per_dpll_param: ++/* 12MHz */ ++.word 0xD8 ++.word 0x05 ++.word 0x07 ++.word 0x09 ++ ++/* 13MHz */ ++.word 0x1B0 ++.word 0x0C ++.word 0x03 ++.word 0x09 ++ ++/* 19.2MHz */ ++.word 0xE1 ++.word 0x09 ++.word 0x07 ++.word 0x09 ++ ++/* 26MHz */ ++.word 0xD8 ++.word 0x0C ++.word 0x07 ++.word 0x09 ++ ++/* 38.4MHz */ ++.word 0xE1 ++.word 0x13 ++.word 0x07 ++.word 0x09 ++ ++.globl get_per_dpll_param ++get_per_dpll_param: ++ adr r0, per_dpll_param ++ mov pc, lr ++ +diff -Nurd git/board/omap3517evm/x-load.lds x-load-shiva/board/omap3517evm/x-load.lds +--- git/board/omap3517evm/x-load.lds 1970-01-01 01:00:00.000000000 +0100 ++++ x-load-shiva/board/omap3517evm/x-load.lds 2009-09-08 16:55:24.000000000 +0200 +@@ -0,0 +1,54 @@ ++/* ++ * November 2006 - Changed to support 3430sdp device ++ * Copyright (c) 2004-2006 Texas Instruments ++ * ++ * (C) Copyright 2002 ++ * Gary Jennejohn, DENX Software Engineering, ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") ++OUTPUT_ARCH(arm) ++ENTRY(_start) ++SECTIONS ++{ ++ . = 0x00000000; ++ ++ . = ALIGN(4); ++ .text : ++ { ++ cpu/omap3/start.o (.text) ++ *(.text) ++ } ++ ++ . = ALIGN(4); ++ .rodata : { *(.rodata) } ++ ++ . = ALIGN(4); ++ .data : { *(.data) } ++ ++ . = ALIGN(4); ++ .got : { *(.got) } ++ ++ . = ALIGN(4); ++ __bss_start = .; ++ .bss : { *(.bss) } ++ _end = .; ++} +diff -Nurd git/drivers/Makefile x-load-shiva/drivers/Makefile +--- git/drivers/Makefile 2009-09-08 16:43:33.000000000 +0200 ++++ x-load-shiva/drivers/Makefile 2009-09-08 18:20:59.000000000 +0200 +@@ -48,6 +48,10 @@ + OBJS += k9f1g08r0a.o + endif + ++ifeq ($(BOARD), omap3517evm) ++OBJS += k9f1g08r0a.o ++endif ++ + ifeq ($(BOARD), omap2420h4) + OBJS += k9k1216.o + endif +diff -Nurd git/drivers/k9f1g08r0a.c x-load-shiva/drivers/k9f1g08r0a.c +--- git/drivers/k9f1g08r0a.c 2009-09-08 16:43:33.000000000 +0200 ++++ x-load-shiva/drivers/k9f1g08r0a.c 2009-09-09 15:46:22.000000000 +0200 +@@ -182,7 +182,11 @@ + NAND_DISABLE_CE(); + + if (get_cpu_rev() == CPU_3430_ES2) +- return (mfr != MT29F1G_MFR || !(id == MT29F1G_ID || id == MT29F2G_ID)); ++#if defined (CONFIG_OMAP34XX) || defined (CONFIG_OMAP3EVM) ++ return (mfr != MT29F1G_MFR || !(id == MT29F1G_ID || id == MT29F2G_ID)); ++#elif defined (CONFIG_OMAP3517EVM) || defined (CONFIG_OMAP3517TEB) ++ return (mfr != MT29F1G_MFR && !(id == MT29F1G_ID || id == MT29F2G_ID)); ++#endif + else + return (mfr != K9F1G08R0A_MFR || id != K9F1G08R0A_ID); + } +diff -Nurd git/include/asm/arch-omap3/cpu.h x-load-shiva/include/asm/arch-omap3/cpu.h +--- git/include/asm/arch-omap3/cpu.h 2009-09-08 16:43:33.000000000 +0200 ++++ x-load-shiva/include/asm/arch-omap3/cpu.h 2009-09-08 17:26:54.000000000 +0200 +@@ -24,7 +24,11 @@ + + #ifndef _OMAP34XX_CPU_H + #define _OMAP34XX_CPU_H ++#if defined (CONFIG_OMAP3517EVM) || defined (CONFIG_OMAP3517TEB) ++#include ++#elif defined (CONFIG_OMAP3430) + #include ++#endif + + /* Register offsets of common modules */ + /* Control */ +@@ -59,7 +63,12 @@ + #define GPMC_CONFIG (OMAP34XX_GPMC_BASE+0x50) + #define GPMC_STATUS (OMAP34XX_GPMC_BASE+0x54) + ++#if defined (CONFIG_OMAP34XX) || defined (CONFIG_OMAP3517EVM) + #define GPMC_CONFIG_CS0 (OMAP34XX_GPMC_BASE+0x60) ++#elif defined (CONFIG_OMAP3517TEB) ++#define GPMC_CONFIG_CS0 (OMAP34XX_GPMC_BASE+0xC0) ++#endif ++ + #define GPMC_CONFIG_WIDTH (0x30) + + #define GPMC_CONFIG1 (0x00) +@@ -142,6 +151,27 @@ + #define SMART_IDLE (0x2 << 3) + #define REF_ON_IDLE (0x1 << 6) + ++/* EMIF4 register */ ++#define EMIF4_BASE OMAP34XX_SDRC_BASE ++#define EMIF4_MOD_ID (EMIF4_BASE + 0x00) ++#define EMIF4_SDRAM_STS (EMIF4_BASE + 0x04) ++#define EMIF4_SDRAM_CFG (EMIF4_BASE + 0x08) ++#define EMIF4_SDRAM_RFCR (EMIF4_BASE + 0x10) ++#define EMIF4_SDRAM_RFCR_SHDW (EMIF4_BASE + 0x14) ++#define EMIF4_SDRAM_TIM1 (EMIF4_BASE + 0x18) ++#define EMIF4_SDRAM_TIM1_SHDW (EMIF4_BASE + 0x1C) ++#define EMIF4_SDRAM_TIM2 (EMIF4_BASE + 0x20) ++#define EMIF4_SDRAM_TIM2_SHDW (EMIF4_BASE + 0x24) ++#define EMIF4_SDRAM_TIM3 (EMIF4_BASE + 0x28) ++#define EMIF4_SDRAM_TIM3_SHDW (EMIF4_BASE + 0x2c) ++#define EMIF4_PWR_MGT_CTRL (EMIF4_BASE + 0x38) ++#define EMIF4_PWR_MGT_CTRL_SHDW (EMIF4_BASE + 0x3C) ++#define EMIF4_IODFT_TLGC (EMIF4_BASE + 0x60) ++#define EMIF4_DDR_PHYCTL1 (EMIF4_BASE + 0xE4) ++#define EMIF4_DDR_PHYCTL1_SHDW (EMIF4_BASE + 0xE8) ++#define EMIF4_DDR_PHYCTL2 (EMIF4_BASE + 0xEC) ++ ++ + /* timer regs offsets (32 bit regs) */ + #define TIDR 0x0 /* r */ + #define TIOCP_CFG 0x10 /* rw */ +diff -Nurd git/include/asm/arch-omap3/mem.h x-load-shiva/include/asm/arch-omap3/mem.h +--- git/include/asm/arch-omap3/mem.h 2009-09-08 16:43:33.000000000 +0200 ++++ x-load-shiva/include/asm/arch-omap3/mem.h 2009-09-08 17:26:54.000000000 +0200 +@@ -324,12 +324,31 @@ + # define SMNAND_GPMC_CONFIG5 0x010C1414 + # define SMNAND_GPMC_CONFIG6 0x00000A80 + ++#if defined (CONFIG_OMAP34xx) ++ + # define M_NAND_GPMC_CONFIG1 0x00001800 + # define M_NAND_GPMC_CONFIG2 SMNAND_GPMC_CONFIG2 + # define M_NAND_GPMC_CONFIG3 SMNAND_GPMC_CONFIG3 + # define M_NAND_GPMC_CONFIG4 SMNAND_GPMC_CONFIG4 + # define M_NAND_GPMC_CONFIG5 SMNAND_GPMC_CONFIG5 + # define M_NAND_GPMC_CONFIG6 SMNAND_GPMC_CONFIG6 ++ ++#elif defined (CONFIG_OMAP3517EVM) || defined (CONFIG_OMAP3517TEB) ++ ++#ifdef NAND_16BIT ++# define M_NAND_GPMC_CONFIG1 0x00001800 ++#else ++# define M_NAND_GPMC_CONFIG1 0x00000800 ++#endif ++# define M_NAND_GPMC_CONFIG2 0x00080800 ++# define M_NAND_GPMC_CONFIG3 0x00080800 ++# define M_NAND_GPMC_CONFIG4 0x06000600 ++# define M_NAND_GPMC_CONFIG5 0x00070808 ++# define M_NAND_GPMC_CONFIG6 0x000003cf ++# define M_NAND_GPMC_CONFIG7 0x00000848 ++ ++#endif ++ + # define STNOR_GPMC_CONFIG1 0x3 + # define STNOR_GPMC_CONFIG2 0x000f0f01 + # define STNOR_GPMC_CONFIG3 0x00050502 +@@ -353,6 +372,8 @@ + # define SMNAND_GPMC_CONFIG6 0x00000A80 + # define SMNAND_GPMC_CONFIG7 0x00000C44 + ++#if defined (CONFIG_OMAP34xx) ++ + # define M_NAND_GPMC_CONFIG1 0x00001800 + # define M_NAND_GPMC_CONFIG2 SMNAND_GPMC_CONFIG2 + # define M_NAND_GPMC_CONFIG3 SMNAND_GPMC_CONFIG3 +@@ -361,6 +382,23 @@ + # define M_NAND_GPMC_CONFIG6 SMNAND_GPMC_CONFIG6 + # define M_NAND_GPMC_CONFIG7 SMNAND_GPMC_CONFIG7 + ++#elif defined (CONFIG_OMAP3517EVM) || defined (CONFIG_OMAP3517TEB) ++ ++#ifdef NAND_16BIT ++# define M_NAND_GPMC_CONFIG1 0x00001800 ++#else ++# define M_NAND_GPMC_CONFIG1 0x00000800 ++#endif ++# define M_NAND_GPMC_CONFIG2 0x00080800 ++# define M_NAND_GPMC_CONFIG3 0x00080800 ++# define M_NAND_GPMC_CONFIG4 0x06000600 ++# define M_NAND_GPMC_CONFIG5 0x00070808 ++# define M_NAND_GPMC_CONFIG6 0x000003cf ++# define M_NAND_GPMC_CONFIG7 0x00000848 ++ ++#endif ++ ++ + # define STNOR_GPMC_CONFIG1 0x1203 + # define STNOR_GPMC_CONFIG2 0x00151501 + # define STNOR_GPMC_CONFIG3 0x00060602 +@@ -407,6 +445,8 @@ + # define SMNAND_GPMC_CONFIG6 0x1F0F0A80 + # define SMNAND_GPMC_CONFIG7 0x00000C44 + ++#if defined (CONFIG_OMAP34xx) ++ + # define M_NAND_GPMC_CONFIG1 0x00001800 + # define M_NAND_GPMC_CONFIG2 SMNAND_GPMC_CONFIG2 + # define M_NAND_GPMC_CONFIG3 SMNAND_GPMC_CONFIG3 +@@ -415,6 +455,23 @@ + # define M_NAND_GPMC_CONFIG6 SMNAND_GPMC_CONFIG6 + # define M_NAND_GPMC_CONFIG7 SMNAND_GPMC_CONFIG7 + ++#elif defined (CONFIG_OMAP3517EVM) || defined (CONFIG_OMAP3517TEB) ++ ++#ifdef NAND_16BIT ++# define M_NAND_GPMC_CONFIG1 0x00001800 ++#else ++# define M_NAND_GPMC_CONFIG1 0x00000800 ++#endif ++# define M_NAND_GPMC_CONFIG2 0x00080800 ++# define M_NAND_GPMC_CONFIG3 0x00080800 ++# define M_NAND_GPMC_CONFIG4 0x06000600 ++# define M_NAND_GPMC_CONFIG5 0x00070808 ++# define M_NAND_GPMC_CONFIG6 0x000003cf ++# define M_NAND_GPMC_CONFIG7 0x00000848 ++ ++#endif ++ ++ + # define STNOR_GPMC_CONFIG1 0x3 + # define STNOR_GPMC_CONFIG2 0x00151501 + # define STNOR_GPMC_CONFIG3 0x00060602 +diff -Nurd git/include/asm/arch-omap3/omap3.h x-load-shiva/include/asm/arch-omap3/omap3.h +--- git/include/asm/arch-omap3/omap3.h 1970-01-01 01:00:00.000000000 +0100 ++++ x-load-shiva/include/asm/arch-omap3/omap3.h 2009-09-08 17:26:54.000000000 +0200 +@@ -0,0 +1,134 @@ ++/* ++ * (C) Copyright 2006 ++ * Texas Instruments, ++ * Richard Woodruff ++ * Syed Mohammed Khasim ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++#ifndef _OMAP3_SYS_H_ ++#define _OMAP3_SYS_H_ ++ ++#include ++ ++/* ++ * OMAP3 specific Section ++ */ ++ ++/* Stuff on L3 Interconnect */ ++#define SMX_APE_BASE 0x68000000 ++ ++/* L3 Firewall */ ++#define A_REQINFOPERM0 (SMX_APE_BASE + 0x05048) ++#define A_READPERM0 (SMX_APE_BASE + 0x05050) ++#define A_WRITEPERM0 (SMX_APE_BASE + 0x05058) ++ ++/* GPMC */ ++#define OMAP34XX_GPMC_BASE (0x6E000000) ++ ++/* SMS */ ++#define OMAP34XX_SMS_BASE 0x6C000000 ++ ++/* SDRC */ ++#define OMAP34XX_SDRC_BASE 0x6D000000 ++ ++/* ++ * L4 Peripherals - L4 Wakeup and L4 Core now ++ */ ++#define OMAP34XX_CORE_L4_IO_BASE 0x48000000 ++ ++#define OMAP34XX_WAKEUP_L4_IO_BASE 0x48300000 ++ ++#define OMAP34XX_L4_PER 0x49000000 ++ ++#define OMAP34XX_L4_IO_BASE OMAP34XX_CORE_L4_IO_BASE ++ ++/* CONTROL */ ++#define OMAP34XX_CTRL_BASE (OMAP34XX_L4_IO_BASE+0x2000) ++ ++/* TAP information dont know for 3430*/ ++#define OMAP34XX_TAP_BASE (0x49000000) /*giving some junk for virtio */ ++ ++/* UART */ ++#define OMAP34XX_UART1 (OMAP34XX_L4_IO_BASE+0x6a000) ++#define OMAP34XX_UART2 (OMAP34XX_L4_IO_BASE+0x6c000) ++#define OMAP34XX_UART3 (OMAP34XX_L4_PER+0x20000) ++ ++/* General Purpose Timers */ ++#define OMAP34XX_GPT1 0x48318000 ++#define OMAP34XX_GPT2 0x49032000 ++#define OMAP34XX_GPT3 0x49034000 ++#define OMAP34XX_GPT4 0x49036000 ++#define OMAP34XX_GPT5 0x49038000 ++#define OMAP34XX_GPT6 0x4903A000 ++#define OMAP34XX_GPT7 0x4903C000 ++#define OMAP34XX_GPT8 0x4903E000 ++#define OMAP34XX_GPT9 0x49040000 ++#define OMAP34XX_GPT10 0x48086000 ++#define OMAP34XX_GPT11 0x48088000 ++#define OMAP34XX_GPT12 0x48304000 ++ ++/* WatchDog Timers (1 secure, 3 GP) */ ++#define WD1_BASE (0x4830C000) ++#define WD2_BASE (0x48314000) ++#define WD3_BASE (0x49030000) ++ ++/* 32KTIMER */ ++#define SYNC_32KTIMER_BASE (0x48320000) ++#define S32K_CR (SYNC_32KTIMER_BASE+0x10) ++ ++/* ++ * SDP3430 specific Section ++ */ ++ ++/* ++ * The 343x's chip selects are programmable. The mask ROM ++ * does configure CS0 to 0x08000000 before dispatch. So, if ++ * you want your code to live below that address, you have to ++ * be prepared to jump though hoops, to reset the base address. ++ * Same as in SDP3430 ++ */ ++/* base address for indirect vectors (internal boot mode) */ ++#define SRAM_OFFSET0 0x40000000 ++#define SRAM_OFFSET1 0x00200000 ++#define SRAM_OFFSET2 0x0000F800 ++#define SRAM_VECT_CODE (SRAM_OFFSET0|SRAM_OFFSET1|SRAM_OFFSET2) ++ ++#define LOW_LEVEL_SRAM_STACK 0x4020FFFC ++ ++/* ++ * TODO: Are they required for OMAP3517? ++ */ ++#if defined(CONFIG_3430SDP) || defined(CONFIG_OMAP3EVM) ++/* FPGA on Debug board.*/ ++#define ETH_CONTROL_REG (DEBUG_BASE+0x30b) ++#define LAN_RESET_REGISTER (DEBUG_BASE+0x1c) ++ ++#define DIP_SWITCH_INPUT_REG2 (DEBUG_BASE+0x60) ++#define LED_REGISTER (DEBUG_BASE+0x40) ++#define FPGA_REV_REGISTER (DEBUG_BASE+0x10) ++#define EEPROM_MAIN_BRD (DEBUG_BASE+0x10000+0x1800) ++#define EEPROM_CONN_BRD (DEBUG_BASE+0x10000+0x1900) ++#define EEPROM_UI_BRD (DEBUG_BASE+0x10000+0x1A00) ++#define EEPROM_MCAM_BRD (DEBUG_BASE+0x10000+0x1B00) ++#define ENHANCED_UI_EE_NAME "750-2075" ++#endif ++ ++#endif /* _OMAP3430_SYS_H_ */ +diff -Nurd git/include/asm/arch-omap3/omap3430.h x-load-shiva/include/asm/arch-omap3/omap3430.h +--- git/include/asm/arch-omap3/omap3430.h 2009-09-08 16:43:33.000000000 +0200 ++++ x-load-shiva/include/asm/arch-omap3/omap3430.h 2009-09-08 17:26:54.000000000 +0200 +@@ -138,4 +138,42 @@ + #define ENHANCED_UI_EE_NAME "750-2075" + #endif + ++#if defined (CONFIG_OMAP3517EVM) || defined (CONFIG_OMAP3517TEB) ++/* EMIF 4 replaces SDRC in OMAP3517 for DDR */ ++#define EMIF4_MOD_ID 0x00 ++#define EMIF4_STATUS 0x04 ++#define EMIF4_SDR_CONFIG 0x08 ++#define EMIF4_LPDDR2_CONFIF 0x0C ++#define EMIF4_SDR_REF_CTRL 0x10 ++#define EMIF4_SDR_REF_CTRL_SHDW 0x14 ++#define EMIF4_SDR_TIM1 0x18 ++#define EMIF4_SDR_TIM1_SHDW 0x1C ++#define EMIF4_SDR_TIM2 0x20 ++#define EMIF4_SDR_TIM2_SHDW 0x24 ++#define EMIF4_SDR_TIM3 0x28 ++#define EMIF4_SDR_TIM3_SHDW 0x2C ++#define EMIF4_LPDDR2_NVM_TIM 0x30 ++#define EMIF4_LPDDR2_NVM_TIM_SHDW 0x34 ++#define EMIF4_PWR_MGMT_CTRL 0x38 ++#define EMIF4_PWR_MGMT_CTRL_SHDW 0x3C ++#define EMIF4_LPDDR2_REG_DATA 0x40 ++#define EMIF4_LPDDR2_REG_CFG 0x50 ++#define EMIF4_OCP_CONFIG 0x54 ++#define EMIF4_OCP_CFG_VAL1 0x58 ++#define EMIF4_OCP_CFG_VAL2 0x5C ++#define EMIF4_PERF_CNT1 0x80 ++#define EMIF4_PERF_CNT2 0x84 ++#define EMIF4_PERF_CNT_CFG 0x88 ++#define EMIF4_PERF_CNT_SEL 0x8C ++#define EMIF4_PERF_CNT_TIM 0x90 ++#define EMIF4_IRQ_EOI 0xA0 ++#define EMIF4_IRQSTS_RAW 0xA4 ++#define EMIF4_IRQSTS 0xAC ++#define EMIF4_IRQEN_SET 0xB4 ++#define EMIF4_IRQEN_CLR 0xBC ++#define EMIF4_DDR_PHY_CTRL1 0xE4 ++#define EMIF4_DDR_PHY_CTRL1_SHDW 0xE8 ++#define EMIF4_DDR_PHY_CTRL2 0xEC ++#endif ++ + #endif /* _OMAP3430_SYS_H_ */ +diff -Nurd git/include/configs/omap3517evm.h x-load-shiva/include/configs/omap3517evm.h +--- git/include/configs/omap3517evm.h 1970-01-01 01:00:00.000000000 +0100 ++++ x-load-shiva/include/configs/omap3517evm.h 2009-09-08 18:29:29.000000000 +0200 +@@ -0,0 +1,200 @@ ++/* ++ * (C) Copyright 2009 ++ * Texas Instruments, ++ * Manikandan Pillai ++ * X-Loader Configuation settings for the OMAP3517EVM board. ++ * ++ * Derived from /include/configs/omap3evm.h ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++/* serial printf facility takes about 3.5K */ ++#define CFG_PRINTF ++ ++/* ++ * High Level Configuration Options ++ */ ++#define CONFIG_ARMCORTEXA8 1 /* This is an ARM V7 CPU core */ ++#define CONFIG_OMAP 1 /* in a TI OMAP core */ ++ ++#define CONFIG_OMAP3517EVM 1 /* working with OMAP3517 EVM */ ++//#define CONFIG_OMAP3517TEB 1 /* working with OMAP3517 TEB */ ++ ++/* Enable the below macro if MMC boot support is required */ ++#define CONFIG_MMC 1 ++#if defined(CONFIG_MMC) ++ #define CFG_CMD_MMC 1 ++ #define CFG_CMD_FAT 1 ++ #define CFG_I2C_SPEED 100000 ++ #define CFG_I2C_SLAVE 1 ++ #define CFG_I2C_BUS 0 ++ #define CFG_I2C_BUS_SELECT 1 ++ #define CONFIG_DRIVER_OMAP34XX_I2C 1 ++#endif ++ ++#include /* get chip and board defs */ ++ ++/* uncomment it if you need timer based udelay(). it takes about 250 bytes */ ++//#define CFG_UDELAY ++ ++/* Clock Defines */ ++#define V_OSCK 26000000 /* Clock output from T2 */ ++ ++#if (V_OSCK > 19200000) ++#define V_SCLK (V_OSCK >> 1) ++#else ++#define V_SCLK V_OSCK ++#endif ++ ++//#define PRCM_CLK_CFG2_266MHZ 1 /* VDD2=1.15v - 133MHz DDR */ ++#define PRCM_CLK_CFG2_332MHZ 1 /* VDD2=1.15v - 166MHz DDR */ ++#define PRCM_PCLK_OPP2 1 /* ARM=381MHz - VDD1=1.20v */ ++ ++# define NAND_BASE_ADR NAND_BASE /* NAND flash */ ++# define ONENAND_BASE ONENAND_MAP /* OneNand flash */ ++ ++#define OMAP34XX_GPMC_CS0_SIZE GPMC_SIZE_128M ++#define ONENAND_ADDR ONENAND_BASE /* physical address of OneNAND at CS0*/ ++ ++#ifdef CFG_PRINTF ++ ++#define CFG_NS16550 ++#define CFG_NS16550_SERIAL ++#define CFG_NS16550_REG_SIZE (-4) ++#define CFG_NS16550_CLK (48000000) ++#define CFG_NS16550_COM3 OMAP34XX_UART3 ++ ++/* ++ * select serial console configuration ++ */ ++#define CONFIG_SERIAL3 3 /* UART1 on OMAP3EVM */ ++#define CONFIG_CONS_INDEX 3 ++ ++#define CONFIG_BAUDRATE 115200 ++#define CFG_PBSIZE 256 ++ ++#endif /* CFG_PRINTF */ ++ ++/* ++ * Miscellaneous configurable options ++ */ ++#define CFG_LOADADDR 0x80008000 ++ ++#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ ++ ++/*----------------------------------------------------------------------- ++ * Stack sizes ++ * ++ * The stack sizes are set up in start.S using the settings below ++ */ ++#define CONFIG_STACKSIZE (128*1024) /* regular stack */ ++ ++/*----------------------------------------------------------------------- ++ * Board NAND Info. ++ */ ++ ++#define CFG_NAND_K9F1G08R0A /* Samsung 8-bit 128MB chip large page NAND chip*/ ++#define NAND_16BIT ++ ++/* NAND is partitioned: ++ * 0x00000000 - 0x0007FFFF Booting Image ++ * 0x00080000 - 0x0023FFFF U-Boot Image ++ * 0x00240000 - 0x0027FFFF U-Boot Env Data (X-loader doesn't care) ++ * 0x00280000 - 0x0077FFFF Kernel Image ++ * 0x00780000 - 0x08000000 depends on application ++ */ ++#define NAND_UBOOT_START 0x0080000 /* Leaving first 4 blocks for x-load */ ++#define NAND_UBOOT_END 0x0240000 /* Giving a space of 2 blocks = 256KB */ ++#define NAND_BLOCK_SIZE 0x20000 ++ ++#define GPMC_CONFIG (OMAP34XX_GPMC_BASE+0x50) ++ ++#if defined (CONFIG_OMAP3517EVM) ++#define GPMC_NAND_COMMAND_0 (OMAP34XX_GPMC_BASE+0x7C) ++#define GPMC_NAND_ADDRESS_0 (OMAP34XX_GPMC_BASE+0x80) ++#define GPMC_NAND_DATA_0 (OMAP34XX_GPMC_BASE+0x84) ++#elif defined (CONFIG_OMAP3517TEB) ++#define GPMC_NAND_COMMAND_0 (OMAP34XX_GPMC_BASE+0xDC) ++#define GPMC_NAND_ADDRESS_0 (OMAP34XX_GPMC_BASE+0xE0) ++#define GPMC_NAND_DATA_0 (OMAP34XX_GPMC_BASE+0xE4) ++#endif ++ ++#ifdef NAND_16BIT ++#define WRITE_NAND_COMMAND(d, adr) \ ++ do {*(volatile u16 *)GPMC_NAND_COMMAND_0 = d;} while(0) ++#define WRITE_NAND_ADDRESS(d, adr) \ ++ do {*(volatile u16 *)GPMC_NAND_ADDRESS_0 = d;} while(0) ++#define WRITE_NAND(d, adr) \ ++ do {*(volatile u16 *)GPMC_NAND_DATA_0 = d;} while(0) ++#define READ_NAND(adr) \ ++ (*(volatile u16 *)GPMC_NAND_DATA_0) ++#define NAND_WAIT_READY() ++#define NAND_WP_OFF() \ ++ do {*(volatile u32 *)(GPMC_CONFIG) |= 0x00000010;} while(0) ++#define NAND_WP_ON() \ ++ do {*(volatile u32 *)(GPMC_CONFIG) &= ~0x00000010;} while(0) ++ ++#else /* to support 8-bit NAND devices */ ++#define WRITE_NAND_COMMAND(d, adr) \ ++ do {*(volatile u8 *)GPMC_NAND_COMMAND_0 = d;} while(0) ++#define WRITE_NAND_ADDRESS(d, adr) \ ++ do {*(volatile u8 *)GPMC_NAND_ADDRESS_0 = d;} while(0) ++#define WRITE_NAND(d, adr) \ ++ do {*(volatile u8 *)GPMC_NAND_DATA_0 = d;} while(0) ++#define READ_NAND(adr) \ ++ (*(volatile u8 *)GPMC_NAND_DATA_0); ++#define NAND_WAIT_READY() ++#define NAND_WP_OFF() \ ++ do {*(volatile u32 *)(GPMC_CONFIG) |= 0x00000010;} while(0) ++#define NAND_WP_ON() \ ++ do {*(volatile u32 *)(GPMC_CONFIG) &= ~0x00000010;} while(0) ++ ++#endif ++ ++#define NAND_CTL_CLRALE(adr) ++#define NAND_CTL_SETALE(adr) ++#define NAND_CTL_CLRCLE(adr) ++#define NAND_CTL_SETCLE(adr) ++#define NAND_DISABLE_CE() ++#define NAND_ENABLE_CE() ++ ++/*----------------------------------------------------------------------- ++ * Board oneNAND Info. ++ */ ++#define CFG_SYNC_BURST_READ 1 ++ ++/* OneNAND is partitioned: ++ * 0x0000000 - 0x0080000 X-Loader ++ * 0x0080000 - 0x0240000 U-boot Image ++ * 0x0240000 - 0x0280000 U-Boot Env Data (X-loader doesn't care) ++ * 0x0280000 - 0x0780000 Kernel Image ++ * 0x0780000 - 0x8000000 depends on application ++ */ ++ ++#define ONENAND_START_BLOCK 4 ++#define ONENAND_END_BLOCK 18 ++#define ONENAND_PAGE_SIZE 2048 /* 2KB */ ++#define ONENAND_BLOCK_SIZE 0x20000 /* 128KB */ ++ ++#endif /* __CONFIG_H */ ++ diff --git a/recipes/x-load/x-load-1.41/0013-board.c-print-boot-method-mmc-onenand-nand.patch b/recipes/x-load/x-load-1.41/0013-board.c-print-boot-method-mmc-onenand-nand.patch new file mode 100644 index 0000000000..8223cb9dcf --- /dev/null +++ b/recipes/x-load/x-load-1.41/0013-board.c-print-boot-method-mmc-onenand-nand.patch @@ -0,0 +1,52 @@ +From 8433611ac9fe90093f57e2a3e5968d9c61de5e28 Mon Sep 17 00:00:00 2001 +From: Vaibhav Hiremath +Date: Mon, 20 Jul 2009 17:54:48 +0530 +Subject: [PATCH] board.c: print boot method (mmc, onenand, nand) + +Pulled from 4e1a4e8d4d670ab7a4c281317a8b440f4ee4581a commit +of sakoman's tree +--- + lib/board.c | 5 +++++ + 1 files changed, 5 insertions(+), 0 deletions(-) + +diff --git a/lib/board.c b/lib/board.c +index bc7d3d1..9dcc31a 100644 +--- a/lib/board.c ++++ b/lib/board.c +@@ -70,10 +70,12 @@ void start_armboot (void) + + #if defined (CONFIG_OMAP34XX) + if ((get_mem_type() == MMC_ONENAND) || (get_mem_type() == MMC_NAND)){ ++ printf("Booting from mmc . . .\n"); + buf += mmc_boot(buf); + } + + if (get_mem_type() == GPMC_ONENAND){ ++ printf("Booting from onenand . . .\n"); + for (i = ONENAND_START_BLOCK; i < ONENAND_END_BLOCK; i++){ + if (!onenand_read_block(buf, i)) + buf += ONENAND_BLOCK_SIZE; +@@ -81,6 +83,7 @@ void start_armboot (void) + } + + if (get_mem_type() == GPMC_NAND){ ++ printf("Booting from nand . . .\n"); + for (i = NAND_UBOOT_START; i < NAND_UBOOT_END; i+= NAND_BLOCK_SIZE){ + if (!nand_read_block(buf, i)) + buf += NAND_BLOCK_SIZE; /* advance buf ptr */ +@@ -88,10 +91,12 @@ void start_armboot (void) + } + #elif defined (CONFIG_OMAP3517EVM) + if (get_mem_type() == GPMC_NAND){ ++ printf("Booting from mmc . . .\n"); + buf += mmc_boot(buf); + } + + if (buf == (uchar *)CFG_LOADADDR){ ++ printf("Booting from nand . . .\n"); + for (i = NAND_UBOOT_START; i < NAND_UBOOT_END; i+= NAND_BLOCK_SIZE){ + if (!nand_read_block(buf, i)) + buf += NAND_BLOCK_SIZE; /* advance buf ptr */ +-- +1.5.4.3 + diff --git a/recipes/x-load/x-load-1.41/0014-board.c-check-for-u-boot-on-mmc-on-all-configurati.patch b/recipes/x-load/x-load-1.41/0014-board.c-check-for-u-boot-on-mmc-on-all-configurati.patch new file mode 100644 index 0000000000..c195a03349 --- /dev/null +++ b/recipes/x-load/x-load-1.41/0014-board.c-check-for-u-boot-on-mmc-on-all-configurati.patch @@ -0,0 +1,95 @@ +From fc8eccdf0b7b131fb0c51892dfc19fc977f77276 Mon Sep 17 00:00:00 2001 +From: Vaibhav Hiremath +Date: Mon, 20 Jul 2009 22:14:59 +0530 +Subject: [PATCH] board.c: check for u-boot on mmc on all configurations, not just those with managed nand + +Pulled from 9fc86b52c5770575b9b02c0049446fa8e266e714 commit +of sakoman's tree +--- + lib/board.c | 60 +++++++++++++++++++++++++--------------------------------- + 1 files changed, 26 insertions(+), 34 deletions(-) + +diff --git a/lib/board.c b/lib/board.c +index 9dcc31a..11e87da 100644 +--- a/lib/board.c ++++ b/lib/board.c +@@ -50,7 +50,7 @@ init_fnc_t *init_sequence[] = { + serial_init, /* serial communications setup */ + print_info, + #endif +- nand_init, /* board specific nand init */ ++ nand_init, /* board specific nand init */ + NULL, + }; + +@@ -68,42 +68,34 @@ void start_armboot (void) + + buf = (uchar*) CFG_LOADADDR; + +-#if defined (CONFIG_OMAP34XX) +- if ((get_mem_type() == MMC_ONENAND) || (get_mem_type() == MMC_NAND)){ +- printf("Booting from mmc . . .\n"); +- buf += mmc_boot(buf); +- } +- +- if (get_mem_type() == GPMC_ONENAND){ +- printf("Booting from onenand . . .\n"); +- for (i = ONENAND_START_BLOCK; i < ONENAND_END_BLOCK; i++){ +- if (!onenand_read_block(buf, i)) +- buf += ONENAND_BLOCK_SIZE; +- } +- } +- +- if (get_mem_type() == GPMC_NAND){ +- printf("Booting from nand . . .\n"); +- for (i = NAND_UBOOT_START; i < NAND_UBOOT_END; i+= NAND_BLOCK_SIZE){ +- if (!nand_read_block(buf, i)) +- buf += NAND_BLOCK_SIZE; /* advance buf ptr */ +- } +- } +-#elif defined (CONFIG_OMAP3517EVM) +- if (get_mem_type() == GPMC_NAND){ +- printf("Booting from mmc . . .\n"); +- buf += mmc_boot(buf); +- } ++#ifdef CONFIG_MMC ++ /* first try mmc */ ++ buf += mmc_boot(buf); ++#endif + +- if (buf == (uchar *)CFG_LOADADDR){ +- printf("Booting from nand . . .\n"); +- for (i = NAND_UBOOT_START; i < NAND_UBOOT_END; i+= NAND_BLOCK_SIZE){ +- if (!nand_read_block(buf, i)) +- buf += NAND_BLOCK_SIZE; /* advance buf ptr */ ++ if (buf == (uchar *)CFG_LOADADDR) { ++ /* if no u-boot on mmc, try onenand and nand */ ++#if !defined (CONFIG_OMAP3517EVM) ++ if (get_mem_type() == GPMC_ONENAND){ ++#ifdef CFG_PRINTF ++ printf("Booting from onenand . . .\n"); ++#endif ++ for (i = ONENAND_START_BLOCK; i < ONENAND_END_BLOCK; i++){ ++ if (!onenand_read_block(buf, i)) ++ buf += ONENAND_BLOCK_SIZE; ++ } + } +- } + #endif +- ++ if (get_mem_type() == GPMC_NAND){ ++#ifdef CFG_PRINTF ++ printf("Booting from nand . . .\n"); ++#endif ++ for (i = NAND_UBOOT_START; i < NAND_UBOOT_END; i+= NAND_BLOCK_SIZE){ ++ if (!nand_read_block(buf, i)) ++ buf += NAND_BLOCK_SIZE; /* advance buf ptr */ ++ } ++ } ++ } + + if (buf == (uchar *)CFG_LOADADDR) + hang(); +-- +1.5.4.3 + diff --git a/recipes/x-load/x-load-1.41/0015-OMAP3EVM-Build-issue-fixed.patch b/recipes/x-load/x-load-1.41/0015-OMAP3EVM-Build-issue-fixed.patch new file mode 100644 index 0000000000..46afd51752 --- /dev/null +++ b/recipes/x-load/x-load-1.41/0015-OMAP3EVM-Build-issue-fixed.patch @@ -0,0 +1,77 @@ +From c44aac2e3e45f9a3a36ba80704104082e5a71100 Mon Sep 17 00:00:00 2001 +From: Vaibhav Hiremath +Date: Mon, 20 Jul 2009 22:17:52 +0530 +Subject: [PATCH] OMAP3EVM: Build issue fixed. + +The x-loader changes was broken for OMAP3EVM, fixed - + + - GPMC macros were not under proper board macro + - Warning fixed from mmc.c +--- + cpu/omap3/mmc.c | 3 ++- + include/asm/arch-omap3/mem.h | 6 +++--- + include/configs/omap3517evm.h | 2 +- + 3 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/cpu/omap3/mmc.c b/cpu/omap3/mmc.c +index b9dd5d0..2453477 100755 +--- a/cpu/omap3/mmc.c ++++ b/cpu/omap3/mmc.c +@@ -46,8 +46,9 @@ block_dev_desc_t *mmc_get_dev(int dev) + + unsigned char mmc_board_init(void) + { +- unsigned int value = 0; + #if defined (CONFIG_OMAP34XX) ++ unsigned int value = 0; ++ + value = CONTROL_PBIAS_LITE; + CONTROL_PBIAS_LITE = value | (1 << 2) | (1 << 1) | (1 << 9); + +diff --git a/include/asm/arch-omap3/mem.h b/include/asm/arch-omap3/mem.h +index 8a92484..ae73a9f 100644 +--- a/include/asm/arch-omap3/mem.h ++++ b/include/asm/arch-omap3/mem.h +@@ -324,7 +324,7 @@ typedef enum { + # define SMNAND_GPMC_CONFIG5 0x010C1414 + # define SMNAND_GPMC_CONFIG6 0x00000A80 + +-#if defined (CONFIG_OMAP34xx) ++#if defined (CONFIG_OMAP34XX) + + # define M_NAND_GPMC_CONFIG1 0x00001800 + # define M_NAND_GPMC_CONFIG2 SMNAND_GPMC_CONFIG2 +@@ -372,7 +372,7 @@ typedef enum { + # define SMNAND_GPMC_CONFIG6 0x00000A80 + # define SMNAND_GPMC_CONFIG7 0x00000C44 + +-#if defined (CONFIG_OMAP34xx) ++#if defined (CONFIG_OMAP34XX) + + # define M_NAND_GPMC_CONFIG1 0x00001800 + # define M_NAND_GPMC_CONFIG2 SMNAND_GPMC_CONFIG2 +@@ -445,7 +445,7 @@ typedef enum { + # define SMNAND_GPMC_CONFIG6 0x1F0F0A80 + # define SMNAND_GPMC_CONFIG7 0x00000C44 + +-#if defined (CONFIG_OMAP34xx) ++#if defined (CONFIG_OMAP34XX) + + # define M_NAND_GPMC_CONFIG1 0x00001800 + # define M_NAND_GPMC_CONFIG2 SMNAND_GPMC_CONFIG2 +diff --git a/include/configs/omap3517evm.h b/include/configs/omap3517evm.h +index 95deacb..16dc8d8 100644 +--- a/include/configs/omap3517evm.h ++++ b/include/configs/omap3517evm.h +@@ -124,7 +124,7 @@ + + #define GPMC_CONFIG (OMAP34XX_GPMC_BASE+0x50) + +-#if defined (CONFIG_OMAP34xx) || (CONFIG_OMAP3517EVM) ++#if defined (CONFIG_OMAP3517EVM) + #define GPMC_NAND_COMMAND_0 (OMAP34XX_GPMC_BASE+0x7C) + #define GPMC_NAND_ADDRESS_0 (OMAP34XX_GPMC_BASE+0x80) + #define GPMC_NAND_DATA_0 (OMAP34XX_GPMC_BASE+0x84) +-- +1.5.4.3 + diff --git a/recipes/x-load/x-load-1.41/0016-mmc-fix-infinite-loop-in-mmc_init_stream.patch b/recipes/x-load/x-load-1.41/0016-mmc-fix-infinite-loop-in-mmc_init_stream.patch new file mode 100644 index 0000000000..1f9b069f66 --- /dev/null +++ b/recipes/x-load/x-load-1.41/0016-mmc-fix-infinite-loop-in-mmc_init_stream.patch @@ -0,0 +1,41 @@ +From 47f5d8f6f659848e164b6151c1dac36fdd4eb7a1 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Fri, 1 Aug 2008 12:55:44 -0700 +Subject: [PATCH] mmc: fix infinite loop in mmc_init_stream + +--- + cpu/omap3/mmc.c | 11 ++++++++--- + 1 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/cpu/omap3/mmc.c b/cpu/omap3/mmc.c +index 2453477..279e2a2 100755 +--- a/cpu/omap3/mmc.c ++++ b/cpu/omap3/mmc.c +@@ -60,16 +60,21 @@ unsigned char mmc_board_init(void) + + void mmc_init_stream(void) + { ++ volatile unsigned int mmc_stat; ++ + OMAP_HSMMC_CON |= INIT_INITSTREAM; + + OMAP_HSMMC_CMD = MMC_CMD0; +- while (!(OMAP_HSMMC_STAT & CC_MASK)); ++ do { ++ mmc_stat = OMAP_HSMMC_STAT; ++ } while (!(mmc_stat & CC_MASK)); + + OMAP_HSMMC_STAT = CC_MASK; + + OMAP_HSMMC_CMD = MMC_CMD0; +- while (!(OMAP_HSMMC_STAT & CC_MASK)); +- ++ do { ++ mmc_stat = OMAP_HSMMC_STAT; ++ } while (!(mmc_stat & CC_MASK)); + + OMAP_HSMMC_STAT = OMAP_HSMMC_STAT; + OMAP_HSMMC_CON &= ~INIT_INITSTREAM; +-- +1.5.4.3 + diff --git a/recipes/x-load/x-load-1.41/0017-lib-board.c-add-missing-call-to-misc_init_r.patch b/recipes/x-load/x-load-1.41/0017-lib-board.c-add-missing-call-to-misc_init_r.patch new file mode 100644 index 0000000000..a923724d4c --- /dev/null +++ b/recipes/x-load/x-load-1.41/0017-lib-board.c-add-missing-call-to-misc_init_r.patch @@ -0,0 +1,25 @@ +From 47756aa64c39111942cad5774862fc5f6def362d Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Thu, 7 Aug 2008 17:38:42 -0700 +Subject: [PATCH] lib/board.c: add missing call to misc_init_r + +--- + lib/board.c | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +diff --git a/lib/board.c b/lib/board.c +index 11e87da..5ef7102 100644 +--- a/lib/board.c ++++ b/lib/board.c +@@ -66,6 +66,8 @@ void start_armboot (void) + } + } + ++ misc_init_r(); ++ + buf = (uchar*) CFG_LOADADDR; + + #ifdef CONFIG_MMC +-- +1.5.4.3 + diff --git a/recipes/x-load/x-load-1.41/0018-omap3evm-provide-missing-udelay-function.patch b/recipes/x-load/x-load-1.41/0018-omap3evm-provide-missing-udelay-function.patch new file mode 100644 index 0000000000..54681cbedc --- /dev/null +++ b/recipes/x-load/x-load-1.41/0018-omap3evm-provide-missing-udelay-function.patch @@ -0,0 +1,27 @@ +From 60455ac7f09e4d1c1472eb206e66185d9fd89ef9 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Mon, 18 Aug 2008 11:11:57 -0700 +Subject: [PATCH] omap3evm: provide missing udelay function + +--- + board/omap3evm/omap3evm.c | 4 ++++ + 1 files changed, 4 insertions(+), 0 deletions(-) + +diff --git a/board/omap3evm/omap3evm.c b/board/omap3evm/omap3evm.c +index 857516b..d4ef29b 100755 +--- a/board/omap3evm/omap3evm.c ++++ b/board/omap3evm/omap3evm.c +@@ -70,6 +70,10 @@ static inline void delay(unsigned long loops) + "bne 1b":"=r" (loops):"0"(loops)); + } + ++void udelay (unsigned long usecs) { ++ delay(usecs); ++} ++ + /***************************************** + * Routine: board_init + * Description: Early hardware init. +-- +1.5.4.3 + diff --git a/recipes/x-load/x-load-1.41/0019-lib-board.c-Specify-where-u-boot-is-being-loaded-fr.patch b/recipes/x-load/x-load-1.41/0019-lib-board.c-Specify-where-u-boot-is-being-loaded-fr.patch new file mode 100644 index 0000000000..d55a53a4ca --- /dev/null +++ b/recipes/x-load/x-load-1.41/0019-lib-board.c-Specify-where-u-boot-is-being-loaded-fr.patch @@ -0,0 +1,45 @@ +From 989f677e807fdfbae2a13ab1444743bfdf2d63f3 Mon Sep 17 00:00:00 2001 +From: Vaibhav Hiremath +Date: Mon, 20 Jul 2009 22:35:36 +0530 +Subject: [PATCH] lib/board.c: Specify where u-boot is being loaded from + +Pulled from 65ed00323f3807197a83abc75d62ed2a8d3f60de commit +from Sakoman's tree +--- + lib/board.c | 6 ++++-- + 1 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/lib/board.c b/lib/board.c +index 5ef7102..e573c66 100644 +--- a/lib/board.c ++++ b/lib/board.c +@@ -73,6 +73,8 @@ void start_armboot (void) + #ifdef CONFIG_MMC + /* first try mmc */ + buf += mmc_boot(buf); ++ if (buf != (uchar *)CFG_LOADADDR) ++ printf("Loading u-boot.bin from mmc\n"); + #endif + + if (buf == (uchar *)CFG_LOADADDR) { +@@ -80,7 +82,7 @@ void start_armboot (void) + #if !defined (CONFIG_OMAP3517EVM) + if (get_mem_type() == GPMC_ONENAND){ + #ifdef CFG_PRINTF +- printf("Booting from onenand . . .\n"); ++ printf("Loading u-boot.bin from onenand\n"); + #endif + for (i = ONENAND_START_BLOCK; i < ONENAND_END_BLOCK; i++){ + if (!onenand_read_block(buf, i)) +@@ -90,7 +92,7 @@ void start_armboot (void) + #endif + if (get_mem_type() == GPMC_NAND){ + #ifdef CFG_PRINTF +- printf("Booting from nand . . .\n"); ++ printf("Loading u-boot.bin from nand\n"); + #endif + for (i = NAND_UBOOT_START; i < NAND_UBOOT_END; i+= NAND_BLOCK_SIZE){ + if (!nand_read_block(buf, i)) +-- +1.5.4.3 + diff --git a/recipes/x-load/x-load-1.41/streen-fix.diff b/recipes/x-load/x-load-1.41/streen-fix.diff new file mode 100644 index 0000000000..e52c9444cf --- /dev/null +++ b/recipes/x-load/x-load-1.41/streen-fix.diff @@ -0,0 +1,39 @@ +diff -Nurd git/board/omap3517evm/omap3517evm.c /OE/angstrom-dev/xload/x-load/board/omap3517evm/omap3517evm.c +--- git/board/omap3517evm/omap3517evm.c 2009-07-02 04:26:52.000000000 +0200 ++++ /OE/angstrom-dev/xload/x-load/board/omap3517evm/omap3517evm.c 2009-09-04 13:08:54.000000000 +0200 +@@ -98,7 +98,7 @@ + */ + #define EMIF4_DDR1_RD_LAT 0x6 + #define EMIF4_DDR1_PWRDN_DIS 0x1 +-#define EMIF4_DDR1_STRBEN_EXT 0x1 ++#define EMIF4_DDR1_STRBEN_EXT 0x0 + #define EMIF4_DDR1_DLL_MODE 0x0 + #define EMIF4_DDR1_VTP_DYN 0x1 + #define EMIF4_DDR1_LB_CK_SEL 0x0 +diff -Nurd git/board/omap3evm/omap3evm.c /OE/angstrom-dev/xload/x-load/board/omap3evm/omap3evm.c +--- git/board/omap3evm/omap3evm.c 2009-07-02 04:26:52.000000000 +0200 ++++ /OE/angstrom-dev/xload/x-load/board/omap3evm/omap3evm.c 2009-09-09 16:36:07.000000000 +0200 +@@ -70,6 +70,10 @@ + "bne 1b":"=r" (loops):"0"(loops)); + } + ++void udelay (unsigned long usecs) { ++ delay(usecs); ++} ++ + /***************************************** + * Routine: board_init + * Description: Early hardware init. +@@ -681,6 +685,12 @@ + sr32(CM_FCLKEN1_CORE, 13, 1, 0x1); + sr32(CM_ICLKEN1_CORE, 13, 1, 0x1); + #endif ++ ++#ifdef CONFIG_MMC ++ /* Enable MMC1 clocks */ ++ sr32(CM_FCLKEN1_CORE, 24, 1, 0x1); ++ sr32(CM_ICLKEN1_CORE, 24, 1, 0x1); ++#endif + delay(1000); + } + diff --git a/recipes/x-load/x-load_1.41.bb b/recipes/x-load/x-load_1.41.bb new file mode 100644 index 0000000000..0a38f5ba0f --- /dev/null +++ b/recipes/x-load/x-load_1.41.bb @@ -0,0 +1,18 @@ +require x-load.inc + +COMPATIBLE_MACHINE = "omap3517-evm" + +SRC_URI = "file://x-loader-03.00.00.01.tar.gz \ +file://0013-board.c-print-boot-method-mmc-onenand-nand.patch;patch=1 \ +file://0014-board.c-check-for-u-boot-on-mmc-on-all-configurati.patch;patch=1 \ +file://0015-OMAP3EVM-Build-issue-fixed.patch;patch=1 \ +file://0016-mmc-fix-infinite-loop-in-mmc_init_stream.patch;patch=1 \ +file://0017-lib-board.c-add-missing-call-to-misc_init_r.patch;patch=1 \ +file://0018-omap3evm-provide-missing-udelay-function.patch;patch=1 \ +file://0019-lib-board.c-Specify-where-u-boot-is-being-loaded-fr.patch;patch=1 \ +file://streen-fix.diff;patch=1 \ +" + +S = "${WORKDIR}/xloader-03.00.00.01" + +PACKAGE_ARCH = "${MACHINE_ARCH}" diff --git a/recipes/x-load/x-load_git.bb b/recipes/x-load/x-load_git.bb index d7ffd20d69..0fa8cdfc62 100644 --- a/recipes/x-load/x-load_git.bb +++ b/recipes/x-load/x-load_git.bb @@ -1,5 +1,7 @@ require x-load.inc +DEFAULT_PREFERENCE_omap3517-evm = "-1" + FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/x-load-git/${MACHINE}" SRCREV = "319b26586fafb86f919f514bcd175838aaab96b3" @@ -14,6 +16,10 @@ SRC_URI_append_beagleboard = " \ file://name.patch;patch=1 \ " +SRC_URI_append_omap3517-evm = " \ + file://xload-shiva.diff;patch=1 \ +" + S = "${WORKDIR}/git" PACKAGE_ARCH = "${MACHINE_ARCH}" -- cgit v1.2.3 From 7e1ca09587a08962d5251502bcddb2d1010b73c9 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Fri, 11 Sep 2009 09:50:31 -0700 Subject: lsof, tcp-wrappers: Fix compilation on linux-uclibceabi Signed-off-by: Khem Raj --- recipes/lsof/lsof_4.78.bb | 3 ++- recipes/tcp-wrappers/tcp-wrappers_7.6.bb | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/recipes/lsof/lsof_4.78.bb b/recipes/lsof/lsof_4.78.bb index 0a24c607fa..a65fc12446 100644 --- a/recipes/lsof/lsof_4.78.bb +++ b/recipes/lsof/lsof_4.78.bb @@ -3,7 +3,7 @@ Its name stands for LiSt Open Files, and it does just that." SECTION = "devel" LICENSE = "BSD" -PR = "r1" +PR = "r2" SRC_URI = "ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/lsof_${PV}.tar.bz2" LOCALSRC = "file://${WORKDIR}/lsof_${PV}/lsof_${PV}_src.tar" @@ -19,6 +19,7 @@ python do_unpack () { export LSOF_OS = "${TARGET_OS}" LSOF_OS_linux-uclibc = "linux" +LSOF_OS_linux-uclibceabi = "linux" LSOF_OS_linux-gnueabi = "linux" export LSOF_INCLUDE = "${STAGING_INCDIR}" diff --git a/recipes/tcp-wrappers/tcp-wrappers_7.6.bb b/recipes/tcp-wrappers/tcp-wrappers_7.6.bb index 1f1afc1342..7cb766bd7a 100644 --- a/recipes/tcp-wrappers/tcp-wrappers_7.6.bb +++ b/recipes/tcp-wrappers/tcp-wrappers_7.6.bb @@ -3,7 +3,7 @@ DESCRIPTION = "Tools for monitoring and filtering incoming requests for tcp \ LICENSE = "tcp-wrappers" PRIORITY = "optional" SECTION = "console/network" -PR ="r3" +PR ="r4" PACKAGES = "${PN}-dbg libwrap libwrap-doc libwrap-dev tcp-wrappers tcp-wrappers-doc" @@ -66,6 +66,7 @@ EXTRA_OEMAKE = "'CC=${CC}' \ EXTRA_OEMAKE_NETGROUP = "-DNETGROUP" EXTRA_OEMAKE_NETGROUP_linux-uclibc = "" +EXTRA_OEMAKE_NETGROUP_linux-uclibceabi = "" do_compile () { oe_runmake 'TABLES=-DHOSTS_DENY=\"${sysconfdir}/hosts.deny\" -DHOSTS_ALLOW=\"${sysconfdir}/hosts.allow\"' \ -- cgit v1.2.3 From 48e831f5beba63b9a374c3165f37e2c22f32e5c2 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Fri, 11 Sep 2009 09:51:50 -0700 Subject: binutils_cvs.bb: Do not use autotools_do_install * CVS checkout include full src tree so we can not do make install because then it will try to install every component in src. We have to install ld gas and binutils only. Signed-off-by: Khem Raj --- recipes/binutils/binutils_cvs.bb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/recipes/binutils/binutils_cvs.bb b/recipes/binutils/binutils_cvs.bb index 88dcd78c90..b335767687 100644 --- a/recipes/binutils/binutils_cvs.bb +++ b/recipes/binutils/binutils_cvs.bb @@ -1,5 +1,5 @@ FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/binutils-cvs" -PV = "0.0+cvs${SRCDATE}" +PV = "2.20+cvs${SRCDATE}" INC_PR = "r5" PR = "${INC_PR}.1" @@ -21,7 +21,7 @@ do_compile () { oe_runmake all-ld all-binutils all-gas } do_install () { - autotools_do_install install-ld install-binutils install-gas + oe_runmake 'DESTDIR=${D}' install-ld install-binutils install-gas # We don't really need these, so we'll remove them... rm -rf ${D}${libdir}/ldscripts -- cgit v1.2.3 From b1213a3ec464b72cdbb4c32bcbb1187f6f026742 Mon Sep 17 00:00:00 2001 From: Phil Blundell Date: Fri, 11 Sep 2009 20:41:33 +0100 Subject: micro: select binutils 2.19.51 --- conf/distro/micro.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/conf/distro/micro.conf b/conf/distro/micro.conf index aca4a18caf..67e3aff3ca 100644 --- a/conf/distro/micro.conf +++ b/conf/distro/micro.conf @@ -61,6 +61,7 @@ MACHINE_KERNEL_VERSION = "2.6" # TOOLCHAIN ############################################################################# LIBC ?= "eglibc" +PREFERRED_BINUTILS = "2.19.51" require conf/distro/include/sane-toolchain.inc ############################################################################# -- cgit v1.2.3 From c0f653bc90814acf4053ec037c7ab3ad022342ff Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Fri, 11 Sep 2009 14:42:54 -0700 Subject: gcc-configure-common.inc: Muck with NATIVE_SYSTEM_HEADER_DIR * GCC's notion of standard includes being in /usr/include is not valid for micro distro which uses flattened layout Signed-off-by: Khem Raj Signed-off-by: Henning Heinold --- recipes/gcc/gcc-configure-common.inc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/recipes/gcc/gcc-configure-common.inc b/recipes/gcc/gcc-configure-common.inc index 7315a20cf9..fb792a8a88 100644 --- a/recipes/gcc/gcc-configure-common.inc +++ b/recipes/gcc/gcc-configure-common.inc @@ -80,7 +80,16 @@ do_configure () { sed -i 's/^LDFLAGS = $/LDFLAGS = @LDFLAGS@/' ${S}/Makefile.tpl (cd ${S} && gnu-configize) || die "failure running gnu-configize" - + # splice our idea of where the headers live into gcc's world + echo "NATIVE_SYSTEM_HEADER_DIR = ${layout_includedir}" > ${T}/t-oe + sed 's%^tmake_file=.*$%& ${T}/t-oe%' < ${S}/gcc/Makefile.in >${S}/gcc/Makefile.in.new + mv ${S}/gcc/Makefile.in.new ${S}/gcc/Makefile.in + cat ${S}/gcc/defaults.h | grep -v "\#endif.*GCC_DEFAULTS_H" > ${S}/gcc/defaults.h.new + echo "#ifndef STANDARD_INCLUDE_DIR" >> ${S}/gcc/defaults.h.new + echo "#define STANDARD_INCLUDE_DIR \"${layout_includedir}\"" >> ${S}/gcc/defaults.h.new + echo "#endif" >> ${S}/gcc/defaults.h.new + echo "#endif /* ! GCC_DEFAULTS_H */" >> ${S}/gcc/defaults.h.new + mv ${S}/gcc/defaults.h.new ${S}/gcc/defaults.h oe_runconf # make sure that no @LDFLAG@ is left in the generated Makefile -- cgit v1.2.3 From aa6a11a7168bf804925f78f9003920bce4b3a5e9 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Fri, 11 Sep 2009 19:00:56 -0700 Subject: screen-4.0.3: Fix compilation and make default. * Fix compilation issues. * Remove DEFAULT_PREFERENCE = "-1" * Tested on Thumb/uclibc Signed-off-by: Khem Raj --- recipes/screen/screen-4.0.3/configure.patch | 582 ++++++------------------ recipes/screen/screen-4.0.3/cross-compile.patch | 331 ++++++++++++++ recipes/screen/screen-4.0.3/no-stropts.patch | 13 + recipes/screen/screen-4.0.3/no-utempter.patch | 17 + recipes/screen/screen-4.0.3/sched.patch | 20 + recipes/screen/screen_4.0.3.bb | 12 +- 6 files changed, 526 insertions(+), 449 deletions(-) create mode 100644 recipes/screen/screen-4.0.3/cross-compile.patch create mode 100644 recipes/screen/screen-4.0.3/no-stropts.patch create mode 100644 recipes/screen/screen-4.0.3/no-utempter.patch create mode 100644 recipes/screen/screen-4.0.3/sched.patch diff --git a/recipes/screen/screen-4.0.3/configure.patch b/recipes/screen/screen-4.0.3/configure.patch index 2770a7a481..8789cb73fb 100644 --- a/recipes/screen/screen-4.0.3/configure.patch +++ b/recipes/screen/screen-4.0.3/configure.patch @@ -1,336 +1,17 @@ - -# -# Patch by Hannes Reich (hannes@skynet.ie) 22-Jul-2005 -# Resolves _some_ of the cross-compilation issues in screen's configure.in -# - ---- screen-4.0.1/configure.in~configure -+++ screen-4.0.1/configure.in -@@ -37,6 +37,323 @@ - VERSION="$rev.$vers.$pat" - AC_NOTE(this is screen version $VERSION) - AC_SUBST(VERSION) -+ -+AH_TOP([ -+/* Copyright (c) 1993-2000 -+ * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) -+ * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) -+ * Copyright (c) 1987 Oliver Laumann -+ * -+ * 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, 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 (see the file COPYING); if not, write to the -+ * Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -+ * -+ */ -+ -+ -+/********************************************************************** -+ * -+ * User Configuration Section -+ */ -+ -+/* -+ * Maximum of simultaneously allowed windows per screen session. -+ */ -+#ifndef MAXWIN -+# define MAXWIN 40 -+#endif -+ -+/* -+ * Define SOCKDIR to be the directory to contain the named sockets -+ * screen creates. This should be in a common subdirectory, such as -+ * /usr/local or /tmp. It makes things a little more secure if you -+ * choose a directory which is not writable by everyone or where the -+ * "sticky" bit is on, but this isn't required. -+ * If SOCKDIR is not defined screen will put the named sockets in -+ * the user's home directory. Notice that this can cause you problems -+ * if some user's HOME directories are AFS- or NFS-mounted. Especially -+ * AFS is unlikely to support named sockets. -+ * -+ * Screen will name the subdirectories "S-$USER" (e.g /tmp/S-davison). -+ */ -+#undef SOCKDIR -+ -+/* -+ * Define this if the SOCKDIR is not shared between hosts. -+ */ -+#define SOCKDIR_IS_LOCAL_TO_HOST -+ -+/* -+ * Screen sources two startup files. First a global file with a path -+ * specified here, second your local $HOME/.screenrc -+ * Don't define this, if you don't want it. -+ */ -+#ifndef ETCSCREENRC -+# define ETCSCREENRC "/usr/local/etc/screenrc" -+#endif -+ -+/* -+ * Screen can look for the environment variable $SYSSCREENRC and -if it -+ * exists- load the file specified in that variable as global screenrc. -+ * If you want to enable this feature, define ALLOW_SYSSCREENRC to one (1). -+ * Otherwise ETCSCREENRC is always loaded. -+ */ -+#define ALLOW_SYSSCREENRC 1 -+ -+/* -+ * Screen needs encoding files for the translation of utf8 -+ * into some encodings, e.g. JIS, BIG5. -+ * Only needed if FONT, ENCODINGS and UTF8 are defined. -+ */ -+#ifndef SCREENENCODINGS -+# define SCREENENCODINGS "/usr/local/lib/screen/encodings" -+#endif -+/* -+ * Define CHECKLOGIN to force Screen users to enter their Unix password -+ * in addition to the screen password. -+ * -+ * Define NOSYSLOG if yo do not have logging facilities. Currently -+ * syslog() will be used to trace ``su'' commands only. -+ */ -+#define CHECKLOGIN 1 -+#undef NOSYSLOG -+ -+ -+/* -+ * define PTYMODE if you do not like the default of 0622, which allows -+ * public write to your pty. -+ * define PTYGROUP to some numerical group-id if you do not want the -+ * tty to be in "your" group. -+ * Note, screen is unable to change mode or group of the pty if it -+ * is not installed with sufficient privilege. (e.g. set-uid-root) -+ * define PTYROFS if the /dev/pty devices are mounted on a read-only -+ * filesystem so screen should not even attempt to set mode or group -+ * even if running as root (e.g. on TiVo). -+ */ -+#undef PTYMODE -+#undef PTYGROUP -+#undef PTYROFS -+ -+/* -+ * If screen is NOT installed set-uid root, screen can provide tty -+ * security by exclusively locking the ptys. While this keeps other -+ * users from opening your ptys, it also keeps your own subprocesses -+ * from being able to open /dev/tty. Define LOCKPTY to add this -+ * exclusive locking. -+ */ -+#undef LOCKPTY -+ -+/* -+ * If you'd rather see the status line on the first line of your -+ * terminal rather than the last, define TOPSTAT. -+ */ -+#undef TOPSTAT -+ -+/* -+ * define DETACH can detach a session. An absolute 'must'. -+ */ -+#define DETACH -+ -+/* -+ * here come the erlangen extensions to screen: -+ * define LOCK if you want to use a lock program for a screenlock. -+ * define PASSWORD for secure reattach of your screen. -+ * define COPY_PASTE to use the famous hacker's treasure zoo. -+ * define POW_DETACH to have a detach_and_logout key (requires DETACH). -+ * define REMOTE_DETACH (-d option) to move screen between terminals. -+ * define AUTO_NUKE to enable Tim MacKenzies clear screen nuking -+ * define PSEUDOS to allow window input/output filtering -+ * define MULTI to allow multiple attaches. -+ * define MULTIUSER to allow other users attach to your session -+ * (if they are in the acl, of course) -+ * define MAPKEYS to include input keyboard translation. -+ * define FONT to support ISO2022/alternet charset support -+ * define COLOR to include ansi color support. This may expose -+ * a bug in x11r6-color-xterm. -+ * define DW_CHARS to include support for double-width character -+ * sets. -+ * define ENCODINGS to include support for encodings like euc or big5. -+ * Needs FONT to work. -+ * define UTF8 if you want support for UTF-8 encoding. -+ * Needs FONT and ENCODINGS to work. -+ * define COLORS16 if you want 16 colors. -+ * Needs COLOR to work. -+ * define BUILTIN_TELNET to add telnet support to screen. -+ * Syntax: screen //telnet host [port] -+ * define RXVT_OSC if you want support for rxvts special -+ * change fgcolor/bgcolor/bgpicture sequences -+ */ -+#undef SIMPLESCREEN -+#ifndef SIMPLESCREEN -+# define LOCK -+# define PASSWORD -+# define COPY_PASTE -+# define REMOTE_DETACH -+# define POW_DETACH -+# define AUTO_NUKE -+# define PSEUDOS -+# define MULTI -+# define MULTIUSER -+# define MAPKEYS -+# define COLOR -+# define FONT -+# define DW_CHARS -+# define ENCODINGS -+# define UTF8 -+# define COLORS16 -+# define ZMODEM -+# define BLANKER_PRG -+#endif /* SIMPLESCREEN */ -+ -+#undef BUILTIN_TELNET -+#undef RXVT_OSC -+#undef COLORS256 -+ -+ -+/* -+ * If you have a braille display you should define HAVE_BRAILLE. -+ * The code inside #ifdef HAVE_BRAILLE was contributed by Hadi Bargi -+ * Rangin (bargi@dots.physics.orst.edu). -+ * WARNING: this is more or less unsupported code, it may be full of -+ * bugs leading to security holes, enable at your own risk! -+ */ -+#undef HAVE_BRAILLE -+ -+ -+/* -+ * As error messages are mostly meaningless to the user, we -+ * try to throw out phrases that are somewhat more familiar -+ * to ...well, at least familiar to us NetHack players. -+ */ -+#ifndef NONETHACK -+# define NETHACK -+#endif /* NONETHACK */ -+ -+/* -+ * If screen is installed with permissions to update /etc/utmp (such -+ * as if it is installed set-uid root), define UTMPOK. -+ */ -+#define UTMPOK -+ -+/* Set LOGINDEFAULT to one (1) -+ * if you want entries added to /etc/utmp by default, else set it to -+ * zero (0). -+ * LOGINDEFAULT will be one (1) whenever LOGOUTOK is undefined! -+ */ -+#define LOGINDEFAULT 1 -+ -+/* Set LOGOUTOK to one (1) -+ * if you want the user to be able to log her/his windows out. -+ * (Meaning: They are there, but not visible in /etc/utmp). -+ * Disabling this feature only makes sense if you have a secure /etc/utmp -+ * database. -+ * Negative examples: suns usually have a world writable utmp file, -+ * xterm will run perfectly without s-bit. -+ * -+ * If LOGOUTOK is undefined and UTMPOK is defined, all windows are -+ * initially and permanently logged in. -+ * -+ * Set CAREFULUTMP to one (1) if you want that users have at least one -+ * window per screen session logged in. -+ */ -+#define LOGOUTOK 1 -+#undef CAREFULUTMP -+ -+ -+/* -+ * If UTMPOK is defined and your system (incorrectly) counts logins by -+ * counting non-null entries in /etc/utmp (instead of counting non-null -+ * entries with no hostname that are not on a pseudo tty), define USRLIMIT -+ * to have screen put an upper-limit on the number of entries to write -+ * into /etc/utmp. This helps to keep you from exceeding a limited-user -+ * license. -+ */ -+#undef USRLIMIT -+ -+/* -+ * both must be defined if you want to favor tcsendbreak over -+ * other calls to generate a break condition on serial lines. -+ * (Do not bother, if you are not using plain tty windows.) -+ */ -+#define POSIX_HAS_A_GOOD_TCSENDBREAK -+#define SUNOS4_AND_WE_TRUST_TCSENDBREAK -+ -+/* -+ * to lower the interrupt load on the host machine, you may want to -+ * adjust the VMIN and VTIME settings used for plain tty windows. -+ * See the termio(4) manual page (Non-Canonical Mode Input Processing) -+ * for details. -+ * if undefined, VMIN=1, VTIME=0 is used as a default - this gives you -+ * best user responsiveness, but highest interrupt frequency. -+ * (Do not bother, if you are not using plain tty windows.) -+ */ -+#define TTYVMIN 100 -+#define TTYVTIME 2 -+ -+/* -+ * looks like the above values are ignored by setting FNDELAY. -+ * This is default for all pty/ttys, you may disable it for -+ * ttys here. After playing with it for a while, one may find out -+ * that this feature may cause screen to lock up. -+ */ -+#ifdef bsdi -+# define TTY_DISABLE_FNBLOCK /* select barfs without it ... */ -+#endif -+ -+ -+/* -+ * Some terminals, e.g. Wyse 120, use a bitfield to select attributes. -+ * This doesn't work with the standard so/ul/m? terminal entries, -+ * because they will cancel each other out. -+ * On TERMINFO machines, "sa" (sgr) may work. If you want screen -+ * to switch attributes only with sgr, define USE_SGR. -+ * This is *not* recomended, do this only if you must. -+ */ -+#undef USE_SGR -+ -+ -+/* -+ * Define USE_LOCALE if you want screen to use the locale names -+ * for the name of the month and day of the week. -+ */ -+#define USE_LOCALE -+ -+/* -+ * Define USE_PAM if your system supports PAM (Pluggable Authentication -+ * Modules) and you want screen to use it instead of calling crypt(). -+ * (You may also need to add -lpam to LIBS in the Makefile.) -+ */ -+#undef USE_PAM -+ -+/* -+ * Define CHECK_SCREEN_W if you want screen to set TERM to screen-w -+ * if the terminal width is greater than 131 columns. No longer needed -+ * on modern systems which use $COLUMNS or the tty settings instead. -+ */ -+#undef CHECK_SCREEN_W -+ -+/********************************************************************** -+ * -+ * End of User Configuration Section -+ * -+ * Rest of this file is modified by 'configure' -+ * Change at your own risk! -+ * -+ */ -+]) -+# end of AH_TOP -+ - AC_PREFIX_PROGRAM(screen) - AC_PREFIX_PROGRAM(gzip) - -@@ -46,6 +363,7 @@ +Index: screen-4.0.3/configure.in +=================================================================== +--- screen-4.0.3.orig/configure.in 2009-09-11 16:59:24.085222816 -0700 ++++ screen-4.0.3/configure.in 2009-09-11 18:42:08.338231443 -0700 +@@ -12,7 +12,7 @@ + dnl + dnl Define some useful macros + dnl +-AC_DEFUN(AC_PROGRAM_SOURCE, ++AC_DEFUN([AC_PROGRAM_SOURCE], + [AC_REQUIRE([AC_PROG_CPP])AC_PROVIDE([$0])cat > conftest.c < #include -@@ -198,6 +519,11 @@ +@@ -514,6 +518,8 @@ oldlibs="$LIBS" LIBS="$LIBS -lelf" AC_CHECKING(SVR4) -+AH_TEMPLATE([SVR4],[]) -+AH_TEMPLATE([BUGGYGETLOGIN], -+[If ttyslot() breaks getlogin() by returning indexes to utmp entries -+ of type DEAD_PROCESS, then our getlogin() replacement should be -+ selected by defining BUGGYGETLOGIN.]) ++AH_TEMPLATE([SVR4]) ++AH_TEMPLATE([BUGGYGETLOGIN]) AC_TRY_LINK([#include ],, [AC_CHECK_HEADER(dwarf.h, AC_DEFINE(SVR4) AC_DEFINE(BUGGYGETLOGIN), -@@ -235,6 +561,9 @@ +@@ -551,6 +557,9 @@ dnl AC_CHECKING(BSD job jontrol) -+AH_TEMPLATE([BSDJOBS], ++AH_TEMPLATE([BSDJOBS], +[Define BSDJOBS if you have BSD-style job control (both process + groups and a tty that deals correctly with them)]) AC_TRY_LINK( [#include #include -@@ -255,6 +584,10 @@ +@@ -571,6 +580,10 @@ dnl **** setreuid(), seteuid() **** dnl AC_CHECKING(setreuid) -+AH_TEMPLATE([HAVE_SETREUID], ++AH_TEMPLATE([HAVE_SETREUID], +[If your system has the calls setreuid() and setregid(), + define HAVE_SETREUID. Otherwise screen will use a forked process to + safely create output files without retaining any special privileges.]) AC_TRY_LINK(,[ #ifdef __hpux setresuid(0, 0, 0); -@@ -269,6 +602,9 @@ +@@ -585,6 +598,9 @@ dnl Solaris seteuid doesn't change the saved uid, bad for dnl multiuser screen sessions AC_CHECKING(seteuid) @@ -459,62 +137,59 @@ AC_TRY_LINK(,[ #if defined(linux) || defined(NeXT) || defined(_AUX_SOURCE) || defined(AUX) || defined(ultrix) || (defined(sun) && defined(SVR4)) || defined(ISC) || defined(sony_news) seteuid_is_broken(0); -@@ -292,7 +628,8 @@ - dnl **** FIFO tests **** +@@ -609,6 +625,8 @@ dnl --AC_CHECKING(fifos) + AC_CHECKING(fifos) +AC_CACHE_CHECK([usable fifos], -+ [screen_cv_sys_fifo_usable], ++ [screen_cv_sys_fifo_usable], AC_TRY_RUN([ #include #include -@@ -357,12 +694,14 @@ +@@ -673,12 +691,15 @@ exit(1); exit(0); } -], AC_NOTE(- your fifos are usable) fifo=1, -AC_NOTE(- your fifos are not usable)) --rm -f /tmp/conftest* +], screen_cv_sys_fifo_usable=yes, screen_cv_sys_fifo_usable=no)) + rm -f /tmp/conftest* -if test -n "$fifo"; then -AC_CHECKING(for broken fifo implementation) +if test X"$screen_cv_sys_fifo_usable" = Xyes; then -+AH_TEMPLATE([BROKEN_PIPE], ++AH_TEMPLATE([BROKEN_PIPE], +[Define this if your system exits select() immediatly if a pipe is + opened read-only and no writer has opened it.]) +AC_CACHE_CHECK([broken fifo implementation], -+ [screen_cv_sys_fifo_broken_impl], ++ [screen_cv_sys_fifo_broken_impl], AC_TRY_RUN([ #include #include -@@ -407,9 +746,11 @@ +@@ -723,8 +744,11 @@ exit(1); exit(0); } -], AC_NOTE(- your implementation is ok), -AC_NOTE(- you have a broken implementation) AC_DEFINE(BROKEN_PIPE) fifobr=1) --rm -f /tmp/conftest* -+], screen_cv_sys_fifo_broken_impl=no, ++], screen_cv_sys_fifo_broken_impl=no, +screen_cv_sys_fifo_broken_impl=yes)) +if test X"$screen_cv_sys_fifo_broken_impl" = Xyes; then -+ AC_DEFINE(BROKEN_PIPE) ++ AC_DEFINE(BROKEN_PIPE) +fi + rm -f /tmp/conftest* fi - dnl -@@ -418,7 +759,8 @@ - dnl may need LIBS="$LIBS -lsocket" here +@@ -735,6 +759,8 @@ dnl --AC_CHECKING(sockets) + AC_CHECKING(sockets) +AC_CACHE_CHECK([sockets are usable], -+ [screen_cv_sys_sockets_usable], ++ [screen_cv_sys_sockets_usable], AC_TRY_RUN([ #include #include -@@ -469,12 +811,16 @@ +@@ -785,12 +811,16 @@ exit(1); exit(0); } @@ -527,15 +202,15 @@ -if test -n "$sock"; then +if test X"$screen_cv_sys_sockets_usable" = Xyes; then AC_CHECKING(socket implementation) -+AH_TEMPLATE([SOCK_NOT_IN_FS], ++AH_TEMPLATE([SOCK_NOT_IN_FS], +[Define this if the unix-domain socket implementation doesn't + create a socket in the filesystem.]) +AC_CACHE_CHECK([if sockets are not stored in the filesystem], -+ [screen_cv_sys_sockets_nofs], ++ [screen_cv_sys_sockets_nofs], AC_TRY_RUN([ #include #include -@@ -500,22 +846,25 @@ +@@ -816,22 +846,25 @@ close(s); exit(0); } @@ -569,7 +244,7 @@ AC_NOTE(- as your fifos are broken lets use the sockets.) else AC_NOTE(- both sockets and fifos usable. let's take fifos.) -@@ -525,7 +874,7 @@ +@@ -841,7 +874,7 @@ AC_NOTE(- using named pipes, of course) AC_DEFINE(NAMEDPIPE) fi @@ -578,20 +253,20 @@ AC_NOTE(- using unix-domain sockets, of course) else AC_MSG_ERROR(you have neither usable sockets nor usable pipes -> no screen) -@@ -535,7 +884,11 @@ +@@ -851,7 +884,11 @@ dnl **** check the select implementation **** dnl -AC_CHECKING(select return value) -+AH_TEMPLATE([SELECT_BROKEN], ++AH_TEMPLATE([SELECT_BROKEN], +[If the select return value doesn't treat a descriptor that is + usable for reading and writing as two hits, define SELECT_BROKEN.]) +AC_CACHE_CHECK([for broken select return value], -+ [screen_cv_sys_select_broken_retval], ++ [screen_cv_sys_select_broken_retval], AC_TRY_RUN([ #include #include -@@ -634,19 +987,26 @@ +@@ -950,17 +987,26 @@ exit(1); exit(0); } @@ -606,7 +281,7 @@ dnl dnl **** termcap or terminfo **** dnl -+AH_TEMPLATE([TERMINFO], ++AH_TEMPLATE([TERMINFO], +[Define TERMINFO if your machine emulates the termcap routines + with the terminfo database. + Thus the .screenrc file is parsed for @@ -615,33 +290,31 @@ AC_CHECKING(for tgetent) AC_TRY_LINK(,tgetent((char *)0, (char *)0);,, olibs="$LIBS" --if test -f /usr/lib/libncursesw.so ; then -- LIBS="-lncursesw $olibs" --fi - AC_CHECKING(libncursesw) -+AC_CHECK_LIB(ncursesw,tgetent) - AC_TRY_LINK(,tgetent((char *)0, (char *)0);,, - LIBS="-lcurses $olibs" +-LIBS="-lcurses $olibs" AC_CHECKING(libcurses) -@@ -668,24 +1028,39 @@ ++AC_CHECK_LIB(ncursesw,tgetent) + AC_TRY_LINK(,[ + #ifdef __hpux + __sorry_hpux_libcurses_is_totally_broken_in_10_10(); +@@ -979,24 +1025,39 @@ AC_TRY_LINK(,tgetent((char *)0, (char *)0);,, - AC_MSG_ERROR(!!! no tgetent - no screen))))))) + AC_MSG_ERROR(!!! no tgetent - no screen)))))) -AC_TRY_RUN([ +AC_CACHE_CHECK([using terminfo database],[screen_cv_sys_terminfo_used], -+ AC_TRY_RUN([ ++ AC_TRY_RUN([ main() { exit(strcmp(tgoto("%p1%d", 0, 1), "1") ? 0 : 1); -}], AC_NOTE(- you use the termcap database), -AC_NOTE(- you use the terminfo database) AC_DEFINE(TERMINFO)) +} -+ ], screen_cv_sys_terminfo_used=no, -+ screen_cv_sys_terminfo_used=yes) ++ ], screen_cv_sys_terminfo_used=no, ++ screen_cv_sys_terminfo_used=yes) +) + +if test X"$screen_cv_sys_terminfo_used" = Xyes; then -+ AC_DEFINE(TERMINFO) ++ AC_DEFINE(TERMINFO) +fi + AC_CHECKING(ospeed) @@ -651,7 +324,7 @@ dnl dnl **** PTY specific things **** dnl -+AH_TEMPLATE([HAVE_DEV_PTC], ++AH_TEMPLATE([HAVE_DEV_PTC], +[define HAVE_DEV_PTC if you have a /dev/ptc character special + device.]) AC_CHECKING(for /dev/ptc) @@ -666,50 +339,70 @@ sysvr4ptys= if test -c /dev/ptmx ; then AC_TRY_LINK([],[ptsname(0);grantpt(0);unlockpt(0);],[AC_DEFINE(HAVE_SVR4_PTYS) -@@ -701,6 +1076,13 @@ +@@ -1012,6 +1073,13 @@ fi AC_CHECKING(for ptyranges) +AH_TEMPLATE([PTYRANGE0], +[define PTYRANGE0 and or PTYRANGE1 if you want to adapt screen -+ to unusual environments. E.g. For SunOs the defaults are "qpr" and -+ "0123456789abcdef". For SunOs 4.1.2 -+ #define PTYRANGE0 "pqrstuvwxyzPQRST" ++ to unusual environments. E.g. For SunOs the defaults are "qpr" and ++ "0123456789abcdef". For SunOs 4.1.2 ++ #define PTYRANGE0 "pqrstuvwxyzPQRST" + is recommended by Dan Jacobson.]) +AH_TEMPLATE([PTYRANGE1],[]) if test -d /dev/ptym ; then pdir='/dev/ptym' else -@@ -817,6 +1199,9 @@ +@@ -1117,7 +1185,7 @@ + AC_NOTE(- ptys are world accessable) + fi + else +- AC_NOTE(- can't determine - assume ptys are world accessable) ++ AC_NOTE(- cannot determine - assume ptys are world accessable) + fi + ] + ) +@@ -1128,6 +1196,7 @@ dnl **** utmp handling **** dnl AC_CHECKING(getutent) -+AH_TEMPLATE([GETUTENT], -+[If your system has getutent(), pututline(), etc. to write to the -+ utmp file, define GETUTENT.]) ++AH_TEMPLATE([GETUTENT], [If your system has setutent() and getutent() define GETUTENT]) AC_TRY_LINK([ #include /* to get time_t on SCO */ #include -@@ -850,6 +1235,7 @@ - [int x = DEAD_PROCESS; pututline((struct utmp *)0); getutent();], AC_DEFINE(GETUTENT), LIBS="$olibs") - ) +@@ -1141,7 +1210,8 @@ + #define pututline _pututline + #endif + ], +-[int x = DEAD_PROCESS; pututline((struct utmp *)0); getutent();], AC_DEFINE(GETUTENT), ++[int x = DEAD_PROCESS; pututline((struct utmp *)0); getutent();], ++[AC_MSG_RESULT(yes); AC_DEFINE(GETUTENT)],[AC_MSG_RESULT(no)]) + olibs="$LIBS" + LIBS="$LIBS -lgen" + AC_CHECKING(getutent with -lgen) +@@ -1158,9 +1228,11 @@ + #define pututline _pututline + #endif + ], +-[int x = DEAD_PROCESS; pututline((struct utmp *)0); getutent();], AC_DEFINE(GETUTENT), LIBS="$olibs") +-) ++[int x = DEAD_PROCESS; pututline((struct utmp *)0); getutent();], ++[AC_MSG_RESULT(yes); AC_DEFINE(GETUTENT)], [AC_MSG_RESULT(no)]) ++LIBS="$olibs" AC_CHECKING(ut_host) -+AH_TEMPLATE([UTHOST],[Define UTHOST if the utmp file has a host field.]) ++AH_TEMPLATE([UTHOST]) AC_TRY_COMPILE([ #include #include -@@ -860,8 +1246,9 @@ +@@ -1171,6 +1243,7 @@ #include #endif ],[struct utmp u; u.ut_host[0] = 0;], AC_DEFINE(UTHOST)) -+AH_TEMPLATE([HAVE_UTEMPTER],[Define if you have the utempter utmp helper program]) ++AH_TEMPLATE([HAVE_UTEMPTER]) AC_CHECK_HEADER(utempter.h, have_utempter=yes, have_utempter=no) --if test "$have_utempter" = yes; then -+if test X"$have_utempter" = Xyes; then + if test "$have_utempter" = yes; then AC_DEFINE(HAVE_UTEMPTER) - LIBS="$LIBS -lutempter" - fi -@@ -869,20 +1256,39 @@ +@@ -1180,20 +1253,39 @@ dnl dnl **** loadav **** dnl @@ -754,7 +447,7 @@ ) if test -z "$load" ; then -@@ -1024,6 +1430,11 @@ +@@ -1335,6 +1427,11 @@ dnl dnl **** signal handling **** dnl @@ -766,15 +459,15 @@ if test -n "$posix" ; then dnl POSIX has reliable signals with void return type. -@@ -1041,6 +1452,7 @@ - #endif - extern void (*signal ()) ();], [int i;], AC_DEFINE(SIGVOID)) - AC_CHECKING(sigset) +@@ -1344,6 +1441,7 @@ + else + + AC_CHECKING(return type of signal handlers) +AH_TEMPLATE([USESIGSET], [Define USESIGSET if you have sigset for BSD 4.1 reliable signals.]) - AC_TRY_LINK([ - #include + AC_TRY_COMPILE( + [#include #include -@@ -1052,6 +1464,9 @@ +@@ -1363,6 +1461,9 @@ #endif ], AC_DEFINE(USESIGSET)) AC_CHECKING(signal implementation) @@ -784,7 +477,7 @@ AC_TRY_RUN([ #include #include -@@ -1094,13 +1509,14 @@ +@@ -1405,13 +1506,14 @@ dnl AC_CHECKING(for crypt and sec libraries) @@ -803,11 +496,11 @@ oldlibs="$LIBS" LIBS="$LIBS -lsun" AC_CHECKING(IRIX sun library) -@@ -1123,6 +1539,13 @@ +@@ -1434,6 +1536,13 @@ dnl **** misc things **** dnl AC_CHECKING(wait union) -+AH_TEMPLATE([BSDWAIT], ++AH_TEMPLATE([BSDWAIT], +[Define BSDWAIT if your system defines a 'union wait' in + + Only allow BSDWAIT i.e. wait3 on nonposix systems, since @@ -817,7 +510,7 @@ AC_TRY_COMPILE([#include #include ],[ -@@ -1133,6 +1556,12 @@ +@@ -1444,6 +1553,13 @@ #endif ],AC_DEFINE(BSDWAIT)) @@ -826,11 +519,12 @@ + This is usually the case for SVID systems, where BSD uses sgttyb. + POSIX systems should define this anyway, even though they use + struct termios.]) ++ + if test -z "$butterfly"; then AC_CHECKING(for termio or termios) AC_TRY_CPP([#include ], AC_DEFINE(TERMIO), -@@ -1142,17 +1571,35 @@ +@@ -1453,17 +1569,35 @@ ) fi @@ -838,7 +532,7 @@ + dnl AC_CHECK_HEADER(shadow.h, AC_DEFINE(SHADOWPW)) AC_CHECKING(getspnam) -+AH_TEMPLATE([SHADOWPW], ++AH_TEMPLATE([SHADOWPW], +[If the passwords are stored in a shadow file and you want the + builtin lock to work properly, define SHADOWPW.]) AC_TRY_LINK([#include ], [getspnam("x");],AC_DEFINE(SHADOWPW)) @@ -850,7 +544,7 @@ AC_TRY_LINK(,[getttyent();], AC_DEFINE(GETTTYENT)) AC_CHECKING(fdwalk) -+AH_TEMPLATE([HAVE_FDWALK], ++AH_TEMPLATE([HAVE_FDWALK], +[Newer versions of Solaris include fdwalk, which can greatly improve + the startup time of screen; otherwise screen spends a lot of time + closing file descriptors.]) @@ -863,11 +557,11 @@ + undefined, screen uses its own (probably slower) version of bcopy().]) + +AC_CACHE_CHECK([if bcopy handles overlap], -+ [screen_cv_sys_bcopy_overlap], ++ [screen_cv_sys_bcopy_overlap], AC_TRY_RUN([ main() { char buf[10]; -@@ -1165,8 +1612,21 @@ +@@ -1476,7 +1610,21 @@ if (strncmp(buf, "cdedef", 6)) exit(1); exit(0); /* libc version works properly. */ @@ -877,20 +571,20 @@ +if test X"$screen_cv_sys_bcopy_overlap" = Xyes; then + AC_DEFINE(USEBCOPY) +fi - -+AH_TEMPLATE([USEMEMMOVE], -+[SYSV machines may have a working memcpy() -- Oh, this is ++ ++AH_TEMPLATE([USEMEMMOVE], ++[SYSV machines may have a working memcpy() -- Oh, this is + quite unlikely. Tell me if you see one. + "But then, memmove() should work, if at all available" he thought... + Boing, never say "works everywhere" unless you checked SCO UNIX. + Their memove fails the test in the configure script. Sigh. (Juergen) +]) +AC_CACHE_CHECK([if memmove handles overlap], -+ [screen_cv_sys_memmove_overlap], ++ [screen_cv_sys_memmove_overlap], + AC_TRY_RUN([ #define bcopy(s,d,l) memmove(d,s,l) - main() { -@@ -1180,9 +1640,15 @@ +@@ -1491,9 +1639,15 @@ if (strncmp(buf, "cdedef", 6)) exit(1); exit(0); /* libc version works properly. */ @@ -904,11 +598,11 @@ +AH_TEMPLATE([USEMEMCPY],[]) +AC_CACHE_CHECK([if memcpy handles overlap], -+ [screen_cv_sys_memcpy_overlap], ++ [screen_cv_sys_memcpy_overlap], AC_TRY_RUN([ #define bcopy(s,d,l) memcpy(d,s,l) main() { -@@ -1196,9 +1662,19 @@ +@@ -1507,9 +1661,19 @@ if (strncmp(buf, "cdedef", 6)) exit(1); exit(0); /* libc version works properly. */ @@ -920,24 +614,24 @@ +fi AC_MSG_CHECKING(long file names) -+AH_TEMPLATE([NAME_MAX], -+[If you are on a SYS V machine that restricts filename length to 14 ++AH_TEMPLATE([NAME_MAX], ++[If you are on a SYS V machine that restricts filename length to 14 + characters, you may need to enforce that by setting NAME_MAX to 14]) -+dnl TODO(Hannes) shipped config.h.in has -+dnl #undef NAME_MAX /* KEEP_UNDEF_HERE override system value */ ++dnl TODO(Hannes) shipped config.h.in has ++dnl #undef NAME_MAX /* KEEP_UNDEF_HERE override system value */ +dnl ahead of this (echo 1 > /tmp/conftest9012345) 2>/dev/null (echo 2 > /tmp/conftest9012346) 2>/dev/null val=`cat /tmp/conftest9012345 2>/dev/null` -@@ -1211,17 +1687,28 @@ +@@ -1522,17 +1686,28 @@ rm -f /tmp/conftest* AC_MSG_CHECKING(for vsprintf) -+AH_TEMPLATE([USEVARARGS], ++AH_TEMPLATE([USEVARARGS], +[If your system has vsprintf() and requires the use of the macros in + "varargs.h" to use functions with variable arguments, + define USEVARARGS.]) - AC_TRY_LINK([#include ],[va_list valist; vsprintf(0,0,valist);], AC_MSG_RESULT(yes);AC_DEFINE(USEVARARGS), AC_MSG_RESULT(no)) + AC_TRY_LINK(,[vsprintf(0,0,0);], AC_MSG_RESULT(yes);AC_DEFINE(USEVARARGS), AC_MSG_RESULT(no)) AC_HEADER_DIRENT @@ -946,7 +640,7 @@ AC_TRY_LINK(,[setenv((char *)0,(char *)0);unsetenv((char *)0);], AC_MSG_RESULT(yes);AC_DEFINE(USESETENV), AC_MSG_RESULT(no) AC_MSG_CHECKING(for putenv) -+AH_TEMPLATE([NEEDPUTENV], ++AH_TEMPLATE([NEEDPUTENV], +[If your system does not come with a setenv()/putenv()/getenv() + functions, you may bring in our own code by defining NEEDPUTENV.]) AC_TRY_LINK(,[putenv((char *)0);unsetenv((char *)0);], AC_MSG_RESULT(yes) , AC_MSG_RESULT(no);AC_DEFINE(NEEDPUTENV) @@ -958,7 +652,7 @@ AC_TRY_LINK([ #include ],[nl_langinfo(CODESET);], AC_MSG_RESULT(yes);AC_DEFINE(HAVE_NL_LANGINFO), AC_MSG_RESULT(no)) -@@ -1271,7 +1758,8 @@ +@@ -1582,7 +1757,8 @@ dnl Ptx bug workaround -- insert -lc after -ltermcap test -n "$seqptx" && LIBS="-ltermcap -lc -lsocket -linet -lnsl -lsec -lseq" diff --git a/recipes/screen/screen-4.0.3/cross-compile.patch b/recipes/screen/screen-4.0.3/cross-compile.patch new file mode 100644 index 0000000000..90b321f405 --- /dev/null +++ b/recipes/screen/screen-4.0.3/cross-compile.patch @@ -0,0 +1,331 @@ + +Patch by Hannes Reich (hannes@skynet.ie) 22-Jul-2005 +Resolves _some_ of the cross-compilation issues in screen's configure.in + +Index: screen-4.0.3/configure.in +=================================================================== +--- screen-4.0.3.orig/configure.in 2003-06-03 04:58:24.000000000 -0700 ++++ screen-4.0.3/configure.in 2009-09-11 16:15:04.533739171 -0700 +@@ -40,6 +40,322 @@ + AC_PREFIX_PROGRAM(screen) + AC_PREFIX_PROGRAM(gzip) + ++AH_TOP([ ++/* Copyright (c) 1993-2000 ++ * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) ++ * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) ++ * Copyright (c) 1987 Oliver Laumann ++ * ++ * 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, 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 (see the file COPYING); if not, write to the ++ * Free Software Foundation, Inc., ++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ */ ++ ++ ++/********************************************************************** ++ * ++ * User Configuration Section ++ */ ++ ++/* ++ * Maximum of simultaneously allowed windows per screen session. ++ */ ++#ifndef MAXWIN ++# define MAXWIN 40 ++#endif ++ ++/* ++ * Define SOCKDIR to be the directory to contain the named sockets ++ * screen creates. This should be in a common subdirectory, such as ++ * /usr/local or /tmp. It makes things a little more secure if you ++ * choose a directory which is not writable by everyone or where the ++ * "sticky" bit is on, but this isn't required. ++ * If SOCKDIR is not defined screen will put the named sockets in ++ * the user's home directory. Notice that this can cause you problems ++ * if some user's HOME directories are AFS- or NFS-mounted. Especially ++ * AFS is unlikely to support named sockets. ++ * ++ * Screen will name the subdirectories "S-$USER" (e.g /tmp/S-davison). ++ */ ++#undef SOCKDIR ++ ++/* ++ * Define this if the SOCKDIR is not shared between hosts. ++ */ ++#define SOCKDIR_IS_LOCAL_TO_HOST ++ ++/* ++ * Screen sources two startup files. First a global file with a path ++ * specified here, second your local $HOME/.screenrc ++ * Don't define this, if you don't want it. ++ */ ++#ifndef ETCSCREENRC ++# define ETCSCREENRC "/usr/local/etc/screenrc" ++#endif ++ ++/* ++ * Screen can look for the environment variable $SYSSCREENRC and -if it ++ * exists- load the file specified in that variable as global screenrc. ++ * If you want to enable this feature, define ALLOW_SYSSCREENRC to one (1). ++ * Otherwise ETCSCREENRC is always loaded. ++ */ ++#define ALLOW_SYSSCREENRC 1 ++ ++/* ++ * Screen needs encoding files for the translation of utf8 ++ * into some encodings, e.g. JIS, BIG5. ++ * Only needed if FONT, ENCODINGS and UTF8 are defined. ++ */ ++#ifndef SCREENENCODINGS ++# define SCREENENCODINGS "/usr/local/lib/screen/encodings" ++#endif ++/* ++ * Define CHECKLOGIN to force Screen users to enter their Unix password ++ * in addition to the screen password. ++ * ++ * Define NOSYSLOG if yo do not have logging facilities. Currently ++ * syslog() will be used to trace ``su'' commands only. ++ */ ++#define CHECKLOGIN 1 ++#undef NOSYSLOG ++ ++ ++/* ++ * define PTYMODE if you do not like the default of 0622, which allows ++ * public write to your pty. ++ * define PTYGROUP to some numerical group-id if you do not want the ++ * tty to be in "your" group. ++ * Note, screen is unable to change mode or group of the pty if it ++ * is not installed with sufficient privilege. (e.g. set-uid-root) ++ * define PTYROFS if the /dev/pty devices are mounted on a read-only ++ * filesystem so screen should not even attempt to set mode or group ++ * even if running as root (e.g. on TiVo). ++ */ ++#undef PTYMODE ++#undef PTYGROUP ++#undef PTYROFS ++ ++/* ++ * If screen is NOT installed set-uid root, screen can provide tty ++ * security by exclusively locking the ptys. While this keeps other ++ * users from opening your ptys, it also keeps your own subprocesses ++ * from being able to open /dev/tty. Define LOCKPTY to add this ++ * exclusive locking. ++ */ ++#undef LOCKPTY ++ ++/* ++ * If you'd rather see the status line on the first line of your ++ * terminal rather than the last, define TOPSTAT. ++ */ ++#undef TOPSTAT ++ ++/* ++ * define DETACH can detach a session. An absolute 'must'. ++ */ ++#define DETACH ++ ++/* ++ * here come the erlangen extensions to screen: ++ * define LOCK if you want to use a lock program for a screenlock. ++ * define PASSWORD for secure reattach of your screen. ++ * define COPY_PASTE to use the famous hacker's treasure zoo. ++ * define POW_DETACH to have a detach_and_logout key (requires DETACH). ++ * define REMOTE_DETACH (-d option) to move screen between terminals. ++ * define AUTO_NUKE to enable Tim MacKenzies clear screen nuking ++ * define PSEUDOS to allow window input/output filtering ++ * define MULTI to allow multiple attaches. ++ * define MULTIUSER to allow other users attach to your session ++ * (if they are in the acl, of course) ++ * define MAPKEYS to include input keyboard translation. ++ * define FONT to support ISO2022/alternet charset support ++ * define COLOR to include ansi color support. This may expose ++ * a bug in x11r6-color-xterm. ++ * define DW_CHARS to include support for double-width character ++ * sets. ++ * define ENCODINGS to include support for encodings like euc or big5. ++ * Needs FONT to work. ++ * define UTF8 if you want support for UTF-8 encoding. ++ * Needs FONT and ENCODINGS to work. ++ * define COLORS16 if you want 16 colors. ++ * Needs COLOR to work. ++ * define BUILTIN_TELNET to add telnet support to screen. ++ * Syntax: screen //telnet host [port] ++ * define RXVT_OSC if you want support for rxvts special ++ * change fgcolor/bgcolor/bgpicture sequences ++ */ ++#undef SIMPLESCREEN ++#ifndef SIMPLESCREEN ++# define LOCK ++# define PASSWORD ++# define COPY_PASTE ++# define REMOTE_DETACH ++# define POW_DETACH ++# define AUTO_NUKE ++# define PSEUDOS ++# define MULTI ++# define MULTIUSER ++# define MAPKEYS ++# define COLOR ++# define FONT ++# define DW_CHARS ++# define ENCODINGS ++# define UTF8 ++# define COLORS16 ++# define ZMODEM ++# define BLANKER_PRG ++#endif /* SIMPLESCREEN */ ++ ++#undef BUILTIN_TELNET ++#undef RXVT_OSC ++#undef COLORS256 ++ ++ ++/* ++ * If you have a braille display you should define HAVE_BRAILLE. ++ * The code inside #ifdef HAVE_BRAILLE was contributed by Hadi Bargi ++ * Rangin (bargi@dots.physics.orst.edu). ++ * WARNING: this is more or less unsupported code, it may be full of ++ * bugs leading to security holes, enable at your own risk! ++ */ ++#undef HAVE_BRAILLE ++ ++ ++/* ++ * As error messages are mostly meaningless to the user, we ++ * try to throw out phrases that are somewhat more familiar ++ * to ...well, at least familiar to us NetHack players. ++ */ ++#ifndef NONETHACK ++# define NETHACK ++#endif /* NONETHACK */ ++ ++/* ++ * If screen is installed with permissions to update /etc/utmp (such ++ * as if it is installed set-uid root), define UTMPOK. ++ */ ++#define UTMPOK ++ ++/* Set LOGINDEFAULT to one (1) ++ * if you want entries added to /etc/utmp by default, else set it to ++ * zero (0). ++ * LOGINDEFAULT will be one (1) whenever LOGOUTOK is undefined! ++ */ ++#define LOGINDEFAULT 1 ++ ++/* Set LOGOUTOK to one (1) ++ * if you want the user to be able to log her/his windows out. ++ * (Meaning: They are there, but not visible in /etc/utmp). ++ * Disabling this feature only makes sense if you have a secure /etc/utmp ++ * database. ++ * Negative examples: suns usually have a world writable utmp file, ++ * xterm will run perfectly without s-bit. ++ * ++ * If LOGOUTOK is undefined and UTMPOK is defined, all windows are ++ * initially and permanently logged in. ++ * ++ * Set CAREFULUTMP to one (1) if you want that users have at least one ++ * window per screen session logged in. ++ */ ++#define LOGOUTOK 1 ++#undef CAREFULUTMP ++ ++ ++/* ++ * If UTMPOK is defined and your system (incorrectly) counts logins by ++ * counting non-null entries in /etc/utmp (instead of counting non-null ++ * entries with no hostname that are not on a pseudo tty), define USRLIMIT ++ * to have screen put an upper-limit on the number of entries to write ++ * into /etc/utmp. This helps to keep you from exceeding a limited-user ++ * license. ++ */ ++#undef USRLIMIT ++ ++/* ++ * both must be defined if you want to favor tcsendbreak over ++ * other calls to generate a break condition on serial lines. ++ * (Do not bother, if you are not using plain tty windows.) ++ */ ++#define POSIX_HAS_A_GOOD_TCSENDBREAK ++#define SUNOS4_AND_WE_TRUST_TCSENDBREAK ++ ++/* ++ * to lower the interrupt load on the host machine, you may want to ++ * adjust the VMIN and VTIME settings used for plain tty windows. ++ * See the termio(4) manual page (Non-Canonical Mode Input Processing) ++ * for details. ++ * if undefined, VMIN=1, VTIME=0 is used as a default - this gives you ++ * best user responsiveness, but highest interrupt frequency. ++ * (Do not bother, if you are not using plain tty windows.) ++ */ ++#define TTYVMIN 100 ++#define TTYVTIME 2 ++ ++/* ++ * looks like the above values are ignored by setting FNDELAY. ++ * This is default for all pty/ttys, you may disable it for ++ * ttys here. After playing with it for a while, one may find out ++ * that this feature may cause screen to lock up. ++ */ ++#ifdef bsdi ++# define TTY_DISABLE_FNBLOCK /* select barfs without it ... */ ++#endif ++ ++ ++/* ++ * Some terminals, e.g. Wyse 120, use a bitfield to select attributes. ++ * This doesn't work with the standard so/ul/m? terminal entries, ++ * because they will cancel each other out. ++ * On TERMINFO machines, "sa" (sgr) may work. If you want screen ++ * to switch attributes only with sgr, define USE_SGR. ++ * This is *not* recomended, do this only if you must. ++ */ ++#undef USE_SGR ++ ++ ++/* ++ * Define USE_LOCALE if you want screen to use the locale names ++ * for the name of the month and day of the week. ++ */ ++#define USE_LOCALE ++ ++/* ++ * Define USE_PAM if your system supports PAM (Pluggable Authentication ++ * Modules) and you want screen to use it instead of calling crypt(). ++ * (You may also need to add -lpam to LIBS in the Makefile.) ++ */ ++#undef USE_PAM ++ ++/* ++ * Define CHECK_SCREEN_W if you want screen to set TERM to screen-w ++ * if the terminal width is greater than 131 columns. No longer needed ++ * on modern systems which use $COLUMNS or the tty settings instead. ++ */ ++#undef CHECK_SCREEN_W ++ ++/********************************************************************** ++ * ++ * End of User Configuration Section ++ * ++ * Rest of this file is modified by 'configure' ++ * Change at your own risk! ++ * ++ */ ++]) ++# end of AH_TOP ++ + old_CFLAGS="$CFLAGS" + AC_PROG_CC + AC_PROG_CPP diff --git a/recipes/screen/screen-4.0.3/no-stropts.patch b/recipes/screen/screen-4.0.3/no-stropts.patch new file mode 100644 index 0000000000..bce651479d --- /dev/null +++ b/recipes/screen/screen-4.0.3/no-stropts.patch @@ -0,0 +1,13 @@ +Index: screen-4.0.3/pty.c +=================================================================== +--- screen-4.0.3.orig/pty.c 2009-09-11 15:44:44.881250800 -0700 ++++ screen-4.0.3/pty.c 2009-09-11 15:45:28.077862097 -0700 +@@ -34,7 +34,7 @@ + #endif + + /* for solaris 2.1, Unixware (SVR4.2) and possibly others */ +-#ifdef HAVE_SVR4_PTYS ++#if defined HAVE_SVR4_PTYS && !defined __UCLIBC__ + # include + #endif + diff --git a/recipes/screen/screen-4.0.3/no-utempter.patch b/recipes/screen/screen-4.0.3/no-utempter.patch new file mode 100644 index 0000000000..22d21bb919 --- /dev/null +++ b/recipes/screen/screen-4.0.3/no-utempter.patch @@ -0,0 +1,17 @@ +Index: screen-4.0.3/configure.in +=================================================================== +--- screen-4.0.3.orig/configure.in 2009-09-11 18:42:08.338231443 -0700 ++++ screen-4.0.3/configure.in 2009-09-11 18:43:39.378663533 -0700 +@@ -1243,12 +1243,6 @@ + #include + #endif + ],[struct utmp u; u.ut_host[0] = 0;], AC_DEFINE(UTHOST)) +-AH_TEMPLATE([HAVE_UTEMPTER]) +-AC_CHECK_HEADER(utempter.h, have_utempter=yes, have_utempter=no) +-if test "$have_utempter" = yes; then +- AC_DEFINE(HAVE_UTEMPTER) +- LIBS="$LIBS -lutempter" +-fi + + dnl + dnl **** loadav **** diff --git a/recipes/screen/screen-4.0.3/sched.patch b/recipes/screen/screen-4.0.3/sched.patch new file mode 100644 index 0000000000..5c635c157b --- /dev/null +++ b/recipes/screen/screen-4.0.3/sched.patch @@ -0,0 +1,20 @@ +diff -urN screen-4.0.3-orig/sched.h screen-4.0.3/sched.h +--- screen-4.0.3-orig/sched.h 2002-01-08 16:42:43.000000000 +0100 ++++ screen-4.0.3/sched.h 2009-01-13 14:53:15.000000000 +0100 +@@ -22,6 +22,10 @@ + * $Id: sched.h,v 1.1.1.1 1993/06/16 23:51:13 jnweiger Exp $ FAU + */ + ++#ifndef _SCHED_H_ ++#define _SCHED_H_ 1 ++#include ++ + struct event + { + struct event *next; +@@ -41,3 +45,4 @@ + #define EV_READ 1 + #define EV_WRITE 2 + #define EV_ALWAYS 3 ++#endif + diff --git a/recipes/screen/screen_4.0.3.bb b/recipes/screen/screen_4.0.3.bb index 1165d46d33..003ca7a1a4 100644 --- a/recipes/screen/screen_4.0.3.bb +++ b/recipes/screen/screen_4.0.3.bb @@ -4,13 +4,15 @@ processes, typically interactive shells." LICENSE = "GPL" SECTION = "console/utils" DEPENDS = "ncurses" -PR = "r0" - -# patch needs adapting -DEFAULT_PREFERENCE = "-1" +PR = "r1" SRC_URI = "${GNU_MIRROR}/screen/screen-${PV}.tar.gz \ - file://configure.patch;patch=1" + file://cross-compile.patch;patch=1 \ + file://configure.patch;patch=1 \ + file://sched.patch;patch=1 \ + file://no-stropts.patch;patch=1 \ + file://no-utempter.patch;patch=1 \ + " inherit autotools -- cgit v1.2.3 From 53c0673ba015ba400d4e18fef5c5903830a06c09 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Fri, 11 Sep 2009 23:31:12 -0700 Subject: powertop: Make it compile on uclibc. * Use INC_PR * Move common stuff to powertop.inc * Add -lint for uclibc bases systems * Add a patch to tinker with order of CFLAGS in commandline * Eliminate the sed expression in favor of a patch to substitute nsursesw with ncurses Signed-off-by: Khem Raj --- conf/checksums.ini | 4 ++++ recipes/powertop/files/ldflags.patch | 13 +++++++++++++ recipes/powertop/powertop.inc | 27 +++++++++++++++++++++++++++ recipes/powertop/powertop_1.10.bb | 19 ++----------------- recipes/powertop/powertop_1.11.bb | 20 ++------------------ recipes/powertop/powertop_1.8.bb | 18 ++---------------- 6 files changed, 50 insertions(+), 51 deletions(-) create mode 100644 recipes/powertop/files/ldflags.patch create mode 100644 recipes/powertop/powertop.inc diff --git a/conf/checksums.ini b/conf/checksums.ini index 5de82f5366..68fba4f082 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -20262,6 +20262,10 @@ sha256=cc60000bbe5f4d7b9beae8a84e1cd1ba69339a489a7d1a7365a3d8fe8fd73d6b md5=3498f5983c683c3a57dce7379a722082 sha256=70e7cc53e5fbade5e447bda9f0ca12f2153bf426e074dbac3a2e97adf46180f2 +[http://www.lesswatts.org/projects/powertop/download/powertop-1.8.tar.gz] +md5=38fd8a6825cd62b6c22df8a44b4e27d0 +sha256=7325ea46e5af59c12ea024e69622ac7753010c8de615d668e1f03b0fc05bad3a + [http://www.linuxpowertop.org/download/powertop-1.8.tar.gz] md5=38fd8a6825cd62b6c22df8a44b4e27d0 sha256=7325ea46e5af59c12ea024e69622ac7753010c8de615d668e1f03b0fc05bad3a diff --git a/recipes/powertop/files/ldflags.patch b/recipes/powertop/files/ldflags.patch new file mode 100644 index 0000000000..690d90f8f8 --- /dev/null +++ b/recipes/powertop/files/ldflags.patch @@ -0,0 +1,13 @@ +Index: powertop-1.11/Makefile +=================================================================== +--- powertop-1.11.orig/Makefile 2008-12-30 10:52:54.000000000 -0800 ++++ powertop-1.11/Makefile 2009-09-11 19:46:19.550388421 -0700 +@@ -20,7 +20,7 @@ + + + powertop: $(OBJS) Makefile powertop.h +- $(CC) ${CFLAGS} $(OBJS) -lncursesw -o powertop ++ $(CC) $(OBJS) ${CFLAGS} -lncurses -o powertop + @(cd po/ && $(MAKE)) + + powertop.1.gz: powertop.1 diff --git a/recipes/powertop/powertop.inc b/recipes/powertop/powertop.inc new file mode 100644 index 0000000000..931abadc44 --- /dev/null +++ b/recipes/powertop/powertop.inc @@ -0,0 +1,27 @@ +DESCRIPTION = "PowerTOP, a tool that helps you find what software is using the most power." +HOMEPAGE = "http://www.linuxpowertop.org/" +LICENSE = "GPLv2" +DEPENDS = "virtual/libintl ncurses" + +INC_PR = "r1" + +SRC_URI = "http://www.lesswatts.org/projects/powertop/download/powertop-${PV}.tar.gz \ + file://ldflags.patch;patch=1 \ + " + +CFLAGS = "${LDFLAGS}" + +do_configure() { + # We do not build ncurses with wide char support + # sed -i -e "s/lncursesw/lncurses/" ${S}/Makefile + : +} + +do_install() { + oe_runmake install DESTDIR=${D} +} + + +LDFLAGS_append_linux-uclibc = " -lintl" +LDFLAGS_append_linux-uclibceabi = " -lintl" +LDFLAGS_append_linux-uclibcspe = " -lintl" diff --git a/recipes/powertop/powertop_1.10.bb b/recipes/powertop/powertop_1.10.bb index 4a429d68ba..49da90e423 100644 --- a/recipes/powertop/powertop_1.10.bb +++ b/recipes/powertop/powertop_1.10.bb @@ -1,17 +1,2 @@ -DESCRIPTION = "PowerTOP, a tool that helps you find what software is using the most power." -HOMEPAGE = "http://www.linuxpowertop.org/" -LICENSE = "GPLv2" -DEPENDS = "virtual/libintl ncurses" - -SRC_URI = "http://www.lesswatts.org/projects/powertop/download/powertop-${PV}.tar.gz" - -CFLAGS += "${LDFLAGS}" - -do_configure() { - # We do not build ncurses with wide char support - sed -i -e "s/lncursesw/lncurses/" ${S}/Makefile -} - -do_install() { - oe_runmake install DESTDIR=${D} -} +require powertop.inc +PR = "${INC_PR}.0" diff --git a/recipes/powertop/powertop_1.11.bb b/recipes/powertop/powertop_1.11.bb index 01148cb9fd..6af5290122 100644 --- a/recipes/powertop/powertop_1.11.bb +++ b/recipes/powertop/powertop_1.11.bb @@ -1,26 +1,10 @@ -DESCRIPTION = "PowerTOP, a tool that helps you find what software is using the most power." -HOMEPAGE = "http://www.linuxpowertop.org/" -LICENSE = "GPLv2" -DEPENDS = "virtual/libintl ncurses" +require powertop.inc -PR = "r1" - -SRC_URI = "http://www.lesswatts.org/projects/powertop/download/powertop-${PV}.tar.gz" +PR = "${INC_PR}.0" SRC_URI_append_armv7a = " file://omap.patch;patch=1;pnum=0" -CFLAGS += "${LDFLAGS}" CFLAGS_append_beagleboard = " -DOMAP3" CFLAGS_append_overo = " -DOMAP3" CFLAGS_append_omap3evm = " -DOMAP3" CFLAGS_append_omapzoom2 = " -DOMAP3" - - -do_configure() { - # We do not build ncurses with wide char support - sed -i -e "s/lncursesw/lncurses/" ${S}/Makefile -} - -do_install() { - oe_runmake install DESTDIR=${D} -} diff --git a/recipes/powertop/powertop_1.8.bb b/recipes/powertop/powertop_1.8.bb index ab84161ddc..e74b8a6add 100644 --- a/recipes/powertop/powertop_1.8.bb +++ b/recipes/powertop/powertop_1.8.bb @@ -1,17 +1,3 @@ -DESCRIPTION = "PowerTOP, a tool that helps you find what software is using the most power." -HOMEPAGE = "http://www.linuxpowertop.org/" -LICENSE = "GPLv2" -DEPENDS = "ncurses" +require powertop.inc +PR = "${INC_PR}.0" -SRC_URI = "http://www.linuxpowertop.org/download/powertop-${PV}.tar.gz" - -CFLAGS += "${LDFLAGS}" - -do_configure() { - # We do not build ncurses with wide char support - sed -i -e "s/lncursesw/lncurses/" ${S}/Makefile -} - -do_install() { - oe_runmake install DESTDIR=${D} -} -- cgit v1.2.3 From 23c18144b10a12aa8593b98125e9733519c69acc Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Fri, 11 Sep 2009 16:06:08 -0700 Subject: ebtables: fix GNU_HASH error --- recipes/ebtables/ebtables_2.0.6.bb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/recipes/ebtables/ebtables_2.0.6.bb b/recipes/ebtables/ebtables_2.0.6.bb index 33ad2b9113..c4fc1c329a 100644 --- a/recipes/ebtables/ebtables_2.0.6.bb +++ b/recipes/ebtables/ebtables_2.0.6.bb @@ -4,6 +4,8 @@ LICENSE = "GPL" SECTION = "console/network" PR = "r2" +TARGET_CC_ARCH += "${LDFLAGS}" + SRC_URI = "${SOURCEFORGE_MIRROR}/ebtables/ebtables-v${PV}.tar.gz \ file://gcc34.patch;patch=1 \ file://gcc4.patch;patch=1 \ -- cgit v1.2.3 From c49513ce80d595ac0f4aa12e93b1786b87c2df20 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 12 Sep 2009 11:49:00 +0200 Subject: cairo git: update SRCREV --- recipes/cairo/cairo_git.bb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/recipes/cairo/cairo_git.bb b/recipes/cairo/cairo_git.bb index 44212103a6..825b601897 100644 --- a/recipes/cairo/cairo_git.bb +++ b/recipes/cairo/cairo_git.bb @@ -1,5 +1,6 @@ #This is a development snapshot, so lets hint OE to use the releases DEFAULT_PREFERENCE = "-1" +DEFAULT_PREFERENCE_angstrom = "1" SECTION = "libs" PRIORITY = "optional" @@ -7,7 +8,10 @@ DEPENDS = "pixman virtual/libx11 libsm libpng fontconfig libxrender" DESCRIPTION = "Cairo graphics library" LICENSE = "MPL LGPL" -PV = "1.5.3+git${SRCDATE}" +SRCREV = "3acccf0ea5ca1fde9cf6b91677588680a2644ee6" + +PV = "1.9.3" +PR_append = "+gitr${SRCREV}" SRC_URI = "git://git.cairographics.org/git/cairo;protocol=git \ " -- cgit v1.2.3 From 6efa4799a897aa64f16caa36f65fe65a5a106cc2 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 12 Sep 2009 14:25:51 +0200 Subject: gtk+: add 2.16.6 --- conf/checksums.ini | 8 ++ recipes/gtk+/gtk+-2.16.6/hardcoded_libtool.patch | 31 +++++++ recipes/gtk+/gtk+-2.16.6/no-demos.patch | 10 +++ recipes/gtk+/gtk+-2.16.6/run-iconcache.patch | 19 +++++ recipes/gtk+/gtk+-2.16.6/toggle-font.diff | 100 +++++++++++++++++++++++ recipes/gtk+/gtk+_2.16.6.bb | 65 +++++++++++++++ 6 files changed, 233 insertions(+) create mode 100644 recipes/gtk+/gtk+-2.16.6/hardcoded_libtool.patch create mode 100644 recipes/gtk+/gtk+-2.16.6/no-demos.patch create mode 100644 recipes/gtk+/gtk+-2.16.6/run-iconcache.patch create mode 100644 recipes/gtk+/gtk+-2.16.6/toggle-font.diff create mode 100644 recipes/gtk+/gtk+_2.16.6.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index 68fba4f082..c86d8abe41 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -10362,6 +10362,10 @@ sha256=ff25cbf43dd5c5f8cddc1b2094505c1d079a576b873a6d3d6b62d95da1bdd1d7 md5=d666f9f5a544e9d4d45804d88b1b5c4d sha256=afcdc5b67974054b111a4c283641303647d1ffa5677ffb8c4ce8621f12e17f88 +[http://download.gnome.org/sources/gtk+/2.16/gtk+-2.16.6.tar.bz2] +md5=416412b336d9f3b6b78ca887395d1726 +sha256=18e0f9792028e6cc5108447678f17d396f9a2cdfec1e6ab5dca98cb844f954af + [http://handhelds.org/packages/gtk-2.0/gtk+-2.2.4.diff.bz2] md5=c6697665e06cad01e87c2cf8d0913725 sha256=2a768a45adea587c4a7d6e3c3567ad7961bf7509e118ae62ce32f5369b1aeeb0 @@ -25186,6 +25190,10 @@ sha256=ac091ba9b2e2e9aff293969b3405b145c09789e59ac0caab2247211a19e09a8a md5=8ffa2ff763badd5de7592004d8d69a63 sha256=197c29803790efc0273bb4577d54629d0769a3b49b091c6430eb6704fd69824f +[http://www.lavrsen.dk/foswiki/pub/Motion/VideoFourLinuxLoopbackDevice/vloopback-1.2.tar.gz] +md5=1b63bf5b3d2b7fae63497d285789aec5 +sha256=d5af0c07aa53a6c93e92a6dd83f34dd9a08a05a0c0169c8ca8b15b023fdadf80 + [http://194.213.43.198/vmedit/vmedit-0.02.tar.gz] md5=7550ea1dd951d2f7fb1a54caa88860b2 sha256=bca8b0073d9527c0293b831c9b8d8f89fc3dc7b5ab30898e7b748843af07a978 diff --git a/recipes/gtk+/gtk+-2.16.6/hardcoded_libtool.patch b/recipes/gtk+/gtk+-2.16.6/hardcoded_libtool.patch new file mode 100644 index 0000000000..82fbbac8d7 --- /dev/null +++ b/recipes/gtk+/gtk+-2.16.6/hardcoded_libtool.patch @@ -0,0 +1,31 @@ +Index: gtk+-2.14.2/configure.in +=================================================================== +--- gtk+-2.14.2.orig/configure.in 2008-09-23 15:52:44.000000000 +0100 ++++ gtk+-2.14.2/configure.in 2008-09-23 15:53:51.000000000 +0100 +@@ -401,7 +401,7 @@ + case $enable_explicit_deps in + auto) + export SED +- deplibs_check_method=`(./libtool --config; echo 'eval echo \"$deplibs_check_method\"') | sh` ++ deplibs_check_method=`(./$host_alias-libtool --config; echo 'eval echo \"$deplibs_check_method\"') | sh` + if test "x$deplibs_check_method" '!=' xpass_all || test "x$enable_static" = xyes ; then + enable_explicit_deps=yes + else +@@ -759,7 +759,7 @@ + dnl Now we check to see if our libtool supports shared lib deps + dnl (in a rather ugly way even) + if $dynworks; then +- pixbuf_libtool_config="${CONFIG_SHELL-/bin/sh} ./libtool --config" ++ pixbuf_libtool_config="${CONFIG_SHELL-/bin/sh} $host_alias-libtool --config" + pixbuf_deplibs_check=`$pixbuf_libtool_config | \ + grep '^[[a-z_]]*check[[a-z_]]*_method=[['\''"]]' | \ + sed 's/.*[['\''"]]\(.*\)[['\''"]]$/\1/'` +@@ -1893,7 +1893,7 @@ + # We are using gmodule-no-export now, but I'm leaving the stripping + # code in place for now, since pango and atk still require gmodule. + export SED +-export_dynamic=`(./libtool --config; echo eval echo \\$export_dynamic_flag_spec) | sh` ++export_dynamic=`($host_alias-libtool --config; echo eval echo \\$export_dynamic_flag_spec) | sh` + if test -n "$export_dynamic"; then + GDK_PIXBUF_DEP_LIBS=`echo $GDK_PIXBUF_DEP_LIBS | sed -e "s/$export_dynamic//"` + GDK_PIXBUF_XLIB_DEP_LIBS=`echo $GDK_PIXBUF_XLIB_DEP_LIBS | sed -e "s/$export_dynamic//"` diff --git a/recipes/gtk+/gtk+-2.16.6/no-demos.patch b/recipes/gtk+/gtk+-2.16.6/no-demos.patch new file mode 100644 index 0000000000..0fc4c48d1a --- /dev/null +++ b/recipes/gtk+/gtk+-2.16.6/no-demos.patch @@ -0,0 +1,10 @@ +--- gtk+-2.10.1/Makefile.am.orig 2006-08-08 12:37:30.000000000 +0100 ++++ gtk+-2.10.1/Makefile.am 2006-08-08 12:37:48.000000000 +0100 +@@ -1,6 +1,6 @@ + ## Makefile.am for GTK+ + +-SRC_SUBDIRS = gdk-pixbuf gdk gtk modules demos tests perf contrib ++SRC_SUBDIRS = gdk-pixbuf gdk gtk modules tests perf contrib + SUBDIRS = po po-properties $(SRC_SUBDIRS) docs m4macros + + # require automake 1.4 diff --git a/recipes/gtk+/gtk+-2.16.6/run-iconcache.patch b/recipes/gtk+/gtk+-2.16.6/run-iconcache.patch new file mode 100644 index 0000000000..ac15e9ab24 --- /dev/null +++ b/recipes/gtk+/gtk+-2.16.6/run-iconcache.patch @@ -0,0 +1,19 @@ +--- /tmp/Makefile.am 2007-01-08 17:44:47.000000000 +0100 ++++ gtk+-2.10.7/gtk/Makefile.am 2007-01-08 17:45:17.025251000 +0100 +@@ -1128,11 +1128,11 @@ + ./gtk-update-icon-cache + endif + +-gtkbuiltincache.h: @REBUILD@ stamp-icons +- $(MAKE) $(AM_MAKEFLAGS) gtk-update-icon-cache$(EXEEXT) +- $(gtk_update_icon_cache_program) --force --ignore-theme-index \ +- --source builtin_icons stock-icons > gtkbuiltincache.h.tmp && \ +- mv gtkbuiltincache.h.tmp gtkbuiltincache.h ++#gtkbuiltincache.h: @REBUILD@ stamp-icons ++# $(MAKE) $(AM_MAKEFLAGS) gtk-update-icon-cache$(EXEEXT) ++# $(gtk_update_icon_cache_program) --force --ignore-theme-index \ ++# --source builtin_icons stock-icons > gtkbuiltincache.h.tmp && \ ++# mv gtkbuiltincache.h.tmp gtkbuiltincache.h + + EXTRA_DIST += \ + $(STOCK_ICONS) \ diff --git a/recipes/gtk+/gtk+-2.16.6/toggle-font.diff b/recipes/gtk+/gtk+-2.16.6/toggle-font.diff new file mode 100644 index 0000000000..59ad150b2f --- /dev/null +++ b/recipes/gtk+/gtk+-2.16.6/toggle-font.diff @@ -0,0 +1,100 @@ +Index: gtk/gtkcellrenderertoggle.c +=================================================================== +--- gtk/gtkcellrenderertoggle.c (revision 18523) ++++ gtk/gtkcellrenderertoggle.c (working copy) +@@ -71,6 +71,8 @@ + PROP_INDICATOR_SIZE + }; + ++/* This is a hard-coded default which promptly gets overridden by a size ++ calculated from the font size. */ + #define TOGGLE_WIDTH 13 + + static guint toggle_cell_signals[LAST_SIGNAL] = { 0 }; +@@ -80,8 +82,9 @@ + typedef struct _GtkCellRendererTogglePrivate GtkCellRendererTogglePrivate; + struct _GtkCellRendererTogglePrivate + { +- gint indicator_size; +- ++ gint indicator_size; /* This is the real size */ ++ gint override_size; /* This is the size set from the indicator-size property */ ++ GtkWidget *cached_widget; + guint inconsistent : 1; + }; + +@@ -104,6 +107,7 @@ + GTK_CELL_RENDERER (celltoggle)->ypad = 2; + + priv->indicator_size = TOGGLE_WIDTH; ++ priv->override_size = 0; + priv->inconsistent = FALSE; + } + +@@ -210,7 +214,7 @@ + g_value_set_boolean (value, celltoggle->radio); + break; + case PROP_INDICATOR_SIZE: +- g_value_set_int (value, priv->indicator_size); ++ g_value_set_int (value, priv->override_size ? priv->override_size : priv->indicator_size); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); +@@ -245,7 +249,7 @@ + celltoggle->radio = g_value_get_boolean (value); + break; + case PROP_INDICATOR_SIZE: +- priv->indicator_size = g_value_get_int (value); ++ priv->override_size = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); +@@ -273,6 +277,27 @@ + } + + static void ++on_widget_style_set (GtkWidget *widget, GtkStyle *previous, gpointer user_data) ++{ ++ GtkCellRendererTogglePrivate *priv = user_data; ++ PangoContext *context; ++ PangoFontMetrics *metrics; ++ int height; ++ ++ context = gtk_widget_get_pango_context (widget); ++ metrics = pango_context_get_metrics (context, ++ widget->style->font_desc, ++ pango_context_get_language (context)); ++ ++ height = pango_font_metrics_get_ascent (metrics) + ++ pango_font_metrics_get_descent (metrics); ++ ++ pango_font_metrics_unref (metrics); ++ ++ priv->indicator_size = PANGO_PIXELS (height * 0.85); ++} ++ ++static void + gtk_cell_renderer_toggle_get_size (GtkCellRenderer *cell, + GtkWidget *widget, + GdkRectangle *cell_area, +@@ -287,6 +312,20 @@ + + priv = GTK_CELL_RENDERER_TOGGLE_GET_PRIVATE (cell); + ++ if (priv->override_size) { ++ priv->indicator_size = priv->override_size; ++ } else if (priv->cached_widget != widget) { ++ if (priv->cached_widget) { ++ g_object_remove_weak_pointer (widget, &priv->cached_widget); ++ g_signal_handlers_disconnect_by_func (priv->cached_widget, on_widget_style_set, priv); ++ } ++ priv->cached_widget = widget; ++ g_object_add_weak_pointer (widget, &priv->cached_widget); ++ g_signal_connect (widget, "style-set", on_widget_style_set, priv); ++ ++ on_widget_style_set (widget, NULL, priv); ++ } ++ + calc_width = (gint) cell->xpad * 2 + priv->indicator_size; + calc_height = (gint) cell->ypad * 2 + priv->indicator_size; + diff --git a/recipes/gtk+/gtk+_2.16.6.bb b/recipes/gtk+/gtk+_2.16.6.bb new file mode 100644 index 0000000000..43df738c30 --- /dev/null +++ b/recipes/gtk+/gtk+_2.16.6.bb @@ -0,0 +1,65 @@ +require gtk+.inc + +DEPENDS += "cairo jasper" + +# disabled per default - this uses as little patches as possible +DEFAULT_PREFERENCE = "-1" + +SRC_URI = "http://download.gnome.org/sources/gtk+/2.16/gtk+-${PV}.tar.bz2 \ + file://xsettings.patch;patch=1 \ + file://run-iconcache.patch;patch=1 \ + file://hardcoded_libtool.patch;patch=1 \ + file://no-demos.patch;patch=1 \ + file://toggle-font.diff;patch=1;pnum=0 \ + " + +EXTRA_OECONF = "--with-libtiff --disable-xkb --disable-glibtest --enable-display-migration gio_can_sniff=yes" + +LIBV = "2.10.0" + +PACKAGES_DYNAMIC = "gtk-module-* gdk-pixbuf-loader-* gtk-immodule-* gtk-printbackend-*" + +python populate_packages_prepend () { + import os.path + + prologue = bb.data.getVar("postinst_prologue", d, 1) + + gtk_libdir = bb.data.expand('${libdir}/gtk-2.0/${LIBV}', d) + loaders_root = os.path.join(gtk_libdir, 'loaders') + immodules_root = os.path.join(gtk_libdir, 'immodules') + printmodules_root = os.path.join(gtk_libdir, 'printbackends'); + modules_root = bb.data.expand('${libdir}/gtk-2.0/modules/',d) + + do_split_packages(d, loaders_root, '^libpixbufloader-(.*)\.so$', 'gdk-pixbuf-loader-%s', 'GDK pixbuf loader for %s', prologue + 'gdk-pixbuf-query-loaders > /etc/gtk-2.0/gdk-pixbuf.loaders', extra_depends='') + do_split_packages(d, immodules_root, '^im-(.*)\.so$', 'gtk-immodule-%s', 'GTK input module for %s', prologue + 'gtk-query-immodules-2.0 > /etc/gtk-2.0/gtk.immodules', extra_depends='') + do_split_packages(d, printmodules_root, '^libprintbackend-(.*)\.so$', 'gtk-printbackend-%s', 'GTK printbackend module for %s', extra_depends='') + do_split_packages(d, modules_root, '^lib(.*)\.so$', 'gtk-module-%s', 'GTK module for %s', extra_depends='') + + if (bb.data.getVar('DEBIAN_NAMES', d, 1)): + bb.data.setVar('PKG_${PN}', 'libgtk-2.0', d) +} + +# gail is part of gtk+ since gtk+-2.13.0 (targetting >=GNOME 2.23): +PROVIDES = "virtual/gail" +RPROVIDES_${PN} = "libgailutil18" +RCONFLICTS_${PN} = "libgailutil18" +RREPLACES_${PN} = "libgailutil18" +RPROVIDES_${PN}-dev = "libgailutil-dev" +RCONFLICTS_${PN}-dev = "libgailutil-dev" +RREPLACES_${PN}-dev = "libgailutil-dev" +RPROVIDES_${PN}-doc = "libgailutil-doc" +RCONFLICTS_${PN}-doc = "libgailutil-doc" +RREPLACES_${PN}-doc = "libgailutil-doc" +RPROVIDES_${PN}-dbg = "libgailutil-dbg" +RCONFLICTS_${PN}-dbg = "libgailutil-dbg" +RREPLACES_${PN}-dbg = "libgailutil-dbg" +# FIXME: replace locales as well + +do_stage_append() { + + # this tool is required by gnome-keyring 2.26.0 to get built + # it is written in Python and use only Python xml + install -d ${STAGING_BINDIR_NATIVE} + install -m 0755 ${S}/gtk/gtk-builder-convert ${STAGING_BINDIR_NATIVE} + +} -- cgit v1.2.3 From bd4726dac9dd258ad787bc2f4f1c17fd35b6d1bd Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 12 Sep 2009 14:27:43 +0200 Subject: angstrom: prefer gtk+ 2.16.6 --- conf/distro/include/angstrom-2008-preferred-versions.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/distro/include/angstrom-2008-preferred-versions.inc b/conf/distro/include/angstrom-2008-preferred-versions.inc index 32cfbfb403..0c0c83117e 100644 --- a/conf/distro/include/angstrom-2008-preferred-versions.inc +++ b/conf/distro/include/angstrom-2008-preferred-versions.inc @@ -11,7 +11,7 @@ PREFERRED_VERSION_glib-2.0-native = "2.18.0" PREFERRED_VERSION_glibmm = "2.18.0" PREFERRED_VERSION_glproto = "1.4.9" PREFERRED_VERSION_gst-pulse = "0.9.7" -PREFERRED_VERSION_gtk+ = "2.16.4" +PREFERRED_VERSION_gtk+ = "2.16.6" PREFERRED_VERSION_gtkmm = "2.14.1" PREFERRED_VERSION_hal = "0.5.13" PREFERRED_VERSION_libgemwidget = "1.0" -- cgit v1.2.3 From 18158e33775356f5d166908d253159b05125a2fb Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 12 Sep 2009 15:55:45 +0200 Subject: glibc-package bbclass: add hack to avoid "kernel too old" error when generating locales in angstrom The proper fix would be to patch linux-libc-headers with 0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch and all arm kernels as well. Since that's quite an undertaking angstrom needs to short term hack like this commit to keep things building while the proper fix is being worked on. --- recipes/glibc/glibc-package.bbclass | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/recipes/glibc/glibc-package.bbclass b/recipes/glibc/glibc-package.bbclass index 69b569e346..4d7f6fdff9 100644 --- a/recipes/glibc/glibc-package.bbclass +++ b/recipes/glibc/glibc-package.bbclass @@ -265,7 +265,12 @@ python package_do_split_gconvs () { elif target_arch == "powerpc": target_arch = "ppc" - kernel_ver = bb.data.getVar("OLDEST_KERNEL", d, 1) + # This is a hack till linux-libc-headers gets patched for the missing arm syscalls and all arm device kernels as well + if bb.data.getVar("DISTRO_NAME", d, 1) == "Angstrom": + kernel_ver = "2.6.24" + else: + kernel_ver = bb.data.getVar("OLDEST_KERNEL", d, 1) + if kernel_ver is None: qemu = "qemu-%s -s 1048576" % target_arch else: -- cgit v1.2.3 From eabc33a1f14a92015dac4508e57a40d26cd385e6 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 12 Sep 2009 16:00:03 +0200 Subject: clutter.inc: rework armv7a machines a bit and add omap3517-evm to compatible machines --- recipes/clutter/clutter.inc | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/recipes/clutter/clutter.inc b/recipes/clutter/clutter.inc index 4e2457946a..4e36669d48 100644 --- a/recipes/clutter/clutter.inc +++ b/recipes/clutter/clutter.inc @@ -2,7 +2,7 @@ DESCRIPTION = "Clutter graphics library" HOMEPAGE = "http://www.clutter-project.org/" LICENSE = "LGPL" -COMPATIBLE_MACHINE = "(zylonite|mx31litekit|omap-3430ldp|omap-3430sdp|mx31ads|qemuarm|qemux86|ipodtouch|beagleboard|overo|omap3evm)" +COMPATIBLE_MACHINE = "(zylonite|mx31litekit|omap-3430ldp|omap-3430sdp|mx31ads|qemuarm|qemux86|ipodtouch|omap3517-evm|beagleboard|overo|omap3evm)" STDDEPENDS = "virtual/libx11 gtk-doc-native pango glib-2.0 libxfixes gtk+" BASE_CONF = "--disable-gtk-doc ${@get_clutter_fpu_setting(bb, d)}" @@ -20,6 +20,10 @@ EXTRA_OECONF_mx31litekit = "${BASE_CONF} --with-flavour=eglnative" PACKAGE_ARCH_mx31litekit = "${MACHINE_ARCH}" LDFLAGS_append_mx31litekit = " -lpvrNULLWSEGL -lstdc++ " +DEPENDS_armv7a = "${STDDEPENDS} libgles-omap3 tslib" +EXTRA_OECONF_armv7a = "${BASE_CONF} --with-flavour=eglx --with-gles=2.0" +PACKAGE_ARCH_armv7a = "${MACHINE_ARCH}" + DEPENDS_omap-3430ldp = "${STDDEPENDS} libgles-omap3 tslib" EXTRA_OECONF_omap-3430ldp = "${BASE_CONF} --with-flavour=eglx" PACKAGE_ARCH_omap-3430ldp = "${MACHINE_ARCH}" @@ -28,18 +32,6 @@ DEPENDS_omap-3430sdp = "${STDDEPENDS} libgles-omap3 tslib" EXTRA_OECONF_omap-3430sdp = "${BASE_CONF} --with-flavour=eglx" PACKAGE_ARCH_omap-3430sdp = "${MACHINE_ARCH}" -DEPENDS_beagleboard = "${STDDEPENDS} libgles-omap3 tslib" -EXTRA_OECONF_beagleboard = "${BASE_CONF} --with-flavour=eglx --with-gles=2.0" -PACKAGE_ARCH_beagleboard = "${MACHINE_ARCH}" - -DEPENDS_omap3evm = "${STDDEPENDS} libgles-omap3 tslib" -EXTRA_OECONF_omap3evm = "${BASE_CONF} --with-flavour=eglx --with-gles=2.0" -PACKAGE_ARCH_omap3evm = "${MACHINE_ARCH}" - -DEPENDS_overo = "${STDDEPENDS} libgles-omap3 tslib" -EXTRA_OECONF_overo = "${BASE_CONF} --with-flavour=eglx --with-gles=2.0" -PACKAGE_ARCH_overo = "${MACHINE_ARCH}" - DEPENDS_mx31ads = "${STDDEPENDS} libgles-mx31 tslib" EXTRA_OECONF_mx31ads = "${BASE_CONF} --with-flavour=eglnative" PACKAGE_ARCH_mx31ads = "${MACHINE_ARCH}" -- cgit v1.2.3 From ca6953db99a4cee228c1daf294913c5687a4d675 Mon Sep 17 00:00:00 2001 From: Michael 'Mickey' Lauer Date: Sat, 12 Sep 2009 17:19:59 +0200 Subject: libgee: move to git version while it's so much under development and depending on vala-native --- conf/distro/include/sane-srcrevs.inc | 1 + recipes/libgee/files/no-tests.patch | 12 ------------ recipes/libgee/libgee_0.3.0.bb | 11 ----------- recipes/libgee/libgee_git.bb | 16 ++++++++++++++++ 4 files changed, 17 insertions(+), 23 deletions(-) delete mode 100644 recipes/libgee/files/no-tests.patch delete mode 100644 recipes/libgee/libgee_0.3.0.bb create mode 100644 recipes/libgee/libgee_git.bb diff --git a/conf/distro/include/sane-srcrevs.inc b/conf/distro/include/sane-srcrevs.inc index b88ac9bc8c..e3400a213b 100644 --- a/conf/distro/include/sane-srcrevs.inc +++ b/conf/distro/include/sane-srcrevs.inc @@ -86,6 +86,7 @@ SRCREV_pn-libexalt-dbus ?= "76" SRCREV_pn-libfakekey ?= "1455" SRCREV_pn-libgdbus ?= "aeab6e3c0185b271ca343b439470491b99cc587f" SRCREV_pn-libgsmd ?= "4505" +SRCREV_pn-libgee ?= "ea130c0837eefe404b53240f8c2ed642ae98a677" SRCREV_pn-libiac ?= "1590" SRCREV_pn-libjana = "749" SRCREV_pn-libmokogsmd2 ?= "4334" diff --git a/recipes/libgee/files/no-tests.patch b/recipes/libgee/files/no-tests.patch deleted file mode 100644 index d2d20b2c4e..0000000000 --- a/recipes/libgee/files/no-tests.patch +++ /dev/null @@ -1,12 +0,0 @@ -Index: libgee-0.1.2/Makefile.am -=================================================================== ---- libgee-0.1.2.orig/Makefile.am -+++ libgee-0.1.2/Makefile.am -@@ -4,7 +4,6 @@ NULL = - - SUBDIRS = \ - gee \ -- tests \ - $(NULL) - - pkgconfigdir = $(libdir)/pkgconfig diff --git a/recipes/libgee/libgee_0.3.0.bb b/recipes/libgee/libgee_0.3.0.bb deleted file mode 100644 index 00ef42d2f4..0000000000 --- a/recipes/libgee/libgee_0.3.0.bb +++ /dev/null @@ -1,11 +0,0 @@ -DESCRIPTION = "libgee is a collection library providing GObject-based interfaces \ -and classes for commonly used data structures." -HOMEPAGE = "http://live.gnome.org/Libgee" -SECTION = "libs" -DEPENDS = "glib-2.0" -LICENSE = "LGPL" - -SRC_URI = "ftp://ftp.gnome.org/pub/GNOME/sources/libgee/0.3/libgee-${PV}.tar.bz2 \ - file://no-tests.patch;patch=1" - -inherit autotools_stage pkgconfig vala diff --git a/recipes/libgee/libgee_git.bb b/recipes/libgee/libgee_git.bb new file mode 100644 index 0000000000..74e0eca488 --- /dev/null +++ b/recipes/libgee/libgee_git.bb @@ -0,0 +1,16 @@ +DESCRIPTION = "libgee is a collection library providing GObject-based interfaces \ +and classes for commonly used data structures." +HOMEPAGE = "http://live.gnome.org/Libgee" +SECTION = "libs" +DEPENDS = "glib-2.0" +LICENSE = "LGPL" +PV = "0.3.0+gitr${SRCREV}" + +SRC_URI = "\ + git://git.gnome.org/libgee;protocol=git;branch=master \ +" +S = "${WORKDIR}/git" + +inherit autotools_stage pkgconfig vala + +FILES_${PN}-dev += "${datadir}/gir-1.0" -- cgit v1.2.3 From 90a1a0ca362f1e9acb8e687e03b488b53f73e085 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sat, 12 Sep 2009 16:01:50 +0200 Subject: device_table-ezx: Add header Signed-off-by: Antonio Ospite --- files/device_table-ezx.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/files/device_table-ezx.txt b/files/device_table-ezx.txt index ad382052e0..b2bfa10659 100644 --- a/files/device_table-ezx.txt +++ b/files/device_table-ezx.txt @@ -1,2 +1,12 @@ +# +#/dev/mem c 640 0 0 1 1 0 0 - +# +#type can be one of: +# f A regular file +# d Directory +# c Character special device file +# b Block special device file +# p Fifo (named pipe) + /dev/mux c 660 0 5 250 0 0 1 8 /dev/input/uinput c 660 0 0 10 223 - - - -- cgit v1.2.3 From 09d4daf8afefdf0db2a5eb9c306bfce2586f78a6 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sat, 12 Sep 2009 16:01:51 +0200 Subject: device_table-ezx: Static mux nodes from mux1 to mux8. Userspace is not supposed to open mux0 anymore; now that kernel mapping has been removed, each muxX corresponds to dlci X (with X in [1,16]). Signed-off-by: Antonio Ospite --- files/device_table-ezx.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/device_table-ezx.txt b/files/device_table-ezx.txt index b2bfa10659..e362617664 100644 --- a/files/device_table-ezx.txt +++ b/files/device_table-ezx.txt @@ -8,5 +8,5 @@ # b Block special device file # p Fifo (named pipe) -/dev/mux c 660 0 5 250 0 0 1 8 +/dev/mux c 660 0 5 250 0 1 1 8 /dev/input/uinput c 660 0 0 10 223 - - - -- cgit v1.2.3 From 4e8143441f59cde0a321c2839cd9d19735639b19 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sat, 12 Sep 2009 16:01:52 +0200 Subject: device_table-ezx: Add static ttyIPC device node This device node is used by ts0710_mux_usb driver to expose the muxed communication with the BP and configure the line discipiline Signed-off-by: Antonio Ospite --- files/device_table-ezx.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/files/device_table-ezx.txt b/files/device_table-ezx.txt index e362617664..e2416dfe9c 100644 --- a/files/device_table-ezx.txt +++ b/files/device_table-ezx.txt @@ -9,4 +9,5 @@ # p Fifo (named pipe) /dev/mux c 660 0 5 250 0 1 1 8 +/dev/ttyIPC c 660 0 5 251 0 - - - /dev/input/uinput c 660 0 0 10 223 - - - -- cgit v1.2.3 From d34d1145f5c7295413b6ee2a4b99ba3f6b87b23f Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sat, 12 Sep 2009 16:01:53 +0200 Subject: device_table-ezx: Add static video device node. Useful if we compile the video driver statically in the kernel Signed-off-by: Antonio Ospite --- files/device_table-ezx.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/files/device_table-ezx.txt b/files/device_table-ezx.txt index e2416dfe9c..f477a67a93 100644 --- a/files/device_table-ezx.txt +++ b/files/device_table-ezx.txt @@ -11,3 +11,4 @@ /dev/mux c 660 0 5 250 0 1 1 8 /dev/ttyIPC c 660 0 5 251 0 - - - /dev/input/uinput c 660 0 0 10 223 - - - +/dev/video c 660 0 44 81 0 - - - -- cgit v1.2.3 From 0c4cf4dcdebc57ec1a0f94f65f2a66bb31b17389 Mon Sep 17 00:00:00 2001 From: Michael 'Mickey' Lauer Date: Sat, 12 Sep 2009 17:36:50 +0200 Subject: fso-alsa-data: create dummy file so that git doesn't remove the directory --- recipes/freesmartphone/fso-alsa-data/default/dummy | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 recipes/freesmartphone/fso-alsa-data/default/dummy diff --git a/recipes/freesmartphone/fso-alsa-data/default/dummy b/recipes/freesmartphone/fso-alsa-data/default/dummy new file mode 100644 index 0000000000..e69de29bb2 -- cgit v1.2.3 From 56ca890cdd6faff2afa66931fc31376d2d9afa87 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Sat, 12 Sep 2009 13:05:20 -0700 Subject: gcc-configure-common.inc: Fiddle with NATIVE_SYSTEM_HEADER_DIR only form cross gcc build * target gcc does not like the NATIVE_SYSTEM_HEADER_DIR being tweaked. for now conditionalize it so it gets included only for cross builds it could be that target gcc for micro wont work because it needs headers in /usr/include and the actual headers are in /include Signed-off-by: Khem Raj --- recipes/gcc/gcc-configure-common.inc | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/recipes/gcc/gcc-configure-common.inc b/recipes/gcc/gcc-configure-common.inc index fb792a8a88..a0a7dfab74 100644 --- a/recipes/gcc/gcc-configure-common.inc +++ b/recipes/gcc/gcc-configure-common.inc @@ -80,16 +80,20 @@ do_configure () { sed -i 's/^LDFLAGS = $/LDFLAGS = @LDFLAGS@/' ${S}/Makefile.tpl (cd ${S} && gnu-configize) || die "failure running gnu-configize" - # splice our idea of where the headers live into gcc's world - echo "NATIVE_SYSTEM_HEADER_DIR = ${layout_includedir}" > ${T}/t-oe - sed 's%^tmake_file=.*$%& ${T}/t-oe%' < ${S}/gcc/Makefile.in >${S}/gcc/Makefile.in.new - mv ${S}/gcc/Makefile.in.new ${S}/gcc/Makefile.in - cat ${S}/gcc/defaults.h | grep -v "\#endif.*GCC_DEFAULTS_H" > ${S}/gcc/defaults.h.new - echo "#ifndef STANDARD_INCLUDE_DIR" >> ${S}/gcc/defaults.h.new - echo "#define STANDARD_INCLUDE_DIR \"${layout_includedir}\"" >> ${S}/gcc/defaults.h.new - echo "#endif" >> ${S}/gcc/defaults.h.new - echo "#endif /* ! GCC_DEFAULTS_H */" >> ${S}/gcc/defaults.h.new - mv ${S}/gcc/defaults.h.new ${S}/gcc/defaults.h + + if [ "${HOST_SYS}" != "${TARGET_SYS}" ]; then + # splice our idea of where the headers live into gcc's world + echo "NATIVE_SYSTEM_HEADER_DIR = ${layout_includedir}" > ${T}/t-oe + sed 's%^tmake_file=.*$%& ${T}/t-oe%' < ${S}/gcc/Makefile.in >${S}/gcc/Makefile.in.new + mv ${S}/gcc/Makefile.in.new ${S}/gcc/Makefile.in + cat ${S}/gcc/defaults.h | grep -v "\#endif.*GCC_DEFAULTS_H" > ${S}/gcc/defaults.h.new + echo "#ifndef STANDARD_INCLUDE_DIR" >> ${S}/gcc/defaults.h.new + echo "#define STANDARD_INCLUDE_DIR \"${layout_includedir}\"" >> ${S}/gcc/defaults.h.new + echo "#endif" >> ${S}/gcc/defaults.h.new + echo "#endif /* ! GCC_DEFAULTS_H */" >> ${S}/gcc/defaults.h.new + mv ${S}/gcc/defaults.h.new ${S}/gcc/defaults.h + fi + oe_runconf # make sure that no @LDFLAG@ is left in the generated Makefile -- cgit v1.2.3 From 462d0b6fb1ff920f0be3ffb72e5d58ee70d166fe Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Sat, 12 Sep 2009 16:20:21 -0700 Subject: uclibc-initial: Create ${UCLIBC_STAGE_PREFIX}/lib Signed-off-by: Khem Raj --- recipes/uclibc/uclibc-initial_0.9.28.bb | 1 + recipes/uclibc/uclibc-initial_0.9.29.bb | 1 + recipes/uclibc/uclibc-initial_0.9.30.1.bb | 1 + recipes/uclibc/uclibc-initial_0.9.30.bb | 1 + recipes/uclibc/uclibc-initial_git.bb | 1 + recipes/uclibc/uclibc-initial_nptl.bb | 2 +- 6 files changed, 6 insertions(+), 1 deletion(-) diff --git a/recipes/uclibc/uclibc-initial_0.9.28.bb b/recipes/uclibc/uclibc-initial_0.9.28.bb index 6e82dcd50a..e0b93f9418 100644 --- a/recipes/uclibc/uclibc-initial_0.9.28.bb +++ b/recipes/uclibc/uclibc-initial_0.9.28.bb @@ -16,6 +16,7 @@ do_stage() { # This conflicts with the c++ version of this header rm -f ${UCLIBC_STAGE_PREFIX}/include/bits/atomicity.h + install -d ${UCLIBC_STAGE_PREFIX}/lib install -m 644 libc/sysdeps/linux/${TARGET_ARCH}/crt[1in].o ${UCLIBC_STAGE_PREFIX}/lib install -m 644 libc/libc.so ${UCLIBC_STAGE_PREFIX}/lib diff --git a/recipes/uclibc/uclibc-initial_0.9.29.bb b/recipes/uclibc/uclibc-initial_0.9.29.bb index 964f319783..f7abdec20f 100644 --- a/recipes/uclibc/uclibc-initial_0.9.29.bb +++ b/recipes/uclibc/uclibc-initial_0.9.29.bb @@ -16,6 +16,7 @@ do_stage() { # This conflicts with the c++ version of this header rm -f ${UCLIBC_STAGE_PREFIX}/include/bits/atomicity.h + install -d ${UCLIBC_STAGE_PREFIX}/lib install -m 644 lib/crt[1in].o ${UCLIBC_STAGE_PREFIX}/lib install -m 644 lib/libc.so ${UCLIBC_STAGE_PREFIX}/lib diff --git a/recipes/uclibc/uclibc-initial_0.9.30.1.bb b/recipes/uclibc/uclibc-initial_0.9.30.1.bb index 5c803b99c6..46c0f66697 100644 --- a/recipes/uclibc/uclibc-initial_0.9.30.1.bb +++ b/recipes/uclibc/uclibc-initial_0.9.30.1.bb @@ -14,6 +14,7 @@ do_stage() { # This conflicts with the c++ version of this header rm -f ${UCLIBC_STAGE_PREFIX}/include/bits/atomicity.h + install -d ${UCLIBC_STAGE_PREFIX}/lib install -m 644 lib/crt[1in].o ${UCLIBC_STAGE_PREFIX}/lib install -m 644 lib/libc.so ${UCLIBC_STAGE_PREFIX}/lib } diff --git a/recipes/uclibc/uclibc-initial_0.9.30.bb b/recipes/uclibc/uclibc-initial_0.9.30.bb index 7cd953605b..9fcb247f61 100644 --- a/recipes/uclibc/uclibc-initial_0.9.30.bb +++ b/recipes/uclibc/uclibc-initial_0.9.30.bb @@ -15,6 +15,7 @@ do_stage() { # This conflicts with the c++ version of this header rm -f ${UCLIBC_STAGE_PREFIX}/include/bits/atomicity.h + install -d ${UCLIBC_STAGE_PREFIX}/lib install -m 644 lib/crt[1in].o ${UCLIBC_STAGE_PREFIX}/lib install -m 644 lib/libc.so ${UCLIBC_STAGE_PREFIX}/lib } diff --git a/recipes/uclibc/uclibc-initial_git.bb b/recipes/uclibc/uclibc-initial_git.bb index 6c91762723..a0077b167a 100644 --- a/recipes/uclibc/uclibc-initial_git.bb +++ b/recipes/uclibc/uclibc-initial_git.bb @@ -14,6 +14,7 @@ do_stage() { # This conflicts with the c++ version of this header rm -f ${UCLIBC_STAGE_PREFIX}/include/bits/atomicity.h + install -d ${UCLIBC_STAGE_PREFIX}/lib install -m 644 lib/crt[1in].o ${UCLIBC_STAGE_PREFIX}/lib install -m 644 lib/libc.so ${UCLIBC_STAGE_PREFIX}/lib } diff --git a/recipes/uclibc/uclibc-initial_nptl.bb b/recipes/uclibc/uclibc-initial_nptl.bb index cca3c1e688..dc376f5bce 100644 --- a/recipes/uclibc/uclibc-initial_nptl.bb +++ b/recipes/uclibc/uclibc-initial_nptl.bb @@ -16,7 +16,7 @@ do_stage() { # This conflicts with the c++ version of this header rm -f ${UCLIBC_STAGE_PREFIX}/include/bits/atomicity.h - + install -d ${UCLIBC_STAGE_PREFIX}/lib install -m 644 lib/crt[1in].o ${UCLIBC_STAGE_PREFIX}/lib install -m 644 lib/libc.so ${UCLIBC_STAGE_PREFIX}/lib -- cgit v1.2.3 From 8d8f4b1fdc2738ddbc170d6911093eac3301886e Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sun, 13 Sep 2009 10:43:53 +0200 Subject: libsoup-2.4: update to 2.27.91 --- conf/checksums.ini | 4 ++++ recipes/gnome/libsoup-2.4_2.27.4.bb | 19 ------------------- recipes/gnome/libsoup-2.4_2.27.91.bb | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+), 19 deletions(-) delete mode 100644 recipes/gnome/libsoup-2.4_2.27.4.bb create mode 100644 recipes/gnome/libsoup-2.4_2.27.91.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index c86d8abe41..9964dc783d 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -15130,6 +15130,10 @@ sha256=afcedda15bde2395dec31a82a243871a0540ea2e13e7a14d15846ad0c1f09a7b md5=c9b676621f1b89245ec5cec0c67198b7 sha256=4d67aa8d2d3c719b67bde58ca3b8a94aa1d172bc242672401d7f3d22685065b9 +[http://ftp.gnome.org/pub/GNOME/sources/libsoup/2.27/libsoup-2.27.91.tar.bz2] +md5=58e5518a483fbef0b72f142e63f43e9f +sha256=b39fd86e555cc530ec587db8860b084e95555e044c0cf8b213e636aff043e4f3 + [http://ftp.gnome.org/pub/GNOME/sources/libsoup-2.4/2.4/libsoup-2.4.1.tar.bz2] md5=d0fc91ccb9da401e9e40d2f4612bdac9 sha256=774094746748fb0c8985210de0994accdc7095c222fba42c5623e2137443b6cd diff --git a/recipes/gnome/libsoup-2.4_2.27.4.bb b/recipes/gnome/libsoup-2.4_2.27.4.bb deleted file mode 100644 index ae503065c0..0000000000 --- a/recipes/gnome/libsoup-2.4_2.27.4.bb +++ /dev/null @@ -1,19 +0,0 @@ -DESCRIPTION = "An HTTP library implementation in C" -SECTION = "x11/gnome/libs" -LICENSE = "GPL" -DEPENDS = "libproxy glib-2.0 gnutls libxml2 sqlite3" - -inherit gnome - -SRC_URI = "${GNOME_MIRROR}/libsoup/${@gnome_verdir("${PV}")}/libsoup-${PV}.tar.bz2" -S = "${WORKDIR}/libsoup-${PV}" - -do_stage() { - autotools_stage_all -} - -PACKAGES =+ "libsoup-gnome" -FILES_libsoup-gnome = "${libdir}/libsoup-gnome*.so.*" -FILES_${PN} = "${libdir}/libsoup-2*.so.*" -FILES_${PN}-dev = "${includedir}/ ${libdir}/" -FILES_${PN}-doc = "${datadir}/" diff --git a/recipes/gnome/libsoup-2.4_2.27.91.bb b/recipes/gnome/libsoup-2.4_2.27.91.bb new file mode 100644 index 0000000000..ae503065c0 --- /dev/null +++ b/recipes/gnome/libsoup-2.4_2.27.91.bb @@ -0,0 +1,19 @@ +DESCRIPTION = "An HTTP library implementation in C" +SECTION = "x11/gnome/libs" +LICENSE = "GPL" +DEPENDS = "libproxy glib-2.0 gnutls libxml2 sqlite3" + +inherit gnome + +SRC_URI = "${GNOME_MIRROR}/libsoup/${@gnome_verdir("${PV}")}/libsoup-${PV}.tar.bz2" +S = "${WORKDIR}/libsoup-${PV}" + +do_stage() { + autotools_stage_all +} + +PACKAGES =+ "libsoup-gnome" +FILES_libsoup-gnome = "${libdir}/libsoup-gnome*.so.*" +FILES_${PN} = "${libdir}/libsoup-2*.so.*" +FILES_${PN}-dev = "${includedir}/ ${libdir}/" +FILES_${PN}-doc = "${datadir}/" -- cgit v1.2.3 From 1cf11450bf8a5396cfda5ce758d12e167497a1c5 Mon Sep 17 00:00:00 2001 From: Brijesh Singh Date: Fri, 4 Sep 2009 23:42:09 -0500 Subject: lpm, sdma, cmem recipes: rename to match PV --- recipes/ti/ti-cmem-module_2.24.01.bb | 66 ++++++++++++++++++++++++++++++++++++ recipes/ti/ti-cmem-module_2.24.bb | 66 ------------------------------------ recipes/ti/ti-lpm-module_2.24.01.bb | 59 ++++++++++++++++++++++++++++++++ recipes/ti/ti-lpm-module_2.24.bb | 62 --------------------------------- recipes/ti/ti-sdma-module_2.24.01.bb | 54 +++++++++++++++++++++++++++++ recipes/ti/ti-sdma-module_2.24.bb | 54 ----------------------------- 6 files changed, 179 insertions(+), 182 deletions(-) create mode 100644 recipes/ti/ti-cmem-module_2.24.01.bb delete mode 100644 recipes/ti/ti-cmem-module_2.24.bb create mode 100644 recipes/ti/ti-lpm-module_2.24.01.bb delete mode 100644 recipes/ti/ti-lpm-module_2.24.bb create mode 100644 recipes/ti/ti-sdma-module_2.24.01.bb delete mode 100644 recipes/ti/ti-sdma-module_2.24.bb diff --git a/recipes/ti/ti-cmem-module_2.24.01.bb b/recipes/ti/ti-cmem-module_2.24.01.bb new file mode 100644 index 0000000000..7f5394647f --- /dev/null +++ b/recipes/ti/ti-cmem-module_2.24.01.bb @@ -0,0 +1,66 @@ +DESCRIPTION = "CMEM module for TI ARM/DSP processors" +inherit module + +# compile and run time dependencies +DEPENDS = "virtual/kernel perl-native" +RDEPENDS = "update-modules" + +SRC_URI = "http://install.source.dir.com/codec_engine_2_24_01.tar.gz \ + file://cmem-remove-show-pte-function.patch;patch=1 " + +# Set the source directory +S = "${WORKDIR}/codec_engine_2_24_01" + +#This is a kernel module, don't set PR directly +MACHINE_KERNEL_PR_append = "a" + +PV = "2241" + +do_compile() { + # TODO :: KERNEL_CC, etc need replacing with user CC + # TODO :: Need to understand why OBJDUMP is required for kernel module + # Unset these since LDFLAGS gets picked up and used incorrectly.... need + # investigation + + unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS + + cd ${S}/cetools/packages/ti/sdo/linuxutils/cmem + make \ + LINUXKERNEL_INSTALL_DIR="${STAGING_KERNEL_DIR}" \ + MVTOOL_PREFIX="${TARGET_PREFIX}" \ + UCTOOL_PREFIX="${TARGET_PREFIX}" \ + clean debug release +} + +do_install () { + install -d ${D}/lib/modules/${KERNEL_VERSION}/kernel/drivers/dsp + install -m 0755 ${S}/cetools/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.ko ${D}/lib/modules/${KERNEL_VERSION}/kernel/drivers/dsp + + cd ${S}/cetools/packages/ti/sdo/linuxutils/cmem/apps + make \ + LINUXKERNEL_INSTALL_DIR="${STAGING_KERNEL_DIR}" \ + MVTOOL_PREFIX="${TARGET_PREFIX}" \ + UCTOOL_PREFIX="${TARGET_PREFIX}" \ + EXEC_DIR="${D}${prefix}/ti/ti-cmem-apps" \ + install +} + +pkg_postinst () { + if [ -n "$D" ]; then + exit 1 + fi + depmod -a + update-modules || true +} + +pkg_postrm () { + update-modules || true +} + +INHIBIT_PACKAGE_STRIP = "1" +FILES_${PN} = "/lib/modules/${KERNEL_VERSION}/kernel/drivers/dsp/cmemk.ko" +PACKAGES += " ti-cmem-apps" +FILES_ti-cmem-apps = "${prefix}/ti/ti-cmem-apps/*" +INSANE_SKIP_ti-cmem-apps = True + + diff --git a/recipes/ti/ti-cmem-module_2.24.bb b/recipes/ti/ti-cmem-module_2.24.bb deleted file mode 100644 index 7f5394647f..0000000000 --- a/recipes/ti/ti-cmem-module_2.24.bb +++ /dev/null @@ -1,66 +0,0 @@ -DESCRIPTION = "CMEM module for TI ARM/DSP processors" -inherit module - -# compile and run time dependencies -DEPENDS = "virtual/kernel perl-native" -RDEPENDS = "update-modules" - -SRC_URI = "http://install.source.dir.com/codec_engine_2_24_01.tar.gz \ - file://cmem-remove-show-pte-function.patch;patch=1 " - -# Set the source directory -S = "${WORKDIR}/codec_engine_2_24_01" - -#This is a kernel module, don't set PR directly -MACHINE_KERNEL_PR_append = "a" - -PV = "2241" - -do_compile() { - # TODO :: KERNEL_CC, etc need replacing with user CC - # TODO :: Need to understand why OBJDUMP is required for kernel module - # Unset these since LDFLAGS gets picked up and used incorrectly.... need - # investigation - - unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS - - cd ${S}/cetools/packages/ti/sdo/linuxutils/cmem - make \ - LINUXKERNEL_INSTALL_DIR="${STAGING_KERNEL_DIR}" \ - MVTOOL_PREFIX="${TARGET_PREFIX}" \ - UCTOOL_PREFIX="${TARGET_PREFIX}" \ - clean debug release -} - -do_install () { - install -d ${D}/lib/modules/${KERNEL_VERSION}/kernel/drivers/dsp - install -m 0755 ${S}/cetools/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.ko ${D}/lib/modules/${KERNEL_VERSION}/kernel/drivers/dsp - - cd ${S}/cetools/packages/ti/sdo/linuxutils/cmem/apps - make \ - LINUXKERNEL_INSTALL_DIR="${STAGING_KERNEL_DIR}" \ - MVTOOL_PREFIX="${TARGET_PREFIX}" \ - UCTOOL_PREFIX="${TARGET_PREFIX}" \ - EXEC_DIR="${D}${prefix}/ti/ti-cmem-apps" \ - install -} - -pkg_postinst () { - if [ -n "$D" ]; then - exit 1 - fi - depmod -a - update-modules || true -} - -pkg_postrm () { - update-modules || true -} - -INHIBIT_PACKAGE_STRIP = "1" -FILES_${PN} = "/lib/modules/${KERNEL_VERSION}/kernel/drivers/dsp/cmemk.ko" -PACKAGES += " ti-cmem-apps" -FILES_ti-cmem-apps = "${prefix}/ti/ti-cmem-apps/*" -INSANE_SKIP_ti-cmem-apps = True - - diff --git a/recipes/ti/ti-lpm-module_2.24.01.bb b/recipes/ti/ti-lpm-module_2.24.01.bb new file mode 100644 index 0000000000..7f47a0d232 --- /dev/null +++ b/recipes/ti/ti-lpm-module_2.24.01.bb @@ -0,0 +1,59 @@ +DESCRIPTION = "LPM module for TI OMAP3 processors" + +require ti-paths.inc + +inherit module +# compile and run time dependencies +DEPENDS = " virtual/kernel perl-native ti-dsplink-module" + +#This is a kernel module, don't set PR directly +MACHINE_KERNEL_PR_append = "a" + +PV = "2241" + +SRC_URI = "http://install.source.dir.com/local_power_manager_1_24.tar.gz" + +# Set the source directory +S = "${WORKDIR}/local_power_manager_1_24" + +do_compile () { + # TODO :: KERNEL_CC, etc need replacing with user CC + # TODO :: Need to understand why OBJDUMP is required for kernel module + # Unset these since LDFLAGS gets picked up and used incorrectly.... need + # investigation + + unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS + + cd ${S}/packages/ti/bios/power/modules/${LPMDSPPOWERSOC}/lpm + make \ + DSPLINK_REPO="${DSPLINK}/.." \ + LINUXKERNEL_INSTALL_DIR="${STAGING_KERNEL_DIR}" \ + MVTOOL_PREFIX="${TARGET_PREFIX}" \ + clean default +} + +do_install () { + + # LPM/CMEM/SDMA drivers - kernel modules + install -d ${D}/lib/modules/${KERNEL_VERSION}/kernel/drivers/dsp + install -m 0755 ${S}/packages/ti/bios/power/modules/${LPMDSPPOWERSOC}/lpm/*.ko ${D}/lib/modules/${KERNEL_VERSION}/kernel/drivers/dsp +} + + +pkg_postinst () { + if [ -n "$D" ]; then + exit 1 + fi + depmod -a + update-modules || true +} + +pkg_postrm () { + update-modules || true +} + +INHIBIT_PACKAGE_STRIP = "1" + +FILES_${PN} = "/lib/modules/${KERNEL_VERSION}/kernel/drivers/dsp/*lpm*ko" +RDEPENDS += " ti-dsplink-module" + diff --git a/recipes/ti/ti-lpm-module_2.24.bb b/recipes/ti/ti-lpm-module_2.24.bb deleted file mode 100644 index 74cb7ca86a..0000000000 --- a/recipes/ti/ti-lpm-module_2.24.bb +++ /dev/null @@ -1,62 +0,0 @@ -DESCRIPTION = "LPM module for TI OMAP3 processors" - -require ti-paths.inc - -inherit module -# compile and run time dependencies -DEPENDS = " virtual/kernel perl-native ti-dsplink-module" - -#This is a kernel module, don't set PR directly -MACHINE_KERNEL_PR_append = "a" - -PV = "2241" - -# LPM seems to be missing from 2.24.01 -DEFAULT_PREFERENCE = "-1" - -SRC_URI = "http://install.source.dir.com/local_power_manager_1_24.tar.gz" - -# Set the source directory -S = "${WORKDIR}/local_power_manager_1_24" - -do_compile () { - # TODO :: KERNEL_CC, etc need replacing with user CC - # TODO :: Need to understand why OBJDUMP is required for kernel module - # Unset these since LDFLAGS gets picked up and used incorrectly.... need - # investigation - - unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS - - cd ${S}/packages/ti/bios/power/modules/${LPMDSPPOWERSOC}/lpm - make \ - DSPLINK_REPO="${DSPLINK}/.." \ - LINUXKERNEL_INSTALL_DIR="${STAGING_KERNEL_DIR}" \ - MVTOOL_PREFIX="${TARGET_PREFIX}" \ - clean default -} - -do_install () { - - # LPM/CMEM/SDMA drivers - kernel modules - install -d ${D}/lib/modules/${KERNEL_VERSION}/kernel/drivers/dsp - install -m 0755 ${S}/packages/ti/bios/power/modules/${LPMDSPPOWERSOC}/lpm/*.ko ${D}/lib/modules/${KERNEL_VERSION}/kernel/drivers/dsp -} - - -pkg_postinst () { - if [ -n "$D" ]; then - exit 1 - fi - depmod -a - update-modules || true -} - -pkg_postrm () { - update-modules || true -} - -INHIBIT_PACKAGE_STRIP = "1" - -FILES_${PN} = "/lib/modules/${KERNEL_VERSION}/kernel/drivers/dsp/*lpm*ko" -RDEPENDS += " ti-dsplink-module" - diff --git a/recipes/ti/ti-sdma-module_2.24.01.bb b/recipes/ti/ti-sdma-module_2.24.01.bb new file mode 100644 index 0000000000..2d9b3a8df7 --- /dev/null +++ b/recipes/ti/ti-sdma-module_2.24.01.bb @@ -0,0 +1,54 @@ +DESCRIPTION = "SDMA module for TI OMAP3 processors" + +inherit module +# compile and run time dependencies +DEPENDS = "virtual/kernel perl-native" + +#This is a kernel module, don't set PR directly +MACHINE_KERNEL_PR_append = "a" + +PV = "2241" + +SRC_URI = "http://install.source.dir.com/codec_engine_2_24_01.tar.gz " + +# Set the source directory +S = "${WORKDIR}/codec_engine_2_24_01" + +do_compile() { + # SDMA - Build the sdma module + # TODO :: KERNEL_CC, etc need replacing with user CC + # TODO :: Need to understand why OBJDUMP is required for kernel module + # Unset these since LDFLAGS gets picked up and used incorrectly.... need + # investigation + + unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS + + cd ${S}/cetools/packages/ti/sdo/linuxutils/sdma + make \ + LINUXKERNEL_INSTALL_DIR="${STAGING_KERNEL_DIR}" \ + MVTOOL_PREFIX="${TARGET_PREFIX}" \ + UCTOOL_PREFIX="${TARGET_PREFIX}" \ + clean debug release +} + +do_install () { + install -d ${D}/lib/modules/${KERNEL_VERSION}/kernel/drivers/dsp + install -m 0755 ${S}/cetools/packages/ti/sdo/linuxutils/sdma/src/module/sdmak.ko ${D}/lib/modules/${KERNEL_VERSION}/kernel/drivers/dsp +} + +pkg_postinst () { + if [ -n "$D" ]; then + exit 1 + fi + depmod -a + update-modules || true +} + +pkg_postrm () { + update-modules || true +} + +INHIBIT_PACKAGE_STRIP = "1" + +FILES_${PN} = "/lib/modules/${KERNEL_VERSION}/kernel/drivers/dsp/sdmak.ko" + diff --git a/recipes/ti/ti-sdma-module_2.24.bb b/recipes/ti/ti-sdma-module_2.24.bb deleted file mode 100644 index 2d9b3a8df7..0000000000 --- a/recipes/ti/ti-sdma-module_2.24.bb +++ /dev/null @@ -1,54 +0,0 @@ -DESCRIPTION = "SDMA module for TI OMAP3 processors" - -inherit module -# compile and run time dependencies -DEPENDS = "virtual/kernel perl-native" - -#This is a kernel module, don't set PR directly -MACHINE_KERNEL_PR_append = "a" - -PV = "2241" - -SRC_URI = "http://install.source.dir.com/codec_engine_2_24_01.tar.gz " - -# Set the source directory -S = "${WORKDIR}/codec_engine_2_24_01" - -do_compile() { - # SDMA - Build the sdma module - # TODO :: KERNEL_CC, etc need replacing with user CC - # TODO :: Need to understand why OBJDUMP is required for kernel module - # Unset these since LDFLAGS gets picked up and used incorrectly.... need - # investigation - - unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS - - cd ${S}/cetools/packages/ti/sdo/linuxutils/sdma - make \ - LINUXKERNEL_INSTALL_DIR="${STAGING_KERNEL_DIR}" \ - MVTOOL_PREFIX="${TARGET_PREFIX}" \ - UCTOOL_PREFIX="${TARGET_PREFIX}" \ - clean debug release -} - -do_install () { - install -d ${D}/lib/modules/${KERNEL_VERSION}/kernel/drivers/dsp - install -m 0755 ${S}/cetools/packages/ti/sdo/linuxutils/sdma/src/module/sdmak.ko ${D}/lib/modules/${KERNEL_VERSION}/kernel/drivers/dsp -} - -pkg_postinst () { - if [ -n "$D" ]; then - exit 1 - fi - depmod -a - update-modules || true -} - -pkg_postrm () { - update-modules || true -} - -INHIBIT_PACKAGE_STRIP = "1" - -FILES_${PN} = "/lib/modules/${KERNEL_VERSION}/kernel/drivers/dsp/sdmak.ko" - -- cgit v1.2.3 From 65a3216b1d40c6ced527adc13d09e1b7abdbec68 Mon Sep 17 00:00:00 2001 From: Brijesh Singh Date: Fri, 4 Sep 2009 23:45:10 -0500 Subject: dvsdk: update README to use ce 2.24.01 --- recipes/ti/README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/recipes/ti/README b/recipes/ti/README index 011bd0ae51..cf37c06844 100644 --- a/recipes/ti/README +++ b/recipes/ti/README @@ -2,7 +2,7 @@ Depending on platform you need to download one or more components from the exter DM355 ----- - - Code Engine 2.24 + - Code Engine 2.24.01 OMAP3530 ------ @@ -14,7 +14,7 @@ OMAP3530 URL's: ------ -* CE 2.24 (codec_engine_2_24.tar.gz) +* CE 2.24.01 (codec_engine_2_24.01.tar.gz) http://software-dl.ti.com/dsps/dsps_registered_sw/sdo_sb/targetcontent/CE/ce_2_24/index.html * DSP/BIOS 5.33.04 (bios_setuplinux_5_33_04.bin) -- cgit v1.2.3 From 5c635b365fd3f67c35a777624dc0ac26aedb27f6 Mon Sep 17 00:00:00 2001 From: Brijesh Singh Date: Sat, 5 Sep 2009 04:13:43 -0500 Subject: gstreamer-ti: bump SRCREV and apply patch from tracker 462 --- .../gstreamer-ti/codec_combo_directory_fix.patch | 52 -------- recipes/ti/gstreamer-ti/gst-buffsize.diff | 113 ---------------- .../ti/gstreamer-ti/gstreamer-ti-tracker-462.patch | 68 ++++++++++ .../ti/gstreamer-ti/gstreamer-ti-tracker-824.patch | 147 +++++++++++++++++++++ recipes/ti/gstreamer-ti_svn.bb | 5 +- 5 files changed, 218 insertions(+), 167 deletions(-) delete mode 100644 recipes/ti/gstreamer-ti/codec_combo_directory_fix.patch delete mode 100644 recipes/ti/gstreamer-ti/gst-buffsize.diff create mode 100644 recipes/ti/gstreamer-ti/gstreamer-ti-tracker-462.patch create mode 100644 recipes/ti/gstreamer-ti/gstreamer-ti-tracker-824.patch diff --git a/recipes/ti/gstreamer-ti/codec_combo_directory_fix.patch b/recipes/ti/gstreamer-ti/codec_combo_directory_fix.patch deleted file mode 100644 index 7c03641707..0000000000 --- a/recipes/ti/gstreamer-ti/codec_combo_directory_fix.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Vishnudas P - -Found the fix here. -http://wiki.davincidsp.com/index.php?title=Configuring_Codec_Engine_in_Arm_apps_with_createFromServer -In the section "Advanced: overwriting fields, creating multiple engines" - -Needed tor reverse the previous patch 263 and apply the attached patch. - -When you call createFromServer the path you give is relative to -package, not the filesystem one. For that you need to set -"engine.server" to the desired full filesystem path. -This is what the attached patch does. - --- - - -diff -Naur ticodecplugin.orig/src/gstticodecplugin_dm6446.cfg ticodecplugin/src/gstticodecplugin_dm6446.cfg ---- ticodecplugin.orig/src/gstticodecplugin_dm6446.cfg 2009-07-21 12:55:32.000000000 -0700 -+++ ticodecplugin/src/gstticodecplugin_dm6446.cfg 2009-07-21 12:55:26.000000000 -0700 -@@ -38,6 +38,8 @@ - "./encodeCombo.x64P", - "ti.sdo.servers.encode" - ); -+codecServer.server = "/usr/share/ti-codec-combos/cs.x64P"; -+ - - /* Load support for the 'Davinci Multimedia Application Interface' modules */ - var DMAI = xdc.loadPackage('ti.sdo.dmai'); -diff -Naur ticodecplugin.orig/src/gstticodecplugin_dm6467.cfg ticodecplugin/src/gstticodecplugin_dm6467.cfg ---- ticodecplugin.orig/src/gstticodecplugin_dm6467.cfg 2009-07-21 12:55:32.000000000 -0700 -+++ ticodecplugin/src/gstticodecplugin_dm6467.cfg 2009-07-21 12:55:26.000000000 -0700 -@@ -39,6 +39,8 @@ - "./encodeCombo.x64P", - "ti.sdo.servers.encode" - ); -+codecServer.server = "/usr/share/ti-codec-combos/cs.x64P"; -+ - - /* Load support for the 'Davinci Multimedia Application Interface' modules */ - var DMAI = xdc.loadPackage('ti.sdo.dmai'); -diff -Naur ticodecplugin.orig/src/gstticodecplugin_omap3530.cfg ticodecplugin/src/gstticodecplugin_omap3530.cfg ---- ticodecplugin.orig/src/gstticodecplugin_omap3530.cfg 2009-07-21 12:55:32.000000000 -0700 -+++ ticodecplugin/src/gstticodecplugin_omap3530.cfg 2009-07-21 12:55:26.000000000 -0700 -@@ -38,6 +38,8 @@ - "./decodeCombo.x64P", - "ti.sdo.servers.decode" - ); -+codecServer.server = "/usr/share/ti-codec-combos/cs.x64P"; -+ - - /* Load support for the DMAI module */ - var DMAI = xdc.loadPackage('ti.sdo.dmai'); diff --git a/recipes/ti/gstreamer-ti/gst-buffsize.diff b/recipes/ti/gstreamer-ti/gst-buffsize.diff deleted file mode 100644 index 2d71286498..0000000000 --- a/recipes/ti/gstreamer-ti/gst-buffsize.diff +++ /dev/null @@ -1,113 +0,0 @@ - ChangeLog | 10 ++++++++++ - src/gsttividdec2.c | 25 +++++++++++++++++++++---- - src/gsttividdec2.h | 2 ++ - 3 files changed, 33 insertions(+), 4 deletions(-) - -diff -Nurd --exclude .svn trunk/gstreamer_ti/ti_build/ticodecplugin/ChangeLog branches/BRANCH_DDOMPE_BUFFERSIZES/gstreamer_ti/ti_build/ticodecplugin/ChangeLog ---- ticodecplugin/ChangeLog 2009-03-03 08:57:50.000000000 +0100 -+++ ticodecplugin/ChangeLog 2009-03-03 08:59:20.000000000 +0100 -@@ -1,3 +1,13 @@ -+2009-03-01 Diego Dompe, RidgeRun -+ * src/gsttividdec2.{c.h}: -+ Create the output buffer tab using the recently added height and width -+ attributes passed by the capabilities. This solves integration problems -+ with other elements like ffmpegcolorspace and xvimagesink, where they -+ will fail because the second buffer pushed over the src pad of the -+ decoder has a size different from the first one. Using the input caps -+ for the creation of the buffer tab we have a more educated guess on the -+ output buffer size, and the resizing won't be required. -+ - 2009-02-25 Brijesh Singh, Texas Instruments, Inc. - * src/{gsttividenc1.{c,h},gsttividenc.{c,h},gsttividdec1.{c,h},gsttividdec. - {c,h},gsttiauddec1.{c,h},gsttiauddec.{c,h},gsttiimgdec1.{c,h},gsttiimgenc1. -diff -Nurd --exclude .svn trunk/gstreamer_ti/ti_build/ticodecplugin/src/gsttividdec2.c branches/BRANCH_DDOMPE_BUFFERSIZES/gstreamer_ti/ti_build/ticodecplugin/src/gsttividdec2.c ---- ticodecplugin/src/gsttividdec2.c 2009-03-03 08:57:50.000000000 +0100 -+++ ticodecplugin/src/gsttividdec2.c 2009-03-03 08:59:20.000000000 +0100 -@@ -21,7 +21,11 @@ - * Original Author: - * Don Darling, Texas Instruments, Inc. - * -+ * Contributors: -+ * Diego Dompe, RidgeRun -+ * - * Copyright (C) $year Texas Instruments Incorporated - http://www.ti.com/ -+ * Copyright (C) $year RidgeRun - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as -@@ -350,6 +354,8 @@ - - viddec2->framerateNum = 0; - viddec2->framerateDen = 0; -+ viddec2->height = 0; -+ viddec2->width = 0; - - viddec2->numOutputBufs = 0UL; - viddec2->hOutBufTab = NULL; -@@ -484,6 +490,14 @@ - viddec2->framerateNum = framerateNum; - viddec2->framerateDen = framerateDen; - } -+ -+ if (!gst_structure_get_int(capStruct, "height", &viddec2->height)) { -+ viddec2->height = 0; -+ } -+ -+ if (!gst_structure_get_int(capStruct, "width", &viddec2->width)) { -+ viddec2->width = 0; -+ } - } - - /* MPEG Decode */ -@@ -1048,6 +1062,7 @@ - Cpu_Device device; - ColorSpace_Type colorSpace; - Int defaultNumBufs; -+ Int outBufSize; - - /* Open the codec engine */ - GST_LOG("opening codec engine \"%s\"\n", viddec2->engineName); -@@ -1116,8 +1131,8 @@ - /* Create codec output buffers */ - GST_LOG("creating output buffer table\n"); - gfxAttrs.colorSpace = colorSpace; -- gfxAttrs.dim.width = params.maxWidth; -- gfxAttrs.dim.height = params.maxHeight; -+ gfxAttrs.dim.width = viddec2->width; -+ gfxAttrs.dim.height = viddec2->height; - gfxAttrs.dim.lineLength = BufferGfx_calcLineLength( - gfxAttrs.dim.width, gfxAttrs.colorSpace); - -@@ -1125,8 +1140,10 @@ - gfxAttrs.bAttrs.useMask = gst_tidmaibuffertransport_GST_FREE | - gst_tividdec2_CODEC_FREE; - -+ outBufSize = gfxAttrs.dim.lineLength * viddec2->height; -+ - viddec2->hOutBufTab = -- BufTab_create(viddec2->numOutputBufs, Vdec2_getOutBufSize(viddec2->hVd), -+ BufTab_create(viddec2->numOutputBufs, outBufSize, - BufferGfx_getBufferAttrs(&gfxAttrs)); - - if (viddec2->hOutBufTab == NULL) { -@@ -1295,7 +1312,7 @@ - */ - outBuf = gst_tidmaibuffertransport_new(hDstBuf); - gst_buffer_set_data(outBuf, GST_BUFFER_DATA(outBuf), -- Buffer_getNumBytesUsed(hDstBuf)); -+ Vdec2_getOutBufSize(viddec2->hVd)); - gst_buffer_set_caps(outBuf, GST_PAD_CAPS(viddec2->srcpad)); - - /* If we have a valid time stamp, set it on the buffer */ -diff -Nurd --exclude .svn trunk/gstreamer_ti/ti_build/ticodecplugin/src/gsttividdec2.h branches/BRANCH_DDOMPE_BUFFERSIZES/gstreamer_ti/ti_build/ticodecplugin/src/gsttividdec2.h ---- ticodecplugin/src/gsttividdec2.h 2009-03-03 08:57:50.000000000 +0100 -+++ ticodecplugin/src/gsttividdec2.h 2009-03-03 08:59:20.000000000 +0100 -@@ -96,6 +96,8 @@ - /* Framerate (Num/Den) */ - gint framerateNum; - gint framerateDen; -+ gint height; -+ gint width; - - /* Buffer management */ - UInt32 numOutputBufs; diff --git a/recipes/ti/gstreamer-ti/gstreamer-ti-tracker-462.patch b/recipes/ti/gstreamer-ti/gstreamer-ti-tracker-462.patch new file mode 100644 index 0000000000..c115161dcc --- /dev/null +++ b/recipes/ti/gstreamer-ti/gstreamer-ti-tracker-462.patch @@ -0,0 +1,68 @@ +diff -uNr ticodecplugin/src/gsttividdec.c ticodecplugin.new/src/gsttividdec.c +--- ticodecplugin/src/gsttividdec.c 2009-09-05 00:04:51.000000000 -0500 ++++ ticodecplugin.new/src/gsttividdec.c 2009-09-05 03:54:42.000000000 -0500 +@@ -82,7 +82,7 @@ + GST_PAD_ALWAYS, + GST_STATIC_CAPS + ("video/mpeg, " +- "mpegversion=(int){ 2, 4 }, " /* MPEG versions 2 and 4 */ ++ "mpegversion=(int){ 2, 4 }, " /* MPEG versions 2 and 4 */ + "systemstream=(boolean)false, " + "framerate=(fraction)[ 0, MAX ], " + "width=(int)[ 1, MAX ], " +@@ -90,7 +90,8 @@ + "video/x-h264, " /* H264 */ + "framerate=(fraction)[ 0, MAX ], " + "width=(int)[ 1, MAX ], " +- "height=(int)[ 1, MAX ]" ++ "height=(int)[ 1, MAX ] ;" ++ "video/x-xvid" /* XVID */ + ) + ); + +@@ -614,6 +615,11 @@ + codec = gst_ticodec_get_codec("H.264 Video Decoder"); + } + ++ /* XVID Decode */ ++ else if (!strcmp(mime, "video/x-xvid")) { ++ codec = gst_ticodec_get_codec("MPEG4 Video Decoder"); ++ } ++ + /* Mime type not supported */ + else { + GST_ERROR("stream type not supported"); +diff -uNr ticodecplugin/src/gsttividdec2.c ticodecplugin.new/src/gsttividdec2.c +--- ticodecplugin/src/gsttividdec2.c 2009-09-05 00:04:51.000000000 -0500 ++++ ticodecplugin.new/src/gsttividdec2.c 2009-09-05 03:54:42.000000000 -0500 +@@ -83,7 +83,7 @@ + GST_PAD_ALWAYS, + GST_STATIC_CAPS + ("video/mpeg, " +- "mpegversion=(int){ 2, 4 }, " /* MPEG versions 2 and 4 */ ++ "mpegversion=(int){ 2, 4 }, " /* MPEG versions 2 and 4 */ + "systemstream=(boolean)false, " + "framerate=(fraction)[ 0, MAX ], " + "width=(int)[ 1, MAX ], " +@@ -91,7 +91,8 @@ + "video/x-h264, " /* H264 */ + "framerate=(fraction)[ 0, MAX ], " + "width=(int)[ 1, MAX ], " +- "height=(int)[ 1, MAX ]" ++ "height=(int)[ 1, MAX ] ;" ++ "video/x-xvid" /* XVID */ + ) + ); + +@@ -625,6 +626,11 @@ + codec = gst_ticodec_get_codec("H.264 Video Decoder"); + } + ++ /* XVID Decode */ ++ else if (!strcmp(mime, "video/x-xvid")) { ++ codec = gst_ticodec_get_codec("MPEG4 Video Decoder"); ++ } ++ + /* Mime type not supported */ + else { + GST_ERROR("stream type not supported"); diff --git a/recipes/ti/gstreamer-ti/gstreamer-ti-tracker-824.patch b/recipes/ti/gstreamer-ti/gstreamer-ti-tracker-824.patch new file mode 100644 index 0000000000..634fa4aaf6 --- /dev/null +++ b/recipes/ti/gstreamer-ti/gstreamer-ti-tracker-824.patch @@ -0,0 +1,147 @@ +--- ticodecplugin/ChangeLog ++++ ticodecplugin.new/ChangeLog +@@ -1,3 +1,7 @@ ++2009-08-14 Don Darling, Texas Instruments, Inc. ++ * src/{gstticodecplugin_omap3530.cfg,gstticodecs_omap3530.c}: ++ Update OMAP3530 Support to use DVSDK 3.00.00.40. ++ + 2009-07-28 Brijesh Singh, Texas Instruments, Inc. + * src/{gstticircbuffer.c}: + Fix potential memory leak in circular buffer when accel framecopy flag is +--- ticodecplugin/src/gstticodecplugin_omap3530.cfg ++++ ticodecplugin.new/src/gstticodecplugin_omap3530.cfg +@@ -12,8 +12,6 @@ + * + */ + +-prog.build.platform = "ti.platforms.evm3530"; +- + /* Load the Codec Engine 'Operating System Abstraction Layer' */ + var osalGlobal = xdc.useModule('ti.sdo.ce.osal.Global'); + +@@ -27,31 +25,20 @@ ipc.commType = ipc.COMM_DSPLINK; + /* + * ======== Engine Configuration ======== + */ +-var Engine = xdc.useModule('ti.sdo.ce.Engine'); +-var encEngine = Engine.createFromServer( +- "encode", +- "./encodeCombo.x64P", +- "ti.sdo.servers.encode" +- ); +-var decEngine = Engine.createFromServer( +- "decode", +- "./decodeCombo.x64P", +- "ti.sdo.servers.decode" ++var Engine = xdc.useModule('ti.sdo.ce.Engine'); ++var demoEngine = Engine.createFromServer( ++ "codecServer", ++ "./bin/cs.x64P", ++ "ti.sdo.server.cs" + ); + +-var encpath = "" + java.lang.System.getenv("ENCODE_COMBO"); +-if (encpath != "" && encpath != "null") { +- encEngine.server = java.lang.System.getenv("ENCODE_COMBO"); +-} +- +-var decpath = "" + java.lang.System.getenv("DECODE_COMBO"); +-if (decpath != "" && decpath != "null") { +- decEngine.server = java.lang.System.getenv("DECODE_COMBO"); ++var combopath = "" + java.lang.System.getenv("CODEC_SERVER"); ++if (combopath != "" && combopath != "null") { ++ demoEngine.server = java.lang.System.getenv("CODEC_SERVER"); + } + + /* Load support for the DMAI module */ + var DMAI = xdc.loadPackage('ti.sdo.dmai'); + +-/* Load support for user space DMA */ +-var SCPY = xdc.useModule("ti.sdo.fc.scpy.SCPY"); +-var SDMA = xdc.useModule("ti.sdo.linuxutils.sdma.SDMA"); ++var SCPY = xdc.useModule('ti.sdo.fc.scpy.SCPY'); ++var SDMA = xdc.useModule('ti.sdo.linuxutils.sdma.SDMA'); +--- ticodecplugin/src/gstticodecs_omap3530.c ++++ ticodecplugin.new/src/gstticodecs_omap3530.c +@@ -22,8 +22,7 @@ + #include "gstticodecs.h" + + /* Declaration of the production engine and decoders shipped with the DVSDK */ +-static Char decodeEngine[] = "decode"; +-static Char encodeEngine[] = "encode"; ++static Char codecServer[] = "codecServer"; + + /* NULL terminated list of speech decoders in the engine to use in the demo */ + GstTICodec gst_ticodec_codecs[] = { +@@ -32,59 +31,55 @@ GstTICodec gst_ticodec_codecs[] = { + { + "AAC Audio Decoder", /* String name of codec used by plugin */ + "aachedec", /* String name of codec used by CE */ +- decodeEngine /* Engine that contains this codec */ ++ codecServer /* Engine that contains this codec */ + }, { + "MPEG1L2 Audio Decoder", /* String name of codec used by plugin */ + "mp3dec", /* String name of codec used by CE */ +- decodeEngine /* Engine that contains this codec */ ++ codecServer /* Engine that contains this codec */ + }, { + "MPEG1L3 Audio Decoder", /* String name of codec used by plugin */ + "mp3dec", /* String name of codec used by CE */ +- decodeEngine /* Engine that contains this codec */ +- }, { +- "WMA Audio Decoder", /* String name of codec used by plugin */ +- "wmadec", /* String name of codec used by CE */ +- decodeEngine /* Engine that contains this codec */ ++ codecServer /* Engine that contains this codec */ + }, +- ++ + /* Video Decoders */ + { + "H.264 Video Decoder", /* String name of codec used by plugin */ + "h264dec", /* String name of codec used by CE */ +- decodeEngine /* Engine that contains this codec */ ++ codecServer /* Engine that contains this codec */ + }, { + "MPEG4 Video Decoder", /* String name of codec used by plugin */ + "mpeg4dec", /* String name of codec used by CE */ +- decodeEngine /* Engine that contains this codec */ ++ codecServer /* Engine that contains this codec */ + }, { + "MPEG2 Video Decoder", /* String name of codec used by plugin */ + "mpeg2dec", /* String name of codec used by CE */ +- decodeEngine /* Engine that contains this codec */ ++ codecServer /* Engine that contains this codec */ + }, + + /* Image Decoders */ + { + "JPEG Image Decoder", /* String name of codec used by plugin */ + "jpegdec", /* String name of codec used by CE */ +- decodeEngine /* Engine that contains this codec */ ++ codecServer /* Engine that contains this codec */ + }, + + /* Video Encoders */ + { + "H.264 Video Encoder", /* String name of codec used by plugin */ + "h264enc", /* String name of codec used by CE */ +- encodeEngine /* Engine that contains this codec */ ++ codecServer /* Engine that contains this codec */ + }, { + "MPEG4 Video Encoder", /* String name of codec used by plugin */ + "mpeg4enc", /* String name of codec used by CE */ +- encodeEngine /* Engine that contains this codec */ ++ codecServer /* Engine that contains this codec */ + }, + + /* Image Encoders */ + { + "JPEG Image Encoder", /* String name of codec used by plugin */ + "jpegenc", /* String name of codec used by CE */ +- encodeEngine /* Engine that contains this codec */ ++ codecServer /* Engine that contains this codec */ + }, + + { NULL } + diff --git a/recipes/ti/gstreamer-ti_svn.bb b/recipes/ti/gstreamer-ti_svn.bb index 59f7046bac..8fcc528019 100644 --- a/recipes/ti/gstreamer-ti_svn.bb +++ b/recipes/ti/gstreamer-ti_svn.bb @@ -7,13 +7,14 @@ inherit autotools DEPENDS = "ti-dmai gstreamer gst-plugins-base gst-plugins-good gst-plugins-ugly" # Fetch source from svn repo -SRCREV = "331" +SRCREV = "335" SRC_URI = "svn://gforge.ti.com/svn/gstreamer_ti/trunk;module=gstreamer_ti;proto=https;user=anonymous;pswd='' \ file://gstreamer-ti-tracker-824.patch;patch=1 \ + file://gstreamer-ti-tracker-462.patch;patch=1 \ " # Again, no '.' in PWD allowed :( -PR = "r32" +PR = "r33" PV = "svnr${SRCREV}" S = "${WORKDIR}/gstreamer_ti/ti_build/ticodecplugin" -- cgit v1.2.3 From dbecbf49e28a9a0f9012482c8de2afdc41701e17 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Sun, 13 Sep 2009 12:17:04 -0700 Subject: sysstat_8.1.6.bb: Fix compilation on uclibc * Add dependency on virtual/libintl Signed-off-by: Khem Raj --- recipes/sysstat/sysstat_8.1.6.bb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/recipes/sysstat/sysstat_8.1.6.bb b/recipes/sysstat/sysstat_8.1.6.bb index a734d14f57..42dd5e2d75 100644 --- a/recipes/sysstat/sysstat_8.1.6.bb +++ b/recipes/sysstat/sysstat_8.1.6.bb @@ -4,6 +4,8 @@ LICENSE = "GPL" SECTION = "console/utils" PR = "r1" +DEPENDS = "virtual/libintl" + SRC_URI = "http://pagesperso-orange.fr/sebastien.godard/sysstat-${PV}.tar.gz" inherit autotools @@ -15,3 +17,6 @@ do_configure_prepend() { FILES_${PN} += "${libdir}/sa" TARGET_CC_ARCH += "${LDFLAGS}" +LDFLAGS_append_linux-uclibc = " -lintl" +LDFLAGS_append_linux-uclibceabi = " -lintl" +LDFLAGS_append_linux-uclibcspe = " -lintl" -- cgit v1.2.3 From 34e6a1ce23f1ef5f627447286c4ae768d8bcb1ad Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Sun, 13 Sep 2009 12:20:02 -0700 Subject: nfs-utils_1.1.2.bb: Fix compilation on uclibc Signed-off-by: Khem Raj --- .../nfs-utils-1.1.2/nfs-utils-uclibc-compile.patch | 49 ++++++++++++++++++++++ recipes/nfs-utils/nfs-utils_1.1.2.bb | 3 +- 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 recipes/nfs-utils/nfs-utils-1.1.2/nfs-utils-uclibc-compile.patch diff --git a/recipes/nfs-utils/nfs-utils-1.1.2/nfs-utils-uclibc-compile.patch b/recipes/nfs-utils/nfs-utils-1.1.2/nfs-utils-uclibc-compile.patch new file mode 100644 index 0000000000..f242eade45 --- /dev/null +++ b/recipes/nfs-utils/nfs-utils-1.1.2/nfs-utils-uclibc-compile.patch @@ -0,0 +1,49 @@ +--- a/support/nfs/svc_socket.c.org 2007-05-11 03:40:57 +0000 ++++ b/support/nfs/svc_socket.c 2007-10-24 15:20:05 +0000 +@@ -67,8 +67,13 @@ + memset (&addr, 0, sizeof (addr)); + addr.sin_family = AF_INET; + ++#ifdef __UCLIBC__ ++ rpcp = getrpcbynumber (number); ++ ret = 0; ++#else + ret = getrpcbynumber_r (number, &rpcbuf, rpcdata, sizeof rpcdata, + &rpcp); ++#endif + if (ret == 0 && rpcp != NULL) + { + /* First try name. */ +--- a/utils/mountd/cache.c.org 2007-05-11 03:40:57 +0000 ++++ b/utils/mountd/cache.c 2007-10-24 15:21:53 +0000 +@@ -131,6 +131,7 @@ + pw = getpwuid(uid); + if (!pw) + rv = -1; ++#ifndef __UCLIBC__ + else { + rv = getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups); + if (rv == -1 && ngroups >= 100) { +@@ -142,6 +143,7 @@ + groups, &ngroups); + } + } ++#endif + qword_printint(f, uid); + qword_printint(f, time(0)+30*60); + if (rv >= 0) { +--- a/tools/rpcgen/rpc_cout.c.org 2007-05-11 03:40:57 +0000 ++++ b/tools/rpcgen/rpc_cout.c 2007-10-24 15:23:17 +0000 +@@ -647,7 +647,11 @@ + int freed=0; + + if(flag == PUT) ++#ifdef __UCLIBC__ ++ f_print(fout,"\t\t IXDR_PUT_"); ++#else + f_print(fout,"\t\t (void) IXDR_PUT_"); ++#endif + else + if(rel== REL_ALIAS) + f_print(fout,"\t\t objp->%s = IXDR_GET_",decl->name); + diff --git a/recipes/nfs-utils/nfs-utils_1.1.2.bb b/recipes/nfs-utils/nfs-utils_1.1.2.bb index 7f29d8a851..cdd5d372cd 100644 --- a/recipes/nfs-utils/nfs-utils_1.1.2.bb +++ b/recipes/nfs-utils/nfs-utils_1.1.2.bb @@ -3,12 +3,13 @@ PRIORITY = "optional" SECTION = "console/network" LICENSE = "GPL" -PR = "r5" +PR = "r6" DEPENDS = "e2fsprogs-libs tcp-wrappers libevent" SRC_URI = "${SOURCEFORGE_MIRROR}/nfs/nfs-utils-${PV}.tar.gz \ file://nfs-utils-tools-unset-cflags.patch;patch=1 \ + file://nfs-utils-uclibc-compile.patch;patch=1 \ file://nfsserver \ " -- cgit v1.2.3 From 848446695abfdb3d3631d70ece7e74311f26d37c Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Sun, 13 Sep 2009 19:46:13 +0000 Subject: emotion_svn: Remove not needed sed hack for edje_cc. --- recipes/efl1/emotion_svn.bb | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/recipes/efl1/emotion_svn.bb b/recipes/efl1/emotion_svn.bb index 79b35d9d50..662628d4c2 100644 --- a/recipes/efl1/emotion_svn.bb +++ b/recipes/efl1/emotion_svn.bb @@ -3,7 +3,7 @@ LICENSE = "MIT BSD" # we no longer build the libxine backend, since the gstreamer backend seems more promising DEPENDS = "eet evas ecore edje gstreamer gst-plugins-base" PV = "0.1.0.042+svnr${SRCREV}" -PR = "r3" +PR = "r4" inherit efl @@ -12,11 +12,3 @@ EXTRA_OECONF = "--disable-xine --enable-gstreamer --with-edje-cc=${STAGING_BINDI PACKAGES =+ "emotion-backend-gstreamer" FILES_emotion-backend-gstreamer = "${libdir}/emotion/*.so" RRECOMMENDS_${PN} = "emotion-backend-gstreamer" - - -do_configure_append() { - for i in $(find ${WORKDIR}/emotion -name 'Makefile'); do - sed -i -e s:/usr/bin/edje_cc:${STAGING_DIR}/${BUILD_SYS}/usr/bin/edje_cc: \ - ${i} - done -} -- cgit v1.2.3 From 97baea51df033a8a35e7c308f09e2d5da5a79a90 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Mon, 14 Sep 2009 09:16:36 +0200 Subject: powertop: fix compilation with the extra states patch --- recipes/powertop/powertop_1.11.bb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/recipes/powertop/powertop_1.11.bb b/recipes/powertop/powertop_1.11.bb index 6af5290122..225fc7414b 100644 --- a/recipes/powertop/powertop_1.11.bb +++ b/recipes/powertop/powertop_1.11.bb @@ -1,10 +1,8 @@ require powertop.inc -PR = "${INC_PR}.0" +PR = "${INC_PR}.1" SRC_URI_append_armv7a = " file://omap.patch;patch=1;pnum=0" -CFLAGS_append_beagleboard = " -DOMAP3" -CFLAGS_append_overo = " -DOMAP3" -CFLAGS_append_omap3evm = " -DOMAP3" -CFLAGS_append_omapzoom2 = " -DOMAP3" +CFLAGS_append_armv7a = " -DOMAP3" + -- cgit v1.2.3 From d4a87d12b3bc156c19d1f589770436e24fe4e49f Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Mon, 14 Sep 2009 10:07:15 +0200 Subject: midori: add 0.10 --- conf/checksums.ini | 4 ++++ recipes/gtk-webcore/midori_0.1.10.bb | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 recipes/gtk-webcore/midori_0.1.10.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index 9964dc783d..f5e30c9bfc 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -17262,6 +17262,10 @@ sha256=e561f66262eaf6b9cbd8e84688184b7f3ba6cba0e34e9791e578bdef9adc7731 md5=069275806e0224b1de3e080c23c95dc5 sha256=7861535eef2c0804dbdc6993db76574b4a812164bed7545a3697a3b97e36d2dd +[http://archive.xfce.org/src/apps/midori/0.1/midori-0.1.10.tar.bz2] +md5=97b6a3a3ccb8458c68c335b2ee8e9197 +sha256=1f6a3af09ea9b9669c4b1a7ca2a8cbee5114dac2612e6f5ced1ea7ea4967fbfc + [http://goodies.xfce.org/releases/midori/midori-0.1.2.tar.bz2] md5=5169ead6783f374cedf3f89bf399bd75 sha256=a966641cf1b6e18e4f58aa3585a9a63905ed50252883804c006a3263674a32ec diff --git a/recipes/gtk-webcore/midori_0.1.10.bb b/recipes/gtk-webcore/midori_0.1.10.bb new file mode 100644 index 0000000000..06d8964082 --- /dev/null +++ b/recipes/gtk-webcore/midori_0.1.10.bb @@ -0,0 +1,31 @@ +require midori.inc + +DEPENDS += "python-native python-docutils-native" + +SRC_URI = "http://archive.xfce.org/src/apps/midori/0.1/midori-${PV}.tar.bz2 \ + file://waf" + +do_configure() { + cp -f ${WORKDIR}/waf ${S}/ + sed -i -e 's:, shell=False::g' wscript + ./configure \ + --prefix=${prefix} \ + --bindir=${bindir} \ + --sbindir=${sbindir} \ + --libexecdir=${libexecdir} \ + --datadir=${datadir} \ + --sysconfdir=${sysconfdir} \ + --sharedstatedir=${sharedstatedir} \ + --localstatedir=${localstatedir} \ + --libdir=${libdir} \ + --includedir=${includedir} \ + --infodir=${infodir} \ + --mandir=${mandir} \ + ${EXTRA_OECONF} + + sed -i /LINK_CC/d ./_build_/c4che/default.cache.py + echo "LINK_CC = '${CXX}'" >> ./_build_/c4che/default.cache.py +} + + + -- cgit v1.2.3 From 517834d5e985ca56c3f840e3bbff145060977b86 Mon Sep 17 00:00:00 2001 From: Cliff Brake Date: Mon, 14 Sep 2009 08:36:26 -0400 Subject: calibrator: add new recipes for cache calibrator Used to load system during RT testing --- recipes/calibrator/calibrator_svn.bb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 recipes/calibrator/calibrator_svn.bb diff --git a/recipes/calibrator/calibrator_svn.bb b/recipes/calibrator/calibrator_svn.bb new file mode 100644 index 0000000000..3ac2793932 --- /dev/null +++ b/recipes/calibrator/calibrator_svn.bb @@ -0,0 +1,14 @@ +DESCRIPTION = "The Calibrator, a Cache-Memory and TLB Calibration Tool" +HOMEPAGE = "http://monetdb.cwi.nl/Calibrator/" +LICENSE = "AS IS" + +SRCREV = "21" +PV = "0.9e+svn${SRCREV}" +PR = "r0" + +SRC_URI = "svn://dev.bec-systems.com/svn/pub;module=calibrator;proto=http" + +inherit autotools + +S = ${WORKDIR}/calibrator + -- cgit v1.2.3 From 05b103fa043460b42b28b84dc61e1c5c8bdfc064 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Mon, 14 Sep 2009 16:14:59 +0200 Subject: julius: add demo files from the TI speechrecognizer demo --- conf/checksums.ini | 4 ++++ recipes/julius/ti-julius-demo_r962.bb | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 recipes/julius/ti-julius-demo_r962.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index f5e30c9bfc..ab11453557 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -5458,6 +5458,10 @@ sha256=6b5a71790120977a96d5a468ed69987107c5079f14b0a4081f460b3b14fbf952 md5=c4559af2366c764c6c42a3fdd40d60d3 sha256=6b5a71790120977a96d5a468ed69987107c5079f14b0a4081f460b3b14fbf952 +[http://dominion.thruhere.net/koen/OE/ecas-julius_acousticfiles.r962.tar.gz] +md5=406df5cd8ffa096bdb51466691e16b82 +sha256=56cba0e065cdbc11dc74e379af9082b0f8a771ec5984733408c21163a8bea588 + [http://eciadsl.flashtux.org/download/eciadsl-usermode-0.11.tar.gz] md5=c3c60c83f6df30021e11da50a699dec9 sha256=2382f315fda4241a0043bac1dfc669f006d8e93e87fa382b263b1672972f4077 diff --git a/recipes/julius/ti-julius-demo_r962.bb b/recipes/julius/ti-julius-demo_r962.bb new file mode 100644 index 0000000000..009a986cd4 --- /dev/null +++ b/recipes/julius/ti-julius-demo_r962.bb @@ -0,0 +1,18 @@ +DESCRIPTION = "TI speech recognizer demo" +LICENSE = "GPL" + +RDEPENDS = "julius" +PACKAGE_ARCH = "all" + +SRC_URI = "http://dominion.thruhere.net/koen/OE/ecas-julius_acousticfiles.${PV}.tar.gz" + +S = "${WORKDIR}/julius_acousticfiles.r962" + +do_install() { + rm ${S}/patches -rf + install -d ${D}${datadir}/ti/julius-demo + cp ${S}/* ${D}${datadir}/ti/julius-demo/ +} + +FILES_${PN} = "${datadir}" + -- cgit v1.2.3 From 0e4c4a74ae68668ac7df3a3236248c0ceec5638a Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Mon, 14 Sep 2009 16:30:30 +0200 Subject: linux-neuros git: updates --- recipes/linux/linux-neuros/neuros-osd2/defconfig | 2287 ++++++++++++++++------ recipes/linux/linux-neuros_git.bb | 7 +- 2 files changed, 1665 insertions(+), 629 deletions(-) diff --git a/recipes/linux/linux-neuros/neuros-osd2/defconfig b/recipes/linux/linux-neuros/neuros-osd2/defconfig index 17c100fe4f..05088204bf 100644 --- a/recipes/linux/linux-neuros/neuros-osd2/defconfig +++ b/recipes/linux/linux-neuros/neuros-osd2/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.23-davinci1 -# Thu Aug 7 13:02:41 2008 +# Linux kernel version: 2.6.31-rc4-davinci1 +# Wed Jul 29 11:55:54 2009 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -9,94 +9,142 @@ CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_MMU=y -# CONFIG_NO_IOPORT is not set CONFIG_GENERIC_HARDIRQS=y CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_HARDIRQS_SW_RESEND=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_ZONE_DMA=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_VECTORS_BASE=0xffff0000 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -# CONFIG_SWAP is not set +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -CONFIG_SYSFS_DEPRECATED=y +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y CONFIG_UID16=y -CONFIG_SYSCTL_SYSCALL=y +# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y -CONFIG_ELF_CORE=y +# CONFIG_ELF_CORE is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y -CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Performance Counters +# CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_COMPAT_BRK is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_MARKERS=y +CONFIG_OPROFILE=y +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_SLOW_WORK=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y +CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +CONFIG_LBDAF=y # CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set # # IO Schedulers # CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_DEFAULT_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_FREEZER=y # # System Type @@ -106,15 +154,15 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_VERSATILE is not set # CONFIG_ARCH_AT91 is not set -# CONFIG_ARCH_CLPS7500 is not set # CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_GEMINI is not set # CONFIG_ARCH_EBSA110 is not set # CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set # CONFIG_ARCH_NETX is not set # CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_IMX is not set # CONFIG_ARCH_IOP13XX is not set # CONFIG_ARCH_IOP32X is not set # CONFIG_ARCH_IOP33X is not set @@ -122,26 +170,28 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_IXP2000 is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set # CONFIG_ARCH_KS8695 is not set # CONFIG_ARCH_NS9XXX is not set -# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_W90X900 is not set # CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set # CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set # CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set CONFIG_ARCH_DAVINCI=y # CONFIG_ARCH_OMAP is not set - -# -# Boot options -# - -# -# Power management -# +CONFIG_AINTC=y +CONFIG_ARCH_DAVINCI_DMx=y # # TI DaVinci Implementations @@ -150,20 +200,23 @@ CONFIG_ARCH_DAVINCI=y # # DaVinci Core Type # -CONFIG_ARCH_DAVINCI644x=y +CONFIG_ARCH_DAVINCI_DM644x=y +# CONFIG_ARCH_DAVINCI_DM355 is not set +# CONFIG_ARCH_DAVINCI_DM646x is not set +# CONFIG_ARCH_DAVINCI_DA830 is not set +# CONFIG_ARCH_DAVINCI_DA850 is not set +# CONFIG_ARCH_DAVINCI_DM365 is not set # # DaVinci Board Type # -CONFIG_MACH_NTOSD_644XA=y # CONFIG_MACH_DAVINCI_EVM is not set -CONFIG_DAVINCI_I2C_EXPANDER=y -CONFIG_DAVINCI_MCBSP=y - -# -# DaVinci Options -# -# CONFIG_DAVINCI_BLK_DEV_CF is not set +# CONFIG_MACH_SFFSDR is not set +CONFIG_MACH_NEUROS_OSD2=y +CONFIG_DAVINCI_MUX=y +# CONFIG_DAVINCI_MUX_DEBUG is not set +# CONFIG_DAVINCI_MUX_WARNINGS is not set +# CONFIG_DAVINCI_RESET_CLOCKS is not set # # Processor Type @@ -187,46 +240,52 @@ CONFIG_ARM_THUMB=y # CONFIG_CPU_DCACHE_DISABLE is not set # CONFIG_CPU_DCACHE_WRITETHROUGH is not set # CONFIG_CPU_CACHE_ROUND_ROBIN is not set -# CONFIG_OUTER_CACHE is not set -CONFIG_FORCE_MAX_ZONEORDER=13 +CONFIG_COMMON_CLKDEV=y # # Bus support # # CONFIG_PCI_SYSCALL is not set # CONFIG_ARCH_SUPPORTS_MSI is not set - -# -# PCCARD (PCMCIA/CardBus) support -# # CONFIG_PCCARD is not set # # Kernel Features # -# CONFIG_TICK_ONESHOT is not set -# CONFIG_NO_HZ is not set -# CONFIG_HIGH_RES_TIMERS is not set -# CONFIG_PREEMPT is not set +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PREEMPT=y CONFIG_HZ=100 CONFIG_AEABI=y -CONFIG_OABI_COMPAT=y -# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4096 -# CONFIG_RESOURCES_64BIT is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_LEDS=y # CONFIG_LEDS_CPU is not set CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set # # Boot options @@ -235,7 +294,13 @@ CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE=" debug " # CONFIG_XIP_KERNEL is not set -# CONFIG_KEXEC is not set +CONFIG_KEXEC=y +CONFIG_ATAGS_PROC=y + +# +# CPU Power Management +# +# CONFIG_CPU_IDLE is not set # # Floating point emulation @@ -244,151 +309,502 @@ CONFIG_CMDLINE=" debug " # # At least one emulation must be selected # -# CONFIG_FPE_NWFPE is not set -# CONFIG_FPE_FASTFPE is not set -# CONFIG_VFP is not set +CONFIG_VFP=y # # Userspace binary formats # CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_AOUT is not set -# CONFIG_BINFMT_MISC is not set +CONFIG_HAVE_AOUT=y +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_MISC=y # # Power management options # -# CONFIG_PM is not set -CONFIG_SUSPEND_UP_POSSIBLE=y - -# -# Networking -# +CONFIG_PM=y +CONFIG_PM_DEBUG=y +# CONFIG_PM_VERBOSE is not set +CONFIG_CAN_PM_TRACE=y +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_SUSPEND_FREEZER=y +# CONFIG_APM_EMULATION is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_NET=y # # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set +CONFIG_PACKET_MMAP=y CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set # CONFIG_XFRM_MIGRATE is not set -# CONFIG_NET_KEY is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_FIB_HASH=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m # CONFIG_ARPD is not set # CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m CONFIG_INET_TUNNEL=m CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +# CONFIG_DEFAULT_RENO is not set CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TCP_MD5SIG is not set -# CONFIG_IP_VS is not set CONFIG_IPV6=m # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set # CONFIG_IPV6_OPTIMISTIC_DAD is not set -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_IPCOMP is not set -# CONFIG_IPV6_MIP6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m CONFIG_INET6_XFRM_MODE_TRANSPORT=m CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m -# CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +# CONFIG_IPV6_PIMSM_V2 is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y # # Core Netfilter Configuration # -# CONFIG_NETFILTER_NETLINK is not set -# CONFIG_NF_CONNTRACK_ENABLED is not set -# CONFIG_NF_CONNTRACK is not set -# CONFIG_NETFILTER_XTABLES is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +# CONFIG_NETFILTER_TPROXY is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_HL=m +# CONFIG_NETFILTER_XT_TARGET_LED is not set +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +# CONFIG_NETFILTER_XT_TARGET_TRACE is not set +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +CONFIG_IP_VS_DEBUG=y +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m # # IP: Netfilter Configuration # -# CONFIG_IP_NF_QUEUE is not set -# CONFIG_IP_NF_IPTABLES is not set -# CONFIG_IP_NF_ARPTABLES is not set - -# -# IPv6: Netfilter Configuration (EXPERIMENTAL) -# -# CONFIG_IP6_NF_QUEUE is not set -# CONFIG_IP6_NF_IPTABLES is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_DCCP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +# CONFIG_BRIDGE_NF_EBTABLES is not set +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m + +# +# DCCP CCIDs Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=y +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +CONFIG_IP_DCCP_TFRC_LIB=y + +# +# DCCP Kernel Hacking +# +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_STP=m +CONFIG_GARP=m +CONFIG_BRIDGE=m +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y # CONFIG_DECNET is not set +CONFIG_LLC=m # CONFIG_LLC2 is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set +CONFIG_WAN_ROUTER=m +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_CLS_IND=y +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set # # Network testing # # CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set +CONFIG_CAN=m +CONFIG_CAN_RAW=m +CONFIG_CAN_BCM=m + +# +# CAN Device Drivers +# +CONFIG_CAN_VCAN=m +# CONFIG_CAN_DEV is not set +# CONFIG_CAN_DEBUG_DEVICES is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +CONFIG_IRDA_ULTRA=y + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_DEBUG=y + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TOIM3232_DONGLE=m +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +# CONFIG_ACT200L_DONGLE is not set +CONFIG_KINGSUN_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KS959_DONGLE=m # -# Wireless +# FIR device drivers # -# CONFIG_CFG80211 is not set +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_MCS_FIR=m +CONFIG_BT=y +CONFIG_BT_L2CAP=y +CONFIG_BT_SCO=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIBTUSB=y +CONFIG_BT_HCIBTSDIO=y +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIBCM203X=y +CONFIG_BT_HCIBPA10X=y +CONFIG_BT_HCIBFUSB=y +# CONFIG_BT_HCIVHCI is not set +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +# CONFIG_RXKAD is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_CFG80211=y +# CONFIG_CFG80211_REG_DEBUG is not set +# CONFIG_CFG80211_DEBUGFS is not set +CONFIG_WIRELESS_OLD_REGULATORY=y CONFIG_WIRELESS_EXT=y -# CONFIG_MAC80211 is not set -CONFIG_IEEE80211=y -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=y -# CONFIG_IEEE80211_CRYPT_CCMP is not set -# CONFIG_IEEE80211_CRYPT_TKIP is not set -CONFIG_IEEE80211_SOFTMAC=y -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_LIB80211=y +CONFIG_LIB80211_CRYPT_WEP=y +CONFIG_LIB80211_CRYPT_CCMP=y +CONFIG_LIB80211_CRYPT_TKIP=y +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=y +CONFIG_MAC80211_DEFAULT_PS=y +CONFIG_MAC80211_DEFAULT_PS_VALUE=1 + +# +# Rate control algorithm selection +# +CONFIG_MAC80211_RC_PID=y +# CONFIG_MAC80211_RC_MINSTREL is not set +CONFIG_MAC80211_RC_DEFAULT_PID=y +# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set +CONFIG_MAC80211_RC_DEFAULT="pid" +# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_WIMAX=m +CONFIG_WIMAX_DEBUG_LEVEL=8 # CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set +CONFIG_NET_9P=m +# CONFIG_NET_9P_DEBUG is not set # # Device Drivers @@ -397,23 +813,30 @@ CONFIG_IEEE80211_SOFTMAC=y # # Generic Driver Options # +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_CONCAT=y CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_CMDLINE_PARTS is not set # CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set # # User Modules And Translation Layers # -CONFIG_MTD_CHAR=y +CONFIG_MTD_CHAR=m CONFIG_MTD_BLKDEVS=y CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set @@ -421,13 +844,14 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers # -CONFIG_MTD_CFI=y +CONFIG_MTD_CFI=m # CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_GEN_PROBE=m # CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_MAP_BANK_WIDTH_1=y CONFIG_MTD_MAP_BANK_WIDTH_2=y @@ -439,10 +863,10 @@ CONFIG_MTD_CFI_I1=y CONFIG_MTD_CFI_I2=y # CONFIG_MTD_CFI_I4 is not set # CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_AMDSTD=m # CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_CFI_UTIL=m # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set @@ -451,7 +875,8 @@ CONFIG_MTD_CFI_UTIL=y # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_COMPAT=y CONFIG_MTD_PHYSMAP_START=0x8000000 CONFIG_MTD_PHYSMAP_LEN=0x0 CONFIG_MTD_PHYSMAP_BANKWIDTH=2 @@ -461,6 +886,8 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # # Self-contained MTD device drivers # +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -473,94 +900,72 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # CONFIG_MTD_DOC2001 is not set # CONFIG_MTD_DOC2001PLUS is not set CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_VERIFY_WRITE=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set # CONFIG_MTD_NAND_ECC_SMC is not set # CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_GPIO is not set CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_NAND_NANDSIM is not set -# CONFIG_MTD_NAND_PLATFORM is not set +CONFIG_MTD_NAND_PLATFORM=y +# CONFIG_MTD_ALAUDA is not set CONFIG_MTD_NAND_DAVINCI=y -CONFIG_NAND_FLASH_HW_ECC=y # CONFIG_MTD_ONENAND is not set +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + # # UBI - Unsorted block images # -# CONFIG_MTD_UBI is not set +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_GLUEBI is not set + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=m -# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=m # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=1 -CONFIG_BLK_DEV_RAM_SIZE=32768 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -# CONFIG_CDROM_PKTCDVD is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_BLK_DEV_XIP is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set # CONFIG_ATA_OVER_ETH is not set -CONFIG_IDE=y -CONFIG_IDE_MAX_HWIFS=1 -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_BLK_DEV_IDESCSI is not set -CONFIG_IDE_TASK_IOCTL=y -CONFIG_IDE_PROC_FS=y - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -# CONFIG_IDEPCI_PCIBUS_ORDER is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -# CONFIG_IDEDMA_ONLYDISK is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_IT8213 is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SL82C105 is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_BLK_DEV_TC86C001 is not set -# CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_DAVINCI=y -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -# CONFIG_BLK_DEV_HD is not set +# CONFIG_MG_DISK is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +CONFIG_EEPROM_93CX6=y +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set # # SCSI device support # -# CONFIG_RAID_ATTRS is not set +CONFIG_RAID_ATTRS=m CONFIG_SCSI=y CONFIG_SCSI_DMA=y # CONFIG_SCSI_TGT is not set @@ -573,14 +978,11 @@ CONFIG_SCSI_PROC_FS=y CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=m +CONFIG_SCSI_MULTI_LUN=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set # CONFIG_SCSI_SCAN_ASYNC is not set @@ -591,65 +993,188 @@ CONFIG_SCSI_WAIT_SCAN=m # # CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=m # CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set +CONFIG_ISCSI_TCP=m +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set # CONFIG_ATA is not set -# CONFIG_MD is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID6_PQ=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +# CONFIG_DM_LOG_USERSPACE is not set +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +# CONFIG_DM_MULTIPATH_QL is not set +# CONFIG_DM_MULTIPATH_ST is not set +CONFIG_DM_DELAY=m +# CONFIG_DM_UEVENT is not set CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set +CONFIG_DUMMY=m +CONFIG_BONDING=m +CONFIG_MACVLAN=m +CONFIG_EQUALIZER=m CONFIG_TUN=m -# CONFIG_PHYLIB is not set +CONFIG_VETH=m +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set +CONFIG_MII=y # CONFIG_AX88796 is not set # CONFIG_SMC91X is not set -CONFIG_TI_DAVINCI_EMAC=y +# CONFIG_TI_DAVINCI_EMAC is not set # CONFIG_DM9000 is not set -CONFIG_NETDEV_1000=y -CONFIG_NETDEV_10000=y +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +CONFIG_SMC911X=y +CONFIG_SMSC911X=y +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set # # Wireless LAN # # CONFIG_WLAN_PRE80211 is not set CONFIG_WLAN_80211=y -# CONFIG_LIBERTAS is not set -# CONFIG_USB_ZD1201 is not set -# CONFIG_HOSTAP is not set +CONFIG_LIBERTAS=y +CONFIG_LIBERTAS_USB=y +# CONFIG_LIBERTAS_SDIO is not set +# CONFIG_LIBERTAS_SPI is not set +# CONFIG_LIBERTAS_DEBUG is not set +# CONFIG_LIBERTAS_THINFIRM is not set +# CONFIG_AT76C50X_USB is not set +CONFIG_USB_ZD1201=y +CONFIG_USB_NET_RNDIS_WLAN=y +CONFIG_RTL8187=y +CONFIG_RTL8187_LEDS=y +# CONFIG_MAC80211_HWSIM is not set +CONFIG_P54_COMMON=y +CONFIG_P54_USB=y +# CONFIG_P54_SPI is not set +CONFIG_P54_LEDS=y +# CONFIG_AR9170_USB is not set +CONFIG_HOSTAP=y +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_B43=y +CONFIG_B43_LEDS=y +CONFIG_B43_HWRNG=y +# CONFIG_B43_DEBUG is not set +# CONFIG_B43LEGACY is not set CONFIG_ZD1211RW=y # CONFIG_ZD1211RW_DEBUG is not set +CONFIG_RT2X00=y +CONFIG_RT2500USB=y +CONFIG_RT73USB=y +# CONFIG_RT2800USB is not set +CONFIG_RT2X00_LIB_USB=y +CONFIG_RT2X00_LIB=y +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_RFKILL=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set +# CONFIG_WL12XX is not set +# CONFIG_IWM is not set + +# +# WiMAX Wireless Broadband devices +# +# CONFIG_WIMAX_I2400M_USB is not set +# CONFIG_WIMAX_I2400M_SDIO is not set # # USB Network Adapters # -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET_MII is not set -# CONFIG_USB_USBNET is not set +CONFIG_USB_CATC=y +CONFIG_USB_KAWETH=y +CONFIG_USB_PEGASUS=y +CONFIG_USB_RTL8150=y +CONFIG_USB_USBNET=y +CONFIG_USB_NET_AX8817X=y +CONFIG_USB_NET_CDCETHER=y +# CONFIG_USB_NET_CDC_EEM is not set +CONFIG_USB_NET_DM9601=y +CONFIG_USB_NET_SMSC95XX=y +CONFIG_USB_NET_GL620A=y +CONFIG_USB_NET_NET1080=y +CONFIG_USB_NET_PLUSB=y +CONFIG_USB_NET_MCS7830=y +CONFIG_USB_NET_RNDIS_HOST=y +CONFIG_USB_NET_CDC_SUBSET=y +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +CONFIG_USB_NET_ZAURUS=y +# CONFIG_USB_NET_INT51X1 is not set # CONFIG_WAN is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +# CONFIG_ATM_TCP is not set CONFIG_PPP=m -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y CONFIG_PPP_ASYNC=m CONFIG_PPP_SYNC_TTY=m CONFIG_PPP_DEFLATE=m -# CONFIG_PPP_BSDCOMP is not set -# CONFIG_PPP_MPPE is not set -# CONFIG_PPPOE is not set -# CONFIG_PPPOL2TP is not set +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +# CONFIG_PPPOATM is not set +CONFIG_PPPOL2TP=m # CONFIG_SLIP is not set CONFIG_SLHC=m -# CONFIG_SHAPER is not set -CONFIG_NETCONSOLE=y +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_NETPOLL=y CONFIG_NETPOLL_TRAP=y CONFIG_NET_POLL_CONTROLLER=y @@ -659,8 +1184,8 @@ CONFIG_NET_POLL_CONTROLLER=y # Input device support # CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set +CONFIG_INPUT_FF_MEMLESS=y +CONFIG_INPUT_POLLDEV=y # # Userland interfaces @@ -670,22 +1195,36 @@ CONFIG_INPUT_MOUSEDEV_PSAUX=y CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_EVBUG is not set # # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_ATKBD is not set # CONFIG_KEYBOARD_LKKBD is not set -CONFIG_KEYBOARD_XTKBD=y +CONFIG_KEYBOARD_GPIO=y +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set # CONFIG_KEYBOARD_NEWTON is not set # CONFIG_KEYBOARD_STOWAWAY is not set -# CONFIG_KEYBOARD_GPIO is not set -# CONFIG_INPUT_MOUSE is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_GPIO is not set +# CONFIG_MOUSE_SYNAPTICS_I2C is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set @@ -695,8 +1234,10 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_KEYSPAN_REMOTE is not set # CONFIG_INPUT_POWERMATE is not set # CONFIG_INPUT_YEALINK is not set -# CONFIG_INPUT_UINPUT is not set -CONFIG_INPUT_NEUROS_IR=m +# CONFIG_INPUT_CM109 is not set +CONFIG_INPUT_TWL4030_PWRBUTTON=y +CONFIG_INPUT_UINPUT=y +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set # # Hardware I/O ports @@ -711,9 +1252,11 @@ CONFIG_SERIO_LIBPS2=y # Character devices # CONFIG_VT=y -# CONFIG_VT_CONSOLE is not set +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_DEVKMEM=y # CONFIG_SERIAL_NONSTANDARD is not set # @@ -721,101 +1264,146 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -# CONFIG_SERIAL_8250_EXTENDED is not set +CONFIG_SERIAL_8250_NR_UARTS=32 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_RSA=y # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set -# CONFIG_WATCHDOG is not set CONFIG_HW_RANDOM=y -# CONFIG_NVRAM is not set +# CONFIG_HW_RANDOM_TIMERIOMEM is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set -CONFIG_RESIZER=y # CONFIG_TCG_TPM is not set -# CONFIG_PREVIEWER is not set -CONFIG_THS7313=y CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y # -# I2C Algorithms +# I2C Hardware Bus support # -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set # -# I2C Hardware Bus support +# I2C system bus drivers (mostly embedded / system-on-chip) # +# CONFIG_I2C_DAVINCI is not set +# CONFIG_I2C_DESIGNWARE is not set # CONFIG_I2C_GPIO is not set # CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_STUB is not set # CONFIG_I2C_TINY_USB is not set -CONFIG_I2C_DAVINCI=y + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set # # Miscellaneous I2C Chip support # -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set # CONFIG_DS1682 is not set -# CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set +# CONFIG_PCF8575 is not set # CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -CONFIG_SENSORS_TLV320AIC23=y -CONFIG_SENSORS_TLV320AIC32=y -CONFIG_SENSORS_TLV320AIC33=y -# CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set -# CONFIG_GPIOEXPANDER_DAVINCI is not set -CONFIG_I2C_NEUROS_MSP430=m -CONFIG_I2C_NEUROS_SIL9034HDMI=m # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y # -# SPI support +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +CONFIG_GPIO_TWL4030=y + # -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set # CONFIG_W1 is not set +CONFIG_POWER_SUPPLY=m +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BATTERY_MAX17040 is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_ABITUGURU3 is not set +# CONFIG_SENSORS_AD7414 is not set # CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADCXX is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set # CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7473 is not set +# CONFIG_SENSORS_ADT7475 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_G760A is not set # CONFIG_SENSORS_GL518SM is not set # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set # CONFIG_SENSORS_LM75 is not set # CONFIG_SENSORS_LM77 is not set # CONFIG_SENSORS_LM78 is not set @@ -826,120 +1414,124 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_MAX1111 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_SHT15 is not set # CONFIG_SENSORS_DME1737 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_ADS7828 is not set # CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP401 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83791D is not set # CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83793 is not set # CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_LIS3_SPI is not set # CONFIG_HWMON_DEBUG_CHIP is not set -CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set -CONFIG_NEUROS_IR_BLASTER=m +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y # -# Multifunction device drivers +# Watchdog Device Drivers # -# CONFIG_MFD_SM501 is not set -# CONFIG_NEW_LEDS is not set - -# -# Multimedia devices -# -CONFIG_VIDEO_DEV=y -CONFIG_VIDEO_V4L1=y -CONFIG_VIDEO_V4L1_COMPAT=y -CONFIG_VIDEO_V4L2=y -CONFIG_VIDEO_CAPTURE_DRIVERS=y -# CONFIG_VIDEO_ADV_DEBUG is not set -CONFIG_VIDEO_HELPER_CHIPS_AUTO=y -CONFIG_VIDEO_TVP5150=y -CONFIG_VIDEO_DAVINCI=y - -# -# Video Capture Decoder -# -# CONFIG_VIDEO_TVP5146 is not set -CONFIG_VIDEO_TVP7000=y -# CONFIG_VIDEO_CPIA is not set -# CONFIG_VIDEO_CPIA2 is not set -# CONFIG_VIDEO_SAA5246A is not set -# CONFIG_VIDEO_SAA5249 is not set -# CONFIG_TUNER_3036 is not set -# CONFIG_TUNER_TEA5761 is not set -CONFIG_V4L_USB_DRIVERS=y -# CONFIG_VIDEO_PVRUSB2 is not set -# CONFIG_VIDEO_EM28XX is not set -# CONFIG_VIDEO_USBVISION is not set -# CONFIG_USB_VICAM is not set -# CONFIG_USB_IBMCAM is not set -# CONFIG_USB_KONICAWC is not set -# CONFIG_USB_QUICKCAM_MESSENGER is not set -# CONFIG_USB_ET61X251 is not set -# CONFIG_VIDEO_OVCAMCHIP is not set -# CONFIG_USB_W9968CF is not set -# CONFIG_USB_OV511 is not set -# CONFIG_USB_SE401 is not set -# CONFIG_USB_SN9C102 is not set -# CONFIG_USB_STV680 is not set -# CONFIG_USB_ZC0301 is not set -# CONFIG_USB_PWC is not set -# CONFIG_USB_ZR364XX is not set -CONFIG_RADIO_ADAPTERS=y -# CONFIG_RADIO_TEA5761 is not set -# CONFIG_USB_DSBR is not set -# CONFIG_DVB_CORE is not set -CONFIG_VIDEO_BUF=y -CONFIG_DAB=y -# CONFIG_USB_DABUSB is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_DAVINCI_WATCHDOG is not set +# CONFIG_TWL4030_WATCHDOG is not set # -# Graphics support +# USB-based Watchdog Cards # -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y # -# Display device support +# Sonics Silicon Backplane +# +CONFIG_SSB=y +# CONFIG_SSB_SILENT is not set +# CONFIG_SSB_DEBUG is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_TPS65010 is not set +CONFIG_TWL4030_CORE=y +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support # -# CONFIG_DISPLAY_SUPPORT is not set # CONFIG_VGASTATE is not set -CONFIG_VIDEO_OUTPUT_CONTROL=y -CONFIG_THS8200=y +# CONFIG_VIDEO_OUTPUT_CONTROL is not set CONFIG_FB=y -CONFIG_FIRMWARE_EDID=y +# CONFIG_FIRMWARE_EDID is not set # CONFIG_FB_DDC is not set -# CONFIG_FB_CFB_FILLRECT is not set -# CONFIG_FB_CFB_COPYAREA is not set -# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set # CONFIG_FB_SYS_FOPS is not set -CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set # CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_TILEBLITTING=y # # Frame buffer hardware drivers # # CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_DAVINCI is not set +CONFIG_FB_DAVINCI=y # CONFIG_FB_VIRTUAL is not set -CONFIG_FB_DM=y +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +CONFIG_DISPLAY_SUPPORT=y + +# +# Display hardware drivers +# # # Console display driver support @@ -948,60 +1540,106 @@ CONFIG_FB_DM=y CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y # CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y # CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y # CONFIG_LOGO is not set - -# -# Sound -# CONFIG_SOUND=y - -# -# Advanced Linux Sound Architecture -# -# CONFIG_SND is not set - -# -# Open Sound System -# -CONFIG_SOUND_PRIME=y -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set -CONFIG_SOUND_DAVINCI=y -CONFIG_SOUND_DAVINCI_AIC32=m -# CONFIG_SOUND_DAVINCI_AIC33 is not set - -# -# DaVinci Audio Options -# -# CONFIG_MONOSTEREO_DIFFJACK is not set -CONFIG_MONOSTEREO_SAMEJACK=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_HWDEP=y +CONFIG_SND_RAWMIDI=y +CONFIG_SND_JACK=y +CONFIG_SND_SEQUENCER=m +# CONFIG_SND_SEQ_DUMMY is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_HRTIMER=m +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_RAWMIDI_SEQ=m +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +# CONFIG_SND_ARM is not set +CONFIG_SND_SPI=y +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_SOC=y +CONFIG_SND_DAVINCI_SOC=y +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +# CONFIG_SOUND_PRIME is not set CONFIG_HID_SUPPORT=y CONFIG_HID=y -# CONFIG_HID_DEBUG is not set +CONFIG_HID_DEBUG=y +# CONFIG_HIDRAW is not set # # USB Input Devices # -CONFIG_USB_HID=m -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set # CONFIG_USB_HIDDEV is not set # -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set +# Special HID drivers +# +CONFIG_HID_A4TECH=y +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_CYPRESS=y +# CONFIG_HID_DRAGONRISE is not set +CONFIG_HID_EZKEY=y +# CONFIG_HID_KYE is not set +CONFIG_HID_GYRATION=y +# CONFIG_HID_KENSINGTON is not set +CONFIG_HID_LOGITECH=y +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +CONFIG_HID_NTRIG=y +CONFIG_HID_PANTHERLORD=y +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=y +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_HID_SUNPLUS=y +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +CONFIG_HID_TOPSEED=y +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_WACOM is not set +# CONFIG_HID_ZEROPLUS is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set # CONFIG_USB_ARCH_HAS_EHCI is not set CONFIG_USB=y # CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set # # Miscellaneous USB options @@ -1009,49 +1647,59 @@ CONFIG_USB=y CONFIG_USB_DEVICEFS=y CONFIG_USB_DEVICE_CLASS=y # CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y # CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set # # USB Host Controller Drivers # +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_OXU210HP_HCD=y # CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_U132_HCD is not set # CONFIG_USB_SL811_HCD is not set # CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set CONFIG_USB_MUSB_HDRC=y CONFIG_USB_MUSB_SOC=y # -# DaVinci 644x USB support +# DaVinci 35x and 644x USB support # CONFIG_USB_MUSB_HOST=y # CONFIG_USB_MUSB_PERIPHERAL is not set # CONFIG_USB_MUSB_OTG is not set # CONFIG_USB_GADGET_MUSB_HDRC is not set CONFIG_USB_MUSB_HDRC_HCD=y -# CONFIG_MUSB_PIO_ONLY is not set -# CONFIG_USB_INVENTRA_DMA is not set -CONFIG_USB_TI_CPPI_DMA=y -CONFIG_USB_MUSB_LOGLEVEL=0 +CONFIG_MUSB_PIO_ONLY=y +# CONFIG_USB_MUSB_DEBUG is not set # # USB Device Class drivers # -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_WDM=m +CONFIG_USB_TMC=m # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # # -# may also be needed; see USB_STORAGE Help for more information +# also be needed; see USB_STORAGE Help for more info # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set # CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set @@ -1059,6 +1707,7 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_ALAUDA is not set # CONFIG_USB_STORAGE_ONETOUCH is not set # CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set # CONFIG_USB_LIBUSUAL is not set # @@ -1066,100 +1715,277 @@ CONFIG_USB_STORAGE=y # # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set -CONFIG_USB_MON=y # # USB port drivers # - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set +CONFIG_USB_SERIAL=m +CONFIG_USB_EZUSB=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +# CONFIG_USB_SERIAL_CP210X is not set +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MOTOROLA=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +# CONFIG_USB_SERIAL_QUALCOMM is not set +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIEMENS_MPI=m +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +# CONFIG_USB_SERIAL_SYMBOL is not set +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTICON=m +CONFIG_USB_SERIAL_DEBUG=m # # USB Miscellaneous drivers # -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m # CONFIG_USB_ADUTUX is not set -# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_SEVSEG is not set # CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_LED=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_FTDI_ELAN=m # CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set +CONFIG_USB_SISUSBVGA=m +CONFIG_USB_SISUSBVGA_CON=y +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m # CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set - -# -# USB DSL modem support -# - -# -# USB Gadget Support -# -CONFIG_USB_GADGET=m +CONFIG_USB_TEST=m +# CONFIG_USB_ISIGHTFW is not set +CONFIG_USB_VST=m +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set # CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_DEBUG_FS=y +CONFIG_USB_GADGET_VBUS_DRAW=2 CONFIG_USB_GADGET_SELECTED=y -# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set # CONFIG_USB_GADGET_FSL_USB2 is not set -# CONFIG_USB_GADGET_NET2280 is not set -# CONFIG_USB_GADGET_PXA2XX is not set -CONFIG_USB_GADGET_M66592=y -CONFIG_USB_M66592=m -# CONFIG_USB_GADGET_GOKU is not set # CONFIG_USB_GADGET_LH7A40X is not set # CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set # CONFIG_USB_GADGET_S3C2410 is not set -# CONFIG_USB_GADGET_AT91 is not set +CONFIG_USB_GADGET_M66592=y +CONFIG_USB_M66592=y +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set CONFIG_USB_GADGET_DUALSPEED=y CONFIG_USB_ZERO=m +# CONFIG_USB_AUDIO is not set CONFIG_USB_ETH=m CONFIG_USB_ETH_RNDIS=y CONFIG_USB_GADGETFS=m CONFIG_USB_FILE_STORAGE=m # CONFIG_USB_FILE_STORAGE_TEST is not set CONFIG_USB_G_SERIAL=m -# CONFIG_USB_MIDI_GADGET is not set +CONFIG_USB_MIDI_GADGET=m +CONFIG_USB_G_PRINTER=m +CONFIG_USB_CDC_COMPOSITE=m + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +CONFIG_USB_GPIO_VBUS=y +CONFIG_TWL4030_USB=y +CONFIG_NOP_USB_XCEIV=y CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set -# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMC_UNSAFE_RESUME=y # -# MMC/SD Card Drivers +# MMC/SD/SDIO Card Drivers # CONFIG_MMC_BLOCK=y CONFIG_MMC_BLOCK_BOUNCE=y +CONFIG_SDIO_UART=y +# CONFIG_MMC_TEST is not set # -# MMC/SD Host Controller Drivers +# MMC/SD/SDIO Host Controller Drivers # +# CONFIG_MMC_SDHCI is not set CONFIG_MMC_DAVINCI=y +CONFIG_MMC_SPI=m +# CONFIG_MEMSTICK is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_GPIO=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set # -# DMA Engine support +# I2C RTC drivers # -# CONFIG_DMA_ENGINE is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +CONFIG_RTC_DRV_TWL4030=y +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set # -# DMA Clients +# SPI RTC drivers # +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_DMADEVICES=y # # DMA Devices # +# CONFIG_AUXDISPLAY is not set +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +# CONFIG_REGULATOR_BQ24022 is not set +# CONFIG_REGULATOR_MAX1586 is not set +CONFIG_REGULATOR_TWL4030=y +# CONFIG_REGULATOR_LP3971 is not set +CONFIG_UIO=m +CONFIG_UIO_PDRV=m +CONFIG_UIO_PDRV_GENIRQ=m +# CONFIG_UIO_SMX is not set +# CONFIG_UIO_SERCOS3 is not set +# CONFIG_STAGING is not set # # File systems @@ -1168,38 +1994,76 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +# CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4_FS=m +# CONFIG_EXT4DEV_COMPAT is not set +CONFIG_EXT4_FS_XATTR=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +# CONFIG_EXT4_FS_SECURITY is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set +CONFIG_JBD2=m +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=m +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_PROC_INFO=y +CONFIG_REISERFS_FS_XATTR=y +# CONFIG_REISERFS_FS_POSIX_ACL is not set +# CONFIG_REISERFS_FS_SECURITY is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_FS_POSIX_ACL=y CONFIG_XFS_FS=m # CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -CONFIG_MINIX_FS=m -# CONFIG_ROMFS_FS is not set +# CONFIG_XFS_DEBUG is not set +CONFIG_GFS2_FS=m +# CONFIG_GFS2_FS_LOCKING_DLM is not set +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +CONFIG_OCFS2_FS_STATS=y +CONFIG_OCFS2_DEBUG_MASKLOG=y +# CONFIG_OCFS2_DEBUG_FS is not set +# CONFIG_OCFS2_FS_POSIX_ACL is not set +CONFIG_BTRFS_FS=m +# CONFIG_BTRFS_FS_POSIX_ACL is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y +CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_QUOTA_TREE=y +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=y +CONFIG_QUOTACTL=y # CONFIG_AUTOFS_FS is not set CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=y +CONFIG_CUSE=y + +# +# Caches +# +# CONFIG_FSCACHE is not set # # CD-ROM/DVD Filesystems # -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y # # DOS/FAT/NT Filesystems @@ -1209,84 +2073,119 @@ CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_FAT_DEFAULT_CODEPAGE=437 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y # # Pseudo filesystems # CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_YAFFS_FS=y -CONFIG_YAFFS_YAFFS1=y -# CONFIG_YAFFS_9BYTE_TAGS is not set -# CONFIG_YAFFS_DOES_ECC is not set -CONFIG_YAFFS_YAFFS2=y -CONFIG_YAFFS_AUTO_YAFFS2=y -# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set -# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set -# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y -CONFIG_JFFS2_FS=y +CONFIG_CONFIGFS_FS=m +CONFIG_MISC_FILESYSTEMS=y +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_AFFS_FS=m +# CONFIG_ECRYPT_FS is not set +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BFS_FS=m +CONFIG_EFS_FS=m +CONFIG_JFFS2_FS=m CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_FS_XATTR is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_FS_POSIX_ACL=y +CONFIG_JFFS2_FS_SECURITY=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_LZO=y CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# +CONFIG_JFFS2_RUBIN=y +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +CONFIG_UBIFS_FS=y +CONFIG_UBIFS_FS_XATTR=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +# CONFIG_UBIFS_FS_DEBUG is not set +CONFIG_CRAMFS=m +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +CONFIG_VXFS_FS=m +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m +CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_ROMFS_FS=m +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +# CONFIG_NILFS2_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_V4_1 is not set +CONFIG_ROOT_NFS=y CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y CONFIG_NFSD_V3=y -# CONFIG_NFSD_V3_ACL is not set -# CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y -CONFIG_ROOT_NFS=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=m CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y -# CONFIG_SUNRPC_BIND34 is not set -# CONFIG_RPCSEC_GSS_KRB5 is not set +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set +CONFIG_CIFS=m +CONFIG_CIFS_STATS=y +CONFIG_CIFS_STATS2=y +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_DFS_UPCALL is not set +CONFIG_CIFS_EXPERIMENTAL=y +CONFIG_NCP_FS=m +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +CONFIG_CODA_FS=m +CONFIG_AFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_9P_FS=m # # Partition Types @@ -1296,146 +2195,284 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_OSF_PARTITION is not set # CONFIG_AMIGA_PARTITION is not set # CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set +CONFIG_MAC_PARTITION=y CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +CONFIG_LDM_DEBUG=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set +CONFIG_EFI_PARTITION=y # CONFIG_SYSV68_PARTITION is not set - -# -# Native Language Support -# CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -CONFIG_NLS_UTF8=m - -# -# Distributed Lock Manager -# -# CONFIG_DLM is not set - -# -# Profiling support -# -CONFIG_PROFILING=y -CONFIG_OPROFILE=y +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=y +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set # # Kernel hacking # -# CONFIG_PRINTK_TIME is not set +CONFIG_PRINTK_TIME=y +CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set +CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_BUGVERBOSE is not set -CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_ARM_UNWIND=y # CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_LL is not set # # Security options # -# CONFIG_KEYS is not set +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set # CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_XOR_BLOCKS=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_FIPS=y CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y CONFIG_CRYPTO_MANAGER=y -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=m +CONFIG_CRYPTO_XCBC=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_ARC4=y -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set +CONFIG_CRYPTO_LZO=y + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m CONFIG_CRYPTO_HW=y +CONFIG_BINARY_PRINTF=y # # Library routines # CONFIG_BITREVERSE=y -CONFIG_CRC_CCITT=m -# CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +CONFIG_CRC_T10DIF=y +CONFIG_CRC_ITU_T=y CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set +CONFIG_CRC7=y +CONFIG_LIBCRC32C=y CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y -CONFIG_PLIST=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/recipes/linux/linux-neuros_git.bb b/recipes/linux/linux-neuros_git.bb index 57d144ec76..9228ec24c8 100644 --- a/recipes/linux/linux-neuros_git.bb +++ b/recipes/linux/linux-neuros_git.bb @@ -2,15 +2,14 @@ require linux.inc DESCRIPTION = "Linux kernel for Neuros OSD devices" -SRCREV = "d29d662688b79d833c99cdcdcb7fb0f5b9d7fba0" +SRCREV = "465f0ba12501e1c4e048f0a3ca8182404aeb66fc" -PV = "2.6.23-${PR}+gitr${SRCREV}" -PR = "r14" +PV = "2.6.30+2.6.31rc5-${PR}+gitr${SRCREV}" PE = "1" COMPATIBLE_MACHINE = "(neuros-osd|neuros-osd2)" -SRC_URI = "git://github.com/neuros/linux-davinci-2.6.git;protocol=git;branch=master \ +SRC_URI = "git://github.com/vu3rdd/linux-davinci-osd2.git;protocol=git;branch=osd2 \ file://defconfig" S = "${WORKDIR}/git" -- cgit v1.2.3 From e00a889a30ca4756e4964261fa8ce36317efe481 Mon Sep 17 00:00:00 2001 From: Cliff Brake Date: Mon, 14 Sep 2009 11:37:17 -0400 Subject: rt-tests: add git recipe --- recipes/rt-tests/rt-tests_git.bb | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 recipes/rt-tests/rt-tests_git.bb diff --git a/recipes/rt-tests/rt-tests_git.bb b/recipes/rt-tests/rt-tests_git.bb new file mode 100644 index 0000000000..fbb07911c6 --- /dev/null +++ b/recipes/rt-tests/rt-tests_git.bb @@ -0,0 +1,26 @@ +DESCRIPTION = "Real-time tests, such as cyclictest, for real-time linux PREEMPT RT kernels" +HOMEPAGE = "http://rt.wiki.kernel.org/index.php/Cyclictest" +LICENSE = "GPL" +PR = "r0" + +SRCREV = "42ab9e7cd259fae674dc2b2aa2962caaf8f09409" + +PV = "0.51+${PR}+gitr${SRCREV}" + +SRC_URI = "git://git.kernel.org/pub/scm/linux/kernel/git/tglx/rt-tests;protocol=git" + +S = "${WORKDIR}/git" + +# Limit to cyclictest only for non-real-time kernels. +# EXTRA_OEMAKE = "cyclictest" + +TARGET_CC_ARCH += "${LDFLAGS}" + +do_install() { + install -d ${D}${bindir} + # any file that is executable by user and/or group + for binary in `find . -perm /u+x,g+x -type f` + do + install -m 0755 $binary ${D}${bindir} + done +} -- cgit v1.2.3 From c5e69bf053b1254f6235d33de498d993e8250913 Mon Sep 17 00:00:00 2001 From: Phil Blundell Date: Mon, 14 Sep 2009 16:57:08 +0100 Subject: binutils_2.19.51: remove already-applied patches, add source checksum --- conf/checksums.ini | 4 ++++ recipes/binutils/binutils_2.19.51.bb | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/conf/checksums.ini b/conf/checksums.ini index ab11453557..4e5fa19142 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -2742,6 +2742,10 @@ sha256=3e8225b4d7ace0a2039de752e11fd6922d3b89a7259a292c347391c4788739f6 md5=c55a2b1eadf818d38e963060412fadca sha256=11a53d332d2295f447ab49402a34d82875bbf5da8dc239ebb909eafdf3c26a36 +[ftp://sourceware.org/pub/binutils/snapshots/binutils-2.19.51.tar.bz2] +md5=fd59f36022f6ea802d1c844a2576e616 +sha256=52f350e2844e87f9e3bb60ade650ad806d020aafa66248ec2a55313d62ed60e4 + [ftp://ftp.gnu.org/gnu/binutils/binutils-2.19.tar.bz2] md5=17a52219dee5a76c1a9d9b0bfd337d66 sha256=bd2ea10ffc2bf62a917b05f4fbe3d02212589c2bc177fa0c51a9c874d3da528a diff --git a/recipes/binutils/binutils_2.19.51.bb b/recipes/binutils/binutils_2.19.51.bb index fe5491ee79..20e86c7f10 100644 --- a/recipes/binutils/binutils_2.19.51.bb +++ b/recipes/binutils/binutils_2.19.51.bb @@ -5,7 +5,6 @@ LICENSE = "GPLv3" SRC_URI = "\ ftp://sourceware.org/pub/binutils/snapshots/binutils-${PV}.tar.bz2 \ - file://binutils-2.16.91.0.6-objcopy-rename-errorcode.patch;patch=1 \ file://binutils-uclibc-100-uclibc-conf.patch;patch=1 \ file://110-arm-eabi-conf.patch;patch=1 \ file://binutils-uclibc-300-001_ld_makefile_patch.patch;patch=1 \ @@ -13,7 +12,6 @@ SRC_URI = "\ file://binutils-uclibc-300-012_check_ldrunpath_length.patch;patch=1 \ file://binutils-uclibc-gas-needs-libm.patch;patch=1 \ file://binutils-arm-pr7093.patch;patch=1 \ - file://uclibc-segfault.patch;patch=1 \ file://ld-stub-crash.patch;patch=1;pnum=0 \ " -- cgit v1.2.3 From 757510da73d00b7587500c73223cf854f783fd8d Mon Sep 17 00:00:00 2001 From: Leon Woestenberg Date: Mon, 14 Sep 2009 22:32:39 +0200 Subject: openrd-base: Support for Marvell Kirkwood ARM based OpenRD-Base board. Signed-off-by: Leon Woestenberg --- conf/machine/openrd-base.conf | 21 + .../linux-kirkwood/newer-arm-mach-types.patch | 181 ++ recipes/linux/linux-kirkwood/openrd-base/.config | 1812 ++++++++++++++++++++ recipes/linux/linux-kirkwood/openrd-base/defconfig | 1812 ++++++++++++++++++++ recipes/linux/linux-kirkwood_2.6.30.5.bb | 9 +- 5 files changed, 3832 insertions(+), 3 deletions(-) create mode 100644 conf/machine/openrd-base.conf create mode 100644 recipes/linux/linux-kirkwood/newer-arm-mach-types.patch create mode 100644 recipes/linux/linux-kirkwood/openrd-base/.config create mode 100644 recipes/linux/linux-kirkwood/openrd-base/defconfig diff --git a/conf/machine/openrd-base.conf b/conf/machine/openrd-base.conf new file mode 100644 index 0000000000..5c2796593a --- /dev/null +++ b/conf/machine/openrd-base.conf @@ -0,0 +1,21 @@ +#@NAME: ARM based OpenRD-Base + +MACHINE_EXTRA_RDEPENDS = "u-boot-utils" +MACHINE_EXTRA_RRECOMMENDS = "kernel-modules" + +# do ubiattach /dev/ubi_ctrl -m 4 +# From dmesg: +# UBI: smallest flash I/O unit: 2048 +# UBI: logical eraseblock size: 129024 bytes +# from ubiattach stdout: +# UBI device number 0, total 4096 LEBs +MKUBIFS_ARGS = "-m 2048 -e 129024 -c 4096" + +# do ubiattach /dev/ubi_ctrl -m 4 +# from dmesg: +# UBI: smallest flash I/O unit: 2048 +# UBI: physical eraseblock size: 131072 bytes (128 KiB) +# UBI: sub-page size: 512 +UBINIZE_ARGS = "-m 2048 -p 128KiB -s 512" + +require conf/machine/include/kirkwood.inc diff --git a/recipes/linux/linux-kirkwood/newer-arm-mach-types.patch b/recipes/linux/linux-kirkwood/newer-arm-mach-types.patch new file mode 100644 index 0000000000..f03308e924 --- /dev/null +++ b/recipes/linux/linux-kirkwood/newer-arm-mach-types.patch @@ -0,0 +1,181 @@ +Index: git/arch/arm/tools/mach-types +=================================================================== +--- git.orig/arch/arm/tools/mach-types 2009-09-14 22:09:58.000000000 +0200 ++++ git/arch/arm/tools/mach-types 2009-09-14 22:10:15.000000000 +0200 +@@ -12,7 +12,7 @@ + # + # http://www.arm.linux.org.uk/developer/machines/?action=new + # +-# Last update: Sat Jun 20 22:28:39 2009 ++# Last update: Sun Sep 13 23:04:38 2009 + # + # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number + # +@@ -1769,7 +1769,7 @@ + mi424wr MACH_MI424WR MI424WR 1778 + axs_ultrax MACH_AXS_ULTRAX AXS_ULTRAX 1779 + at572d940deb MACH_AT572D940DEB AT572D940DEB 1780 +-davinci_da8xx_evm MACH_DAVINCI_DA8XX_EVM DAVINCI_DA8XX_EVM 1781 ++davinci_da830_evm MACH_DAVINCI_DA830_EVM DAVINCI_DA830_EVM 1781 + ep9302 MACH_EP9302 EP9302 1782 + at572d940hfek MACH_AT572D940HFEB AT572D940HFEB 1783 + cybook3 MACH_CYBOOK3 CYBOOK3 1784 +@@ -1962,7 +1962,7 @@ + arm11 MACH_ARM11 ARM11 1972 + cpuat9260 MACH_CPUAT9260 CPUAT9260 1973 + cpupxa255 MACH_CPUPXA255 CPUPXA255 1974 +-cpuimx27 MACH_CPUIMX27 CPUIMX27 1975 ++eukrea_cpuimx27 MACH_CPUIMX27 CPUIMX27 1975 + cheflux MACH_CHEFLUX CHEFLUX 1976 + eb_cpux9k2 MACH_EB_CPUX9K2 EB_CPUX9K2 1977 + opcotec MACH_OPCOTEC OPCOTEC 1978 +@@ -2249,14 +2249,14 @@ + darwin MACH_DARWIN DARWIN 2262 + oratiscomu MACH_ORATISCOMU ORATISCOMU 2263 + rtsbc20 MACH_RTSBC20 RTSBC20 2264 +-i780 MACH_I780 I780 2265 ++sgh_i780 MACH_I780 I780 2265 + gemini324 MACH_GEMINI324 GEMINI324 2266 + oratislan MACH_ORATISLAN ORATISLAN 2267 + oratisalog MACH_ORATISALOG ORATISALOG 2268 + oratismadi MACH_ORATISMADI ORATISMADI 2269 + oratisot16 MACH_ORATISOT16 ORATISOT16 2270 + oratisdesk MACH_ORATISDESK ORATISDESK 2271 +-v2p_ca9 MACH_V2P_CA9 V2P_CA9 2272 ++v2_ca9 MACH_V2P_CA9 V2P_CA9 2272 + sintexo MACH_SINTEXO SINTEXO 2273 + cm3389 MACH_CM3389 CM3389 2274 + omap3_cio MACH_OMAP3_CIO OMAP3_CIO 2275 +@@ -2280,3 +2280,132 @@ + htctopaz MACH_HTCTOPAZ HTCTOPAZ 2293 + matrix504 MACH_MATRIX504 MATRIX504 2294 + mrfsa MACH_MRFSA MRFSA 2295 ++sc_p270 MACH_SC_P270 SC_P270 2296 ++atlas5_evb MACH_ATLAS5_EVB ATLAS5_EVB 2297 ++pelco_lobox MACH_PELCO_LOBOX PELCO_LOBOX 2298 ++dilax_pcu200 MACH_DILAX_PCU200 DILAX_PCU200 2299 ++leonardo MACH_LEONARDO LEONARDO 2300 ++zoran_approach7 MACH_ZORAN_APPROACH7 ZORAN_APPROACH7 2301 ++dp6xx MACH_DP6XX DP6XX 2302 ++bcm2153_vesper MACH_BCM2153_VESPER BCM2153_VESPER 2303 ++mahimahi MACH_MAHIMAHI MAHIMAHI 2304 ++clickc MACH_CLICKC CLICKC 2305 ++zb_gateway MACH_ZB_GATEWAY ZB_GATEWAY 2306 ++tazcard MACH_TAZCARD TAZCARD 2307 ++tazdev MACH_TAZDEV TAZDEV 2308 ++annax_cb_arm MACH_ANNAX_CB_ARM ANNAX_CB_ARM 2309 ++annax_dm3 MACH_ANNAX_DM3 ANNAX_DM3 2310 ++cerebric MACH_CEREBRIC CEREBRIC 2311 ++orca MACH_ORCA ORCA 2312 ++pc9260 MACH_PC9260 PC9260 2313 ++ems285a MACH_EMS285A EMS285A 2314 ++gec2410 MACH_GEC2410 GEC2410 2315 ++gec2440 MACH_GEC2440 GEC2440 2316 ++mw903 MACH_ARCH_MW903 ARCH_MW903 2317 ++mw2440 MACH_MW2440 MW2440 2318 ++ecac2378 MACH_ECAC2378 ECAC2378 2319 ++tazkiosk MACH_TAZKIOSK TAZKIOSK 2320 ++whiterabbit_mch MACH_WHITERABBIT_MCH WHITERABBIT_MCH 2321 ++sbox9263 MACH_SBOX9263 SBOX9263 2322 ++oreo MACH_OREO OREO 2323 ++smdk6442 MACH_SMDK6442 SMDK6442 2324 ++openrd_base MACH_OPENRD_BASE OPENRD_BASE 2325 ++incredible MACH_INCREDIBLE INCREDIBLE 2326 ++incrediblec MACH_INCREDIBLEC INCREDIBLEC 2327 ++heroct MACH_HEROCT HEROCT 2328 ++mmnet1000 MACH_MMNET1000 MMNET1000 2329 ++devkit8000 MACH_DEVKIT8000 DEVKIT8000 2330 ++devkit9000 MACH_DEVKIT9000 DEVKIT9000 2331 ++mx31txtr MACH_MX31TXTR MX31TXTR 2332 ++u380 MACH_U380 U380 2333 ++oamp3_hualu MACH_HUALU_BOARD HUALU_BOARD 2334 ++npcmx50 MACH_NPCMX50 NPCMX50 2335 ++mx51_lange51 MACH_MX51_LANGE51 MX51_LANGE51 2336 ++mx51_lange52 MACH_MX51_LANGE52 MX51_LANGE52 2337 ++riom MACH_RIOM RIOM 2338 ++comcas MACH_COMCAS COMCAS 2339 ++wsi_mx27 MACH_WSI_MX27 WSI_MX27 2340 ++cm_t35 MACH_CM_T35 CM_T35 2341 ++net2big MACH_NET2BIG NET2BIG 2342 ++motorola_a1600 MACH_MOTOROLA_A1600 MOTOROLA_A1600 2343 ++igep0020 MACH_IGEP0020 IGEP0020 2344 ++igep0010 MACH_IGEP0010 IGEP0010 2345 ++mv6281gtwge2 MACH_MV6281GTWGE2 MV6281GTWGE2 2346 ++scat100 MACH_SCAT100 SCAT100 2347 ++sanmina MACH_SANMINA SANMINA 2348 ++momento MACH_MOMENTO MOMENTO 2349 ++nuc9xx MACH_NUC9XX NUC9XX 2350 ++nuc910evb MACH_NUC910EVB NUC910EVB 2351 ++nuc920evb MACH_NUC920EVB NUC920EVB 2352 ++nuc950evb MACH_NUC950EVB NUC950EVB 2353 ++nuc945evb MACH_NUC945EVB NUC945EVB 2354 ++nuc960evb MACH_NUC960EVB NUC960EVB 2355 ++nuc932evb MACH_NUC932EVB NUC932EVB 2356 ++nuc900 MACH_NUC900 NUC900 2357 ++sd1soc MACH_SD1SOC SD1SOC 2358 ++ln2440bc MACH_LN2440BC LN2440BC 2359 ++rsbc MACH_RSBC RSBC 2360 ++openrd_client MACH_OPENRD_CLIENT OPENRD_CLIENT 2361 ++hpipaq11x MACH_HPIPAQ11X HPIPAQ11X 2362 ++wayland MACH_WAYLAND WAYLAND 2363 ++acnbsx102 MACH_ACNBSX102 ACNBSX102 2364 ++hwat91 MACH_HWAT91 HWAT91 2365 ++at91sam9263cs MACH_AT91SAM9263CS AT91SAM9263CS 2366 ++csb732 MACH_CSB732 CSB732 2367 ++u8500 MACH_U8500 U8500 2368 ++huqiu MACH_HUQIU HUQIU 2369 ++mx51_kunlun MACH_MX51_KUNLUN MX51_KUNLUN 2370 ++pmt1g MACH_PMT1G PMT1G 2371 ++htcelf MACH_HTCELF HTCELF 2372 ++armadillo420 MACH_ARMADILLO420 ARMADILLO420 2373 ++armadillo440 MACH_ARMADILLO440 ARMADILLO440 2374 ++u_chip_dual_arm MACH_U_CHIP_DUAL_ARM U_CHIP_DUAL_ARM 2375 ++csr_bdb3 MACH_CSR_BDB3 CSR_BDB3 2376 ++dolby_cat1018 MACH_DOLBY_CAT1018 DOLBY_CAT1018 2377 ++hy9307 MACH_HY9307 HY9307 2378 ++aspire_easystore MACH_A_ES A_ES 2379 ++davinci_irif MACH_DAVINCI_IRIF DAVINCI_IRIF 2380 ++agama9263 MACH_AGAMA9263 AGAMA9263 2381 ++marvell_jasper MACH_MARVELL_JASPER MARVELL_JASPER 2382 ++flint MACH_FLINT FLINT 2383 ++tavorevb3 MACH_TAVOREVB3 TAVOREVB3 2384 ++sch_m490 MACH_SCH_M490 SCH_M490 2386 ++rbl01 MACH_RBL01 RBL01 2387 ++omnifi MACH_OMNIFI OMNIFI 2388 ++otavalo MACH_OTAVALO OTAVALO 2389 ++sienna MACH_SIENNA SIENNA 2390 ++htc_excalibur_s620 MACH_HTC_EXCALIBUR_S620 HTC_EXCALIBUR_S620 2391 ++htc_opal MACH_HTC_OPAL HTC_OPAL 2392 ++touchbook MACH_TOUCHBOOK TOUCHBOOK 2393 ++latte MACH_LATTE LATTE 2394 ++xa200 MACH_XA200 XA200 2395 ++nimrod MACH_NIMROD NIMROD 2396 ++cc9p9215_3g MACH_CC9P9215_3G CC9P9215_3G 2397 ++cc9p9215_3gjs MACH_CC9P9215_3GJS CC9P9215_3GJS 2398 ++tk71 MACH_TK71 TK71 2399 ++comham3525 MACH_COMHAM3525 COMHAM3525 2400 ++mx31erebus MACH_MX31EREBUS MX31EREBUS 2401 ++mcardmx27 MACH_MCARDMX27 MCARDMX27 2402 ++paradise MACH_PARADISE PARADISE 2403 ++tide MACH_TIDE TIDE 2404 ++wzl2440 MACH_WZL2440 WZL2440 2405 ++sdrdemo MACH_SDRDEMO SDRDEMO 2406 ++ethercan2 MACH_ETHERCAN2 ETHERCAN2 2407 ++ecmimg20 MACH_ECMIMG20 ECMIMG20 2408 ++omap_dragon MACH_OMAP_DRAGON OMAP_DRAGON 2409 ++halo MACH_HALO HALO 2410 ++huangshan MACH_HUANGSHAN HUANGSHAN 2411 ++vl_ma2sc MACH_VL_MA2SC VL_MA2SC 2412 ++raumfeld_rc MACH_RAUMFELD_RC RAUMFELD_RC 2413 ++raumfeld_connector MACH_RAUMFELD_CONNECTOR RAUMFELD_CONNECTOR 2414 ++raumfeld_speaker MACH_RAUMFELD_SPEAKER RAUMFELD_SPEAKER 2415 ++multibus_master MACH_MULTIBUS_MASTER MULTIBUS_MASTER 2416 ++multibus_pbk MACH_MULTIBUS_PBK MULTIBUS_PBK 2417 ++tnetv107x MACH_TNETV107X TNETV107X 2418 ++snake MACH_SNAKE SNAKE 2419 ++cwmx27 MACH_CWMX27 CWMX27 2420 ++sch_m480 MACH_SCH_M480 SCH_M480 2421 ++platypus MACH_PLATYPUS PLATYPUS 2422 ++pss2 MACH_PSS2 PSS2 2423 ++davinci_apm150 MACH_DAVINCI_APM150 DAVINCI_APM150 2424 ++str9100 MACH_STR9100 STR9100 2425 diff --git a/recipes/linux/linux-kirkwood/openrd-base/.config b/recipes/linux/linux-kirkwood/openrd-base/.config new file mode 100644 index 0000000000..adb4ca64f1 --- /dev/null +++ b/recipes/linux/linux-kirkwood/openrd-base/.config @@ -0,0 +1,1812 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.31-rc9 +# Mon Sep 14 00:31:10 2009 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=19 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Performance Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_PCI_QUIRKS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_MARKERS=y +CONFIG_OPROFILE=y +CONFIG_HAVE_OPROFILE=y +CONFIG_KPROBES=y +CONFIG_KRETPROBES=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_FREEZER is not set + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +CONFIG_ARCH_KIRKWOOD=y +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set + +# +# Marvell Kirkwood Implementations +# +# CONFIG_MACH_DB88F6281_BP is not set +# CONFIG_MACH_RD88F6192_NAS is not set +# CONFIG_MACH_RD88F6281 is not set +# CONFIG_MACH_MV88F6281GTW_GE is not set +# CONFIG_MACH_SHEEVAPLUG is not set +# CONFIG_MACH_TS219 is not set +CONFIG_MACH_OPENRD_BASE=y +CONFIG_PLAT_ORION=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_FEROCEON=y +# CONFIG_CPU_FEROCEON_OLD_ID is not set +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_FEROCEON=y +CONFIG_CPU_TLB_FEROCEON=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +CONFIG_OUTER_CACHE=y +CONFIG_CACHE_FEROCEON_L2=y +# CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH is not set + +# +# Bus support +# +CONFIG_PCI=y +CONFIG_PCI_SYSCALL=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_PCI_LEGACY=y +CONFIG_PCI_DEBUG=y +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ALIGNMENT_TRAP=y +CONFIG_UACCESS_WITH_MEMCPY=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +CONFIG_NET_DSA=y +# CONFIG_NET_DSA_TAG_DSA is not set +CONFIG_NET_DSA_TAG_EDSA=y +# CONFIG_NET_DSA_TAG_TRAILER is not set +CONFIG_NET_DSA_MV88E6XXX=y +# CONFIG_NET_DSA_MV88E6060 is not set +# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set +# CONFIG_NET_DSA_MV88E6131 is not set +CONFIG_NET_DSA_MV88E6123_61_65=y +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +# CONFIG_NET_TCPPROBE is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +CONFIG_CFG80211=y +# CONFIG_CFG80211_REG_DEBUG is not set +# CONFIG_CFG80211_DEBUGFS is not set +CONFIG_WIRELESS_OLD_REGULATORY=y +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_LIB80211=y +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=y +CONFIG_MAC80211_DEFAULT_PS=y +CONFIG_MAC80211_DEFAULT_PS_VALUE=1 + +# +# Rate control algorithm selection +# +CONFIG_MAC80211_RC_MINSTREL=y +# CONFIG_MAC80211_RC_DEFAULT_PID is not set +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel" +# CONFIG_MAC80211_LEDS is not set +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_DATAFLASH is not set +CONFIG_MTD_M25P80=y +CONFIG_M25PXX_USE_FAST_READ=y +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_CAFE is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +CONFIG_MTD_NAND_ORION=y +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_GLUEBI is not set + +# +# UBI debugging options +# +CONFIG_MTD_UBI_DEBUG=y +# CONFIG_MTD_UBI_DEBUG_MSG is not set +CONFIG_MTD_UBI_DEBUG_PARANOID=y +# CONFIG_MTD_UBI_DEBUG_DISABLE_BGT is not set +# CONFIG_MTD_UBI_DEBUG_EMULATE_BITFLIPS is not set +# CONFIG_MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES is not set +# CONFIG_MTD_UBI_DEBUG_EMULATE_ERASE_FAILURES is not set + +# +# Additional UBI debugging messages +# +# CONFIG_MTD_UBI_DEBUG_MSG_BLD is not set +# CONFIG_MTD_UBI_DEBUG_MSG_EBA is not set +# CONFIG_MTD_UBI_DEBUG_MSG_WL is not set +# CONFIG_MTD_UBI_DEBUG_MSG_IO is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_MPT2SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_FCOE is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_SATA_PMP=y +CONFIG_SATA_AHCI=y +# CONFIG_SATA_SIL24 is not set +CONFIG_ATA_SFF=y +# CONFIG_SATA_SVW is not set +# CONFIG_ATA_PIIX is not set +CONFIG_SATA_MV=y +# CONFIG_SATA_NV is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set +# CONFIG_PATA_SCH is not set +# CONFIG_MD is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# You can enable one or both FireWire driver stacks. +# + +# +# See the help texts for more information. +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_ARCNET is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +CONFIG_MARVELL_PHY=y +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_R6040 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SMSC9420 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_SC92031 is not set +# CONFIG_ATL2 is not set +CONFIG_NETDEV_1000=y +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set +# CONFIG_IGBVF is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_CNIC is not set +CONFIG_MV643XX_ETH=y +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL1C is not set +# CONFIG_JME is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +CONFIG_WLAN_80211=y +CONFIG_LIBERTAS=y +# CONFIG_LIBERTAS_USB is not set +CONFIG_LIBERTAS_SDIO=y +# CONFIG_LIBERTAS_SPI is not set +# CONFIG_LIBERTAS_DEBUG is not set +# CONFIG_LIBERTAS_THINFIRM is not set +# CONFIG_ATMEL is not set +# CONFIG_AT76C50X_USB is not set +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_USB_NET_RNDIS_WLAN is not set +# CONFIG_RTL8180 is not set +# CONFIG_RTL8187 is not set +# CONFIG_ADM8211 is not set +# CONFIG_MAC80211_HWSIM is not set +# CONFIG_MWL8K is not set +# CONFIG_P54_COMMON is not set +# CONFIG_ATH5K is not set +# CONFIG_ATH9K is not set +# CONFIG_AR9170_USB is not set +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set +# CONFIG_IWLWIFI is not set +# CONFIG_HOSTAP is not set +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +# CONFIG_ZD1211RW is not set +# CONFIG_RT2X00 is not set +# CONFIG_HERMES is not set +# CONFIG_WL12XX is not set +# CONFIG_IWM is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_KEYBOARD_GPIO=y +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_DEVKMEM is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_GPIO is not set +CONFIG_I2C_MV64XXX=y +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Graphics adapter I2C/DDC channel drivers +# +# CONFIG_I2C_VOODOO3 is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_PCF8575 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +CONFIG_SPI_ORION=y + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set + +# +# PCI GPIO expanders: +# +# CONFIG_GPIO_BT8XX is not set + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=y +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_CYPRESS=y +CONFIG_HID_DRAGONRISE=y +# CONFIG_DRAGONRISE_FF is not set +CONFIG_HID_EZKEY=y +CONFIG_HID_KYE=y +CONFIG_HID_GYRATION=y +CONFIG_HID_KENSINGTON=y +CONFIG_HID_LOGITECH=y +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +CONFIG_HID_NTRIG=y +CONFIG_HID_PANTHERLORD=y +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=y +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_HID_SUNPLUS=y +CONFIG_HID_GREENASIA=y +# CONFIG_GREENASIA_FF is not set +CONFIG_HID_SMARTJOYPLUS=y +# CONFIG_SMARTJOYPLUS_FF is not set +CONFIG_HID_TOPSEED=y +CONFIG_HID_THRUSTMASTER=y +# CONFIG_THRUSTMASTER_FF is not set +CONFIG_HID_ZEROPLUS=y +# CONFIG_ZEROPLUS_FF is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_WHCI_HCD is not set +# CONFIG_USB_HWA_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +CONFIG_USB_PRINTER=m +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_UWB is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +CONFIG_SDIO_UART=y +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_TIFM_SD is not set +CONFIG_MMC_MVSDIO=y +# CONFIG_MMC_SPI is not set +# CONFIG_MMC_CB710 is not set +# CONFIG_MMC_VIA_SDMMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +CONFIG_RTC_DRV_S35390A=y +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_MV=y +CONFIG_DMADEVICES=y + +# +# DMA Devices +# +CONFIG_MV_XOR=y +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_REGULATOR is not set +# CONFIG_UIO is not set +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_UBIFS_FS is not set +CONFIG_CRAMFS=y +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=y +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_KPROBES_SANITY_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_LKDTM is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +# CONFIG_PAGE_POISONING is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_ARM_UNWIND=y +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/recipes/linux/linux-kirkwood/openrd-base/defconfig b/recipes/linux/linux-kirkwood/openrd-base/defconfig new file mode 100644 index 0000000000..1271b90cd9 --- /dev/null +++ b/recipes/linux/linux-kirkwood/openrd-base/defconfig @@ -0,0 +1,1812 @@ +# leon was here +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.31-rc9 +# Mon Sep 14 00:31:10 2009 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=19 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Performance Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_PCI_QUIRKS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_MARKERS=y +CONFIG_OPROFILE=y +CONFIG_HAVE_OPROFILE=y +CONFIG_KPROBES=y +CONFIG_KRETPROBES=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_FREEZER is not set + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +CONFIG_ARCH_KIRKWOOD=y +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set + +# +# Marvell Kirkwood Implementations +# +# CONFIG_MACH_DB88F6281_BP is not set +# CONFIG_MACH_RD88F6192_NAS is not set +# CONFIG_MACH_RD88F6281 is not set +# CONFIG_MACH_MV88F6281GTW_GE is not set +# CONFIG_MACH_SHEEVAPLUG is not set +# CONFIG_MACH_TS219 is not set +CONFIG_MACH_OPENRD_BASE=y +CONFIG_PLAT_ORION=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_FEROCEON=y +# CONFIG_CPU_FEROCEON_OLD_ID is not set +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_FEROCEON=y +CONFIG_CPU_TLB_FEROCEON=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +CONFIG_OUTER_CACHE=y +CONFIG_CACHE_FEROCEON_L2=y +# CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH is not set + +# +# Bus support +# +CONFIG_PCI=y +CONFIG_PCI_SYSCALL=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_PCI_LEGACY=y +CONFIG_PCI_DEBUG=y +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ALIGNMENT_TRAP=y +CONFIG_UACCESS_WITH_MEMCPY=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +CONFIG_NET_DSA=y +# CONFIG_NET_DSA_TAG_DSA is not set +CONFIG_NET_DSA_TAG_EDSA=y +# CONFIG_NET_DSA_TAG_TRAILER is not set +CONFIG_NET_DSA_MV88E6XXX=y +# CONFIG_NET_DSA_MV88E6060 is not set +# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set +# CONFIG_NET_DSA_MV88E6131 is not set +CONFIG_NET_DSA_MV88E6123_61_65=y +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +# CONFIG_NET_TCPPROBE is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +CONFIG_CFG80211=y +# CONFIG_CFG80211_REG_DEBUG is not set +# CONFIG_CFG80211_DEBUGFS is not set +CONFIG_WIRELESS_OLD_REGULATORY=y +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_LIB80211=y +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=y +CONFIG_MAC80211_DEFAULT_PS=y +CONFIG_MAC80211_DEFAULT_PS_VALUE=1 + +# +# Rate control algorithm selection +# +CONFIG_MAC80211_RC_MINSTREL=y +# CONFIG_MAC80211_RC_DEFAULT_PID is not set +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel" +# CONFIG_MAC80211_LEDS is not set +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_DATAFLASH is not set +CONFIG_MTD_M25P80=y +CONFIG_M25PXX_USE_FAST_READ=y +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_CAFE is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +CONFIG_MTD_NAND_ORION=y +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_GLUEBI is not set + +# +# UBI debugging options +# +CONFIG_MTD_UBI_DEBUG=y +# CONFIG_MTD_UBI_DEBUG_MSG is not set +CONFIG_MTD_UBI_DEBUG_PARANOID=y +# CONFIG_MTD_UBI_DEBUG_DISABLE_BGT is not set +# CONFIG_MTD_UBI_DEBUG_EMULATE_BITFLIPS is not set +# CONFIG_MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES is not set +# CONFIG_MTD_UBI_DEBUG_EMULATE_ERASE_FAILURES is not set + +# +# Additional UBI debugging messages +# +# CONFIG_MTD_UBI_DEBUG_MSG_BLD is not set +# CONFIG_MTD_UBI_DEBUG_MSG_EBA is not set +# CONFIG_MTD_UBI_DEBUG_MSG_WL is not set +# CONFIG_MTD_UBI_DEBUG_MSG_IO is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_MPT2SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_FCOE is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_SATA_PMP=y +CONFIG_SATA_AHCI=y +# CONFIG_SATA_SIL24 is not set +CONFIG_ATA_SFF=y +# CONFIG_SATA_SVW is not set +# CONFIG_ATA_PIIX is not set +CONFIG_SATA_MV=y +# CONFIG_SATA_NV is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set +# CONFIG_PATA_SCH is not set +# CONFIG_MD is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# You can enable one or both FireWire driver stacks. +# + +# +# See the help texts for more information. +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_ARCNET is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +CONFIG_MARVELL_PHY=y +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_R6040 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SMSC9420 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_SC92031 is not set +# CONFIG_ATL2 is not set +CONFIG_NETDEV_1000=y +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set +# CONFIG_IGBVF is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_CNIC is not set +CONFIG_MV643XX_ETH=y +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL1C is not set +# CONFIG_JME is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +CONFIG_WLAN_80211=y +CONFIG_LIBERTAS=y +# CONFIG_LIBERTAS_USB is not set +CONFIG_LIBERTAS_SDIO=y +# CONFIG_LIBERTAS_SPI is not set +# CONFIG_LIBERTAS_DEBUG is not set +# CONFIG_LIBERTAS_THINFIRM is not set +# CONFIG_ATMEL is not set +# CONFIG_AT76C50X_USB is not set +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_USB_NET_RNDIS_WLAN is not set +# CONFIG_RTL8180 is not set +# CONFIG_RTL8187 is not set +# CONFIG_ADM8211 is not set +# CONFIG_MAC80211_HWSIM is not set +# CONFIG_MWL8K is not set +# CONFIG_P54_COMMON is not set +# CONFIG_ATH5K is not set +# CONFIG_ATH9K is not set +# CONFIG_AR9170_USB is not set +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set +# CONFIG_IWLWIFI is not set +# CONFIG_HOSTAP is not set +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +# CONFIG_ZD1211RW is not set +# CONFIG_RT2X00 is not set +# CONFIG_HERMES is not set +# CONFIG_WL12XX is not set +# CONFIG_IWM is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_KEYBOARD_GPIO=y +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_DEVKMEM is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_GPIO is not set +CONFIG_I2C_MV64XXX=y +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Graphics adapter I2C/DDC channel drivers +# +# CONFIG_I2C_VOODOO3 is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_PCF8575 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +CONFIG_SPI_ORION=y + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set + +# +# PCI GPIO expanders: +# +# CONFIG_GPIO_BT8XX is not set + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=y +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_CYPRESS=y +CONFIG_HID_DRAGONRISE=y +# CONFIG_DRAGONRISE_FF is not set +CONFIG_HID_EZKEY=y +CONFIG_HID_KYE=y +CONFIG_HID_GYRATION=y +CONFIG_HID_KENSINGTON=y +CONFIG_HID_LOGITECH=y +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +CONFIG_HID_NTRIG=y +CONFIG_HID_PANTHERLORD=y +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=y +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_HID_SUNPLUS=y +CONFIG_HID_GREENASIA=y +# CONFIG_GREENASIA_FF is not set +CONFIG_HID_SMARTJOYPLUS=y +# CONFIG_SMARTJOYPLUS_FF is not set +CONFIG_HID_TOPSEED=y +CONFIG_HID_THRUSTMASTER=y +# CONFIG_THRUSTMASTER_FF is not set +CONFIG_HID_ZEROPLUS=y +# CONFIG_ZEROPLUS_FF is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_WHCI_HCD is not set +# CONFIG_USB_HWA_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +CONFIG_USB_PRINTER=m +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_UWB is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +CONFIG_SDIO_UART=y +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_TIFM_SD is not set +CONFIG_MMC_MVSDIO=y +# CONFIG_MMC_SPI is not set +# CONFIG_MMC_CB710 is not set +# CONFIG_MMC_VIA_SDMMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +CONFIG_RTC_DRV_S35390A=y +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_MV=y +CONFIG_DMADEVICES=y + +# +# DMA Devices +# +CONFIG_MV_XOR=y +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_REGULATOR is not set +# CONFIG_UIO is not set +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_UBIFS_FS is not set +CONFIG_CRAMFS=y +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=y +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_KPROBES_SANITY_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_LKDTM is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +# CONFIG_PAGE_POISONING is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_ARM_UNWIND=y +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/recipes/linux/linux-kirkwood_2.6.30.5.bb b/recipes/linux/linux-kirkwood_2.6.30.5.bb index 43898c81eb..84dbb8dbcc 100644 --- a/recipes/linux/linux-kirkwood_2.6.30.5.bb +++ b/recipes/linux/linux-kirkwood_2.6.30.5.bb @@ -1,7 +1,7 @@ DESCRIPTION = "Linux Kernel for Marvell Kirkwood based devices" SECTION = "kernel" LICENSE = "GPL" -COMPATIBLE_MACHINE = "sheevaplug" +COMPATIBLE_MACHINE = "(openrd-base|sheevaplug)" require linux.inc @@ -9,9 +9,12 @@ require linux.inc PV = "2.6.30.5" SRCREV = "6fa23e56edcb79a348c968aada8190944f4f3633" + SRC_URI = "git://git.marvell.com/orion.git;protocol=git;branch=stable-2.6.30 \ - file://defconfig \ - " + file://defconfig" + +SRCREV_openrd-base = "8cb424312d88810bb62edbeef42a510725ceb482" +SRC_URI_append_openrd-base = " file://newer-arm-mach-types.patch;patch=1 " S = "${WORKDIR}/git" -- cgit v1.2.3 From 13bea4b76e58eb0342654c749d259536407e16d3 Mon Sep 17 00:00:00 2001 From: Phil Blundell Date: Mon, 14 Sep 2009 22:21:14 +0100 Subject: micro: select Thumb code where possible --- conf/distro/micro.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/conf/distro/micro.conf b/conf/distro/micro.conf index 67e3aff3ca..5ee6f9b393 100644 --- a/conf/distro/micro.conf +++ b/conf/distro/micro.conf @@ -62,6 +62,7 @@ MACHINE_KERNEL_VERSION = "2.6" ############################################################################# LIBC ?= "eglibc" PREFERRED_BINUTILS = "2.19.51" +PREFERRED_ARM_INSTRUCTION_SET = "thumb" require conf/distro/include/sane-toolchain.inc ############################################################################# -- cgit v1.2.3 From 2aaa77d10a35012cd1c7a86c1fb583c4fabcf782 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Mon, 14 Sep 2009 20:11:36 -0700 Subject: xserver-xorg-1.5.3: Fix the build with nptl * These two patches are ported from http://bugs.gentoo.org/show_bug.cgi?id=263679#c13 it fixes the following error. ../../glx/.libs/libglx.a(glapi.o): In function `_glapi_set_dispatch': glapi.c:(.text+0x117ac): undefined reference to `pthread_once' collect2: ld returned 1 exit status make[3]: *** [Xvfb] Error 1 Signed-off-by: Khem Raj --- .../xorg-server-1.5.3-configure.patch | 38 ++++++++ ...g-server-1.5.3-glcore-prepare-for-dynamic.patch | 108 +++++++++++++++++++++ recipes/xorg-xserver/xserver-xorg_1.5.3.bb | 4 +- 3 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 recipes/xorg-xserver/xserver-xorg-1.5.3/xorg-server-1.5.3-configure.patch create mode 100644 recipes/xorg-xserver/xserver-xorg-1.5.3/xorg-server-1.5.3-glcore-prepare-for-dynamic.patch diff --git a/recipes/xorg-xserver/xserver-xorg-1.5.3/xorg-server-1.5.3-configure.patch b/recipes/xorg-xserver/xserver-xorg-1.5.3/xorg-server-1.5.3-configure.patch new file mode 100644 index 0000000000..85db023a6d --- /dev/null +++ b/recipes/xorg-xserver/xserver-xorg-1.5.3/xorg-server-1.5.3-configure.patch @@ -0,0 +1,38 @@ +From ddb265e3c5e99065ceeef92ecb9fd94b4c3e169e Mon Sep 17 00:00:00 2001 +From: Daniel Stone +Date: Thu, 7 May 2009 14:23:25 +0200 +Subject: [PATCH 36/78] configure.ac: Add GLX_SYS_LIBS for Xvfb and Xnest + +This fixes the linking for these two when using DRI2, which requires +DLOPEN_LIBS. +(cherry picked from commit ae38151ddda9984effca5bb7c582540061201dce) + +Conflicts: + + configure.ac +--- + configure.ac | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +Index: xorg-server-1.5.3/configure.ac +=================================================================== +--- xorg-server-1.5.3.orig/configure.ac 2008-11-05 11:46:15.000000000 -0800 ++++ xorg-server-1.5.3/configure.ac 2009-09-14 19:48:11.043879237 -0700 +@@ -1215,7 +1215,7 @@ + + if test "x$XVFB" = xyes; then + XVFB_LIBS="$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB" +- XVFB_SYS_LIBS="$XVFBMODULES_LIBS" ++ XVFB_SYS_LIBS="$XVFBMODULES_LIBS $GLX_SYS_LIBS" + AC_SUBST([XVFB_LIBS]) + AC_SUBST([XVFB_SYS_LIBS]) + fi +@@ -1233,7 +1233,7 @@ + + if test "x$XNEST" = xyes; then + XNEST_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $DIX_LIB $OS_LIB $CONFIG_LIB" +- XNEST_SYS_LIBS="$XNESTMODULES_LIBS" ++ XNEST_SYS_LIBS="$XNESTMODULES_LIBS $GLX_SYS_LIBS" + AC_SUBST([XNEST_LIBS]) + AC_SUBST([XNEST_SYS_LIBS]) + fi diff --git a/recipes/xorg-xserver/xserver-xorg-1.5.3/xorg-server-1.5.3-glcore-prepare-for-dynamic.patch b/recipes/xorg-xserver/xserver-xorg-1.5.3/xorg-server-1.5.3-glcore-prepare-for-dynamic.patch new file mode 100644 index 0000000000..17eb0f58a6 --- /dev/null +++ b/recipes/xorg-xserver/xserver-xorg-1.5.3/xorg-server-1.5.3-glcore-prepare-for-dynamic.patch @@ -0,0 +1,108 @@ +From 70df9cb2b93ed3d4b7d6e201a58951c9981bbc93 Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?R=C3=A9mi=20Cardona?= +Date: Thu, 7 May 2009 14:19:22 +0200 +Subject: [PATCH 35/78] cherry-pick the rest of "glcore: prepare for dynamic loading" + +When f2c30a57e3c6169fbecdbb60ac24ad2a5e9aa8a4 was cherry-picked into the +1.5 branch, some parts were lost. This commit brings the missing bits. + +Conflicts: + + configure.ac +--- + configure.ac | 2 +- + hw/kdrive/ephyr/Makefile.am | 4 ++++ + hw/kdrive/fake/Makefile.am | 4 ++++ + hw/kdrive/fbdev/Makefile.am | 4 ++++ + hw/kdrive/sdl/Makefile.am | 4 ++++ + hw/kdrive/vesa/Makefile.am | 4 ++++ + 6 files changed, 21 insertions(+), 1 deletions(-) + +Index: xorg-server-1.5.3/configure.ac +=================================================================== +--- xorg-server-1.5.3.orig/configure.ac 2009-09-14 19:48:11.043879237 -0700 ++++ xorg-server-1.5.3/configure.ac 2009-09-14 19:49:34.903881120 -0700 +@@ -1964,7 +1964,7 @@ + KDRIVE_LOCAL_LIBS="$TSLIB_LIBS $DIX_LIB $KDRIVE_LIB $KDRIVE_STUB_LIB $CONFIG_LIB" + KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS" + KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB $OS_LIB" +- KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVER_SYS_LIBS" ++ KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVER_SYS_LIBS $GLX_SYS_LIBS" + + # check if we can build Xephyr + PKG_CHECK_MODULES(XEPHYR, $XEPHYR_REQUIRED_LIBS, [xephyr="yes"], [xephyr="no"]) +Index: xorg-server-1.5.3/hw/kdrive/ephyr/Makefile.am +=================================================================== +--- xorg-server-1.5.3.orig/hw/kdrive/ephyr/Makefile.am 2008-11-05 08:52:17.000000000 -0800 ++++ xorg-server-1.5.3/hw/kdrive/ephyr/Makefile.am 2009-09-14 19:49:34.903881120 -0700 +@@ -67,6 +67,10 @@ + Xephyr_SOURCES = \ + ephyrinit.c + ++if GLX ++Xephyr_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) ++endif ++ + Xephyr_LDADD = \ + libxephyr.a \ + libxephyr-hostx.a \ +Index: xorg-server-1.5.3/hw/kdrive/fake/Makefile.am +=================================================================== +--- xorg-server-1.5.3.orig/hw/kdrive/fake/Makefile.am 2008-07-11 08:12:13.000000000 -0700 ++++ xorg-server-1.5.3/hw/kdrive/fake/Makefile.am 2009-09-14 19:49:34.903881120 -0700 +@@ -16,6 +16,10 @@ + Xfake_SOURCES = \ + fakeinit.c + ++if GLX ++Xfake_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) ++endif ++ + Xfake_LDADD = \ + libfake.a \ + @KDRIVE_LIBS@ \ +Index: xorg-server-1.5.3/hw/kdrive/fbdev/Makefile.am +=================================================================== +--- xorg-server-1.5.3.orig/hw/kdrive/fbdev/Makefile.am 2008-07-11 08:12:13.000000000 -0700 ++++ xorg-server-1.5.3/hw/kdrive/fbdev/Makefile.am 2009-09-14 19:49:34.903881120 -0700 +@@ -14,6 +14,10 @@ + Xfbdev_SOURCES = \ + fbinit.c + ++if GLX ++Xfbdev_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) ++endif ++ + Xfbdev_LDADD = \ + libfbdev.a \ + @KDRIVE_LIBS@ +Index: xorg-server-1.5.3/hw/kdrive/sdl/Makefile.am +=================================================================== +--- xorg-server-1.5.3.orig/hw/kdrive/sdl/Makefile.am 2008-07-11 08:12:13.000000000 -0700 ++++ xorg-server-1.5.3/hw/kdrive/sdl/Makefile.am 2009-09-14 19:49:34.903881120 -0700 +@@ -7,6 +7,10 @@ + + Xsdl_SOURCES = sdl.c + ++if GLX ++Xsdl_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) ++endif ++ + Xsdl_LDADD = \ + @KDRIVE_LIBS@ \ + @XSDL_LIBS@ +Index: xorg-server-1.5.3/hw/kdrive/vesa/Makefile.am +=================================================================== +--- xorg-server-1.5.3.orig/hw/kdrive/vesa/Makefile.am 2008-11-05 08:52:17.000000000 -0800 ++++ xorg-server-1.5.3/hw/kdrive/vesa/Makefile.am 2009-09-14 19:49:34.903881120 -0700 +@@ -19,6 +19,10 @@ + Xvesa_SOURCES = \ + vesainit.c + ++if GLX ++Xvesa_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) ++endif ++ + Xvesa_LDADD = \ + libvesa.a \ + @KDRIVE_LIBS@ diff --git a/recipes/xorg-xserver/xserver-xorg_1.5.3.bb b/recipes/xorg-xserver/xserver-xorg_1.5.3.bb index 39697246e3..879b5160f3 100644 --- a/recipes/xorg-xserver/xserver-xorg_1.5.3.bb +++ b/recipes/xorg-xserver/xserver-xorg_1.5.3.bb @@ -4,11 +4,13 @@ DESCRIPTION = "the X.Org X server" DEPENDS += "pixman libpciaccess openssl" RDEPENDS += "hal" PE = "2" -PR = "${INC_PR}.0" +PR = "${INC_PR}.1" SRC_URI += "file://drmfix.patch;patch=1 \ file://sysroot_fix.patch;patch=1 \ file://xorg-avr32-support.diff;patch=1 \ + file://xorg-server-1.5.3-configure.patch;patch=1 \ + file://xorg-server-1.5.3-glcore-prepare-for-dynamic.patch;patch=1 \ " MESA_VER = "7.2" -- cgit v1.2.3 From 7c8f742ecc69974bcf20fe6449b460a2cde6f9ef Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Mon, 14 Sep 2009 20:17:36 -0700 Subject: cross.bbclass: Override BASEPKG_HOST_SYS * BASEPKG_HOST_SYS from bitbake.conf is set as if packages were being built for target. So we need to override it for cross packages. Signed-off-by: Khem Raj Acked-by: Andrea Adami gmail.com> --- classes/cross.bbclass | 1 + 1 file changed, 1 insertion(+) diff --git a/classes/cross.bbclass b/classes/cross.bbclass index 7debde6669..68e3803f3e 100644 --- a/classes/cross.bbclass +++ b/classes/cross.bbclass @@ -17,6 +17,7 @@ HOST_OS = "${BUILD_OS}" HOST_PREFIX = "${BUILD_PREFIX}" HOST_CC_ARCH = "${BUILD_CC_ARCH}" HOST_EXEEXT = "${BUILD_EXEEXT}" +BASEPKG_HOST_SYS = "${HOST_ARCH}${HOST_VENDOR}-${HOST_OS}" CPPFLAGS = "${BUILD_CPPFLAGS}" CFLAGS = "${BUILD_CFLAGS}" -- cgit v1.2.3 From b230286329e96ca4fe7b00140f566796b9cfc025 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Mon, 14 Sep 2009 20:15:50 -0700 Subject: eglibc: Bump the SRCREV to get new fixes. Signed-off-by: Khem Raj --- recipes/eglibc/eglibc_2.10.bb | 2 +- recipes/eglibc/eglibc_2.9.bb | 2 +- recipes/eglibc/eglibc_svn.bb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/recipes/eglibc/eglibc_2.10.bb b/recipes/eglibc/eglibc_2.10.bb index b31e23ef48..ec36d926a3 100644 --- a/recipes/eglibc/eglibc_2.10.bb +++ b/recipes/eglibc/eglibc_2.10.bb @@ -4,7 +4,7 @@ DEPENDS += "gperf-native" FILESPATHPKG =. "eglibc-svn:" PV = "2.10" PR = "${INC_PR}.1" -SVN_REV="8632" +SVN_REV="8873" EGLIBC_BRANCH="eglibc-2_10" SRC_URI = "svn://svn.eglibc.org/branches;module=eglibc-2_10;rev=${SVN_REV};proto=svn \ file://eglibc-svn-arm-lowlevellock-include-tls.patch;patch=1 \ diff --git a/recipes/eglibc/eglibc_2.9.bb b/recipes/eglibc/eglibc_2.9.bb index f75718fa32..cf9549c7a7 100644 --- a/recipes/eglibc/eglibc_2.9.bb +++ b/recipes/eglibc/eglibc_2.9.bb @@ -4,7 +4,7 @@ DEPENDS += "gperf-native" FILESPATHPKG =. "eglibc-svn:" PV = "2.9" PR = "${INC_PR}.2" -SVN_REV="7430" +SVN_REV="8690" EGLIBC_BRANCH="eglibc-2_9" SRC_URI = "svn://svn.eglibc.org/branches;module=eglibc-2_9;rev=${SVN_REV};proto=svn \ file://eglibc-svn-arm-lowlevellock-include-tls.patch;patch=1 \ diff --git a/recipes/eglibc/eglibc_svn.bb b/recipes/eglibc/eglibc_svn.bb index be2310829c..1f54edb336 100644 --- a/recipes/eglibc/eglibc_svn.bb +++ b/recipes/eglibc/eglibc_svn.bb @@ -1,7 +1,7 @@ require eglibc.inc DEPENDS += "gperf-native" -SRCREV = "8831" +SRCREV = "8917" DEFAULT_PREFERENCE = "-1" FILESPATHPKG =. "eglibc-svn:" PV = "2.10+svnr${SRCREV}" -- cgit v1.2.3 From 2bc7690bb202a33d450df83bd45fd64337954d93 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Tue, 15 Sep 2009 01:11:36 -0700 Subject: libcgicc: Add new recipe for 3.2.8 release * Move common parts to libcgicc.inc * Add new recipe for 3.2.8 release * Fixes bug 5314 * Thanks to Jim Sheldon for reporting and providing a recipe for 3.2.7 release. Unfortunately that recipe did not work well. Signed-off-by: Khem Raj --- conf/checksums.ini | 4 ++++ recipes/libcgicc/libcgicc.inc | 15 +++++++++++++++ recipes/libcgicc/libcgicc_3.2.3.bb | 15 +-------------- recipes/libcgicc/libcgicc_3.2.8.bb | 2 ++ 4 files changed, 22 insertions(+), 14 deletions(-) create mode 100644 recipes/libcgicc/libcgicc.inc create mode 100644 recipes/libcgicc/libcgicc_3.2.8.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index 4e5fa19142..681e70b887 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -3646,6 +3646,10 @@ sha256=f377e4be57862a260e924c3778a241a2a424772fb98ba8b8cc5f04050ff12ac5 md5=cd7a7a5a1fd186bd8f481c4e17354a0b sha256=88fc878aa30d9529d3599891732143c5ac602f4d863126ca2a51d7f7692b7b2d +[ftp://ftp.gnu.org/gnu/cgicc/cgicc-3.2.8.tar.gz] +md5=7bfe01649f2b7bf582a8d0034ed0b32b +sha256=8718e1b9919b6381d55ef7ebca42564278b76225e83ab94db99cee18668e4033 + [http://www.bangstate.com/changedfiles-1.0-rc1.tar.gz] md5=e44e2a833151632dae7b68e815400bc1 sha256=26991b827f96a49ebd164409852d781b0a74a765c385c56c21a7ae44d030ab42 diff --git a/recipes/libcgicc/libcgicc.inc b/recipes/libcgicc/libcgicc.inc new file mode 100644 index 0000000000..ee7a1f5afe --- /dev/null +++ b/recipes/libcgicc/libcgicc.inc @@ -0,0 +1,15 @@ +DESCRIPTION = "a C++ class library for writing CGI applications" +HOMEPAGE = "http://www.gnu.org/software/cgicc/" +LICENSE = "http://www.gnu.org/software/cgicc/doc/cgicc_license.html" + +SRC_URI = "ftp://ftp.gnu.org/gnu/cgicc/cgicc-${PV}.tar.gz" + +S = "${WORKDIR}/cgicc-${PV}" + +inherit autotools + +do_stage () { + install -d ${STAGING_INCDIR}/cgicc + cp -LR cgicc/*.h ${STAGING_INCDIR}/cgicc + oe_libinstall -C cgicc libcgicc ${STAGING_LIBDIR} +} diff --git a/recipes/libcgicc/libcgicc_3.2.3.bb b/recipes/libcgicc/libcgicc_3.2.3.bb index dc066f1f2f..da7c954c5a 100644 --- a/recipes/libcgicc/libcgicc_3.2.3.bb +++ b/recipes/libcgicc/libcgicc_3.2.3.bb @@ -1,14 +1 @@ -DESCRIPTION = "a C++ class library for writing CGI applications" -HOMEPAGE = "http://www.cgicc.org/" -LICENSE = "LGPL" - -SRC_URI = "http://www.cgicc.org/files/cgicc-${PV}.tar.bz2" -S = "${WORKDIR}/cgicc-${PV}" - -inherit autotools - -do_stage () { - install -d ${STAGING_INCDIR}/cgicc - cp -LR cgicc/*.h ${STAGING_INCDIR}/cgicc - oe_libinstall -C cgicc libcgicc ${STAGING_LIBDIR} -} +require libcgicc.inc diff --git a/recipes/libcgicc/libcgicc_3.2.8.bb b/recipes/libcgicc/libcgicc_3.2.8.bb new file mode 100644 index 0000000000..16b70fb019 --- /dev/null +++ b/recipes/libcgicc/libcgicc_3.2.8.bb @@ -0,0 +1,2 @@ +require libcgicc.inc +EXTRA_OECONF += " --disable-demos --htmldir=${docdir}" -- cgit v1.2.3 From fbe1669439e632589ddf843137761aebb76f1549 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Tue, 15 Sep 2009 01:40:40 -0700 Subject: vagalume: Rename vagalume_0.7.bb as vagalume_0.7.1.bb * Fixes PR 5146 * Credit to bugs@vdm-design.de for reporting and posting recipe Signed-off-by: Khem Raj --- conf/checksums.ini | 14 +++++++------- recipes/vagalume/vagalume_0.7.1.bb | 14 ++++++++++++++ recipes/vagalume/vagalume_0.7.bb | 14 -------------- 3 files changed, 21 insertions(+), 21 deletions(-) create mode 100644 recipes/vagalume/vagalume_0.7.1.bb delete mode 100644 recipes/vagalume/vagalume_0.7.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index 681e70b887..4271836486 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -3646,6 +3646,10 @@ sha256=f377e4be57862a260e924c3778a241a2a424772fb98ba8b8cc5f04050ff12ac5 md5=cd7a7a5a1fd186bd8f481c4e17354a0b sha256=88fc878aa30d9529d3599891732143c5ac602f4d863126ca2a51d7f7692b7b2d +[ftp://ftp.gnu.org/gnu/cgicc/cgicc-3.2.7.tar.gz] +md5=f3bb4101e741fbef91e58613e51439f8 +sha256=9f57a21545b47ce1a6ca95c3e4a534af758c29d7da0f50dd22911cdbaa32bcb5 + [ftp://ftp.gnu.org/gnu/cgicc/cgicc-3.2.8.tar.gz] md5=7bfe01649f2b7bf582a8d0034ed0b32b sha256=8718e1b9919b6381d55ef7ebca42564278b76225e83ab94db99cee18668e4033 @@ -25014,13 +25018,9 @@ sha256=4154c5a3830bba25bd63b175f4fba07867ef029124d8c9470fac45235569dde5 md5=5ec548c343de435b94a7b39f5c853292 sha256=10263676cb872ca48d8d605be44eb1e6260419675409732e7e5a76eb41843cee -[http://garage.maemo.org/frs/download.php/4505/vagalume_0.7.orig.tar.gz] -md5=97e1497eed21ef0ac82514ead94c5ee4 -sha256=82b42534276018809aec934b572845e495ea19fc0c6abf6b6ef1e8571b91ccee - -[http://people.igalia.com/berto/files/vagalume/source/vagalume_0.7.orig.tar.gz] -md5=97e1497eed21ef0ac82514ead94c5ee4 -sha256=82b42534276018809aec934b572845e495ea19fc0c6abf6b6ef1e8571b91ccee +[http://vagalume.igalia.com/files/source/vagalume_0.7.1.orig.tar.gz] +md5=c7929eefe38cab5985834d5163292121 +sha256=6f37a0a9a5deb501176bc119b2df61746ccdd6ba95c80f179d8fff1ed323371e [http://download.gnome.org/sources/vala/0.1/vala-0.1.5.tar.bz2] md5=4e082ecb7f60ebdc49f3bd19ae7ebca2 diff --git a/recipes/vagalume/vagalume_0.7.1.bb b/recipes/vagalume/vagalume_0.7.1.bb new file mode 100644 index 0000000000..5b29ae17b6 --- /dev/null +++ b/recipes/vagalume/vagalume_0.7.1.bb @@ -0,0 +1,14 @@ +DESCRIPTION = "Last.fm client" +AUTHOR = "agarcia@igalia.com" +HOMEPAGE = "http://vagalume.igalia.com/" +SECTION = "x11" +DEPENDS = "gtk+ gstreamer" +RRECOMMENDS = "dbus-x11" + +SRC_URI = "http://vagalume.igalia.com/files/source/vagalume_${PV}.orig.tar.gz\ + " +S = "${WORKDIR}/vagalume-${PV}.orig" + +inherit autotools + +FILES_${PN} += "${datadir}/icons ${datadir}/dbus-1" diff --git a/recipes/vagalume/vagalume_0.7.bb b/recipes/vagalume/vagalume_0.7.bb deleted file mode 100644 index f541dcdbb3..0000000000 --- a/recipes/vagalume/vagalume_0.7.bb +++ /dev/null @@ -1,14 +0,0 @@ -DESCRIPTION = "Last.fm client" -AUTHOR = "agarcia@igalia.com" -HOMEPAGE = "http://people.igalia.com/berto/" -SECTION = "x11" -DEPENDS = "gtk+ gstreamer" -RRECOMMENDS = "dbus-x11" -PR = "r0" - -SRC_URI = "\ - http://garage.maemo.org/frs/download.php/4505/vagalume_${PV}.orig.tar.gz\ -" -S = "${WORKDIR}/vagalume-${PV}.orig" - -inherit autotools -- cgit v1.2.3 From f111ae953c303d608d1b3b7c945a11c03e0a620e Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Tue, 15 Sep 2009 10:49:50 +0100 Subject: linux-libc-headers_2.6.31.bb : add newest kernel headers, this has the 0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch enabled which is getting to be needed for udev. DEF_PREF = -1 for now as I havent tested this properly yet --- conf/checksums.ini | 4 + ...IF_RESTORE_SIGMASK-support-and-enable-the.patch | 429 +++++++++++++++++++++ .../linux-libc-headers_2.6.31.bb | 51 +++ 3 files changed, 484 insertions(+) create mode 100644 recipes/linux-libc-headers/linux-libc-headers-2.6.31/0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch create mode 100644 recipes/linux-libc-headers/linux-libc-headers_2.6.31.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index 4271836486..30fcf01067 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -16066,6 +16066,10 @@ sha256=58a5ea16d499fe06f90fcbf1d687d1235d2cb9bc28bf979867bd3faadf38fc3f md5=7a80058a6382e5108cdb5554d1609615 sha256=d7b9f19b92fd5c693c16cd62f441d051b699f28ec6a175d1b464e58bacd8c78f +[http://kernel.org/pub/linux/kernel/v2.6/linux-2.6.31.tar.bz2] +md5=84c077a37684e4cbfa67b18154390d8a +sha256=0acd83f7b85db7ee18c2b0b7505e1ba6fd722c36f49a8870a831c851660e3512 + [http://kernel.org//pub/linux/kernel/v2.6/linux-2.6.9.tar.bz2] md5=e921200f074ca97184e150ef5a4af825 sha256=f5dba6366e87e91234d1b0069cfea655b0a4cb37ea97f899226f16998e6ab9f1 diff --git a/recipes/linux-libc-headers/linux-libc-headers-2.6.31/0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch b/recipes/linux-libc-headers/linux-libc-headers-2.6.31/0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch new file mode 100644 index 0000000000..1dee314700 --- /dev/null +++ b/recipes/linux-libc-headers/linux-libc-headers-2.6.31/0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch @@ -0,0 +1,429 @@ +Path: news.gmane.org!not-for-mail +From: Mikael Pettersson +Newsgroups: gmane.linux.ports.arm.kernel +Subject: [PATCH][v3] ARM support for + TIF_RESTORE_SIGMASK/pselect6/ppoll/epoll_pwait +Date: Sat, 15 Aug 2009 13:09:28 +0200 (MEST) +Lines: 362 +Approved: news@gmane.org +Message-ID: <200908151109.n7FB9Sbs000150@pilspetsen.it.uu.se> +NNTP-Posting-Host: lo.gmane.org +Mime-Version: 1.0 +Content-Type: text/plain; charset="us-ascii" +Content-Transfer-Encoding: 7bit +X-Trace: ger.gmane.org 1250334940 22899 80.91.229.12 (15 Aug 2009 11:15:40 GMT) +X-Complaints-To: usenet@ger.gmane.org +NNTP-Posting-Date: Sat, 15 Aug 2009 11:15:40 +0000 (UTC) +To: linux-arm-kernel@lists.arm.linux.org.uk +Original-X-From: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane.org@lists.arm.linux.org.uk Sat Aug 15 13:15:33 2009 +Return-path: +Envelope-to: linux-arm-kernel@m.gmane.org +Original-Received: from zeniv.linux.org.uk ([195.92.253.2]) + by lo.gmane.org with esmtp (Exim 4.50) + id 1McHER-0000U2-PG + for linux-arm-kernel@m.gmane.org; Sat, 15 Aug 2009 13:15:31 +0200 +Original-Received: from [2002:4e20:1eda:1:201:3dff:fe00:156] (helo=lists.arm.linux.org.uk) + by ZenIV.linux.org.uk with esmtpsa (Exim 4.69 #1 (Red Hat Linux)) + id 1McH9u-0005LV-3W; Sat, 15 Aug 2009 11:10:57 +0000 +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=arm.linux.org.uk; s=lists; h=Date:Message-Id:From:To:Subject: + List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help: + List-Subscribe:MIME-Version:Content-Type: + Content-Transfer-Encoding; bh=RVq9hPAexlUcptd3h6j5nomOyoEIjcDWAP + VeJtlhsa4=; b=HAoqRMC9svNzKlR0f938E0cRlLoJZvG2aSun171woWZAClu/Ud + IYN0iD2vm4eF+kYQkTYD6PGFCMbNnugmZe6gCpS0QhijoKyOzRBdykQHJuOLQtLE + q9KJzp24cQ/vwsV2+O1OqcmIFboIg2L5JQaUuv0djS7OkdspH0ysmi1lg= +Original-Received: from [::1] (helo=lists.arm.linux.org.uk) + by lists.arm.linux.org.uk with esmtp (Exim 4.69) + (envelope-from ) + id 1McH9o-0002us-34; Sat, 15 Aug 2009 12:10:44 +0100 +Original-Received: from aun.it.uu.se ([130.238.12.36] ident=root) + by lists.arm.linux.org.uk with esmtps (TLSv1:AES256-SHA:256) + (Exim 4.69) (envelope-from ) id 1McH8h-0002uj-Ck + for linux-arm-kernel@lists.arm.linux.org.uk; + Sat, 15 Aug 2009 12:09:35 +0100 +Original-Received: from pilspetsen.it.uu.se (daemon@pilspetsen.it.uu.se [130.238.18.39]) + by aun.it.uu.se (8.13.6/8.13.6) with ESMTP id n7FB9S04005839 + for ; + Sat, 15 Aug 2009 13:09:28 +0200 (MEST) +Original-Received: (from mikpe@localhost) + by pilspetsen.it.uu.se (8.13.8+Sun/8.13.7) id n7FB9Sbs000150 + for linux-arm-kernel@lists.arm.linux.org.uk; + Sat, 15 Aug 2009 13:09:28 +0200 (MEST) +X-BeenThere: linux-arm-kernel@lists.arm.linux.org.uk +X-Mailman-Version: 2.1.9 +Precedence: list +List-Id: ARM Linux kernel discussions +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane.org@lists.arm.linux.org.uk +Xref: news.gmane.org gmane.linux.ports.arm.kernel:64340 +Archived-At: + +This patch adds support for TIF_RESTORE_SIGMASK to ARM's signal handling, +which allows to hook up the pselect6, ppoll, and epoll_pwait syscalls on ARM. + +Tested here with eabi userspace and a test program with a deliberate race +between a child's exit and the parent's sigprocmask/select sequence. +Using sys_pselect6() instead of sigprocmask/select reliably prevents the race. + +The other arch's support for TIF_RESTORE_SIGMASK has evolved over time: + +In 2.6.16: +- add TIF_RESTORE_SIGMASK which parallels TIF_SIGPENDING +- test both when checking for pending signal [bad, changed later] +- reimplement sys_sigsuspend() to use current->saved_sigmask, + TIF_RESTORE_SIGMASK [changed later], and -ERESTARTNOHAND; + ditto for sys_rt_sigsuspend(), but drop private code and + use common code via __ARCH_WANT_SYS_RT_SIGSUSPEND; +- there are now no "extra" calls to do_signal() so its oldset + parameter is always ¤t->blocked so need not be passed, + also its return value is changed to void +- change handle_signal() to return 0/-errno +- change do_signal() to honor TIF_RESTORE_SIGMASK: + + get oldset from current->saved_sigmask if TIF_RESTORE_SIGMASK is set + + if handle_signal() was successful then clear TIF_RESTORE_SIGMASK + + if no signal was delivered and TIF_RESTORE_SIGMASK is set then + clear it and restore the sigmask +- hook up sys_pselect6() and sys_ppoll() + +In 2.6.19: +- hook up sys_epoll_pwait() + +In 2.6.26: +- allow archs to override how TIF_RESTORE_SIGMASK is implemented; + default set_restore_sigmask() sets both TIF_RESTORE_SIGMASK and + TIF_SIGPENDING; archs need now just test TIF_SIGPENDING again + when checking for pending signal work; some archs now implement + TIF_RESTORE_SIGMASK as a secondary/non-atomic thread flag bit +- call set_restore_sigmask() in sys_sigsuspend() instead of setting + TIF_RESTORE_SIGMASK + +In 2.6.29-rc: +- kill sys_pselect7() which no arch wanted + +So for 2.6.31-rc6/ARM this patch does the following: +- Add TIF_RESTORE_SIGMASK. Use the generic set_restore_sigmask() + which sets both TIF_SIGPENDING and TIF_RESTORE_SIGMASK, so + TIF_RESTORE_SIGMASK need not claim one of the scarce low thread + flags, and existing TIF_SIGPENDING and _TIF_WORK_MASK tests need + not be extended for TIF_RESTORE_SIGMASK. +- sys_sigsuspend() is reimplemented to use current->saved_sigmask and + set_restore_sigmask(), making it identical to most other archs. +- The private code for sys_rt_sigsuspend() is removed, instead generic + code supplies it via __ARCH_WANT_SYS_RT_SIGSUSPEND. +- sys_sigsuspend() and sys_rt_sigsuspend() no longer need a pt_regs + parameter, so their assembly code wrappers are removed. +- handle_signal() is changed to return 0 on success or -errno. +- The oldset parameter to do_signal() is now redundant and removed, + and the return value is now also redundant so it's changed to void. +- do_signal() is changed to honor TIF_RESTORE_SIGMASK: + + get oldset from current->saved_sigmask if TIF_RESTORE_SIGMASK is set + + if handle_signal() was successful then clear TIF_RESTORE_SIGMASK + + if no signal was delivered and TIF_RESTORE_SIGMASK is set then + clear it and restore the sigmask +- Hook up sys_pselect6, sys_ppoll, and sys_epoll_pwait. + +Signed-off-by: Mikael Pettersson +--- +Changes from previous versions: + +v2 (only posted as incremental diff against v1): +- moved sigmask restoration in no-signal-delivered case into + "if (syscall)" block for extra protection against exception + path also invoking do_signal() +v3 (this version): +- moved oldset initialisation into "if (signr > 0)" block, + as requested by Russell + + arch/arm/include/asm/thread_info.h | 2 + arch/arm/include/asm/unistd.h | 7 +-- + arch/arm/kernel/calls.S | 10 ++-- + arch/arm/kernel/entry-common.S | 10 ---- + arch/arm/kernel/signal.c | 86 +++++++++++++++---------------------- + 5 files changed, 48 insertions(+), 67 deletions(-) + +diff -rupN linux-2.6.31-rc6/arch/arm/include/asm/thread_info.h linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/include/asm/thread_info.h +--- linux-2.6.31-rc6/arch/arm/include/asm/thread_info.h 2009-08-14 11:11:10.000000000 +0200 ++++ linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/include/asm/thread_info.h 2009-08-14 11:26:44.000000000 +0200 +@@ -140,6 +140,7 @@ extern void vfp_sync_state(struct thread + #define TIF_USING_IWMMXT 17 + #define TIF_MEMDIE 18 + #define TIF_FREEZE 19 ++#define TIF_RESTORE_SIGMASK 20 + + #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) + #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) +@@ -147,6 +148,7 @@ extern void vfp_sync_state(struct thread + #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) + #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) + #define _TIF_FREEZE (1 << TIF_FREEZE) ++#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) + + /* + * Change these and you break ASM code in entry-common.S +diff -rupN linux-2.6.31-rc6/arch/arm/include/asm/unistd.h linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/include/asm/unistd.h +--- linux-2.6.31-rc6/arch/arm/include/asm/unistd.h 2009-08-14 11:11:10.000000000 +0200 ++++ linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/include/asm/unistd.h 2009-08-14 11:26:44.000000000 +0200 +@@ -360,8 +360,8 @@ + #define __NR_readlinkat (__NR_SYSCALL_BASE+332) + #define __NR_fchmodat (__NR_SYSCALL_BASE+333) + #define __NR_faccessat (__NR_SYSCALL_BASE+334) +- /* 335 for pselect6 */ +- /* 336 for ppoll */ ++#define __NR_pselect6 (__NR_SYSCALL_BASE+335) ++#define __NR_ppoll (__NR_SYSCALL_BASE+336) + #define __NR_unshare (__NR_SYSCALL_BASE+337) + #define __NR_set_robust_list (__NR_SYSCALL_BASE+338) + #define __NR_get_robust_list (__NR_SYSCALL_BASE+339) +@@ -372,7 +372,7 @@ + #define __NR_vmsplice (__NR_SYSCALL_BASE+343) + #define __NR_move_pages (__NR_SYSCALL_BASE+344) + #define __NR_getcpu (__NR_SYSCALL_BASE+345) +- /* 346 for epoll_pwait */ ++#define __NR_epoll_pwait (__NR_SYSCALL_BASE+346) + #define __NR_kexec_load (__NR_SYSCALL_BASE+347) + #define __NR_utimensat (__NR_SYSCALL_BASE+348) + #define __NR_signalfd (__NR_SYSCALL_BASE+349) +@@ -432,6 +432,7 @@ + #define __ARCH_WANT_SYS_SIGPENDING + #define __ARCH_WANT_SYS_SIGPROCMASK + #define __ARCH_WANT_SYS_RT_SIGACTION ++#define __ARCH_WANT_SYS_RT_SIGSUSPEND + + #if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT) + #define __ARCH_WANT_SYS_TIME +diff -rupN linux-2.6.31-rc6/arch/arm/kernel/calls.S linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/kernel/calls.S +--- linux-2.6.31-rc6/arch/arm/kernel/calls.S 2009-08-14 11:11:10.000000000 +0200 ++++ linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/kernel/calls.S 2009-08-14 11:26:44.000000000 +0200 +@@ -81,7 +81,7 @@ + CALL(sys_ni_syscall) /* was sys_ssetmask */ + /* 70 */ CALL(sys_setreuid16) + CALL(sys_setregid16) +- CALL(sys_sigsuspend_wrapper) ++ CALL(sys_sigsuspend) + CALL(sys_sigpending) + CALL(sys_sethostname) + /* 75 */ CALL(sys_setrlimit) +@@ -188,7 +188,7 @@ + CALL(sys_rt_sigpending) + CALL(sys_rt_sigtimedwait) + CALL(sys_rt_sigqueueinfo) +- CALL(sys_rt_sigsuspend_wrapper) ++ CALL(sys_rt_sigsuspend) + /* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64)) + CALL(ABI(sys_pwrite64, sys_oabi_pwrite64)) + CALL(sys_chown16) +@@ -344,8 +344,8 @@ + CALL(sys_readlinkat) + CALL(sys_fchmodat) + CALL(sys_faccessat) +-/* 335 */ CALL(sys_ni_syscall) /* eventually pselect6 */ +- CALL(sys_ni_syscall) /* eventually ppoll */ ++/* 335 */ CALL(sys_pselect6) ++ CALL(sys_ppoll) + CALL(sys_unshare) + CALL(sys_set_robust_list) + CALL(sys_get_robust_list) +@@ -355,7 +355,7 @@ + CALL(sys_vmsplice) + CALL(sys_move_pages) + /* 345 */ CALL(sys_getcpu) +- CALL(sys_ni_syscall) /* eventually epoll_pwait */ ++ CALL(sys_epoll_pwait) + CALL(sys_kexec_load) + CALL(sys_utimensat) + CALL(sys_signalfd) +diff -rupN linux-2.6.31-rc6/arch/arm/kernel/entry-common.S linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/kernel/entry-common.S +--- linux-2.6.31-rc6/arch/arm/kernel/entry-common.S 2009-08-14 11:11:10.000000000 +0200 ++++ linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/kernel/entry-common.S 2009-08-14 11:26:44.000000000 +0200 +@@ -373,16 +373,6 @@ sys_clone_wrapper: + b sys_clone + ENDPROC(sys_clone_wrapper) + +-sys_sigsuspend_wrapper: +- add r3, sp, #S_OFF +- b sys_sigsuspend +-ENDPROC(sys_sigsuspend_wrapper) +- +-sys_rt_sigsuspend_wrapper: +- add r2, sp, #S_OFF +- b sys_rt_sigsuspend +-ENDPROC(sys_rt_sigsuspend_wrapper) +- + sys_sigreturn_wrapper: + add r0, sp, #S_OFF + b sys_sigreturn +diff -rupN linux-2.6.31-rc6/arch/arm/kernel/signal.c linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/kernel/signal.c +--- linux-2.6.31-rc6/arch/arm/kernel/signal.c 2009-08-14 11:11:10.000000000 +0200 ++++ linux-2.6.31-rc6.arm-restore-sigmask-v3/arch/arm/kernel/signal.c 2009-08-14 11:26:44.000000000 +0200 +@@ -47,57 +47,22 @@ const unsigned long sigreturn_codes[7] = + MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, + }; + +-static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall); +- + /* + * atomically swap in the new signal mask, and wait for a signal. + */ +-asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs) ++asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask) + { +- sigset_t saveset; +- + mask &= _BLOCKABLE; + spin_lock_irq(¤t->sighand->siglock); +- saveset = current->blocked; ++ current->saved_sigmask = current->blocked; + siginitset(¤t->blocked, mask); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); +- regs->ARM_r0 = -EINTR; +- +- while (1) { +- current->state = TASK_INTERRUPTIBLE; +- schedule(); +- if (do_signal(&saveset, regs, 0)) +- return regs->ARM_r0; +- } +-} +- +-asmlinkage int +-sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs) +-{ +- sigset_t saveset, newset; +- +- /* XXX: Don't preclude handling different sized sigset_t's. */ +- if (sigsetsize != sizeof(sigset_t)) +- return -EINVAL; +- +- if (copy_from_user(&newset, unewset, sizeof(newset))) +- return -EFAULT; +- sigdelsetmask(&newset, ~_BLOCKABLE); +- +- spin_lock_irq(¤t->sighand->siglock); +- saveset = current->blocked; +- current->blocked = newset; +- recalc_sigpending(); +- spin_unlock_irq(¤t->sighand->siglock); +- regs->ARM_r0 = -EINTR; + +- while (1) { +- current->state = TASK_INTERRUPTIBLE; +- schedule(); +- if (do_signal(&saveset, regs, 0)) +- return regs->ARM_r0; +- } ++ current->state = TASK_INTERRUPTIBLE; ++ schedule(); ++ set_restore_sigmask(); ++ return -ERESTARTNOHAND; + } + + asmlinkage int +@@ -545,7 +510,7 @@ static inline void setup_syscall_restart + /* + * OK, we're invoking a handler + */ +-static void ++static int + handle_signal(unsigned long sig, struct k_sigaction *ka, + siginfo_t *info, sigset_t *oldset, + struct pt_regs * regs, int syscall) +@@ -596,7 +561,7 @@ handle_signal(unsigned long sig, struct + + if (ret != 0) { + force_sigsegv(sig, tsk); +- return; ++ return ret; + } + + /* +@@ -610,6 +575,7 @@ handle_signal(unsigned long sig, struct + recalc_sigpending(); + spin_unlock_irq(&tsk->sighand->siglock); + ++ return 0; + } + + /* +@@ -621,7 +587,7 @@ handle_signal(unsigned long sig, struct + * the kernel can handle, and then we build all the user-level signal handling + * stack-frames in one go after that. + */ +-static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) ++static void do_signal(struct pt_regs *regs, int syscall) + { + struct k_sigaction ka; + siginfo_t info; +@@ -634,7 +600,7 @@ static int do_signal(sigset_t *oldset, s + * if so. + */ + if (!user_mode(regs)) +- return 0; ++ return; + + if (try_to_freeze()) + goto no_signal; +@@ -643,9 +609,24 @@ static int do_signal(sigset_t *oldset, s + + signr = get_signal_to_deliver(&info, &ka, regs, NULL); + if (signr > 0) { +- handle_signal(signr, &ka, &info, oldset, regs, syscall); ++ sigset_t *oldset; ++ ++ if (test_thread_flag(TIF_RESTORE_SIGMASK)) ++ oldset = ¤t->saved_sigmask; ++ else ++ oldset = ¤t->blocked; ++ if (handle_signal(signr, &ka, &info, oldset, regs, syscall) == 0) { ++ /* ++ * A signal was successfully delivered; the saved ++ * sigmask will have been stored in the signal frame, ++ * and will be restored by sigreturn, so we can simply ++ * clear the TIF_RESTORE_SIGMASK flag. ++ */ ++ if (test_thread_flag(TIF_RESTORE_SIGMASK)) ++ clear_thread_flag(TIF_RESTORE_SIGMASK); ++ } + single_step_set(current); +- return 1; ++ return; + } + + no_signal: +@@ -697,14 +678,21 @@ static int do_signal(sigset_t *oldset, s + regs->ARM_r0 == -ERESTARTNOINTR) { + setup_syscall_restart(regs); + } ++ ++ /* If there's no signal to deliver, we just put the saved sigmask ++ * back. ++ */ ++ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { ++ clear_thread_flag(TIF_RESTORE_SIGMASK); ++ sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); ++ } + } + single_step_set(current); +- return 0; + } + + asmlinkage void + do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall) + { + if (thread_flags & _TIF_SIGPENDING) +- do_signal(¤t->blocked, regs, syscall); ++ do_signal(regs, syscall); + } + +------------------------------------------------------------------- +List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel +FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php +Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php + diff --git a/recipes/linux-libc-headers/linux-libc-headers_2.6.31.bb b/recipes/linux-libc-headers/linux-libc-headers_2.6.31.bb new file mode 100644 index 0000000000..33872e6f89 --- /dev/null +++ b/recipes/linux-libc-headers/linux-libc-headers_2.6.31.bb @@ -0,0 +1,51 @@ +require linux-libc-headers.inc + +INHIBIT_DEFAULT_DEPS = "1" +DEPENDS += "unifdef-native" +PR = "r0" + +DEFAULT_PREFERENCE = "-1" + +SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-${PV}.tar.bz2 \ + file://0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch;patch=1 \ + " +S = "${WORKDIR}/linux-${PV}" + +set_arch() { + case ${TARGET_ARCH} in + alpha*) ARCH=alpha ;; + arm*) ARCH=arm ;; + cris*) ARCH=cris ;; + hppa*) ARCH=parisc ;; + i*86*) ARCH=i386 ;; + ia64*) ARCH=ia64 ;; + mips*) ARCH=mips ;; + m68k*) ARCH=m68k ;; + powerpc*) ARCH=powerpc ;; + s390*) ARCH=s390 ;; + sh*) ARCH=sh ;; + sparc64*) ARCH=sparc64 ;; + sparc*) ARCH=sparc ;; + x86_64*) ARCH=x86_64 ;; + avr32*) ARCH=avr32 ;; + bfin*) ARCH=blackfin ;; + esac +} + +do_configure() { + set_arch + oe_runmake allnoconfig ARCH=$ARCH +} + +do_compile () { +} + +do_install() { + set_arch + oe_runmake headers_install INSTALL_HDR_PATH=${D}${exec_prefix} ARCH=$ARCH +} + +do_stage () { + set_arch + oe_runmake headers_install INSTALL_HDR_PATH=${STAGING_DIR_HOST}${layout_prefix} ARCH=$ARCH +} -- cgit v1.2.3 From dd6f2e9c436ee71f728f454ca118453479516a5b Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Tue, 15 Sep 2009 10:52:28 +0100 Subject: transmission : make use .inc file as all recipes are pretty identical. --- recipes/transmission/transmission.inc | 38 +++++++++++++++++++++++++++++++ recipes/transmission/transmission_1.40.bb | 32 ++------------------------ recipes/transmission/transmission_1.61.bb | 35 +++------------------------- recipes/transmission/transmission_1.73.bb | 38 ++----------------------------- 4 files changed, 45 insertions(+), 98 deletions(-) create mode 100644 recipes/transmission/transmission.inc diff --git a/recipes/transmission/transmission.inc b/recipes/transmission/transmission.inc new file mode 100644 index 0000000000..1601f09ec2 --- /dev/null +++ b/recipes/transmission/transmission.inc @@ -0,0 +1,38 @@ +DESCRIPTION = "Transmission is a BitTorrent client w/ a built-in Ajax-Powered Webif GUI." +SECTION = "network" +HOMEPAGE = "www.transmissionbt.com/" +DEPENDS = "gtk+ gnutls openssl gettext libtool intltool-native curl glib-2.0-native" +LICENSE = "GPLv2" +PR = "r2" +SRC_URI = "http://mirrors.m0k.org/transmission/files/transmission-${PV}.tar.bz2 \ + file://init \ + file://config" + +INITSCRIPT_NAME = "transmission" +INITSCRIPT_PARAMS = "defaults 60 " + +inherit autotools update-rc.d + +do_install_append() { + install -d ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/init ${D}${sysconfdir}/init.d/transmission + install -d ${D}${sysconfdir}/default + install -m 0755 ${WORKDIR}/config ${D}${sysconfdir}/default/transmission-daemon + install -d ${D}${localstatedir}/lib/transmission-daemon +} + +FILES_${PN} += "${datadir}/icons" +CONFFILES_${PN} = "${sysconfdir}/default/transmission-daemon" + +# No need for online check, since update-rc.d will prepend it to here +pkg_postinst_${PN}() { +grep -q transmission ${sysconfdir}/group || addgroup transmission +grep -q transmission ${sysconfdir}/passwd || adduser -h ${localstatedir}/lib/transmission-daemon -S -D -G transmission -s ${base_bindir}/false transmission +chown -R transmission:transmission /var/lib/transmission-daemon/ +} + +pkg_postrm_${PN}() { +delgroup transmission +deluser transmission +} + diff --git a/recipes/transmission/transmission_1.40.bb b/recipes/transmission/transmission_1.40.bb index c40939fd3b..8001a99ef0 100644 --- a/recipes/transmission/transmission_1.40.bb +++ b/recipes/transmission/transmission_1.40.bb @@ -1,32 +1,4 @@ -DESCRIPTION = "Transmission is a BitTorrent client w/ a built-in Ajax-Powered Webif GUI." -SECTION = "network" -HOMEPAGE = "www.transmissionbt.com/" -DEPENDS = "openssl gettext libtool intltool-native curl glib-2.0-native" -LICENSE = "GPLv2" -PR = "r2" -SRC_URI = "http://mirrors.m0k.org/transmission/files/transmission-${PV}.tar.bz2 \ - file://init" - -INITSCRIPT_NAME = "transmission" -INITSCRIPT_PARAMS = "defaults 60 " - -inherit autotools update-rc.d +require transmission.inc -do_install_append() { - install -d -p ${D}${sysconfdir}/init.d - install -m 0755 ${WORKDIR}/init ${D}${sysconfdir}/init.d/transmission -} - -# No need for online check, since update-rc.d will prepend it to here -pkg_postinst_${PN}() { -grep -q transmission ${sysconfdir}/group || addgroup transmission -grep -q transmission ${sysconfdir}/passwd || adduser -h /home/transmission -S -D -G transmission -s ${base_bindir}/false transmission -mkdir -p /home/transmission/.config -chown transmission:transmission /home/transmission/.config -} - -pkg_postrm_${PN}() { -delgroup transmission -deluser transmission -} +PR = "r2" diff --git a/recipes/transmission/transmission_1.61.bb b/recipes/transmission/transmission_1.61.bb index dd2b3a4dad..31c73d9865 100644 --- a/recipes/transmission/transmission_1.61.bb +++ b/recipes/transmission/transmission_1.61.bb @@ -1,35 +1,6 @@ -DESCRIPTION = "Transmission is a BitTorrent client w/ a built-in Ajax-Powered Webif GUI." -SECTION = "network" -HOMEPAGE = "www.transmissionbt.com/" -DEPENDS = "gtk+ gnutls openssl gettext libtool intltool-native curl glib-2.0-native" -LICENSE = "GPLv2" -PR = "r5" -SRC_URI = "http://mirrors.m0k.org/transmission/files/transmission-${PV}.tar.bz2 \ - file://webupload.patch;patch=1;pnum=0 \ - file://init" - -INITSCRIPT_NAME = "transmission" -INITSCRIPT_PARAMS = "defaults 60 " - -inherit autotools update-rc.d +require transmission.inc -do_install_append() { - install -d -p ${D}${sysconfdir}/init.d - install -m 0755 ${WORKDIR}/init ${D}${sysconfdir}/init.d/transmission -} +SRC_URI_append = " file://webupload.patch;patch=1;pnum=0" -FILES_${PN} += "${datadir}/icons" - -# No need for online check, since update-rc.d will prepend it to here -pkg_postinst_${PN}() { -grep -q transmission ${sysconfdir}/group || addgroup transmission -grep -q transmission ${sysconfdir}/passwd || adduser -h /home/transmission -S -D -G transmission -s ${base_bindir}/false transmission -mkdir -p /home/transmission/.config -chown transmission:transmission /home/transmission/.config -} - -pkg_postrm_${PN}() { -delgroup transmission -deluser transmission -} +PR = "r5" diff --git a/recipes/transmission/transmission_1.73.bb b/recipes/transmission/transmission_1.73.bb index 1601f09ec2..8001a99ef0 100644 --- a/recipes/transmission/transmission_1.73.bb +++ b/recipes/transmission/transmission_1.73.bb @@ -1,38 +1,4 @@ -DESCRIPTION = "Transmission is a BitTorrent client w/ a built-in Ajax-Powered Webif GUI." -SECTION = "network" -HOMEPAGE = "www.transmissionbt.com/" -DEPENDS = "gtk+ gnutls openssl gettext libtool intltool-native curl glib-2.0-native" -LICENSE = "GPLv2" -PR = "r2" -SRC_URI = "http://mirrors.m0k.org/transmission/files/transmission-${PV}.tar.bz2 \ - file://init \ - file://config" - -INITSCRIPT_NAME = "transmission" -INITSCRIPT_PARAMS = "defaults 60 " - -inherit autotools update-rc.d - -do_install_append() { - install -d ${D}${sysconfdir}/init.d - install -m 0755 ${WORKDIR}/init ${D}${sysconfdir}/init.d/transmission - install -d ${D}${sysconfdir}/default - install -m 0755 ${WORKDIR}/config ${D}${sysconfdir}/default/transmission-daemon - install -d ${D}${localstatedir}/lib/transmission-daemon -} +require transmission.inc -FILES_${PN} += "${datadir}/icons" -CONFFILES_${PN} = "${sysconfdir}/default/transmission-daemon" - -# No need for online check, since update-rc.d will prepend it to here -pkg_postinst_${PN}() { -grep -q transmission ${sysconfdir}/group || addgroup transmission -grep -q transmission ${sysconfdir}/passwd || adduser -h ${localstatedir}/lib/transmission-daemon -S -D -G transmission -s ${base_bindir}/false transmission -chown -R transmission:transmission /var/lib/transmission-daemon/ -} - -pkg_postrm_${PN}() { -delgroup transmission -deluser transmission -} +PR = "r2" -- cgit v1.2.3 From ff4773355412adf6bb7258bb6c8b45bc43bb5d17 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 15 Sep 2009 12:14:07 +0200 Subject: linux-omap 2.6.31: add memhole patch --- .../linux/linux-omap-2.6.31/arch-has-holes.diff | 145 +++++++++++++++++++++ recipes/linux/linux-omap_2.6.31.bb | 1 + 2 files changed, 146 insertions(+) create mode 100755 recipes/linux/linux-omap-2.6.31/arch-has-holes.diff diff --git a/recipes/linux/linux-omap-2.6.31/arch-has-holes.diff b/recipes/linux/linux-omap-2.6.31/arch-has-holes.diff new file mode 100755 index 0000000000..d6fccc9696 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/arch-has-holes.diff @@ -0,0 +1,145 @@ +From: Russell King - ARM Linux +To: Rabin Vincent +Cc: "Aguirre Rodriguez, Sergio Alberto" , + "Syed Mohammed, Khasim" , + "linux-arm-kernel@lists.arm.linux.org.uk" + , + "linux-omap@vger.kernel.org" +Subject: Re: Exception while handling MEM Hole on OMAP3 / ARM Cortex A8 +Message-ID: <20090907142210.GB23361@n2100.arm.linux.org.uk> +List-ID: +X-Mailing-List: linux-omap@vger.kernel.org + +On Tue, Aug 18, 2009 at 08:31:49AM +0530, Rabin Vincent wrote: +> Here's a fixed version: + +And here's my revised version with these fixes in. I changed the +while loop to a do..while loop instead (since we will always have +at least one memory bank, it's pointless doing that test for the +first iteration.) + +Acks and tested-bys would be useful please. + +diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h +index 376be1a..cefedf0 100644 +--- a/arch/arm/include/asm/memory.h ++++ b/arch/arm/include/asm/memory.h +@@ -218,7 +218,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x) + * + * page_to_pfn(page) convert a struct page * to a PFN number + * pfn_to_page(pfn) convert a _valid_ PFN number to struct page * +- * pfn_valid(pfn) indicates whether a PFN number is valid + * + * virt_to_page(k) convert a _valid_ virtual address to struct page * + * virt_addr_valid(k) indicates whether a virtual address is valid +@@ -227,10 +226,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x) + + #define ARCH_PFN_OFFSET PHYS_PFN_OFFSET + +-#ifndef CONFIG_SPARSEMEM +-#define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr)) +-#endif +- + #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) + #define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) + +@@ -247,18 +242,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x) + #define arch_pfn_to_nid(pfn) PFN_TO_NID(pfn) + #define arch_local_page_offset(pfn, nid) LOCAL_MAP_NR((pfn) << PAGE_SHIFT) + +-#define pfn_valid(pfn) \ +- ({ \ +- unsigned int nid = PFN_TO_NID(pfn); \ +- int valid = nid < MAX_NUMNODES; \ +- if (valid) { \ +- pg_data_t *node = NODE_DATA(nid); \ +- valid = (pfn - node->node_start_pfn) < \ +- node->node_spanned_pages; \ +- } \ +- valid; \ +- }) +- + #define virt_to_page(kaddr) \ + (ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr)) + +diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h +index 9c746af..3a32af4 100644 +--- a/arch/arm/include/asm/page.h ++++ b/arch/arm/include/asm/page.h +@@ -194,6 +194,10 @@ typedef unsigned long pgprot_t; + + typedef struct page *pgtable_t; + ++#ifndef CONFIG_SPARSEMEM ++extern int pfn_valid(unsigned long); ++#endif ++ + #include + + #endif /* !__ASSEMBLY__ */ + +--- /tmp/init.c 2009-09-15 10:17:10.000000000 +0200 ++++ git/arch/arm/mm/init.c 2009-09-15 10:17:01.000000000 +0200 +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -349,12 +350,43 @@ + free_area_init_node(node, zone_size, min, zhole_size); + } + ++#ifndef CONFIG_SPARSEMEM ++int pfn_valid(unsigned long pfn) ++{ ++ struct meminfo *mi = &meminfo; ++ unsigned int left = 0, right = mi->nr_banks; ++ ++ do { ++ unsigned int mid = (right + left) / 2; ++ struct membank *bank = &mi->bank[mid]; ++ ++ if (pfn < bank_pfn_start(bank)) ++ right = mid; ++ else if (pfn >= bank_pfn_end(bank)) ++ left = mid + 1; ++ else ++ return 1; ++ } while (left < right); ++ return 0; ++} ++EXPORT_SYMBOL(pfn_valid); ++#endif ++ ++static int __init meminfo_cmp(const void *_a, const void *_b) ++{ ++ const struct membank *a = _a, *b = _b; ++ long cmp = bank_pfn_start(a) - bank_pfn_start(b); ++ return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; ++} ++ + void __init bootmem_init(void) + { + struct meminfo *mi = &meminfo; + unsigned long min, max_low, max_high; + int node, initrd_node; + ++ sort(&mi->bank, mi->nr_banks, sizeof(mi->bank[0]), meminfo_cmp, NULL); ++ + /* + * Locate which node contains the ramdisk image, if any. + */ +diff -purN git2/arch/arm/Kconfig git/arch/arm/Kconfig +--- git2/arch/arm/Kconfig 2009-07-20 05:07:12.000000000 +0530 ++++ git/arch/arm/Kconfig 2009-08-17 12:08:37.000000000 +0530 +@@ -569,6 +570,7 @@ config ARCH_OMAP + select ARCH_REQUIRE_GPIOLIB + select GENERIC_TIME + select GENERIC_CLOCKEVENTS ++ select ARCH_HAS_HOLES_MEMORYMODEL + help + Support for TI's OMAP platform (OMAP1 and OMAP2). + diff --git a/recipes/linux/linux-omap_2.6.31.bb b/recipes/linux/linux-omap_2.6.31.bb index cf7f69318f..b2387fc6e7 100644 --- a/recipes/linux/linux-omap_2.6.31.bb +++ b/recipes/linux/linux-omap_2.6.31.bb @@ -47,6 +47,7 @@ SRC_URI_append = " \ file://expansion-boards/tincantools-zippy.patch;patch=1 \ file://madc/madc-driver.patch;patch=1 \ file://madc/madc.patch;patch=1 \ + file://arch-has-holes.diff;patch=1 \ " SRC_URI_append_beagleboard = " file://logo_linux_clut224.ppm \ -- cgit v1.2.3 From bdb0b9755876fbb2463dc30b64b57f8c57afc396 Mon Sep 17 00:00:00 2001 From: Steffen Sledz Date: Tue, 15 Sep 2009 15:26:48 +0200 Subject: gob2-native: missing glib-2.0-native dependency added --- recipes/gob2/gob2-native_2.0.14.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/gob2/gob2-native_2.0.14.bb b/recipes/gob2/gob2-native_2.0.14.bb index e6a26f13d2..45bce0121d 100644 --- a/recipes/gob2/gob2-native_2.0.14.bb +++ b/recipes/gob2/gob2-native_2.0.14.bb @@ -1,5 +1,5 @@ require gob2_${PV}.bb -DEPENDS = "bison-native flex-native" +DEPENDS = "bison-native flex-native glib-2.0-native" inherit native -- cgit v1.2.3 From 72c1fd8a2b6ab59a28467c033ec7fa18cfb67225 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sun, 13 Sep 2009 16:33:51 +0200 Subject: u-boot git: add omap3-touchbook support --- recipes/u-boot/u-boot-git/headphone.patch | 35 +++++++++++++++++++++++++++++++ recipes/u-boot/u-boot-git/spi3.patch | 20 ++++++++++++++++++ recipes/u-boot/u-boot-git/spi4.patch | 22 +++++++++++++++++++ recipes/u-boot/u-boot_git.bb | 11 ++++++++++ 4 files changed, 88 insertions(+) create mode 100644 recipes/u-boot/u-boot-git/headphone.patch create mode 100644 recipes/u-boot/u-boot-git/spi3.patch create mode 100644 recipes/u-boot/u-boot-git/spi4.patch diff --git a/recipes/u-boot/u-boot-git/headphone.patch b/recipes/u-boot/u-boot-git/headphone.patch new file mode 100644 index 0000000000..c7eb89e7e7 --- /dev/null +++ b/recipes/u-boot/u-boot-git/headphone.patch @@ -0,0 +1,35 @@ +- Set GPIO_56 muxing for headphone jack detection. + +- Set GPT9_PWM muxing. +- Bring up GPIO_176 high to turn on the screen. + +--- a/board/omap3/beagle/beagle.h 2009-02-19 13:30:50.000000000 -0800 ++++ b/board/omap3/beagle/beagle.h 2009-02-19 13:12:16.000000000 -0800 +@@ -117,8 +117,8 @@ + MUX_VAL(CP(GPMC_NCS1), (IDIS | PTU | EN | M0)) /*GPMC_nCS1*/\ + MUX_VAL(CP(GPMC_NCS2), (IDIS | PTU | EN | M0)) /*GPMC_nCS2*/\ + MUX_VAL(CP(GPMC_NCS3), (IDIS | PTU | EN | M0)) /*GPMC_nCS3*/\ +- MUX_VAL(CP(GPMC_NCS4), (IDIS | PTU | EN | M0)) /*GPMC_nCS4*/\ +- MUX_VAL(CP(GPMC_NCS5), (IDIS | PTD | DIS | M0)) /*GPMC_nCS5*/\ ++ MUX_VAL(CP(GPMC_NCS4), (IDIS | PTU | DIS | M3)) /*GPMC_nCS4 -- GPT9_PWM*/\ ++ MUX_VAL(CP(GPMC_NCS5), (IEN | PTD | DIS | M4)) /*GPMC_nCS5 -- PHONES_DETECT GPIO_56*/\ + MUX_VAL(CP(GPMC_NCS6), (IEN | PTD | DIS | M1)) /*SYS_nDMA_REQ2*/\ + MUX_VAL(CP(GPMC_NCS7), (IEN | PTU | EN | M1)) /*SYS_nDMA_REQ3*/\ + MUX_VAL(CP(GPMC_NBE1), (IEN | PTD | DIS | M0)) /*GPMC_nBE1*/\ +--- a/board/omap3/beagle/beagle.c 2009-02-19 13:30:50.000000000 -0800 ++++ b/board/omap3/beagle/beagle.c 2009-02-19 13:12:16.000000000 -0800 +@@ -244,12 +244,12 @@ + power_init_r(); + + /* Configure GPIOs to output */ +- writel(~(GPIO23 | GPIO10 | GPIO8 | GPIO2 | GPIO1), &gpio6_base->oe); ++ writel(~(GPIO16 | GPIO23 | GPIO10 | GPIO8 | GPIO2 | GPIO1), &gpio6_base->oe); + writel(~(GPIO31 | GPIO30 | GPIO29 | GPIO28 | GPIO22 | GPIO21 | + GPIO15 | GPIO14 | GPIO13 | GPIO12), &gpio5_base->oe); + + /* Set GPIOs */ +- writel(GPIO23 | GPIO10 | GPIO8 | GPIO2 | GPIO1, ++ writel(GPIO16 | GPIO23 | GPIO10 | GPIO8 | GPIO2 | GPIO1, + &gpio6_base->setdataout); + writel(GPIO31 | GPIO30 | GPIO29 | GPIO28 | GPIO22 | GPIO21 | + GPIO15 | GPIO14 | GPIO13 | GPIO12, &gpio5_base->setdataout); diff --git a/recipes/u-boot/u-boot-git/spi3.patch b/recipes/u-boot/u-boot-git/spi3.patch new file mode 100644 index 0000000000..57f60b5daf --- /dev/null +++ b/recipes/u-boot/u-boot-git/spi3.patch @@ -0,0 +1,20 @@ +--- a/board/omap3/beagle/beagle.h 2009-02-19 13:30:50.000000000 -0800 ++++ b/board/omap3/beagle/beagle.h 2009-02-19 13:12:16.000000000 -0800 +@@ -205,12 +205,12 @@ + MUX_VAL(CP(MMC1_DAT6), (IEN | PTU | EN | M0)) /*MMC1_DAT6*/\ + MUX_VAL(CP(MMC1_DAT7), (IEN | PTU | EN | M0)) /*MMC1_DAT7*/\ + /*Wireless LAN */\ +- MUX_VAL(CP(MMC2_CLK), (IEN | PTU | EN | M4)) /*GPIO_130*/\ +- MUX_VAL(CP(MMC2_CMD), (IEN | PTU | EN | M4)) /*GPIO_131*/\ +- MUX_VAL(CP(MMC2_DAT0), (IEN | PTU | EN | M4)) /*GPIO_132*/\ ++ MUX_VAL(CP(MMC2_CLK), (IEN | PTU | DIS | M1)) /*MCSPI3_CLK*/\ ++ MUX_VAL(CP(MMC2_CMD), (IEN | PTU | DIS | M1)) /*MCSPI3_SIMO*/\ ++ MUX_VAL(CP(MMC2_DAT0), (IEN | PTU | EN | M1)) /*MCSPI3_SOMI*/\ + MUX_VAL(CP(MMC2_DAT1), (IEN | PTU | EN | M4)) /*GPIO_133*/\ +- MUX_VAL(CP(MMC2_DAT2), (IEN | PTU | EN | M4)) /*GPIO_134*/\ +- MUX_VAL(CP(MMC2_DAT3), (IEN | PTU | EN | M4)) /*GPIO_135*/\ ++ MUX_VAL(CP(MMC2_DAT2), (IEN | PTU | EN | M1)) /*MCSPI3_CS1*/\ ++ MUX_VAL(CP(MMC2_DAT3), (IEN | PTU | EN | M1)) /*MCSPI3_CS0*/\ + MUX_VAL(CP(MMC2_DAT4), (IEN | PTU | EN | M4)) /*GPIO_136*/\ + MUX_VAL(CP(MMC2_DAT5), (IEN | PTU | EN | M4)) /*GPIO_137*/\ + MUX_VAL(CP(MMC2_DAT6), (IEN | PTU | EN | M4)) /*GPIO_138*/\ diff --git a/recipes/u-boot/u-boot-git/spi4.patch b/recipes/u-boot/u-boot-git/spi4.patch new file mode 100644 index 0000000000..3b0781f999 --- /dev/null +++ b/recipes/u-boot/u-boot-git/spi4.patch @@ -0,0 +1,22 @@ +--- a/board/omap3/beagle/beagle.h 2009-02-19 13:30:50.000000000 -0800 ++++ b/board/omap3/beagle/beagle.h 2009-02-19 13:12:16.000000000 -0800 +@@ -233,13 +233,13 @@ + MUX_VAL(CP(MCBSP4_DR), (IEN | PTD | DIS | M1)) /*SSI1_FLAG_RX*/\ + MUX_VAL(CP(MCBSP4_DX), (IEN | PTD | DIS | M1)) /*SSI1_RDY_RX*/\ + MUX_VAL(CP(MCBSP4_FSX), (IEN | PTD | DIS | M1)) /*SSI1_WAKE*/\ +- MUX_VAL(CP(MCBSP1_CLKR), (IDIS | PTD | DIS | M4)) /*GPIO_156*/\ +- MUX_VAL(CP(MCBSP1_FSR), (IDIS | PTU | EN | M4)) /*GPIO_157*/\ ++ MUX_VAL(CP(MCBSP1_CLKR), (IEN | PTU | DIS | M1)) /*MCSPI4_CLK*/\ ++ MUX_VAL(CP(MCBSP1_FSR), (IEN | PTU | EN | M4)) /*GPIO_157*/\ +- MUX_VAL(CP(MCBSP1_DX), (IDIS | PTD | DIS | M4)) /*GPIO_158*/\ +- MUX_VAL(CP(MCBSP1_DR), (IDIS | PTD | DIS | M4)) /*GPIO_159*/\ ++ MUX_VAL(CP(MCBSP1_DX), (IEN | PTU | DIS | M1)) /*MCSPI4_SIMO*/\ ++ MUX_VAL(CP(MCBSP1_DR), (IEN | PTU | EN | M1)) /*MCSPI4_SOMI*/\ + MUX_VAL(CP(MCBSP_CLKS), (IEN | PTU | DIS | M0)) /*McBSP_CLKS*/\ +- MUX_VAL(CP(MCBSP1_FSX), (IDIS | PTD | DIS | M4)) /*GPIO_161*/\ +- MUX_VAL(CP(MCBSP1_CLKX), (IDIS | PTD | DIS | M4)) /*GPIO_162*/\ ++ MUX_VAL(CP(MCBSP1_FSX), (IEN | PTU | EN | M1)) /*MCSPI4_CS0*/\ ++ MUX_VAL(CP(MCBSP1_CLKX), (IEN | PTU | EN | M4)) /*GPIO_162*/\ + /*Serial Interface*/\ + MUX_VAL(CP(UART3_CTS_RCTX), (IEN | PTD | EN | M0)) /*UART3_CTS_RCTX*/\ + MUX_VAL(CP(UART3_RTS_SD), (IDIS | PTD | DIS | M0)) /*UART3_RTS_SD */\ diff --git a/recipes/u-boot/u-boot_git.bb b/recipes/u-boot/u-boot_git.bb index fea52ac27e..e5e1c24e16 100644 --- a/recipes/u-boot/u-boot_git.bb +++ b/recipes/u-boot/u-boot_git.bb @@ -21,6 +21,17 @@ SRC_URI_beagleboard = "git://gitorious.org/u-boot-omap3/mainline.git;branch=omap SRCREV_beagleboard = "d363f9cb0918a1b6b92e2e20d01543d0c4f53274" PV_beagleboard = "2009.05+${PR}+gitr${SRCREV}" +SRC_URI_omap3-touchbook = "git://gitorious.org/u-boot-omap3/mainline.git;branch=omap3-dev;protocol=git \ + file://fw-env.patch;patch=1 \ + file://dss2.patch;patch=1 \ + file://spi3.patch;patch=1 \ + file://spi4.patch;patch=1 \ + file://headphone.patch;patch=1 \ +" +SRCREV_omap3-touchbook = "d363f9cb0918a1b6b92e2e20d01543d0c4f53274" +PV_omap3-touchbook = "2009.05+${PR}+gitr${SRCREV}" + + SRC_URI_omap3evm = "git://gitorious.org/u-boot-omap3/mainline.git;branch=omap3-dev;protocol=git" SRCREV_omap3evm = "2dea1db2a3b7c12ed70bbf8ee50755089c5e5170" PV_omap3evm = "2009.03+${PR}+gitr${SRCREV}" -- cgit v1.2.3 From d861047e32eacf91974108a5eeba1f847bad5b9f Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sun, 13 Sep 2009 16:30:10 +0200 Subject: linux-omap 2.6.29: add support for the omap3-touchbook --- .../omap3-touchbook/accelerometer-mma7455l.patch | 677 + .../accelerometer-touchscreen-mux-spi.patch | 64 + .../linux-omap-2.6.29/omap3-touchbook/aufs-1.patch | 35 + .../linux-omap-2.6.29/omap3-touchbook/aufs-2.patch | 285 + .../linux-omap-2.6.29/omap3-touchbook/aufs-3.patch | 23604 +++++++ .../aufs-squashfs-mount-to-avoid-initramfs.patch | 40 + .../battery1-tps65950-charging-management-1.patch | 221 + .../battery1-tps65950-charging-management-2.patch | 246 + .../battery2-bq27200-gpio-charged.patch | 53 + .../battery2-bq27200-no-error-message.patch | 39 + .../omap3-touchbook/beagle-asoc.patch | 35 + .../omap3-touchbook/board-omap3beagle.c | 739 + .../omap3-touchbook/boot-no-power-message.patch | 11 + .../linux-omap-2.6.29/omap3-touchbook/defconfig | 2720 + .../omap3-touchbook/defconfig.orig | 2701 + .../omap3-touchbook/dspbridge.patch | 66715 +++++++++++++++++++ .../dss2-blank-rotate-accessible-by-user.patch | 20 + .../omap3-touchbook/dss2-export-status.patch | 44 + .../dss2-fix-XY-coordinates-when-rotating.patch | 177 + .../dss2-fix-scaling-when-rotating.patch | 52 + .../linux-omap-2.6.29/omap3-touchbook/ehci.patch | 131 + .../omap3-touchbook/logo_linux_clut224.ppm | 773 + .../omap3-touchbook/memory-move-malloc-end.patch | 9 + .../screen-backlight-accessible-by-user.patch | 11 + .../omap3-touchbook/screen-backlight.patch | 10 + .../sound-headphone-detection.patch | 93 + .../omap3-touchbook/tincantools-puppy.diff | 66 + .../touchscreen-ads7846-export-settings.patch | 87 + .../touchscreen-ads7846-rotation-support.patch | 108 + ...-lower-current-consumption-upon-insertion.patch | 30 + .../omap3-touchbook/usb-otg-pc-connection.patch | 36 + recipes/linux/linux-omap_2.6.29.bb | 31 +- 32 files changed, 99862 insertions(+), 1 deletion(-) create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/accelerometer-mma7455l.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/accelerometer-touchscreen-mux-spi.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-1.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-2.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-3.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-squashfs-mount-to-avoid-initramfs.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery1-tps65950-charging-management-1.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery1-tps65950-charging-management-2.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery2-bq27200-gpio-charged.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery2-bq27200-no-error-message.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/beagle-asoc.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/board-omap3beagle.c create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/boot-no-power-message.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/defconfig create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/defconfig.orig create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/dspbridge.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/dss2-blank-rotate-accessible-by-user.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/dss2-export-status.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/dss2-fix-XY-coordinates-when-rotating.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/dss2-fix-scaling-when-rotating.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/ehci.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/logo_linux_clut224.ppm create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/memory-move-malloc-end.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/screen-backlight-accessible-by-user.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/screen-backlight.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/sound-headphone-detection.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/tincantools-puppy.diff create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/touchscreen-ads7846-export-settings.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/touchscreen-ads7846-rotation-support.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/usb-lower-current-consumption-upon-insertion.patch create mode 100644 recipes/linux/linux-omap-2.6.29/omap3-touchbook/usb-otg-pc-connection.patch diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/accelerometer-mma7455l.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/accelerometer-mma7455l.patch new file mode 100644 index 0000000000..f6d522e352 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/accelerometer-mma7455l.patch @@ -0,0 +1,677 @@ +From 0b60175d1b7db1301e2ad3ad4d64fb0c8d121c0a Mon Sep 17 00:00:00 2001 +From: Tim Yamin +Date: Sat, 11 Apr 2009 13:05:21 -0700 +Subject: [PATCH] MMA7455L driver. + +--- + drivers/input/misc/Kconfig | 9 + + drivers/input/misc/Makefile | 1 + + drivers/input/misc/mma7455l.c | 614 +++++++++++++++++++++++++++++++++++++++++ + include/linux/mma7455l.h | 11 + + 4 files changed, 635 insertions(+), 0 deletions(-) + +diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig +index 6fa9e38..05dca18 100644 +--- a/drivers/input/misc/Kconfig ++++ b/drivers/input/misc/Kconfig +@@ -237,4 +237,13 @@ config INPUT_PCF50633_PMU + Say Y to include support for delivering PMU events via input + layer on NXP PCF50633. + ++config INPUT_MMA7455L ++ tristate "Freescale MMA7455L 3-axis accelerometer" ++ depends on SPI_MASTER ++ help ++ SPI driver for the Freescale MMA7455L 3-axis accelerometer. ++ ++ The userspace interface is a 3-axis (X/Y/Z) relative movement ++ Linux input device, reporting REL_[XYZ] events. ++ + endif +diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile +index 2fabcdb..e355d82 100644 +--- a/drivers/input/misc/Makefile ++++ b/drivers/input/misc/Makefile +@@ -23,3 +23,4 @@ obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o + obj-$(CONFIG_INPUT_APANEL) += apanel.o + obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o + obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o ++obj-$(CONFIG_INPUT_MMA7455L) += mma7455l.o +diff --git a/drivers/input/misc/mma7455l.c b/drivers/input/misc/mma7455l.c +new file mode 100644 +index 0000000..b33c513 +--- /dev/null ++++ b/drivers/input/misc/mma7455l.c +@@ -0,0 +1,614 @@ ++/* Linux kernel driver for the Freescale MMA7455L 3-axis accelerometer ++ * ++ * Copyright (C) 2009 by Always Innovating, Inc. ++ * Author: Gregoire Gentil ++ * Author: Tim Yamin ++ * All rights reserved. ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ * ++ */ ++ ++/* ++ * What this driver doesn't yet support: ++ * ++ * - I2C ++ * - INT2 handling ++ * - Pulse detection (and the sysctls to control it) ++ * - 10-bit measurement ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define MMA7455L_WHOAMI_MAGIC 0x55 ++ ++enum mma7455l_reg { ++ MMA7455L_REG_XOUTL = 0x00, ++ MMA7455L_REG_XOUTH = 0x01, ++ MMA7455L_REG_YOUTL = 0x02, ++ MMA7455L_REG_YOUTH = 0x03, ++ MMA7455L_REG_ZOUTL = 0x04, ++ MMA7455L_REG_ZOUTH = 0x05, ++ MMA7455L_REG_XOUT8 = 0x06, ++ MMA7455L_REG_YOUT8 = 0x07, ++ MMA7455L_REG_ZOUT8 = 0x08, ++ MMA7455L_REG_STATUS = 0x09, ++ MMA7455L_REG_DETSRC = 0x0a, ++ MMA7455L_REG_TOUT = 0x0b, ++ MMA7455L_REG_RESERVED1 = 0x0c, ++ MMA7455L_REG_I2CAD = 0x0d, ++ MMA7455L_REG_USRINF = 0x0e, ++ MMA7455L_REG_WHOAMI = 0x0f, ++ MMA7455L_REG_XOFFL = 0x10, ++ MMA7455L_REG_XOFFH = 0x11, ++ MMA7455L_REG_YOFFL = 0x12, ++ MMA7455L_REG_YOFFH = 0x13, ++ MMA7455L_REG_ZOFFL = 0x14, ++ MMA7455L_REG_ZOFFH = 0x15, ++ MMA7455L_REG_MCTL = 0x16, ++ MMA7455L_REG_INTRST = 0x17, ++ MMA7455L_REG_CTL1 = 0x18, ++ MMA7455L_REG_CTL2 = 0x19, ++ MMA7455L_REG_LDTH = 0x1a, ++ MMA7455L_REG_PDTH = 0x1b, ++ MMA7455L_REG_PW = 0x1c, ++ MMA7455L_REG_LT = 0x1d, ++ MMA7455L_REG_TW = 0x1e, ++ MMA7455L_REG_RESERVED2 = 0x1f, ++}; ++ ++enum mma7455l_reg_status { ++ MMA7455L_STATUS_XDA = 0x08, ++ MMA7455L_STATUS_YDA = 0x10, ++ MMA7455L_STATUS_ZDA = 0x20, ++}; ++ ++enum mma7455l_mode { ++ MMA7455L_MODE_STANDBY = 0, ++ MMA7455L_MODE_MEASUREMENT = 1, ++ MMA7455L_MODE_LEVELDETECTION = 0x42, /* Set DRPD to on */ ++ MMA7455L_MODE_PULSEDETECTION = 0x43, /* Set DRPD to on */ ++ MMA7455L_MODE_MASK = 0x43, ++}; ++ ++enum mma7455l_gselect { ++ MMA7455L_GSELECT_8 = 0x0, ++ MMA7455L_GSELECT_2 = 0x4, ++ MMA7455L_GSELECT_4 = 0x8, ++ MMA7455L_GSELECT_MASK = 0xC, ++}; ++ ++/* FIXME */ ++#define MMA7455L_F_FS 0x0020 /* ADC full scale */ ++ ++struct mma7455l_info { ++ struct spi_device *spi_dev; ++ struct input_dev *input_dev; ++ struct mutex lock; ++ struct delayed_work work; ++ ++ u8 mode; ++ u8 gSelect; ++ ++ u8 flags; ++ u8 working; ++}; ++ ++/* lowlevel register access functions */ ++ ++#define WRITE_BIT (1 << 7) ++#define ADDR_SHIFT 1 ++ ++static inline u_int8_t __reg_read(struct mma7455l_info *mma, u_int8_t reg) ++{ ++ int rc; ++ u_int8_t cmd; ++ ++ cmd = ((reg & 0x3f) << ADDR_SHIFT); ++ rc = spi_w8r8(mma->spi_dev, cmd); ++ ++ return rc; ++} ++ ++static u_int8_t reg_read(struct mma7455l_info *mma, u_int8_t reg) ++{ ++ u_int8_t ret; ++ ++ mutex_lock(&mma->lock); ++ ret = __reg_read(mma, reg); ++ mutex_unlock(&mma->lock); ++ ++ return ret; ++} ++ ++static s16 __reg_read_10(struct mma7455l_info *mma, u8 reg1, u8 reg2) ++{ ++ u8 v1, v2; ++ ++ v1 = __reg_read(mma, reg1); ++ v2 = __reg_read(mma, reg2); ++ ++ return (v2 & 0x4) << 13 | (v2 & 0x3) << 8 | v1; ++} ++ ++static inline int __reg_write(struct mma7455l_info *mma, u_int8_t reg, u_int8_t val) ++{ ++ u_int8_t buf[2]; ++ ++ buf[0] = ((reg & 0x3f) << ADDR_SHIFT) | WRITE_BIT; ++ buf[1] = val; ++ ++ return spi_write(mma->spi_dev, buf, sizeof(buf)); ++} ++ ++static int reg_write(struct mma7455l_info *mma, u_int8_t reg, u_int8_t val) ++{ ++ int ret; ++ ++ mutex_lock(&mma->lock); ++ ret = __reg_write(mma, reg, val); ++ mutex_unlock(&mma->lock); ++ ++ return ret; ++} ++ ++static s16 __reg_write_10(struct mma7455l_info *mma, u8 reg1, u8 reg2, s16 value) ++{ ++ int ret; ++ u8 v1, v2; ++ ++ v1 = value & 0xFF; ++ if(value < 0) ++ v2 = ((value >> 8) & 0x3) | 0x4; ++ else ++ v2 = 0; ++ ++ ret = __reg_write(mma, reg1, v1); ++ ret = __reg_write(mma, reg2, v2); ++ return ret; ++} ++ ++static void mma7455l_work(struct work_struct *work) ++{ ++ struct mma7455l_info *mma = ++ container_of(work, struct mma7455l_info, work.work); ++ ++ s8 val; ++ mma->working = 1; ++ ++ /* FIXME: 10 bit accuracy? */ ++ if (!(mma->flags & MMA7455L_STATUS_XDA)) { ++ val = reg_read(mma, MMA7455L_REG_XOUT8); ++ input_report_abs(mma->input_dev, ABS_X, val); ++ } ++ if (!(mma->flags & MMA7455L_STATUS_YDA)) { ++ val = reg_read(mma, MMA7455L_REG_YOUT8); ++ input_report_abs(mma->input_dev, ABS_Y, val); ++ } ++ if (!(mma->flags & MMA7455L_STATUS_ZDA)) { ++ val = reg_read(mma, MMA7455L_REG_ZOUT8); ++ input_report_abs(mma->input_dev, ABS_Z, val); ++ } ++ ++ mma->working = 0; ++ input_sync(mma->input_dev); ++ put_device(&mma->spi_dev->dev); ++ ++ /* Enable IRQ and clear out interrupt */ ++ reg_write(mma, MMA7455L_REG_INTRST, 0x3); ++ reg_write(mma, MMA7455L_REG_INTRST, 0x0); ++ enable_irq(mma->spi_dev->irq); ++} ++ ++static void mma7455l_schedule_work(struct mma7455l_info *mma) ++{ ++ int status; ++ ++ get_device(&mma->spi_dev->dev); ++ status = schedule_delayed_work(&mma->work, HZ / 10); ++} ++ ++static irqreturn_t mma7455l_interrupt(int irq, void *_mma) ++{ ++ struct mma7455l_info *mma = _mma; ++ mma7455l_schedule_work(mma); ++ ++ /* Disable any further interrupts until we have processed ++ * the current one */ ++ disable_irq(mma->spi_dev->irq); ++ return IRQ_HANDLED; ++} ++ ++/* sysfs */ ++ ++static void get_mode(struct mma7455l_info *mma, u8 *mode, u8 *gSelect) ++{ ++ u8 tmp = reg_read(mma, MMA7455L_REG_MCTL); ++ ++ *mode = tmp & MMA7455L_MODE_MASK; ++ *gSelect = tmp & MMA7455L_GSELECT_MASK; ++} ++ ++static void set_mode(struct mma7455l_info *mma, u8 mode, u8 gSelect) ++{ ++ reg_write(mma, MMA7455L_REG_MCTL, mode | gSelect); ++} ++ ++static void update_mode(struct mma7455l_info *mma, u8 mode, u8 gSelect) ++{ ++ mma->mode = mode; ++ mma->gSelect = gSelect; ++ ++ reg_write(mma, MMA7455L_REG_MCTL, mma->mode | mma->gSelect); ++} ++ ++static ssize_t show_measure(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct mma7455l_info *mma = dev_get_drvdata(dev); ++ s8 x, y, z; ++ u8 old_Mode, old_gSelect; ++ ++ get_mode(mma, &old_Mode, &old_gSelect); ++ set_mode(mma, MMA7455L_MODE_MEASUREMENT, MMA7455L_GSELECT_2); ++ ++ while (reg_read(mma, MMA7455L_REG_STATUS) == 0) { ++ msleep(10); ++ } ++ ++ x = reg_read(mma, MMA7455L_REG_XOUT8); ++ y = reg_read(mma, MMA7455L_REG_YOUT8); ++ z = reg_read(mma, MMA7455L_REG_ZOUT8); ++ ++ set_mode(mma, old_Mode, old_gSelect); ++ return sprintf(buf, "%d %d %d\n", x, y, z); ++} ++ ++static ssize_t show_mode(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct mma7455l_info *mma = dev_get_drvdata(dev); ++ ++ switch(mma->mode) ++ { ++ case MMA7455L_MODE_STANDBY: ++ return sprintf(buf, "Standby\n"); ++ break; ++ case MMA7455L_MODE_MEASUREMENT: ++ return sprintf(buf, "Measurement\n"); ++ break; ++ case MMA7455L_MODE_LEVELDETECTION: ++ return sprintf(buf, "Level Detection\n"); ++ break; ++ case MMA7455L_MODE_PULSEDETECTION: ++ return sprintf(buf, "Pulse Detection\n"); ++ break; ++ } ++ ++ return sprintf(buf, "Unknown mode!\n"); ++} ++ ++static ssize_t show_gSelect(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct mma7455l_info *mma = dev_get_drvdata(dev); ++ ++ switch(mma->gSelect) ++ { ++ case MMA7455L_GSELECT_8: ++ return sprintf(buf, "8\n"); ++ break; ++ case MMA7455L_GSELECT_4: ++ return sprintf(buf, "4\n"); ++ break; ++ case MMA7455L_GSELECT_2: ++ return sprintf(buf, "2\n"); ++ break; ++ } ++ ++ return sprintf(buf, "Unknown gSelect!\n"); ++} ++ ++static ssize_t show_level_threshold(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct mma7455l_info *mma = dev_get_drvdata(dev); ++ return sprintf(buf, "%u\n", reg_read(mma, MMA7455L_REG_LDTH)); ++} ++ ++static ssize_t show_calibration(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ s16 x, y, z; ++ struct mma7455l_info *mma = dev_get_drvdata(dev); ++ ++ mutex_lock(&mma->lock); ++ x = __reg_read_10(mma, MMA7455L_REG_XOFFL, MMA7455L_REG_XOFFH); ++ y = __reg_read_10(mma, MMA7455L_REG_YOFFL, MMA7455L_REG_YOFFH); ++ z = __reg_read_10(mma, MMA7455L_REG_ZOFFL, MMA7455L_REG_ZOFFH); ++ mutex_unlock(&mma->lock); ++ ++ return sprintf(buf, "%d %d %d\n", x, y, z); ++} ++ ++static ssize_t write_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) ++{ ++ struct mma7455l_info *mma = dev_get_drvdata(dev); ++ ++ if (!strncmp(buf, "Standby", count)) ++ update_mode(mma, MMA7455L_MODE_STANDBY, mma->gSelect); ++ else if (!strncmp(buf, "Measurement", count)) ++ update_mode(mma, MMA7455L_MODE_MEASUREMENT, mma->gSelect); ++ else if (!strncmp(buf, "Level Detection", count)) ++ update_mode(mma, MMA7455L_MODE_LEVELDETECTION, mma->gSelect); ++ else if (!strncmp(buf, "Pulse Detection", count)) ++ update_mode(mma, MMA7455L_MODE_PULSEDETECTION, mma->gSelect); ++ ++ return count; ++} ++ ++static ssize_t write_gSelect(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) ++{ ++ unsigned long v; ++ struct mma7455l_info *mma = dev_get_drvdata(dev); ++ ++ if(strict_strtoul(buf, 10, &v) == 0) ++ { ++ switch(v) ++ { ++ case 8: ++ update_mode(mma, mma->mode, MMA7455L_GSELECT_8); ++ break; ++ case 4: ++ update_mode(mma, mma->mode, MMA7455L_GSELECT_4); ++ break; ++ case 2: ++ update_mode(mma, mma->mode, MMA7455L_GSELECT_2); ++ break; ++ default: ++ return -EINVAL; ++ break; ++ } ++ return count; ++ } ++ ++ return -EINVAL; ++} ++ ++static ssize_t write_level_threshold(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) ++{ ++ unsigned long v; ++ struct mma7455l_info *mma = dev_get_drvdata(dev); ++ ++ if(strict_strtoul(buf, 10, &v) == 0) ++ { ++ if(v <= 0xFF) { ++ reg_write(mma, MMA7455L_REG_LDTH, v); ++ return count; ++ } else ++ return -EINVAL; ++ } ++ ++ return -EINVAL; ++} ++ ++static ssize_t write_calibration(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) ++{ ++ int x, y, z; ++ struct mma7455l_info *mma = dev_get_drvdata(dev); ++ ++ if (sscanf(buf, "%d %d %d", &x, &y, &z) == 3) ++ { ++ mutex_lock(&mma->lock); ++ __reg_write_10(mma, MMA7455L_REG_XOFFL, MMA7455L_REG_XOFFH, x); ++ __reg_write_10(mma, MMA7455L_REG_YOFFL, MMA7455L_REG_YOFFH, y); ++ __reg_write_10(mma, MMA7455L_REG_ZOFFL, MMA7455L_REG_ZOFFH, z); ++ mutex_unlock(&mma->lock); ++ ++ return count; ++ } ++ ++ return -EINVAL; ++} ++ ++static DEVICE_ATTR(measure, S_IRUGO, show_measure, NULL); ++static DEVICE_ATTR(mode, S_IRUGO | S_IWUGO, show_mode, write_mode); ++static DEVICE_ATTR(gSelect, S_IRUGO | S_IWUGO, show_gSelect, write_gSelect); ++static DEVICE_ATTR(level_threshold, S_IRUGO | S_IWUGO, show_level_threshold, write_level_threshold); ++static DEVICE_ATTR(calibration, S_IRUGO | S_IWUGO, show_calibration, write_calibration); ++ ++static struct attribute *mma7455l_sysfs_entries[] = { ++ &dev_attr_measure.attr, ++ &dev_attr_mode.attr, ++ &dev_attr_gSelect.attr, ++ &dev_attr_level_threshold.attr, ++ &dev_attr_calibration.attr, ++ NULL ++}; ++ ++static struct attribute_group mma7455l_attr_group = { ++ .attrs = mma7455l_sysfs_entries, ++}; ++ ++/* input device handling and driver core interaction */ ++static int mma7455l_input_open(struct input_dev *inp) ++{ ++ struct mma7455l_info *mma = input_get_drvdata(inp); ++ if(mma->mode == MMA7455L_MODE_STANDBY) ++ update_mode(mma, MMA7455L_MODE_MEASUREMENT, mma->gSelect); ++ ++ return 0; ++} ++ ++static void mma7455l_input_close(struct input_dev *inp) ++{ ++ struct mma7455l_info *mma = input_get_drvdata(inp); ++ update_mode(mma, MMA7455L_MODE_STANDBY, MMA7455L_GSELECT_2); ++} ++ ++static int __devinit mma7455l_probe(struct spi_device *spi) ++{ ++ int rc; ++ struct mma7455l_info *mma; ++ struct mma7455l_platform_data *pdata = spi->dev.platform_data; ++ u_int8_t wai; ++ ++ mma = kzalloc(sizeof(*mma), GFP_KERNEL); ++ if (!mma) ++ return -ENOMEM; ++ ++ mutex_init(&mma->lock); ++ INIT_DELAYED_WORK(&mma->work, mma7455l_work); ++ mma->spi_dev = spi; ++ mma->flags = mma->working = 0; ++ ++ spi_set_drvdata(spi, mma); ++ ++ rc = spi_setup(spi); ++ if (rc < 0) { ++ printk(KERN_ERR "mma7455l error durign spi_setup of mma7455l driver\n"); ++ dev_set_drvdata(&spi->dev, NULL); ++ kfree(mma); ++ return rc; ++ } ++ ++ wai = reg_read(mma, MMA7455L_REG_WHOAMI); ++ if (wai != MMA7455L_WHOAMI_MAGIC) { ++ printk(KERN_ERR "mma7455l unknown whoami signature 0x%02x\n", wai); ++ dev_set_drvdata(&spi->dev, NULL); ++ kfree(mma); ++ return -ENODEV; ++ } ++ ++ rc = request_irq(mma->spi_dev->irq, mma7455l_interrupt, IRQF_TRIGGER_HIGH, ++ "mma7455l", mma); ++ if (rc < 0) { ++ dev_err(&spi->dev, "mma7455l error requesting IRQ %d\n", ++ mma->spi_dev->irq); ++ /* FIXME */ ++ return rc; ++ } ++ ++ rc = sysfs_create_group(&spi->dev.kobj, &mma7455l_attr_group); ++ if (rc) { ++ dev_err(&spi->dev, "error creating sysfs group\n"); ++ return rc; ++ } ++ ++ /* initialize input layer details */ ++ mma->input_dev = input_allocate_device(); ++ if (!mma->input_dev) { ++ dev_err(&spi->dev, "mma7455l Unable to allocate input device\n"); ++ /* FIXME */ ++ } ++ ++ set_bit(EV_ABS, mma->input_dev->evbit); ++ set_bit(ABS_X, mma->input_dev->absbit); ++ set_bit(ABS_Y, mma->input_dev->absbit); ++ set_bit(ABS_Z, mma->input_dev->absbit); ++ ++ input_set_drvdata(mma->input_dev, mma); ++ mma->input_dev->name = "MMA7455L"; ++ mma->input_dev->open = mma7455l_input_open; ++ mma->input_dev->close = mma7455l_input_close; ++ ++ rc = input_register_device(mma->input_dev); ++ if(!rc) ++ { ++ update_mode(mma, MMA7455L_MODE_STANDBY, MMA7455L_GSELECT_2); ++ ++ mutex_lock(&mma->lock); ++ __reg_write_10(mma, MMA7455L_REG_XOFFL, MMA7455L_REG_XOFFH, pdata->calibration_x); ++ __reg_write_10(mma, MMA7455L_REG_YOFFL, MMA7455L_REG_YOFFH, pdata->calibration_y); ++ __reg_write_10(mma, MMA7455L_REG_ZOFFL, MMA7455L_REG_ZOFFH, pdata->calibration_z); ++ mutex_unlock(&mma->lock); ++ ++ return 0; ++ } ++ ++ input_free_device(mma->input_dev); ++ return rc; ++} ++ ++static int __devexit mma7455l_remove(struct spi_device *spi) ++{ ++ struct mma7455l_info *mma = dev_get_drvdata(&spi->dev); ++ ++ sysfs_remove_group(&spi->dev.kobj, &mma7455l_attr_group); ++ input_unregister_device(mma->input_dev); ++ dev_set_drvdata(&spi->dev, NULL); ++ kfree(mma); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int mma7455l_suspend(struct spi_device *spi, pm_message_t message) ++{ ++ struct mma7455l_info *mma = dev_get_drvdata(&spi->dev); ++ get_mode(mma, &mma->mode, &mma->gSelect); ++ set_mode(mma, MMA7455L_MODE_STANDBY, MMA7455L_GSELECT_2); ++ ++ return 0; ++} ++ ++static int mma7455l_resume(struct spi_device *spi) ++{ ++ struct mma7455l_info *mma = dev_get_drvdata(&spi->dev); ++ update_mode(mma, mma->mode, mma->gSelect); ++ ++ return 0; ++} ++#else ++#define mma7455l_suspend NULL ++#define mma7455l_resume NULL ++#endif ++ ++static struct spi_driver mma7455l_driver = { ++ .driver = { ++ .name = "mma7455l", ++ .owner = THIS_MODULE, ++ }, ++ ++ .probe = mma7455l_probe, ++ .remove = __devexit_p(mma7455l_remove), ++ .suspend = mma7455l_suspend, ++ .resume = mma7455l_resume, ++}; ++ ++static int __init mma7455l_init(void) ++{ ++ return spi_register_driver(&mma7455l_driver); ++} ++ ++static void __exit mma7455l_exit(void) ++{ ++ spi_unregister_driver(&mma7455l_driver); ++} ++ ++MODULE_AUTHOR("Gregoire Gentil "); ++MODULE_LICENSE("GPL"); ++ ++module_init(mma7455l_init); ++module_exit(mma7455l_exit); +diff --git a/include/linux/mma7455l.h b/include/linux/mma7455l.h +new file mode 100644 +index 0000000..12ab50a +--- /dev/null ++++ b/include/linux/mma7455l.h +@@ -0,0 +1,11 @@ ++#ifndef _LINUX_MMA7455L_H ++#define _LINUX_MMA7455L_H ++ ++struct mma7455l_platform_data { ++ /* Calibration offsets */ ++ s16 calibration_x; ++ s16 calibration_y; ++ s16 calibration_z; ++}; ++ ++#endif /* _LINUX_MMA7455L_H */ + diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/accelerometer-touchscreen-mux-spi.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/accelerometer-touchscreen-mux-spi.patch new file mode 100644 index 0000000000..57bb4196dd --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/accelerometer-touchscreen-mux-spi.patch @@ -0,0 +1,64 @@ +--- a/arch/arm/mach-omap2/devices.c 2009-02-17 21:15:12.000000000 -0800 ++++ b/arch/arm/mach-omap2/devices.c 2009-02-17 22:30:26.000000000 -0800 +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -347,6 +348,37 @@ + .platform_data = &omap2_mcspi4_config, + }, + }; ++ ++static struct spi_gpio_platform_data spi3_gpio_platform_data = { ++ .miso = 132, ++ .mosi = 131, ++ .sck = 130, ++ .num_chipselect = 1, ++}; ++ ++static struct platform_device spi3_gpio = { ++ .name = "spi_gpio", ++ .id = 3, ++ .dev = { ++ .platform_data = &spi3_gpio_platform_data, ++ }, ++}; ++ ++static struct spi_gpio_platform_data spi4_gpio_platform_data = { ++ .miso = 159, ++ .mosi = 158, ++ .sck = 156, ++ .num_chipselect = 1, ++}; ++ ++static struct platform_device spi4_gpio = { ++ .name = "spi_gpio", ++ .id = 4, ++ .dev = { ++ .platform_data = &spi4_gpio_platform_data, ++ }, ++}; ++ + #endif + + static void omap_init_mcspi(void) +--- a/drivers/input/touchscreen/ads7846.c 2009-04-07 10:04:12.000000000 -0700 ++++ b/drivers/input/touchscreen/ads7846.c 2009-04-11 12:39:51.000000000 -0700 +@@ -887,13 +919,6 @@ + return 0; + } + +- err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); +- if (err) { +- dev_err(&spi->dev, "failed to request pendown GPIO%d\n", +- pdata->gpio_pendown); +- return err; +- } +- + ts->gpio_pendown = pdata->gpio_pendown; + return 0; + } diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-1.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-1.patch new file mode 100644 index 0000000000..3b54e71791 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-1.patch @@ -0,0 +1,35 @@ +aufs2 kbuild patch for linux-2.6.29 + +diff --git a/fs/Kconfig b/fs/Kconfig +index 93945dd..75156dd 100644 +--- a/fs/Kconfig ++++ b/fs/Kconfig +@@ -222,6 +222,7 @@ source "fs/qnx4/Kconfig" + source "fs/romfs/Kconfig" + source "fs/sysv/Kconfig" + source "fs/ufs/Kconfig" ++source "fs/aufs/Kconfig" + + endif # MISC_FILESYSTEMS + +diff --git a/fs/Makefile b/fs/Makefile +index dc20db3..a4e9a65 100644 +--- a/fs/Makefile ++++ b/fs/Makefile +@@ -124,3 +124,4 @@ obj-$(CONFIG_DEBUG_FS) += debugfs/ + obj-$(CONFIG_OCFS2_FS) += ocfs2/ + obj-$(CONFIG_BTRFS_FS) += btrfs/ + obj-$(CONFIG_GFS2_FS) += gfs2/ ++obj-$(CONFIG_AUFS_FS) += aufs/ +diff --git a/include/linux/Kbuild b/include/linux/Kbuild +index 106c3ba..d0c7262 100644 +--- a/include/linux/Kbuild ++++ b/include/linux/Kbuild +@@ -34,6 +34,7 @@ header-y += atmppp.h + header-y += atmsap.h + header-y += atmsvc.h + header-y += atm_zatm.h ++header-y += aufs_type.h + header-y += auto_fs4.h + header-y += ax25.h + header-y += b1lli.h diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-2.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-2.patch new file mode 100644 index 0000000000..bc3d5d8795 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-2.patch @@ -0,0 +1,285 @@ +aufs2 standalone patch for linux-2.6.29 + +diff --git a/fs/namei.c b/fs/namei.c +index bbc15c2..f446c65 100644 +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -335,6 +335,9 @@ int deny_write_access(struct file * file) + + return 0; + } ++#ifdef CONFIG_AUFS_FS_MODULE ++EXPORT_SYMBOL(deny_write_access); ++#endif + + /** + * path_get - get a reference to a path +@@ -1196,7 +1199,7 @@ out: + * needs parent already locked. Doesn't follow mounts. + * SMP-safe. + */ +-static struct dentry *lookup_hash(struct nameidata *nd) ++struct dentry *lookup_hash(struct nameidata *nd) + { + int err; + +@@ -1205,8 +1208,11 @@ static struct dentry *lookup_hash(struct nameidata *nd) + return ERR_PTR(err); + return __lookup_hash(&nd->last, nd->path.dentry, nd); + } ++#ifdef CONFIG_AUFS_FS_MODULE ++EXPORT_SYMBOL(lookup_hash); ++#endif + +-static int __lookup_one_len(const char *name, struct qstr *this, ++int __lookup_one_len(const char *name, struct qstr *this, + struct dentry *base, int len) + { + unsigned long hash; +@@ -1227,6 +1233,9 @@ static int __lookup_one_len(const char *name, struct qstr *this, + this->hash = end_name_hash(hash); + return 0; + } ++#ifdef CONFIG_AUFS_FS_MODULE ++EXPORT_SYMBOL(__lookup_one_len); ++#endif + + /** + * lookup_one_len - filesystem helper to lookup single pathname component +diff --git a/fs/namespace.c b/fs/namespace.c +index 06f8e63..dcdc4ff 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -37,6 +37,9 @@ + + /* spinlock for vfsmount related operations, inplace of dcache_lock */ + __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock); ++#if defined(CONFIG_AUFS_FS_MODULE) && defined(CONFIG_AUFS_EXPORT) ++EXPORT_SYMBOL(vfsmount_lock); ++#endif + + static int event; + static DEFINE_IDA(mnt_id_ida); +diff --git a/fs/open.c b/fs/open.c +index a3a78ce..7d70245 100644 +--- a/fs/open.c ++++ b/fs/open.c +@@ -220,6 +220,9 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, + mutex_unlock(&dentry->d_inode->i_mutex); + return err; + } ++#ifdef CONFIG_AUFS_FS_MODULE ++EXPORT_SYMBOL(do_truncate); ++#endif + + static long do_sys_truncate(const char __user *pathname, loff_t length) + { +diff --git a/fs/splice.c b/fs/splice.c +index 4ed0ba4..a110d76 100644 +--- a/fs/splice.c ++++ b/fs/splice.c +@@ -888,8 +888,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); + /* + * Attempt to initiate a splice from pipe to file. + */ +-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, +- loff_t *ppos, size_t len, unsigned int flags) ++long do_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags) + { + int ret; + +@@ -908,13 +908,16 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, + + return out->f_op->splice_write(pipe, out, ppos, len, flags); + } ++#ifdef CONFIG_AUFS_FS_MODULE ++EXPORT_SYMBOL(do_splice_from); ++#endif + + /* + * Attempt to initiate a splice from a file to a pipe. + */ +-static long do_splice_to(struct file *in, loff_t *ppos, +- struct pipe_inode_info *pipe, size_t len, +- unsigned int flags) ++long do_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags) + { + int ret; + +@@ -930,6 +933,9 @@ static long do_splice_to(struct file *in, loff_t *ppos, + + return in->f_op->splice_read(in, ppos, pipe, len, flags); + } ++#ifdef CONFIG_AUFS_FS_MODULE ++EXPORT_SYMBOL(do_splice_to); ++#endif + + /** + * splice_direct_to_actor - splices data directly between two non-pipes +diff --git a/fs/super.c b/fs/super.c +index 6ce5014..95eefb9 100644 +--- a/fs/super.c ++++ b/fs/super.c +@@ -287,6 +287,9 @@ int fsync_super(struct super_block *sb) + __fsync_super(sb); + return sync_blockdev(sb->s_bdev); + } ++#ifdef CONFIG_AUFS_FS_MODULE ++EXPORT_SYMBOL(fsync_super); ++#endif + + /** + * generic_shutdown_super - common helper for ->kill_sb() +diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h +index 23bf02f..49e5b47 100644 +--- a/include/linux/lockdep.h ++++ b/include/linux/lockdep.h +@@ -58,7 +58,7 @@ enum lock_usage_bit + #define LOCKF_USED_IN_IRQ_READ \ + (LOCKF_USED_IN_HARDIRQ_READ | LOCKF_USED_IN_SOFTIRQ_READ) + +-#define MAX_LOCKDEP_SUBCLASSES 8UL ++#define MAX_LOCKDEP_SUBCLASSES 12UL + + /* + * Lock-classes are keyed via unique addresses, by embedding the +diff --git a/include/linux/namei.h b/include/linux/namei.h +index fc2e035..182d43b 100644 +--- a/include/linux/namei.h ++++ b/include/linux/namei.h +@@ -75,6 +75,9 @@ extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry + extern struct file *nameidata_to_filp(struct nameidata *nd, int flags); + extern void release_open_intent(struct nameidata *); + ++extern struct dentry *lookup_hash(struct nameidata *nd); ++extern int __lookup_one_len(const char *name, struct qstr *this, ++ struct dentry *base, int len); + extern struct dentry *lookup_one_len(const char *, struct dentry *, int); + extern struct dentry *lookup_one_noperm(const char *, struct dentry *); + +diff --git a/include/linux/splice.h b/include/linux/splice.h +index 528dcb9..5123bc6 100644 +--- a/include/linux/splice.h ++++ b/include/linux/splice.h +@@ -71,4 +71,10 @@ extern ssize_t splice_to_pipe(struct pipe_inode_info *, + extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *, + splice_direct_actor *); + ++extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags); ++extern long do_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags); ++ + #endif +diff --git a/security/device_cgroup.c b/security/device_cgroup.c +index 3aacd0f..76c8876 100644 +--- a/security/device_cgroup.c ++++ b/security/device_cgroup.c +@@ -507,6 +507,9 @@ acc_check: + + return -EPERM; + } ++#ifdef CONFIG_AUFS_FS_MODULE ++EXPORT_SYMBOL(devcgroup_inode_permission); ++#endif + + int devcgroup_inode_mknod(int mode, dev_t dev) + { +diff --git a/security/security.c b/security/security.c +index c3586c0..f8798f8 100644 +--- a/security/security.c ++++ b/security/security.c +@@ -389,6 +389,9 @@ int security_path_mkdir(struct path *path, struct dentry *dentry, int mode) + return 0; + return security_ops->path_mkdir(path, dentry, mode); + } ++#ifdef CONFIG_AUFS_FS_MODULE ++EXPORT_SYMBOL(security_path_mkdir); ++#endif + + int security_path_rmdir(struct path *path, struct dentry *dentry) + { +@@ -396,6 +399,9 @@ int security_path_rmdir(struct path *path, struct dentry *dentry) + return 0; + return security_ops->path_rmdir(path, dentry); + } ++#ifdef CONFIG_AUFS_FS_MODULE ++EXPORT_SYMBOL(security_path_rmdir); ++#endif + + int security_path_unlink(struct path *path, struct dentry *dentry) + { +@@ -403,6 +409,9 @@ int security_path_unlink(struct path *path, struct dentry *dentry) + return 0; + return security_ops->path_unlink(path, dentry); + } ++#ifdef CONFIG_AUFS_FS_MODULE ++EXPORT_SYMBOL(security_path_unlink); ++#endif + + int security_path_symlink(struct path *path, struct dentry *dentry, + const char *old_name) +@@ -411,6 +420,9 @@ int security_path_symlink(struct path *path, struct dentry *dentry, + return 0; + return security_ops->path_symlink(path, dentry, old_name); + } ++#ifdef CONFIG_AUFS_FS_MODULE ++EXPORT_SYMBOL(security_path_symlink); ++#endif + + int security_path_link(struct dentry *old_dentry, struct path *new_dir, + struct dentry *new_dentry) +@@ -419,6 +431,9 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir, + return 0; + return security_ops->path_link(old_dentry, new_dir, new_dentry); + } ++#ifdef CONFIG_AUFS_FS_MODULE ++EXPORT_SYMBOL(security_path_link); ++#endif + + int security_path_rename(struct path *old_dir, struct dentry *old_dentry, + struct path *new_dir, struct dentry *new_dentry) +@@ -429,6 +444,9 @@ int security_path_rename(struct path *old_dir, struct dentry *old_dentry, + return security_ops->path_rename(old_dir, old_dentry, new_dir, + new_dentry); + } ++#ifdef CONFIG_AUFS_FS_MODULE ++EXPORT_SYMBOL(security_path_rename); ++#endif + + int security_path_truncate(struct path *path, loff_t length, + unsigned int time_attrs) +@@ -437,6 +455,9 @@ int security_path_truncate(struct path *path, loff_t length, + return 0; + return security_ops->path_truncate(path, length, time_attrs); + } ++#ifdef CONFIG_AUFS_FS_MODULE ++EXPORT_SYMBOL(security_path_truncate); ++#endif + #endif + + int security_inode_create(struct inode *dir, struct dentry *dentry, int mode) +@@ -506,6 +527,9 @@ int security_inode_readlink(struct dentry *dentry) + return 0; + return security_ops->inode_readlink(dentry); + } ++#ifdef CONFIG_AUFS_FS_MODULE ++EXPORT_SYMBOL(security_inode_readlink); ++#endif + + int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd) + { +@@ -520,6 +544,9 @@ int security_inode_permission(struct inode *inode, int mask) + return 0; + return security_ops->inode_permission(inode, mask); + } ++#ifdef CONFIG_AUFS_FS_MODULE ++EXPORT_SYMBOL(security_inode_permission); ++#endif + + int security_inode_setattr(struct dentry *dentry, struct iattr *attr) + { diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-3.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-3.patch new file mode 100644 index 0000000000..34a035a037 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-3.patch @@ -0,0 +1,23604 @@ +diff -Naur a/Documentation/ABI/testing/debugfs-aufs b/Documentation/ABI/testing/debugfs-aufs +--- a/Documentation/ABI/testing/debugfs-aufs 1969-12-31 16:00:00.000000000 -0800 ++++ b/Documentation/ABI/testing/debugfs-aufs 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,40 @@ ++What: /debug/aufs/si_/ ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ Under /debug/aufs, a directory named si_ is created ++ per aufs mount, where is a unique id generated ++ internally. ++ ++What: /debug/aufs/si_/xib ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ It shows the consumed blocks by xib (External Inode Number ++ Bitmap), its block size and file size. ++ When the aufs mount option 'noxino' is specified, it ++ will be empty. About XINO files, see ++ Documentation/filesystems/aufs/aufs.5 in detail. ++ ++What: /debug/aufs/si_/xino0, xino1 ... xinoN ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ It shows the consumed blocks by xino (External Inode Number ++ Translation Table), its link count, block size and file ++ size. ++ When the aufs mount option 'noxino' is specified, it ++ will be empty. About XINO files, see ++ Documentation/filesystems/aufs/aufs.5 in detail. ++ ++What: /debug/aufs/si_/xigen ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ It shows the consumed blocks by xigen (External Inode ++ Generation Table), its block size and file size. ++ If CONFIG_AUFS_EXPORT is disabled, this entry will not ++ be created. ++ When the aufs mount option 'noxino' is specified, it ++ will be empty. About XINO files, see ++ Documentation/filesystems/aufs/aufs.5 in detail. +diff -Naur a/Documentation/ABI/testing/sysfs-aufs b/Documentation/ABI/testing/sysfs-aufs +--- a/Documentation/ABI/testing/sysfs-aufs 1969-12-31 16:00:00.000000000 -0800 ++++ b/Documentation/ABI/testing/sysfs-aufs 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,25 @@ ++What: /sys/fs/aufs/si_/ ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ Under /sys/fs/aufs, a directory named si_ is created ++ per aufs mount, where is a unique id generated ++ internally. ++ ++What: /sys/fs/aufs/si_/br0, br1 ... brN ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ It shows the abolute path of a member directory (which ++ is called branch) in aufs, and its permission. ++ ++What: /sys/fs/aufs/si_/xi_path ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ It shows the abolute path of XINO (External Inode Number ++ Bitmap, Translation Table and Generation Table) file ++ even if it is the default path. ++ When the aufs mount option 'noxino' is specified, it ++ will be empty. About XINO files, see ++ Documentation/filesystems/aufs/aufs.5 in detail. +diff -Naur a/fs/aufs/aufs.h b/fs/aufs/aufs.h +--- a/fs/aufs/aufs.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/aufs.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,51 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * all header files ++ */ ++ ++#ifndef __AUFS_H__ ++#define __AUFS_H__ ++ ++#ifdef __KERNEL__ ++ ++#include "debug.h" ++ ++#include "branch.h" ++#include "cpup.h" ++#include "dcsub.h" ++#include "dbgaufs.h" ++#include "dentry.h" ++#include "dir.h" ++#include "file.h" ++#include "fstype.h" ++#include "inode.h" ++#include "loop.h" ++#include "module.h" ++#include "opts.h" ++#include "rwsem.h" ++#include "spl.h" ++#include "super.h" ++#include "sysaufs.h" ++#include "vfsub.h" ++#include "whout.h" ++#include "wkq.h" ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_H__ */ +diff -Naur a/fs/aufs/branch.c b/fs/aufs/branch.c +--- a/fs/aufs/branch.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/branch.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,956 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * branch management ++ */ ++ ++#include ++#include "aufs.h" ++ ++/* ++ * free a single branch ++ */ ++static void au_br_do_free(struct au_branch *br) ++{ ++ int i; ++ struct au_wbr *wbr; ++ ++ if (br->br_xino.xi_file) ++ fput(br->br_xino.xi_file); ++ mutex_destroy(&br->br_xino.xi_nondir_mtx); ++ ++ AuDebugOn(atomic_read(&br->br_count)); ++ ++ wbr = br->br_wbr; ++ if (wbr) { ++ for (i = 0; i < AuBrWh_Last; i++) ++ dput(wbr->wbr_wh[i]); ++ AuDebugOn(atomic_read(&wbr->wbr_wh_running)); ++ au_rwsem_destroy(&wbr->wbr_wh_rwsem); ++ } ++ ++ /* some filesystems acquire extra lock */ ++ lockdep_off(); ++ mntput(br->br_mnt); ++ lockdep_on(); ++ ++ kfree(wbr); ++ kfree(br); ++} ++ ++/* ++ * frees all branches ++ */ ++void au_br_free(struct au_sbinfo *sbinfo) ++{ ++ aufs_bindex_t bmax; ++ struct au_branch **br; ++ ++ bmax = sbinfo->si_bend + 1; ++ br = sbinfo->si_branch; ++ while (bmax--) ++ au_br_do_free(*br++); ++} ++ ++/* ++ * find the index of a branch which is specified by @br_id. ++ */ ++int au_br_index(struct super_block *sb, aufs_bindex_t br_id) ++{ ++ aufs_bindex_t bindex, bend; ++ ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) ++ if (au_sbr_id(sb, bindex) == br_id) ++ return bindex; ++ return -1; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * add a branch ++ */ ++ ++static int test_overlap(struct super_block *sb, struct dentry *h_d1, ++ struct dentry *h_d2) ++{ ++ if (unlikely(h_d1 == h_d2)) ++ return 1; ++ return !!au_test_subdir(h_d1, h_d2) ++ || !!au_test_subdir(h_d2, h_d1) ++ || au_test_loopback_overlap(sb, h_d1, h_d2) ++ || au_test_loopback_overlap(sb, h_d2, h_d1); ++} ++ ++/* ++ * returns a newly allocated branch. @new_nbranch is a number of branches ++ * after adding a branch. ++ */ ++static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch, ++ int perm) ++{ ++ struct au_branch *add_branch; ++ struct dentry *root; ++ ++ root = sb->s_root; ++ add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS); ++ if (unlikely(!add_branch)) ++ goto out; ++ ++ add_branch->br_wbr = NULL; ++ if (au_br_writable(perm)) { ++ /* may be freed separately at changing the branch permission */ ++ add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr), ++ GFP_NOFS); ++ if (unlikely(!add_branch->br_wbr)) ++ goto out_br; ++ } ++ ++ if (unlikely(au_sbr_realloc(au_sbi(sb), new_nbranch) ++ || au_di_realloc(au_di(root), new_nbranch) ++ || au_ii_realloc(au_ii(root->d_inode), new_nbranch))) ++ goto out_wbr; ++ return add_branch; /* success */ ++ ++ out_wbr: ++ kfree(add_branch->br_wbr); ++ out_br: ++ kfree(add_branch); ++ out: ++ return ERR_PTR(-ENOMEM); ++} ++ ++/* ++ * test if the branch permission is legal or not. ++ */ ++static int test_br(struct inode *inode, int brperm, char *path) ++{ ++ int err; ++ ++ err = 0; ++ if (unlikely(au_br_writable(brperm) && IS_RDONLY(inode))) { ++ AuErr("write permission for readonly mount or inode, %s\n", ++ path); ++ err = -EINVAL; ++ } ++ ++ return err; ++} ++ ++/* ++ * returns: ++ * 0: success, the caller will add it ++ * plus: success, it is already unified, the caller should ignore it ++ * minus: error ++ */ ++static int test_add(struct super_block *sb, struct au_opt_add *add, int remount) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct dentry *root; ++ struct inode *inode, *h_inode; ++ ++ root = sb->s_root; ++ bend = au_sbend(sb); ++ if (unlikely(bend >= 0 ++ && au_find_dbindex(root, add->path.dentry) >= 0)) { ++ err = 1; ++ if (!remount) { ++ err = -EINVAL; ++ AuErr("%s duplicated\n", add->pathname); ++ } ++ goto out; ++ } ++ ++ err = -ENOSPC; /* -E2BIG; */ ++ if (unlikely(AUFS_BRANCH_MAX <= add->bindex ++ || AUFS_BRANCH_MAX - 1 <= bend)) { ++ AuErr("number of branches exceeded %s\n", add->pathname); ++ goto out; ++ } ++ ++ err = -EDOM; ++ if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) { ++ AuErr("bad index %d\n", add->bindex); ++ goto out; ++ } ++ ++ inode = add->path.dentry->d_inode; ++ err = -ENOENT; ++ if (unlikely(!inode->i_nlink)) { ++ AuErr("no existence %s\n", add->pathname); ++ goto out; ++ } ++ ++ err = -EINVAL; ++ if (unlikely(inode->i_sb == sb)) { ++ AuErr("%s must be outside\n", add->pathname); ++ goto out; ++ } ++ ++ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) { ++ AuErr("unsupported filesystem, %s (%s)\n", ++ add->pathname, au_sbtype(inode->i_sb)); ++ goto out; ++ } ++ ++ err = test_br(add->path.dentry->d_inode, add->perm, add->pathname); ++ if (unlikely(err)) ++ goto out; ++ ++ if (bend < 0) ++ return 0; /* success */ ++ ++ err = -EINVAL; ++ for (bindex = 0; bindex <= bend; bindex++) ++ if (unlikely(test_overlap(sb, add->path.dentry, ++ au_h_dptr(root, bindex)))) { ++ AuErr("%s is overlapped\n", add->pathname); ++ goto out; ++ } ++ ++ err = 0; ++ if (au_opt_test(au_mntflags(sb), WARN_PERM)) { ++ h_inode = au_h_dptr(root, 0)->d_inode; ++ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO) ++ || h_inode->i_uid != inode->i_uid ++ || h_inode->i_gid != inode->i_gid) ++ AuWarn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n", ++ add->pathname, ++ inode->i_uid, inode->i_gid, ++ (inode->i_mode & S_IALLUGO), ++ h_inode->i_uid, h_inode->i_gid, ++ (h_inode->i_mode & S_IALLUGO)); ++ } ++ ++ out: ++ return err; ++} ++ ++/* ++ * initialize or clean the whiteouts for an adding branch ++ */ ++static int au_br_init_wh(struct super_block *sb, struct au_branch *br, ++ int new_perm, struct dentry *h_root) ++{ ++ int err, old_perm; ++ aufs_bindex_t bindex; ++ struct mutex *h_mtx; ++ struct au_wbr *wbr; ++ struct au_hinode *hdir; ++ ++ wbr = br->br_wbr; ++ old_perm = br->br_perm; ++ br->br_perm = new_perm; ++ hdir = NULL; ++ h_mtx = NULL; ++ bindex = au_br_index(sb, br->br_id); ++ if (0 <= bindex) { ++ hdir = au_hi(sb->s_root->d_inode, bindex); ++ au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT); ++ } else { ++ h_mtx = &h_root->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_PARENT); ++ } ++ if (!wbr) ++ err = au_wh_init(h_root, br, sb); ++ else { ++ wbr_wh_write_lock(wbr); ++ err = au_wh_init(h_root, br, sb); ++ wbr_wh_write_unlock(wbr); ++ } ++ if (hdir) ++ au_hin_imtx_unlock(hdir); ++ else ++ mutex_unlock(h_mtx); ++ br->br_perm = old_perm; ++ ++ if (!err && wbr && !au_br_writable(new_perm)) { ++ kfree(wbr); ++ br->br_wbr = NULL; ++ } ++ ++ return err; ++} ++ ++static int au_wbr_init(struct au_branch *br, struct super_block *sb, ++ int perm, struct path *path) ++{ ++ int err; ++ struct au_wbr *wbr; ++ ++ wbr = br->br_wbr; ++ init_rwsem(&wbr->wbr_wh_rwsem); ++ memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh)); ++ atomic_set(&wbr->wbr_wh_running, 0); ++ wbr->wbr_bytes = 0; ++ ++ err = au_br_init_wh(sb, br, perm, path->dentry); ++ ++ return err; ++} ++ ++/* intialize a new branch */ ++static int au_br_init(struct au_branch *br, struct super_block *sb, ++ struct au_opt_add *add) ++{ ++ int err; ++ ++ err = 0; ++ memset(&br->br_xino, 0, sizeof(br->br_xino)); ++ mutex_init(&br->br_xino.xi_nondir_mtx); ++ br->br_perm = add->perm; ++ br->br_mnt = add->path.mnt; /* set first, mntget() later */ ++ atomic_set(&br->br_count, 0); ++ br->br_xino_upper = AUFS_XINO_TRUNC_INIT; ++ atomic_set(&br->br_xino_running, 0); ++ br->br_id = au_new_br_id(sb); ++ ++ if (au_br_writable(add->perm)) { ++ err = au_wbr_init(br, sb, add->perm, &add->path); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ if (au_opt_test(au_mntflags(sb), XINO)) { ++ err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino, ++ au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1); ++ if (unlikely(err)) { ++ AuDebugOn(br->br_xino.xi_file); ++ goto out; ++ } ++ } ++ ++ sysaufs_br_init(br); ++ mntget(add->path.mnt); ++ ++ out: ++ return err; ++} ++ ++static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex, ++ struct au_branch *br, aufs_bindex_t bend, ++ aufs_bindex_t amount) ++{ ++ struct au_branch **brp; ++ ++ brp = sbinfo->si_branch + bindex; ++ memmove(brp + 1, brp, sizeof(*brp) * amount); ++ *brp = br; ++ sbinfo->si_bend++; ++ if (unlikely(bend < 0)) ++ sbinfo->si_bend = 0; ++} ++ ++static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex, ++ aufs_bindex_t bend, aufs_bindex_t amount) ++{ ++ struct au_hdentry *hdp; ++ ++ hdp = dinfo->di_hdentry + bindex; ++ memmove(hdp + 1, hdp, sizeof(*hdp) * amount); ++ au_h_dentry_init(hdp); ++ dinfo->di_bend++; ++ if (unlikely(bend < 0)) ++ dinfo->di_bstart = 0; ++} ++ ++static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex, ++ aufs_bindex_t bend, aufs_bindex_t amount) ++{ ++ struct au_hinode *hip; ++ ++ hip = iinfo->ii_hinode + bindex; ++ memmove(hip + 1, hip, sizeof(*hip) * amount); ++ hip->hi_inode = NULL; ++ au_hin_init(hip, NULL); ++ iinfo->ii_bend++; ++ if (unlikely(bend < 0)) ++ iinfo->ii_bstart = 0; ++} ++ ++static void au_br_do_add(struct super_block *sb, struct dentry *h_dentry, ++ struct au_branch *br, aufs_bindex_t bindex) ++{ ++ struct dentry *root; ++ struct inode *root_inode; ++ aufs_bindex_t bend, amount; ++ ++ root = sb->s_root; ++ root_inode = root->d_inode; ++ au_plink_block_maintain(sb); ++ bend = au_sbend(sb); ++ amount = bend + 1 - bindex; ++ au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount); ++ au_br_do_add_hdp(au_di(root), bindex, bend, amount); ++ au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount); ++ au_set_h_dptr(root, bindex, dget(h_dentry)); ++ au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode), ++ /*flags*/0); ++} ++ ++int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount) ++{ ++ int err; ++ unsigned long long maxb; ++ aufs_bindex_t bend, add_bindex; ++ struct dentry *root, *h_dentry; ++ struct inode *root_inode; ++ struct au_branch *add_branch; ++ ++ root = sb->s_root; ++ root_inode = root->d_inode; ++ IMustLock(root_inode); ++ err = test_add(sb, add, remount); ++ if (unlikely(err < 0)) ++ goto out; ++ if (err) { ++ err = 0; ++ goto out; /* success */ ++ } ++ ++ bend = au_sbend(sb); ++ add_branch = au_br_alloc(sb, bend + 2, add->perm); ++ err = PTR_ERR(add_branch); ++ if (IS_ERR(add_branch)) ++ goto out; ++ ++ err = au_br_init(add_branch, sb, add); ++ if (unlikely(err)) { ++ au_br_do_free(add_branch); ++ goto out; ++ } ++ ++ add_bindex = add->bindex; ++ h_dentry = add->path.dentry; ++ if (!remount) ++ au_br_do_add(sb, h_dentry, add_branch, add_bindex); ++ else { ++ sysaufs_brs_del(sb, add_bindex); ++ au_br_do_add(sb, h_dentry, add_branch, add_bindex); ++ sysaufs_brs_add(sb, add_bindex); ++ } ++ ++ if (!add_bindex) ++ au_cpup_attr_all(root_inode, /*force*/1); ++ else ++ au_add_nlink(root_inode, h_dentry->d_inode); ++ maxb = h_dentry->d_sb->s_maxbytes; ++ if (sb->s_maxbytes < maxb) ++ sb->s_maxbytes = maxb; ++ ++ /* ++ * this test/set prevents aufs from handling unnecesary inotify events ++ * of xino files, in a case of re-adding a writable branch which was ++ * once detached from aufs. ++ */ ++ if (au_xino_brid(sb) < 0 ++ && au_br_writable(add_branch->br_perm) ++ && !au_test_fs_bad_xino(h_dentry->d_sb) ++ && add_branch->br_xino.xi_file ++ && add_branch->br_xino.xi_file->f_dentry->d_parent == h_dentry) ++ au_xino_brid_set(sb, add_branch->br_id); ++ ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * delete a branch ++ */ ++ ++/* to show the line number, do not make it inlined function */ ++#define AuVerbose(do_info, fmt, args...) do { \ ++ if (do_info) \ ++ AuInfo(fmt, ##args); \ ++} while (0) ++ ++/* ++ * test if the branch is deletable or not. ++ */ ++static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex, ++ unsigned int sigen) ++{ ++ int err, i, j, ndentry; ++ aufs_bindex_t bstart, bend; ++ unsigned char verbose; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry *d; ++ struct inode *inode; ++ ++ err = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_dcsub_pages(&dpages, root, NULL, NULL); ++ if (unlikely(err)) ++ goto out_dpages; ++ ++ verbose = !!au_opt_test(au_mntflags(root->d_sb), VERBOSE); ++ for (i = 0; !err && i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ ndentry = dpage->ndentry; ++ for (j = 0; !err && j < ndentry; j++) { ++ d = dpage->dentries[j]; ++ AuDebugOn(!atomic_read(&d->d_count)); ++ inode = d->d_inode; ++ if (au_digen(d) == sigen && au_iigen(inode) == sigen) ++ di_read_lock_child(d, AuLock_IR); ++ else { ++ di_write_lock_child(d); ++ err = au_reval_dpath(d, sigen); ++ if (!err) ++ di_downgrade_lock(d, AuLock_IR); ++ else { ++ di_write_unlock(d); ++ break; ++ } ++ } ++ ++ bstart = au_dbstart(d); ++ bend = au_dbend(d); ++ if (bstart <= bindex ++ && bindex <= bend ++ && au_h_dptr(d, bindex) ++ && (!S_ISDIR(inode->i_mode) || bstart == bend)) { ++ err = -EBUSY; ++ AuVerbose(verbose, "busy %.*s\n", AuDLNPair(d)); ++ } ++ di_read_unlock(d, AuLock_IR); ++ } ++ } ++ ++ out_dpages: ++ au_dpages_free(&dpages); ++ out: ++ return err; ++} ++ ++static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex, ++ unsigned int sigen) ++{ ++ int err; ++ struct inode *i; ++ aufs_bindex_t bstart, bend; ++ unsigned char verbose; ++ ++ err = 0; ++ verbose = !!au_opt_test(au_mntflags(sb), VERBOSE); ++ list_for_each_entry(i, &sb->s_inodes, i_sb_list) { ++ AuDebugOn(!atomic_read(&i->i_count)); ++ if (!list_empty(&i->i_dentry)) ++ continue; ++ ++ if (au_iigen(i) == sigen) ++ ii_read_lock_child(i); ++ else { ++ ii_write_lock_child(i); ++ err = au_refresh_hinode_self(i, /*do_attr*/1); ++ if (!err) ++ ii_downgrade_lock(i); ++ else { ++ ii_write_unlock(i); ++ break; ++ } ++ } ++ ++ bstart = au_ibstart(i); ++ bend = au_ibend(i); ++ if (bstart <= bindex ++ && bindex <= bend ++ && au_h_iptr(i, bindex) ++ && (!S_ISDIR(i->i_mode) || bstart == bend)) { ++ err = -EBUSY; ++ AuVerbose(verbose, "busy i%lu\n", i->i_ino); ++ ii_read_unlock(i); ++ break; ++ } ++ ii_read_unlock(i); ++ } ++ ++ return err; ++} ++ ++static int test_children_busy(struct dentry *root, aufs_bindex_t bindex) ++{ ++ int err; ++ unsigned int sigen; ++ ++ sigen = au_sigen(root->d_sb); ++ DiMustNoWaiters(root); ++ IiMustNoWaiters(root->d_inode); ++ di_write_unlock(root); ++ err = test_dentry_busy(root, bindex, sigen); ++ if (!err) ++ err = test_inode_busy(root->d_sb, bindex, sigen); ++ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */ ++ ++ return err; ++} ++ ++static void au_br_do_del_brp(struct au_sbinfo *sbinfo, ++ const aufs_bindex_t bindex, ++ const aufs_bindex_t bend) ++{ ++ struct au_branch **brp, **p; ++ ++ brp = sbinfo->si_branch + bindex; ++ if (bindex < bend) ++ memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex)); ++ sbinfo->si_branch[0 + bend] = NULL; ++ sbinfo->si_bend--; ++ ++ p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, GFP_NOFS); ++ if (p) ++ sbinfo->si_branch = p; ++} ++ ++static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex, ++ const aufs_bindex_t bend) ++{ ++ struct au_hdentry *hdp, *p; ++ ++ hdp = dinfo->di_hdentry + bindex; ++ if (bindex < bend) ++ memmove(hdp, hdp + 1, sizeof(*hdp) * (bend - bindex)); ++ dinfo->di_hdentry[0 + bend].hd_dentry = NULL; ++ dinfo->di_bend--; ++ ++ p = krealloc(dinfo->di_hdentry, sizeof(*p) * bend, GFP_NOFS); ++ if (p) ++ dinfo->di_hdentry = p; ++} ++ ++static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex, ++ const aufs_bindex_t bend) ++{ ++ struct au_hinode *hip, *p; ++ ++ hip = iinfo->ii_hinode + bindex; ++ if (bindex < bend) ++ memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex)); ++ iinfo->ii_hinode[0 + bend].hi_inode = NULL; ++ au_hin_init(iinfo->ii_hinode + bend, NULL); ++ iinfo->ii_bend--; ++ ++ p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, GFP_NOFS); ++ if (p) ++ iinfo->ii_hinode = p; ++} ++ ++static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex, ++ struct au_branch *br) ++{ ++ aufs_bindex_t bend; ++ struct au_sbinfo *sbinfo; ++ struct dentry *root; ++ struct inode *inode; ++ ++ root = sb->s_root; ++ inode = root->d_inode; ++ au_plink_block_maintain(sb); ++ sbinfo = au_sbi(sb); ++ bend = sbinfo->si_bend; ++ ++ dput(au_h_dptr(root, bindex)); ++ au_hiput(au_hi(inode, bindex)); ++ au_br_do_free(br); ++ ++ au_br_do_del_brp(sbinfo, bindex, bend); ++ au_br_do_del_hdp(au_di(root), bindex, bend); ++ au_br_do_del_hip(au_ii(inode), bindex, bend); ++} ++ ++int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount) ++{ ++ int err, rerr, i; ++ unsigned int mnt_flags; ++ aufs_bindex_t bindex, bend, br_id; ++ unsigned char do_wh, verbose; ++ struct au_branch *br; ++ struct au_wbr *wbr; ++ ++ err = 0; ++ bindex = au_find_dbindex(sb->s_root, del->h_path.dentry); ++ if (bindex < 0) { ++ if (remount) ++ goto out; /* success */ ++ err = -ENOENT; ++ AuErr("%s no such branch\n", del->pathname); ++ goto out; ++ } ++ AuDbg("bindex b%d\n", bindex); ++ ++ err = -EBUSY; ++ mnt_flags = au_mntflags(sb); ++ verbose = !!au_opt_test(mnt_flags, VERBOSE); ++ bend = au_sbend(sb); ++ if (unlikely(!bend)) { ++ AuVerbose(verbose, "no more branches left\n"); ++ goto out; ++ } ++ br = au_sbr(sb, bindex); ++ i = atomic_read(&br->br_count); ++ if (unlikely(i)) { ++ AuVerbose(verbose, "%d file(s) opened\n", i); ++ goto out; ++ } ++ ++ wbr = br->br_wbr; ++ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph); ++ if (do_wh) { ++ for (i = 0; i < AuBrWh_Last; i++) { ++ dput(wbr->wbr_wh[i]); ++ wbr->wbr_wh[i] = NULL; ++ } ++ } ++ ++ err = test_children_busy(sb->s_root, bindex); ++ if (unlikely(err)) { ++ if (do_wh) ++ goto out_wh; ++ goto out; ++ } ++ ++ err = 0; ++ br_id = br->br_id; ++ if (!remount) ++ au_br_do_del(sb, bindex, br); ++ else { ++ sysaufs_brs_del(sb, bindex); ++ au_br_do_del(sb, bindex, br); ++ sysaufs_brs_add(sb, bindex); ++ } ++ ++ if (!bindex) ++ au_cpup_attr_all(sb->s_root->d_inode, /*force*/1); ++ else ++ au_sub_nlink(sb->s_root->d_inode, del->h_path.dentry->d_inode); ++ if (au_opt_test(mnt_flags, PLINK)) ++ au_plink_half_refresh(sb, br_id); ++ ++ if (sb->s_maxbytes == del->h_path.dentry->d_sb->s_maxbytes) { ++ bend--; ++ sb->s_maxbytes = 0; ++ for (bindex = 0; bindex <= bend; bindex++) { ++ unsigned long long maxb; ++ ++ maxb = au_sbr_sb(sb, bindex)->s_maxbytes; ++ if (sb->s_maxbytes < maxb) ++ sb->s_maxbytes = maxb; ++ } ++ } ++ ++ if (au_xino_brid(sb) == br->br_id) ++ au_xino_brid_set(sb, -1); ++ goto out; /* success */ ++ ++ out_wh: ++ /* revert */ ++ rerr = au_br_init_wh(sb, br, br->br_perm, del->h_path.dentry); ++ if (rerr) ++ AuWarn("failed re-creating base whiteout, %s. (%d)\n", ++ del->pathname, rerr); ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * change a branch permission ++ */ ++ ++static int do_need_sigen_inc(int a, int b) ++{ ++ return au_br_whable(a) && !au_br_whable(b); ++} ++ ++static int need_sigen_inc(int old, int new) ++{ ++ return do_need_sigen_inc(old, new) ++ || do_need_sigen_inc(new, old); ++} ++ ++static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ int err; ++ unsigned long n, ul, bytes, files; ++ aufs_bindex_t bstart; ++ struct file *file, *hf, **a; ++ const int step_bytes = 1024, /* memory allocation unit */ ++ step_files = step_bytes / sizeof(*a); ++ ++ err = -ENOMEM; ++ n = 0; ++ bytes = step_bytes; ++ files = step_files; ++ a = kmalloc(bytes, GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ /* no need file_list_lock() since sbinfo is locked? defered? */ ++ list_for_each_entry(file, &sb->s_files, f_u.fu_list) { ++ if (special_file(file->f_dentry->d_inode->i_mode)) ++ continue; ++ ++ AuDbg("%.*s\n", AuDLNPair(file->f_dentry)); ++ fi_read_lock(file); ++ if (unlikely(au_test_mmapped(file))) { ++ err = -EBUSY; ++ FiMustNoWaiters(file); ++ fi_read_unlock(file); ++ goto out_free; ++ } ++ ++ bstart = au_fbstart(file); ++ if (!S_ISREG(file->f_dentry->d_inode->i_mode) ++ || !(file->f_mode & FMODE_WRITE) ++ || bstart != bindex) { ++ FiMustNoWaiters(file); ++ fi_read_unlock(file); ++ continue; ++ } ++ ++ hf = au_h_fptr(file, bstart); ++ FiMustNoWaiters(file); ++ fi_read_unlock(file); ++ ++ if (n < files) ++ a[n++] = hf; ++ else { ++ void *p; ++ ++ err = -ENOMEM; ++ bytes += step_bytes; ++ files += step_files; ++ p = krealloc(a, bytes, GFP_NOFS); ++ if (p) { ++ a = p; ++ a[n++] = hf; ++ } else ++ goto out_free; ++ } ++ } ++ ++ err = 0; ++ for (ul = 0; ul < n; ul++) { ++ /* todo: already flushed? */ ++ /* cf. fs/super.c:mark_files_ro() */ ++ hf = a[ul]; ++ hf->f_mode &= ~FMODE_WRITE; ++ if (!file_check_writeable(hf)) { ++ file_release_write(hf); ++ mnt_drop_write(hf->f_vfsmnt); ++ } ++ } ++ ++ out_free: ++ kfree(a); ++ out: ++ return err; ++} ++ ++int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount, ++ int *do_update) ++{ ++ int err, rerr; ++ aufs_bindex_t bindex; ++ struct dentry *root; ++ struct au_branch *br; ++ ++ root = sb->s_root; ++ au_plink_block_maintain(sb); ++ bindex = au_find_dbindex(root, mod->h_root); ++ if (bindex < 0) { ++ if (remount) ++ return 0; /* success */ ++ err = -ENOENT; ++ AuErr("%s no such branch\n", mod->path); ++ goto out; ++ } ++ AuDbg("bindex b%d\n", bindex); ++ ++ err = test_br(mod->h_root->d_inode, mod->perm, mod->path); ++ if (unlikely(err)) ++ goto out; ++ ++ br = au_sbr(sb, bindex); ++ if (br->br_perm == mod->perm) ++ return 0; /* success */ ++ ++ if (au_br_writable(br->br_perm)) { ++ /* remove whiteout base */ ++ err = au_br_init_wh(sb, br, mod->perm, mod->h_root); ++ if (unlikely(err)) ++ goto out; ++ ++ if (!au_br_writable(mod->perm)) { ++ /* rw --> ro, file might be mmapped */ ++ DiMustNoWaiters(root); ++ IiMustNoWaiters(root->d_inode); ++ di_write_unlock(root); ++ err = au_br_mod_files_ro(sb, bindex); ++ /* aufs_write_lock() calls ..._child() */ ++ di_write_lock_child(root); ++ ++ if (unlikely(err)) { ++ rerr = -ENOMEM; ++ br->br_wbr = kmalloc(sizeof(*br->br_wbr), ++ GFP_NOFS); ++ if (br->br_wbr) ++ rerr = au_br_init_wh ++ (sb, br, br->br_perm, ++ mod->h_root); ++ if (unlikely(rerr)) { ++ AuIOErr("nested error %d (%d)\n", ++ rerr, err); ++ br->br_perm = mod->perm; ++ } ++ } ++ } ++ } else if (au_br_writable(mod->perm)) { ++ /* ro --> rw */ ++ err = -ENOMEM; ++ br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS); ++ if (br->br_wbr) { ++ struct path path = { ++ .mnt = br->br_mnt, ++ .dentry = mod->h_root ++ }; ++ ++ err = au_wbr_init(br, sb, mod->perm, &path); ++ if (unlikely(err)) { ++ kfree(br->br_wbr); ++ br->br_wbr = NULL; ++ } ++ } ++ } ++ ++ if (!err) { ++ *do_update |= need_sigen_inc(br->br_perm, mod->perm); ++ br->br_perm = mod->perm; ++ } ++ ++ out: ++ return err; ++} +diff -Naur a/fs/aufs/branch.h b/fs/aufs/branch.h +--- a/fs/aufs/branch.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/branch.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,215 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * branch filesystems and xino for them ++ */ ++ ++#ifndef __AUFS_BRANCH_H__ ++#define __AUFS_BRANCH_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++#include "rwsem.h" ++#include "super.h" ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* a xino file */ ++struct au_xino_file { ++ struct file *xi_file; ++ struct mutex xi_nondir_mtx; ++ ++ /* todo: make xino files an array to support huge inode number */ ++ ++#ifdef CONFIG_DEBUG_FS ++ struct dentry *xi_dbgaufs; ++#endif ++}; ++ ++/* members for writable branch only */ ++enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last}; ++struct au_wbr { ++ struct rw_semaphore wbr_wh_rwsem; ++ struct dentry *wbr_wh[AuBrWh_Last]; ++ atomic_t wbr_wh_running; ++#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */ ++#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */ ++#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */ ++ ++ /* mfs mode */ ++ unsigned long long wbr_bytes; ++}; ++ ++/* protected by superblock rwsem */ ++struct au_branch { ++ struct au_xino_file br_xino; ++ ++ aufs_bindex_t br_id; ++ ++ int br_perm; ++ struct vfsmount *br_mnt; ++ atomic_t br_count; ++ ++ struct au_wbr *br_wbr; ++ ++ /* xino truncation */ ++ blkcnt_t br_xino_upper; /* watermark in blocks */ ++ atomic_t br_xino_running; ++ ++#ifdef CONFIG_SYSFS ++ /* an entry under sysfs per mount-point */ ++ char br_name[8]; ++ struct attribute br_attr; ++#endif ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* branch permission and attribute */ ++enum { ++ AuBrPerm_RW, /* writable, linkable wh */ ++ AuBrPerm_RO, /* readonly, no wh */ ++ AuBrPerm_RR, /* natively readonly, no wh */ ++ ++ AuBrPerm_RWNoLinkWH, /* un-linkable whiteouts */ ++ ++ AuBrPerm_ROWH, /* whiteout-able */ ++ AuBrPerm_RRWH, /* whiteout-able */ ++ ++ AuBrPerm_Last ++}; ++ ++static inline int au_br_writable(int brperm) ++{ ++ return brperm == AuBrPerm_RW || brperm == AuBrPerm_RWNoLinkWH; ++} ++ ++static inline int au_br_whable(int brperm) ++{ ++ return brperm == AuBrPerm_RW ++ || brperm == AuBrPerm_ROWH ++ || brperm == AuBrPerm_RRWH; ++} ++ ++static inline int au_br_rdonly(struct au_branch *br) ++{ ++ return ((br->br_mnt->mnt_sb->s_flags & MS_RDONLY) ++ || !au_br_writable(br->br_perm)) ++ ? -EROFS : 0; ++} ++ ++static inline int au_br_hinotifyable(int brperm __maybe_unused) ++{ ++#ifdef CONFIG_AUFS_HINOTIFY ++ return brperm != AuBrPerm_RR && brperm != AuBrPerm_RRWH; ++#else ++ return 0; ++#endif ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* branch.c */ ++struct au_sbinfo; ++void au_br_free(struct au_sbinfo *sinfo); ++int au_br_index(struct super_block *sb, aufs_bindex_t br_id); ++struct au_opt_add; ++int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount); ++struct au_opt_del; ++int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount); ++struct au_opt_mod; ++int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount, ++ int *do_update); ++ ++/* xino.c */ ++static const loff_t au_loff_max = LLONG_MAX; ++ ++int au_xib_trunc(struct super_block *sb); ++ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size, ++ loff_t *pos); ++ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size, ++ loff_t *pos); ++struct file *au_xino_create2(struct file *base_file, struct file *copy_src); ++struct file *au_xino_create(struct super_block *sb, char *fname, int silent); ++ino_t au_xino_new_ino(struct super_block *sb); ++int au_xino_write0(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t ino); ++int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t ino); ++int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t *ino); ++int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino, ++ struct file *base_file, int do_test); ++int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex); ++ ++struct au_opt_xino; ++int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount); ++void au_xino_clr(struct super_block *sb); ++struct file *au_xino_def(struct super_block *sb); ++int au_xino_path(struct seq_file *seq, struct file *file); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* Superblock to branch */ ++static inline ++aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_sbr(sb, bindex)->br_id; ++} ++ ++static inline ++struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_sbr(sb, bindex)->br_mnt; ++} ++ ++static inline ++struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_sbr_mnt(sb, bindex)->mnt_sb; ++} ++ ++static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ atomic_dec(&au_sbr(sb, bindex)->br_count); ++} ++ ++static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_sbr(sb, bindex)->br_perm; ++} ++ ++static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_br_whable(au_sbr_perm(sb, bindex)); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * wbr_wh_read_lock, wbr_wh_write_lock ++ * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock ++ */ ++AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem); ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_BRANCH_H__ */ +diff -Naur a/fs/aufs/cpup.c b/fs/aufs/cpup.c +--- a/fs/aufs/cpup.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/cpup.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,1039 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * copy-up functions, see wbr_policy.c for copy-down ++ */ ++ ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++void au_cpup_attr_flags(struct inode *dst, struct inode *src) ++{ ++ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE ++ | S_NOATIME | S_NOCMTIME; ++ ++ dst->i_flags |= src->i_flags & ~mask; ++ if (au_test_fs_notime(dst->i_sb)) ++ dst->i_flags |= S_NOATIME | S_NOCMTIME; ++} ++ ++void au_cpup_attr_timesizes(struct inode *inode) ++{ ++ struct inode *h_inode; ++ ++ h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ fsstack_copy_attr_times(inode, h_inode); ++ vfsub_copy_inode_size(inode, h_inode); ++} ++ ++void au_cpup_attr_nlink(struct inode *inode, int force) ++{ ++ struct inode *h_inode; ++ struct super_block *sb; ++ aufs_bindex_t bindex, bend; ++ ++ sb = inode->i_sb; ++ bindex = au_ibstart(inode); ++ h_inode = au_h_iptr(inode, bindex); ++ if (!force ++ && !S_ISDIR(h_inode->i_mode) ++ && au_opt_test(au_mntflags(sb), PLINK) ++ && au_plink_test(inode)) ++ return; ++ ++ inode->i_nlink = h_inode->i_nlink; ++ ++ /* ++ * fewer nlink makes find(1) noisy, but larger nlink doesn't. ++ * it may includes whplink directory. ++ */ ++ if (S_ISDIR(h_inode->i_mode)) { ++ bend = au_ibend(inode); ++ for (bindex++; bindex <= bend; bindex++) { ++ h_inode = au_h_iptr(inode, bindex); ++ if (h_inode) ++ au_add_nlink(inode, h_inode); ++ } ++ } ++} ++ ++void au_cpup_attr_changeable(struct inode *inode) ++{ ++ struct inode *h_inode; ++ ++ h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ inode->i_mode = h_inode->i_mode; ++ inode->i_uid = h_inode->i_uid; ++ inode->i_gid = h_inode->i_gid; ++ au_cpup_attr_timesizes(inode); ++ au_cpup_attr_flags(inode, h_inode); ++} ++ ++void au_cpup_igen(struct inode *inode, struct inode *h_inode) ++{ ++ struct au_iinfo *iinfo = au_ii(inode); ++ ++ iinfo->ii_higen = h_inode->i_generation; ++ iinfo->ii_hsb1 = h_inode->i_sb; ++} ++ ++void au_cpup_attr_all(struct inode *inode, int force) ++{ ++ struct inode *h_inode; ++ ++ h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ au_cpup_attr_changeable(inode); ++ if (inode->i_nlink > 0) ++ au_cpup_attr_nlink(inode, force); ++ inode->i_rdev = h_inode->i_rdev; ++ inode->i_blkbits = h_inode->i_blkbits; ++ au_cpup_igen(inode, h_inode); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */ ++ ++/* keep the timestamps of the parent dir when cpup */ ++void au_dtime_store(struct au_dtime *dt, struct dentry *dentry, ++ struct path *h_path) ++{ ++ struct inode *h_inode; ++ ++ dt->dt_dentry = dentry; ++ dt->dt_h_path = *h_path; ++ h_inode = h_path->dentry->d_inode; ++ dt->dt_atime = h_inode->i_atime; ++ dt->dt_mtime = h_inode->i_mtime; ++ /* smp_mb(); */ ++} ++ ++void au_dtime_revert(struct au_dtime *dt) ++{ ++ struct iattr attr; ++ int err; ++ ++ attr.ia_atime = dt->dt_atime; ++ attr.ia_mtime = dt->dt_mtime; ++ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET ++ | ATTR_ATIME | ATTR_ATIME_SET; ++ ++ err = vfsub_notify_change(&dt->dt_h_path, &attr); ++ if (unlikely(err)) ++ AuWarn("restoring timestamps failed(%d). ignored\n", err); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static noinline_for_stack ++int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src) ++{ ++ int err, sbits; ++ struct iattr ia; ++ struct path h_path; ++ struct inode *h_isrc; ++ ++ h_path.dentry = au_h_dptr(dst, bindex); ++ h_path.mnt = au_sbr_mnt(dst->d_sb, bindex); ++ h_isrc = h_src->d_inode; ++ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID ++ | ATTR_ATIME | ATTR_MTIME ++ | ATTR_ATIME_SET | ATTR_MTIME_SET; ++ ia.ia_mode = h_isrc->i_mode; ++ ia.ia_uid = h_isrc->i_uid; ++ ia.ia_gid = h_isrc->i_gid; ++ ia.ia_atime = h_isrc->i_atime; ++ ia.ia_mtime = h_isrc->i_mtime; ++ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID)); ++ au_cpup_attr_flags(h_path.dentry->d_inode, h_isrc); ++ err = vfsub_notify_change(&h_path, &ia); ++ ++ /* is this nfs only? */ ++ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) { ++ ia.ia_valid = ATTR_FORCE | ATTR_MODE; ++ ia.ia_mode = h_isrc->i_mode; ++ err = vfsub_notify_change(&h_path, &ia); ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_do_copy_file(struct file *dst, struct file *src, loff_t len, ++ char *buf, unsigned long blksize) ++{ ++ int err; ++ size_t sz, rbytes, wbytes; ++ unsigned char all_zero; ++ char *p, *zp; ++ struct mutex *h_mtx; ++ /* reduce stack usage */ ++ struct iattr *ia; ++ ++ zp = page_address(ZERO_PAGE(0)); ++ if (unlikely(!zp)) ++ return -ENOMEM; /* possible? */ ++ ++ err = 0; ++ all_zero = 0; ++ while (len) { ++ AuDbg("len %lld\n", len); ++ sz = blksize; ++ if (len < blksize) ++ sz = len; ++ ++ rbytes = 0; ++ /* todo: signal_pending? */ ++ while (!rbytes || err == -EAGAIN || err == -EINTR) { ++ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos); ++ err = rbytes; ++ } ++ if (unlikely(err < 0)) ++ break; ++ ++ all_zero = 0; ++ if (len >= rbytes && rbytes == blksize) ++ all_zero = !memcmp(buf, zp, rbytes); ++ if (!all_zero) { ++ wbytes = rbytes; ++ p = buf; ++ while (wbytes) { ++ size_t b; ++ ++ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos); ++ err = b; ++ /* todo: signal_pending? */ ++ if (unlikely(err == -EAGAIN || err == -EINTR)) ++ continue; ++ if (unlikely(err < 0)) ++ break; ++ wbytes -= b; ++ p += b; ++ } ++ } else { ++ loff_t res; ++ ++ AuLabel(hole); ++ res = vfsub_llseek(dst, rbytes, SEEK_CUR); ++ err = res; ++ if (unlikely(res < 0)) ++ break; ++ } ++ len -= rbytes; ++ err = 0; ++ } ++ ++ /* the last block may be a hole */ ++ if (!err && all_zero) { ++ AuLabel(last hole); ++ ++ err = 1; ++ if (au_test_nfs(dst->f_dentry->d_sb)) { ++ /* nfs requires this step to make last hole */ ++ /* is this only nfs? */ ++ do { ++ /* todo: signal_pending? */ ++ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos); ++ } while (err == -EAGAIN || err == -EINTR); ++ if (err == 1) ++ dst->f_pos--; ++ } ++ ++ if (err == 1) { ++ ia = (void *)buf; ++ ia->ia_size = dst->f_pos; ++ ia->ia_valid = ATTR_SIZE | ATTR_FILE; ++ ia->ia_file = dst; ++ h_mtx = &dst->f_dentry->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2); ++ err = vfsub_notify_change(&dst->f_path, ia); ++ mutex_unlock(h_mtx); ++ } ++ } ++ ++ return err; ++} ++ ++int au_copy_file(struct file *dst, struct file *src, loff_t len) ++{ ++ int err; ++ unsigned long blksize; ++ unsigned char do_kfree; ++ char *buf; ++ ++ err = -ENOMEM; ++ blksize = dst->f_dentry->d_sb->s_blocksize; ++ if (!blksize || PAGE_SIZE < blksize) ++ blksize = PAGE_SIZE; ++ AuDbg("blksize %lu\n", blksize); ++ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *)); ++ if (do_kfree) ++ buf = kmalloc(blksize, GFP_NOFS); ++ else ++ buf = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!buf)) ++ goto out; ++ ++ if (len > (1 << 22)) ++ AuDbg("copying a large file %lld\n", (long long)len); ++ ++ src->f_pos = 0; ++ dst->f_pos = 0; ++ err = au_do_copy_file(dst, src, len, buf, blksize); ++ if (do_kfree) ++ kfree(buf); ++ else ++ free_page((unsigned long)buf); ++ ++ out: ++ return err; ++} ++ ++/* ++ * to support a sparse file which is opened with O_APPEND, ++ * we need to close the file. ++ */ ++static int au_cp_regular(struct dentry *dentry, aufs_bindex_t bdst, ++ aufs_bindex_t bsrc, loff_t len) ++{ ++ int err, i; ++ enum { SRC, DST }; ++ struct { ++ aufs_bindex_t bindex; ++ unsigned int flags; ++ struct dentry *dentry; ++ struct file *file; ++ void *label, *label_file; ++ } *f, file[] = { ++ { ++ .bindex = bsrc, ++ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE, ++ .file = NULL, ++ .label = &&out, ++ .label_file = &&out_src ++ }, ++ { ++ .bindex = bdst, ++ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE, ++ .file = NULL, ++ .label = &&out_src, ++ .label_file = &&out_dst ++ } ++ }; ++ struct super_block *sb; ++ ++ /* bsrc branch can be ro/rw. */ ++ sb = dentry->d_sb; ++ f = file; ++ for (i = 0; i < 2; i++, f++) { ++ f->dentry = au_h_dptr(dentry, f->bindex); ++ f->file = au_h_open(dentry, f->bindex, f->flags, /*file*/NULL); ++ err = PTR_ERR(f->file); ++ if (IS_ERR(f->file)) ++ goto *f->label; ++ err = -EINVAL; ++ if (unlikely(!f->file->f_op)) ++ goto *f->label_file; ++ } ++ ++ /* try stopping to update while we copyup */ ++ IMustLock(file[SRC].dentry->d_inode); ++ err = au_copy_file(file[DST].file, file[SRC].file, len); ++ ++ out_dst: ++ fput(file[DST].file); ++ au_sbr_put(sb, file[DST].bindex); ++ out_src: ++ fput(file[SRC].file); ++ au_sbr_put(sb, file[SRC].bindex); ++ out: ++ return err; ++} ++ ++static int au_do_cpup_regular(struct dentry *dentry, aufs_bindex_t bdst, ++ aufs_bindex_t bsrc, loff_t len, ++ struct inode *h_dir, struct path *h_path) ++{ ++ int err, rerr; ++ loff_t l; ++ ++ err = 0; ++ l = i_size_read(au_h_iptr(dentry->d_inode, bsrc)); ++ if (len == -1 || l < len) ++ len = l; ++ if (len) ++ err = au_cp_regular(dentry, bdst, bsrc, len); ++ if (!err) ++ goto out; /* success */ ++ ++ rerr = vfsub_unlink(h_dir, h_path, /*force*/0); ++ if (rerr) { ++ AuIOErr("failed unlinking cpup-ed %.*s(%d, %d)\n", ++ AuDLNPair(h_path->dentry), err, rerr); ++ err = -EIO; ++ } ++ ++ out: ++ return err; ++} ++ ++static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src, ++ struct inode *h_dir) ++{ ++ int err, symlen; ++ mm_segment_t old_fs; ++ char *sym; ++ ++ err = -ENOSYS; ++ if (unlikely(!h_src->d_inode->i_op->readlink)) ++ goto out; ++ ++ err = -ENOMEM; ++ sym = __getname(); ++ if (unlikely(!sym)) ++ goto out; ++ ++ old_fs = get_fs(); ++ set_fs(KERNEL_DS); ++ symlen = h_src->d_inode->i_op->readlink(h_src, (char __user *)sym, ++ PATH_MAX); ++ err = symlen; ++ set_fs(old_fs); ++ ++ if (symlen > 0) { ++ sym[symlen] = 0; ++ err = vfsub_symlink(h_dir, h_path, sym); ++ } ++ __putname(sym); ++ ++ out: ++ return err; ++} ++ ++/* return with the lower dst inode is locked */ ++static noinline_for_stack ++int cpup_entry(struct dentry *dentry, aufs_bindex_t bdst, ++ aufs_bindex_t bsrc, loff_t len, unsigned int flags, ++ struct dentry *dst_parent) ++{ ++ int err; ++ umode_t mode; ++ unsigned int mnt_flags; ++ unsigned char isdir; ++ const unsigned char do_dt = !!au_ftest_cpup(flags, DTIME); ++ struct au_dtime dt; ++ struct path h_path; ++ struct dentry *h_src, *h_dst, *h_parent; ++ struct inode *h_inode, *h_dir; ++ struct super_block *sb; ++ ++ /* bsrc branch can be ro/rw. */ ++ h_src = au_h_dptr(dentry, bsrc); ++ h_inode = h_src->d_inode; ++ AuDebugOn(h_inode != au_h_iptr(dentry->d_inode, bsrc)); ++ ++ /* try stopping to be referenced while we are creating */ ++ h_dst = au_h_dptr(dentry, bdst); ++ h_parent = h_dst->d_parent; /* dir inode is locked */ ++ h_dir = h_parent->d_inode; ++ IMustLock(h_dir); ++ AuDebugOn(h_parent != h_dst->d_parent); ++ ++ sb = dentry->d_sb; ++ h_path.mnt = au_sbr_mnt(sb, bdst); ++ if (do_dt) { ++ h_path.dentry = h_parent; ++ au_dtime_store(&dt, dst_parent, &h_path); ++ } ++ h_path.dentry = h_dst; ++ ++ isdir = 0; ++ mode = h_inode->i_mode; ++ switch (mode & S_IFMT) { ++ case S_IFREG: ++ /* try stopping to update while we are referencing */ ++ IMustLock(h_inode); ++ err = vfsub_create(h_dir, &h_path, mode | S_IWUSR); ++ if (!err) ++ err = au_do_cpup_regular ++ (dentry, bdst, bsrc, len, ++ au_h_iptr(dst_parent->d_inode, bdst), &h_path); ++ break; ++ case S_IFDIR: ++ isdir = 1; ++ err = vfsub_mkdir(h_dir, &h_path, mode); ++ if (!err) { ++ /* ++ * strange behaviour from the users view, ++ * particularry setattr case ++ */ ++ if (au_ibstart(dst_parent->d_inode) == bdst) ++ au_cpup_attr_nlink(dst_parent->d_inode, ++ /*force*/1); ++ au_cpup_attr_nlink(dentry->d_inode, /*force*/1); ++ } ++ break; ++ case S_IFLNK: ++ err = au_do_cpup_symlink(&h_path, h_src, h_dir); ++ break; ++ case S_IFCHR: ++ case S_IFBLK: ++ AuDebugOn(!capable(CAP_MKNOD)); ++ /*FALLTHROUGH*/ ++ case S_IFIFO: ++ case S_IFSOCK: ++ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev); ++ break; ++ default: ++ AuIOErr("Unknown inode type 0%o\n", mode); ++ err = -EIO; ++ } ++ ++ mnt_flags = au_mntflags(sb); ++ if (!au_opt_test(mnt_flags, UDBA_NONE) ++ && !isdir ++ && au_opt_test(mnt_flags, XINO) ++ && h_inode->i_nlink == 1 ++ /* todo: unnecessary? */ ++ /* && dentry->d_inode->i_nlink == 1 */ ++ && bdst < bsrc ++ && !au_ftest_cpup(flags, KEEPLINO)) ++ au_xino_write0(sb, bsrc, h_inode->i_ino, /*ino*/0); ++ /* ignore this error */ ++ ++ if (do_dt) ++ au_dtime_revert(&dt); ++ return err; ++} ++ ++/* ++ * copyup the @dentry from @bsrc to @bdst. ++ * the caller must set the both of lower dentries. ++ * @len is for truncating when it is -1 copyup the entire file. ++ * in link/rename cases, @dst_parent may be different from the real one. ++ */ ++static int au_cpup_single(struct dentry *dentry, aufs_bindex_t bdst, ++ aufs_bindex_t bsrc, loff_t len, unsigned int flags, ++ struct dentry *dst_parent) ++{ ++ int err, rerr; ++ aufs_bindex_t old_ibstart; ++ unsigned char isdir, plink; ++ struct au_dtime dt; ++ struct path h_path; ++ struct dentry *h_src, *h_dst, *h_parent; ++ struct inode *dst_inode, *h_dir, *inode; ++ struct super_block *sb; ++ ++ AuDebugOn(bsrc <= bdst); ++ ++ sb = dentry->d_sb; ++ h_path.mnt = au_sbr_mnt(sb, bdst); ++ h_dst = au_h_dptr(dentry, bdst); ++ h_parent = h_dst->d_parent; /* dir inode is locked */ ++ h_dir = h_parent->d_inode; ++ IMustLock(h_dir); ++ ++ h_src = au_h_dptr(dentry, bsrc); ++ inode = dentry->d_inode; ++ ++ if (!dst_parent) ++ dst_parent = dget_parent(dentry); ++ else ++ dget(dst_parent); ++ ++ plink = !!au_opt_test(au_mntflags(sb), PLINK); ++ dst_inode = au_h_iptr(inode, bdst); ++ if (dst_inode) { ++ if (unlikely(!plink)) { ++ err = -EIO; ++ AuIOErr("i%lu exists on a upper branch " ++ "but plink is disabled\n", inode->i_ino); ++ goto out; ++ } ++ ++ if (dst_inode->i_nlink) { ++ const int do_dt = au_ftest_cpup(flags, DTIME); ++ ++ h_src = au_plink_lkup(inode, bdst); ++ err = PTR_ERR(h_src); ++ if (IS_ERR(h_src)) ++ goto out; ++ if (unlikely(!h_src->d_inode)) { ++ err = -EIO; ++ AuIOErr("i%lu exists on a upper branch " ++ "but plink is broken\n", inode->i_ino); ++ dput(h_src); ++ goto out; ++ } ++ ++ if (do_dt) { ++ h_path.dentry = h_parent; ++ au_dtime_store(&dt, dst_parent, &h_path); ++ } ++ h_path.dentry = h_dst; ++ err = vfsub_link(h_src, h_dir, &h_path); ++ if (do_dt) ++ au_dtime_revert(&dt); ++ dput(h_src); ++ goto out; ++ } else ++ /* todo: cpup_wh_file? */ ++ /* udba work */ ++ au_update_brange(inode, 1); ++ } ++ ++ old_ibstart = au_ibstart(inode); ++ err = cpup_entry(dentry, bdst, bsrc, len, flags, dst_parent); ++ if (unlikely(err)) ++ goto out; ++ dst_inode = h_dst->d_inode; ++ mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2); ++ ++ err = cpup_iattr(dentry, bdst, h_src); ++ isdir = S_ISDIR(dst_inode->i_mode); ++ if (!err) { ++ if (bdst < old_ibstart) ++ au_set_ibstart(inode, bdst); ++ au_set_h_iptr(inode, bdst, au_igrab(dst_inode), ++ au_hi_flags(inode, isdir)); ++ mutex_unlock(&dst_inode->i_mutex); ++ if (!isdir ++ && h_src->d_inode->i_nlink > 1 ++ && plink) ++ au_plink_append(inode, bdst, h_dst); ++ goto out; /* success */ ++ } ++ ++ /* revert */ ++ h_path.dentry = h_parent; ++ mutex_unlock(&dst_inode->i_mutex); ++ au_dtime_store(&dt, dst_parent, &h_path); ++ h_path.dentry = h_dst; ++ if (!isdir) ++ rerr = vfsub_unlink(h_dir, &h_path, /*force*/0); ++ else ++ rerr = vfsub_rmdir(h_dir, &h_path); ++ au_dtime_revert(&dt); ++ if (rerr) { ++ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr); ++ err = -EIO; ++ } ++ ++ out: ++ dput(dst_parent); ++ return err; ++} ++ ++struct au_cpup_single_args { ++ int *errp; ++ struct dentry *dentry; ++ aufs_bindex_t bdst, bsrc; ++ loff_t len; ++ unsigned int flags; ++ struct dentry *dst_parent; ++}; ++ ++static void au_call_cpup_single(void *args) ++{ ++ struct au_cpup_single_args *a = args; ++ *a->errp = au_cpup_single(a->dentry, a->bdst, a->bsrc, a->len, ++ a->flags, a->dst_parent); ++} ++ ++int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst, ++ aufs_bindex_t bsrc, loff_t len, unsigned int flags, ++ struct dentry *dst_parent) ++{ ++ int err, wkq_err; ++ umode_t mode; ++ struct dentry *h_dentry; ++ ++ h_dentry = au_h_dptr(dentry, bsrc); ++ mode = h_dentry->d_inode->i_mode & S_IFMT; ++ if ((mode != S_IFCHR && mode != S_IFBLK) ++ || capable(CAP_MKNOD)) ++ err = au_cpup_single(dentry, bdst, bsrc, len, flags, ++ dst_parent); ++ else { ++ struct au_cpup_single_args args = { ++ .errp = &err, ++ .dentry = dentry, ++ .bdst = bdst, ++ .bsrc = bsrc, ++ .len = len, ++ .flags = flags, ++ .dst_parent = dst_parent ++ }; ++ wkq_err = au_wkq_wait(au_call_cpup_single, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ return err; ++} ++ ++/* ++ * copyup the @dentry from the first active lower branch to @bdst, ++ * using au_cpup_single(). ++ */ ++static int au_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, ++ unsigned int flags) ++{ ++ int err; ++ aufs_bindex_t bsrc, bend; ++ ++ bend = au_dbend(dentry); ++ for (bsrc = bdst + 1; bsrc <= bend; bsrc++) ++ if (au_h_dptr(dentry, bsrc)) ++ break; ++ ++ err = au_lkup_neg(dentry, bdst); ++ if (!err) { ++ err = au_cpup_single(dentry, bdst, bsrc, len, flags, NULL); ++ if (!err) ++ return 0; /* success */ ++ ++ /* revert */ ++ au_set_h_dptr(dentry, bdst, NULL); ++ au_set_dbstart(dentry, bsrc); ++ } ++ ++ return err; ++} ++ ++struct au_cpup_simple_args { ++ int *errp; ++ struct dentry *dentry; ++ aufs_bindex_t bdst; ++ loff_t len; ++ unsigned int flags; ++}; ++ ++static void au_call_cpup_simple(void *args) ++{ ++ struct au_cpup_simple_args *a = args; ++ *a->errp = au_cpup_simple(a->dentry, a->bdst, a->len, a->flags); ++} ++ ++int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, ++ unsigned int flags) ++{ ++ int err, wkq_err; ++ unsigned char do_sio; ++ struct dentry *parent; ++ struct inode *h_dir; ++ ++ parent = dget_parent(dentry); ++ h_dir = au_h_iptr(parent->d_inode, bdst); ++ do_sio = !!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE); ++ if (!do_sio) { ++ /* ++ * testing CAP_MKNOD is for generic fs, ++ * but CAP_FSETID is for xfs only, currently. ++ */ ++ umode_t mode = dentry->d_inode->i_mode; ++ do_sio = (((mode & (S_IFCHR | S_IFBLK)) ++ && !capable(CAP_MKNOD)) ++ || ((mode & (S_ISUID | S_ISGID)) ++ && !capable(CAP_FSETID))); ++ } ++ if (!do_sio) ++ err = au_cpup_simple(dentry, bdst, len, flags); ++ else { ++ struct au_cpup_simple_args args = { ++ .errp = &err, ++ .dentry = dentry, ++ .bdst = bdst, ++ .len = len, ++ .flags = flags ++ }; ++ wkq_err = au_wkq_wait(au_call_cpup_simple, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ dput(parent); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * copyup the deleted file for writing. ++ */ ++static int au_do_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, ++ struct dentry *wh_dentry, struct file *file, ++ loff_t len) ++{ ++ int err; ++ aufs_bindex_t bstart; ++ struct au_dinfo *dinfo; ++ struct dentry *h_d_dst, *h_d_start; ++ ++ dinfo = au_di(dentry); ++ bstart = dinfo->di_bstart; ++ h_d_dst = dinfo->di_hdentry[0 + bdst].hd_dentry; ++ dinfo->di_bstart = bdst; ++ dinfo->di_hdentry[0 + bdst].hd_dentry = wh_dentry; ++ h_d_start = dinfo->di_hdentry[0 + bstart].hd_dentry; ++ if (file) ++ dinfo->di_hdentry[0 + bstart].hd_dentry ++ = au_h_fptr(file, au_fbstart(file))->f_dentry; ++ err = au_cpup_single(dentry, bdst, bstart, len, !AuCpup_DTIME, ++ /*h_parent*/NULL); ++ if (!err && file) { ++ err = au_reopen_nondir(file); ++ dinfo->di_hdentry[0 + bstart].hd_dentry = h_d_start; ++ } ++ dinfo->di_hdentry[0 + bdst].hd_dentry = h_d_dst; ++ dinfo->di_bstart = bstart; ++ ++ return err; ++} ++ ++static int au_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, ++ struct file *file) ++{ ++ int err; ++ struct au_dtime dt; ++ struct dentry *parent, *h_parent, *wh_dentry; ++ struct au_branch *br; ++ struct path h_path; ++ ++ br = au_sbr(dentry->d_sb, bdst); ++ parent = dget_parent(dentry); ++ h_parent = au_h_dptr(parent, bdst); ++ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out; ++ ++ h_path.dentry = h_parent; ++ h_path.mnt = br->br_mnt; ++ au_dtime_store(&dt, parent, &h_path); ++ err = au_do_cpup_wh(dentry, bdst, wh_dentry, file, len); ++ if (unlikely(err)) ++ goto out_wh; ++ ++ dget(wh_dentry); ++ h_path.dentry = wh_dentry; ++ err = vfsub_unlink(h_parent->d_inode, &h_path, /*force*/0); ++ if (unlikely(err)) { ++ AuIOErr("failed remove copied-up tmp file %.*s(%d)\n", ++ AuDLNPair(wh_dentry), err); ++ err = -EIO; ++ } ++ au_dtime_revert(&dt); ++ au_set_hi_wh(dentry->d_inode, bdst, wh_dentry); ++ ++ out_wh: ++ dput(wh_dentry); ++ out: ++ dput(parent); ++ return err; ++} ++ ++struct au_cpup_wh_args { ++ int *errp; ++ struct dentry *dentry; ++ aufs_bindex_t bdst; ++ loff_t len; ++ struct file *file; ++}; ++ ++static void au_call_cpup_wh(void *args) ++{ ++ struct au_cpup_wh_args *a = args; ++ *a->errp = au_cpup_wh(a->dentry, a->bdst, a->len, a->file); ++} ++ ++int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, ++ struct file *file) ++{ ++ int err, wkq_err; ++ struct dentry *parent, *h_orph, *h_parent, *h_dentry; ++ struct inode *dir, *h_dir, *h_tmpdir, *h_inode; ++ struct au_wbr *wbr; ++ ++ parent = dget_parent(dentry); ++ dir = parent->d_inode; ++ h_orph = NULL; ++ h_parent = NULL; ++ h_dir = au_igrab(au_h_iptr(dir, bdst)); ++ h_tmpdir = h_dir; ++ if (!h_dir->i_nlink) { ++ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr; ++ h_orph = wbr->wbr_orph; ++ ++ h_parent = dget(au_h_dptr(parent, bdst)); ++ au_set_h_dptr(parent, bdst, NULL); ++ au_set_h_dptr(parent, bdst, dget(h_orph)); ++ h_tmpdir = h_orph->d_inode; ++ au_set_h_iptr(dir, bdst, NULL, 0); ++ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0); ++ ++ /* this temporary unlock is safe */ ++ if (file) ++ h_dentry = au_h_fptr(file, au_fbstart(file))->f_dentry; ++ else ++ h_dentry = au_h_dptr(dentry, au_dbstart(dentry)); ++ h_inode = h_dentry->d_inode; ++ IMustLock(h_inode); ++ mutex_unlock(&h_inode->i_mutex); ++ mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT2); ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ } ++ ++ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)) ++ err = au_cpup_wh(dentry, bdst, len, file); ++ else { ++ struct au_cpup_wh_args args = { ++ .errp = &err, ++ .dentry = dentry, ++ .bdst = bdst, ++ .len = len, ++ .file = file ++ }; ++ wkq_err = au_wkq_wait(au_call_cpup_wh, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ if (h_orph) { ++ mutex_unlock(&h_tmpdir->i_mutex); ++ au_set_h_iptr(dir, bdst, NULL, 0); ++ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0); ++ au_set_h_dptr(parent, bdst, NULL); ++ au_set_h_dptr(parent, bdst, h_parent); ++ } ++ iput(h_dir); ++ dput(parent); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * generic routine for both of copy-up and copy-down. ++ */ ++/* cf. revalidate function in file.c */ ++int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, ++ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, ++ struct dentry *h_parent, void *arg), ++ void *arg) ++{ ++ int err; ++ struct au_pin pin; ++ struct dentry *d, *parent, *h_parent, *real_parent; ++ ++ err = 0; ++ parent = dget_parent(dentry); ++ if (IS_ROOT(parent)) ++ goto out; ++ ++ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2, ++ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE); ++ ++ /* do not use au_dpage */ ++ real_parent = parent; ++ while (1) { ++ dput(parent); ++ parent = dget_parent(dentry); ++ h_parent = au_h_dptr(parent, bdst); ++ if (h_parent) ++ goto out; /* success */ ++ ++ /* find top dir which is necessary to cpup */ ++ do { ++ d = parent; ++ dput(parent); ++ parent = dget_parent(d); ++ di_read_lock_parent3(parent, !AuLock_IR); ++ h_parent = au_h_dptr(parent, bdst); ++ di_read_unlock(parent, !AuLock_IR); ++ } while (!h_parent); ++ ++ if (d != real_parent) ++ di_write_lock_child3(d); ++ ++ /* somebody else might create while we were sleeping */ ++ if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) { ++ if (au_h_dptr(d, bdst)) ++ au_update_dbstart(d); ++ ++ au_pin_set_dentry(&pin, d); ++ err = au_do_pin(&pin); ++ if (!err) { ++ err = cp(d, bdst, h_parent, arg); ++ au_unpin(&pin); ++ } ++ } ++ ++ if (d != real_parent) ++ di_write_unlock(d); ++ if (unlikely(err)) ++ break; ++ } ++ ++ out: ++ dput(parent); ++ return err; ++} ++ ++static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst, ++ struct dentry *h_parent __maybe_unused , ++ void *arg __maybe_unused) ++{ ++ return au_sio_cpup_simple(dentry, bdst, -1, AuCpup_DTIME); ++} ++ ++int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) ++{ ++ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL); ++} ++ ++int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) ++{ ++ int err; ++ struct dentry *parent; ++ struct inode *dir; ++ ++ parent = dget_parent(dentry); ++ dir = parent->d_inode; ++ err = 0; ++ if (au_h_iptr(dir, bdst)) ++ goto out; ++ ++ di_read_unlock(parent, AuLock_IR); ++ di_write_lock_parent(parent); ++ /* someone else might change our inode while we were sleeping */ ++ if (!au_h_iptr(dir, bdst)) ++ err = au_cpup_dirs(dentry, bdst); ++ di_downgrade_lock(parent, AuLock_IR); ++ ++ out: ++ dput(parent); ++ return err; ++} +diff -Naur a/fs/aufs/cpup.h b/fs/aufs/cpup.h +--- a/fs/aufs/cpup.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/cpup.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,81 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * copy-up/down functions ++ */ ++ ++#ifndef __AUFS_CPUP_H__ ++#define __AUFS_CPUP_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++ ++struct inode; ++struct file; ++ ++void au_cpup_attr_flags(struct inode *dst, struct inode *src); ++void au_cpup_attr_timesizes(struct inode *inode); ++void au_cpup_attr_nlink(struct inode *inode, int force); ++void au_cpup_attr_changeable(struct inode *inode); ++void au_cpup_igen(struct inode *inode, struct inode *h_inode); ++void au_cpup_attr_all(struct inode *inode, int force); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* cpup flags */ ++#define AuCpup_DTIME 1 /* do dtime_store/revert */ ++#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino, ++ for link(2) */ ++#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name) ++#define au_fset_cpup(flags, name) { (flags) |= AuCpup_##name; } ++#define au_fclr_cpup(flags, name) { (flags) &= ~AuCpup_##name; } ++ ++int au_copy_file(struct file *dst, struct file *src, loff_t len); ++int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst, ++ aufs_bindex_t bsrc, loff_t len, unsigned int flags, ++ struct dentry *dst_parent); ++int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, ++ unsigned int flags); ++int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, ++ struct file *file); ++ ++int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, ++ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, ++ struct dentry *h_parent, void *arg), ++ void *arg); ++int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst); ++int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* keep timestamps when copyup */ ++struct au_dtime { ++ struct dentry *dt_dentry; ++ struct path dt_h_path; ++ struct timespec dt_atime, dt_mtime; ++}; ++void au_dtime_store(struct au_dtime *dt, struct dentry *dentry, ++ struct path *h_path); ++void au_dtime_revert(struct au_dtime *dt); ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_CPUP_H__ */ +diff -Naur a/fs/aufs/dbgaufs.c b/fs/aufs/dbgaufs.c +--- a/fs/aufs/dbgaufs.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/dbgaufs.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,313 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * debugfs interface ++ */ ++ ++#include ++#include "aufs.h" ++ ++#ifndef CONFIG_SYSFS ++#error DEBUG_FS depends upon SYSFS ++#endif ++ ++static struct dentry *dbgaufs; ++static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH; ++ ++/* 20 is max digits length of ulong 64 */ ++struct dbgaufs_arg { ++ int n; ++ char a[20 * 4]; ++}; ++ ++/* ++ * common function for all XINO files ++ */ ++static int dbgaufs_xi_release(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ kfree(file->private_data); ++ return 0; ++} ++ ++static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt) ++{ ++ int err; ++ struct kstat st; ++ struct dbgaufs_arg *p; ++ ++ err = -ENOMEM; ++ p = kmalloc(sizeof(*p), GFP_NOFS); ++ if (unlikely(!p)) ++ goto out; ++ ++ err = 0; ++ p->n = 0; ++ file->private_data = p; ++ if (!xf) ++ goto out; ++ ++ err = vfs_getattr(xf->f_vfsmnt, xf->f_dentry, &st); ++ if (!err) { ++ if (do_fcnt) ++ p->n = snprintf ++ (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n", ++ (long)file_count(xf), st.blocks, st.blksize, ++ (long long)st.size); ++ else ++ p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n", ++ st.blocks, st.blksize, ++ (long long)st.size); ++ AuDebugOn(p->n >= sizeof(p->a)); ++ } else { ++ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err); ++ err = 0; ++ } ++ ++ out: ++ return err; ++ ++} ++ ++static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct dbgaufs_arg *p; ++ ++ p = file->private_data; ++ return simple_read_from_buffer(buf, count, ppos, p->a, p->n); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int dbgaufs_xib_open(struct inode *inode, struct file *file) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ ++ sbinfo = inode->i_private; ++ sb = sbinfo->si_sb; ++ si_noflush_read_lock(sb); ++ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0); ++ si_read_unlock(sb); ++ return err; ++} ++ ++static const struct file_operations dbgaufs_xib_fop = { ++ .open = dbgaufs_xib_open, ++ .release = dbgaufs_xi_release, ++ .read = dbgaufs_xi_read ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define DbgaufsXi_PREFIX "xi" ++ ++static int dbgaufs_xino_open(struct inode *inode, struct file *file) ++{ ++ int err; ++ long l; ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ struct file *xf; ++ struct qstr *name; ++ ++ err = -ENOENT; ++ xf = NULL; ++ name = &file->f_dentry->d_name; ++ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX) ++ || memcmp(name->name, DbgaufsXi_PREFIX, ++ sizeof(DbgaufsXi_PREFIX) - 1))) ++ goto out; ++ err = strict_strtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l); ++ if (unlikely(err)) ++ goto out; ++ ++ sbinfo = inode->i_private; ++ sb = sbinfo->si_sb; ++ si_noflush_read_lock(sb); ++ if (l <= au_sbend(sb)) { ++ xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file; ++ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1); ++ } else ++ err = -ENOENT; ++ si_read_unlock(sb); ++ ++ out: ++ return err; ++} ++ ++static const struct file_operations dbgaufs_xino_fop = { ++ .open = dbgaufs_xino_open, ++ .release = dbgaufs_xi_release, ++ .read = dbgaufs_xi_read ++}; ++ ++void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ aufs_bindex_t bend; ++ struct au_branch *br; ++ struct au_xino_file *xi; ++ ++ if (!au_sbi(sb)->si_dbgaufs) ++ return; ++ ++ bend = au_sbend(sb); ++ for (; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ xi = &br->br_xino; ++ if (xi->xi_dbgaufs) { ++ debugfs_remove(xi->xi_dbgaufs); ++ xi->xi_dbgaufs = NULL; ++ } ++ } ++} ++ ++void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ struct au_sbinfo *sbinfo; ++ struct dentry *parent; ++ struct au_branch *br; ++ struct au_xino_file *xi; ++ aufs_bindex_t bend; ++ char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */ ++ ++ sbinfo = au_sbi(sb); ++ parent = sbinfo->si_dbgaufs; ++ if (!parent) ++ return; ++ ++ bend = au_sbend(sb); ++ for (; bindex <= bend; bindex++) { ++ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex); ++ br = au_sbr(sb, bindex); ++ xi = &br->br_xino; ++ AuDebugOn(xi->xi_dbgaufs); ++ xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent, ++ sbinfo, &dbgaufs_xino_fop); ++ /* ignore an error */ ++ if (unlikely(!xi->xi_dbgaufs)) ++ AuWarn1("failed %s under debugfs\n", name); ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_EXPORT ++static int dbgaufs_xigen_open(struct inode *inode, struct file *file) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ ++ sbinfo = inode->i_private; ++ sb = sbinfo->si_sb; ++ si_noflush_read_lock(sb); ++ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0); ++ si_read_unlock(sb); ++ return err; ++} ++ ++static const struct file_operations dbgaufs_xigen_fop = { ++ .open = dbgaufs_xigen_open, ++ .release = dbgaufs_xi_release, ++ .read = dbgaufs_xi_read ++}; ++ ++static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo) ++{ ++ int err; ++ ++ err = -EIO; ++ sbinfo->si_dbgaufs_xigen = debugfs_create_file ++ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo, ++ &dbgaufs_xigen_fop); ++ if (sbinfo->si_dbgaufs_xigen) ++ err = 0; ++ ++ return err; ++} ++#else ++static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo) ++{ ++ return 0; ++} ++#endif /* CONFIG_AUFS_EXPORT */ ++ ++/* ---------------------------------------------------------------------- */ ++ ++void dbgaufs_si_fin(struct au_sbinfo *sbinfo) ++{ ++ debugfs_remove_recursive(sbinfo->si_dbgaufs); ++ sbinfo->si_dbgaufs = NULL; ++ kobject_put(&sbinfo->si_kobj); ++} ++ ++int dbgaufs_si_init(struct au_sbinfo *sbinfo) ++{ ++ int err; ++ char name[SysaufsSiNameLen]; ++ ++ err = -ENOENT; ++ if (!dbgaufs) { ++ AuErr1("/debug/aufs is uninitialized\n"); ++ goto out; ++ } ++ ++ err = -EIO; ++ sysaufs_name(sbinfo, name); ++ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs); ++ if (unlikely(!sbinfo->si_dbgaufs)) ++ goto out; ++ kobject_get(&sbinfo->si_kobj); ++ ++ sbinfo->si_dbgaufs_xib = debugfs_create_file ++ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo, ++ &dbgaufs_xib_fop); ++ if (unlikely(!sbinfo->si_dbgaufs_xib)) ++ goto out_dir; ++ ++ err = dbgaufs_xigen_init(sbinfo); ++ if (!err) ++ goto out; /* success */ ++ ++ out_dir: ++ dbgaufs_si_fin(sbinfo); ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void dbgaufs_fin(void) ++{ ++ debugfs_remove(dbgaufs); ++} ++ ++int __init dbgaufs_init(void) ++{ ++ int err; ++ ++ err = -EIO; ++ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL); ++ if (dbgaufs) ++ err = 0; ++ return err; ++} +diff -Naur a/fs/aufs/dbgaufs.h b/fs/aufs/dbgaufs.h +--- a/fs/aufs/dbgaufs.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/dbgaufs.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,79 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * debugfs interface ++ */ ++ ++#ifndef __DBGAUFS_H__ ++#define __DBGAUFS_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++ ++struct super_block; ++struct au_sbinfo; ++ ++#ifdef CONFIG_DEBUG_FS ++/* dbgaufs.c */ ++void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex); ++void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex); ++void dbgaufs_si_fin(struct au_sbinfo *sbinfo); ++int dbgaufs_si_init(struct au_sbinfo *sbinfo); ++void dbgaufs_fin(void); ++int __init dbgaufs_init(void); ++ ++#else ++ ++static inline ++void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ /* empty */ ++} ++ ++static inline ++void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ /* empty */ ++} ++ ++static inline ++void dbgaufs_si_fin(struct au_sbinfo *sbinfo) ++{ ++ /* empty */ ++} ++ ++static inline ++int dbgaufs_si_init(struct au_sbinfo *sbinfo) ++{ ++ return 0; ++} ++ ++#define dbgaufs_fin() do {} while (0) ++ ++static inline ++int __init dbgaufs_init(void) ++{ ++ return 0; ++} ++#endif /* CONFIG_DEBUG_FS */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __DBGAUFS_H__ */ +diff -Naur a/fs/aufs/dcsub.c b/fs/aufs/dcsub.c +--- a/fs/aufs/dcsub.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/dcsub.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,223 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * sub-routines for dentry cache ++ */ ++ ++#include "aufs.h" ++ ++static void au_dpage_free(struct au_dpage *dpage) ++{ ++ int i; ++ struct dentry **p; ++ ++ p = dpage->dentries; ++ for (i = 0; i < dpage->ndentry; i++) ++ dput(*p++); ++ free_page((unsigned long)dpage->dentries); ++} ++ ++int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp) ++{ ++ int err; ++ void *p; ++ ++ err = -ENOMEM; ++ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp); ++ if (unlikely(!dpages->dpages)) ++ goto out; ++ ++ p = (void *)__get_free_page(gfp); ++ if (unlikely(!p)) ++ goto out_dpages; ++ ++ dpages->dpages[0].ndentry = 0; ++ dpages->dpages[0].dentries = p; ++ dpages->ndpage = 1; ++ return 0; /* success */ ++ ++ out_dpages: ++ kfree(dpages->dpages); ++ out: ++ return err; ++} ++ ++void au_dpages_free(struct au_dcsub_pages *dpages) ++{ ++ int i; ++ struct au_dpage *p; ++ ++ p = dpages->dpages; ++ for (i = 0; i < dpages->ndpage; i++) ++ au_dpage_free(p++); ++ kfree(dpages->dpages); ++} ++ ++static int au_dpages_append(struct au_dcsub_pages *dpages, ++ struct dentry *dentry, gfp_t gfp) ++{ ++ int err, sz; ++ struct au_dpage *dpage; ++ void *p; ++ ++ dpage = dpages->dpages + dpages->ndpage - 1; ++ sz = PAGE_SIZE / sizeof(dentry); ++ if (unlikely(dpage->ndentry >= sz)) { ++ AuLabel(new dpage); ++ err = -ENOMEM; ++ sz = dpages->ndpage * sizeof(*dpages->dpages); ++ p = au_kzrealloc(dpages->dpages, sz, ++ sz + sizeof(*dpages->dpages), gfp); ++ if (unlikely(!p)) ++ goto out; ++ ++ dpages->dpages = p; ++ dpage = dpages->dpages + dpages->ndpage; ++ p = (void *)__get_free_page(gfp); ++ if (unlikely(!p)) ++ goto out; ++ ++ dpage->ndentry = 0; ++ dpage->dentries = p; ++ dpages->ndpage++; ++ } ++ ++ dpage->dentries[dpage->ndentry++] = dget(dentry); ++ return 0; /* success */ ++ ++ out: ++ return err; ++} ++ ++int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root, ++ au_dpages_test test, void *arg) ++{ ++ int err; ++ struct dentry *this_parent = root; ++ struct list_head *next; ++ struct super_block *sb = root->d_sb; ++ ++ err = 0; ++ spin_lock(&dcache_lock); ++ repeat: ++ next = this_parent->d_subdirs.next; ++ resume: ++ if (this_parent->d_sb == sb ++ && !IS_ROOT(this_parent) ++ && atomic_read(&this_parent->d_count) ++ && this_parent->d_inode ++ && (!test || test(this_parent, arg))) { ++ err = au_dpages_append(dpages, this_parent, GFP_ATOMIC); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ while (next != &this_parent->d_subdirs) { ++ struct list_head *tmp = next; ++ struct dentry *dentry = list_entry(tmp, struct dentry, ++ d_u.d_child); ++ next = tmp->next; ++ if (/*d_unhashed(dentry) || */!dentry->d_inode) ++ continue; ++ if (!list_empty(&dentry->d_subdirs)) { ++ this_parent = dentry; ++ goto repeat; ++ } ++ if (dentry->d_sb == sb ++ && atomic_read(&dentry->d_count) ++ && (!test || test(dentry, arg))) { ++ err = au_dpages_append(dpages, dentry, GFP_ATOMIC); ++ if (unlikely(err)) ++ goto out; ++ } ++ } ++ ++ if (this_parent != root) { ++ next = this_parent->d_u.d_child.next; ++ this_parent = this_parent->d_parent; /* dcache_lock is locked */ ++ goto resume; ++ } ++ out: ++ spin_unlock(&dcache_lock); ++ return err; ++} ++ ++int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry, ++ int do_include, au_dpages_test test, void *arg) ++{ ++ int err; ++ ++ err = 0; ++ spin_lock(&dcache_lock); ++ if (do_include && (!test || test(dentry, arg))) { ++ err = au_dpages_append(dpages, dentry, GFP_ATOMIC); ++ if (unlikely(err)) ++ goto out; ++ } ++ while (!IS_ROOT(dentry)) { ++ dentry = dentry->d_parent; /* dcache_lock is locked */ ++ if (!test || test(dentry, arg)) { ++ err = au_dpages_append(dpages, dentry, GFP_ATOMIC); ++ if (unlikely(err)) ++ break; ++ } ++ } ++ ++ out: ++ spin_unlock(&dcache_lock); ++ ++ return err; ++} ++ ++struct dentry *au_test_subdir(struct dentry *d1, struct dentry *d2) ++{ ++ struct dentry *trap, **dentries; ++ int err, i, j; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ ++ trap = ERR_PTR(-ENOMEM); ++ err = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_dcsub_pages_rev(&dpages, d1, /*do_include*/1, NULL, NULL); ++ if (unlikely(err)) ++ goto out_dpages; ++ ++ trap = d1; ++ for (i = 0; !err && i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ dentries = dpage->dentries; ++ for (j = 0; !err && j < dpage->ndentry; j++) { ++ struct dentry *d; ++ ++ d = dentries[j]; ++ err = (d == d2); ++ if (!err) ++ trap = d; ++ } ++ } ++ if (!err) ++ trap = NULL; ++ ++ out_dpages: ++ au_dpages_free(&dpages); ++ out: ++ return trap; ++} +diff -Naur a/fs/aufs/dcsub.h b/fs/aufs/dcsub.h +--- a/fs/aufs/dcsub.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/dcsub.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,54 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * sub-routines for dentry cache ++ */ ++ ++#ifndef __AUFS_DCSUB_H__ ++#define __AUFS_DCSUB_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++ ++struct dentry; ++ ++struct au_dpage { ++ int ndentry; ++ struct dentry **dentries; ++}; ++ ++struct au_dcsub_pages { ++ int ndpage; ++ struct au_dpage *dpages; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp); ++void au_dpages_free(struct au_dcsub_pages *dpages); ++typedef int (*au_dpages_test)(struct dentry *dentry, void *arg); ++int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root, ++ au_dpages_test test, void *arg); ++int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry, ++ int do_include, au_dpages_test test, void *arg); ++struct dentry *au_test_subdir(struct dentry *d1, struct dentry *d2); ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_DCSUB_H__ */ +diff -Naur a/fs/aufs/debug.c b/fs/aufs/debug.c +--- a/fs/aufs/debug.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/debug.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,427 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * debug print functions ++ */ ++ ++#include ++#include ++#include "aufs.h" ++ ++int aufs_debug; ++MODULE_PARM_DESC(debug, "debug print"); ++module_param_named(debug, aufs_debug, int, S_IRUGO | S_IWUSR | S_IWGRP); ++ ++char *au_plevel = KERN_DEBUG; ++#define dpri(fmt, arg...) do { \ ++ if (au_debug_test()) \ ++ printk("%s" fmt, au_plevel, ##arg); \ ++} while (0) ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_dpri_whlist(struct au_nhash *whlist) ++{ ++ unsigned long ul, n; ++ struct hlist_head *head; ++ struct au_vdir_wh *tpos; ++ struct hlist_node *pos; ++ ++ n = whlist->nh_num; ++ head = whlist->nh_head; ++ for (ul = 0; ul < n; ul++) { ++ hlist_for_each_entry(tpos, pos, head, wh_hash) ++ dpri("b%d, %.*s, %d\n", ++ tpos->wh_bindex, ++ tpos->wh_str.len, tpos->wh_str.name, ++ tpos->wh_str.len); ++ head++; ++ } ++} ++ ++void au_dpri_vdir(struct au_vdir *vdir) ++{ ++ unsigned long ul; ++ union au_vdir_deblk_p p; ++ unsigned char *o; ++ ++ if (!vdir || IS_ERR(vdir)) { ++ dpri("err %ld\n", PTR_ERR(vdir)); ++ return; ++ } ++ ++ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n", ++ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk, ++ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version); ++ for (ul = 0; ul < vdir->vd_nblk; ul++) { ++ p.deblk = vdir->vd_deblk[ul]; ++ o = p.deblk; ++ dpri("[%lu]: %p\n", ul, o); ++ } ++} ++ ++static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, ++ struct dentry *wh) ++{ ++ char *n = NULL; ++ int l = 0; ++ ++ if (!inode || IS_ERR(inode)) { ++ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode)); ++ return -1; ++ } ++ ++ /* the type of i_blocks depends upon CONFIG_LSF */ ++ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long) ++ && sizeof(inode->i_blocks) != sizeof(u64)); ++ if (wh) { ++ n = (void *)wh->d_name.name; ++ l = wh->d_name.len; ++ } ++ ++ dpri("i%d: i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu," ++ " ct %lld, np %lu, st 0x%lx, f 0x%x, g %x%s%.*s\n", ++ bindex, ++ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??", ++ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode, ++ i_size_read(inode), (unsigned long long)inode->i_blocks, ++ (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff, ++ inode->i_mapping ? inode->i_mapping->nrpages : 0, ++ inode->i_state, inode->i_flags, inode->i_generation, ++ l ? ", wh " : "", l, n); ++ return 0; ++} ++ ++void au_dpri_inode(struct inode *inode) ++{ ++ struct au_iinfo *iinfo; ++ aufs_bindex_t bindex; ++ int err; ++ ++ err = do_pri_inode(-1, inode, NULL); ++ if (err || !au_test_aufs(inode->i_sb)) ++ return; ++ ++ iinfo = au_ii(inode); ++ if (!iinfo) ++ return; ++ dpri("i-1: bstart %d, bend %d, gen %d\n", ++ iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode)); ++ if (iinfo->ii_bstart < 0) ++ return; ++ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) ++ do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, ++ iinfo->ii_hinode[0 + bindex].hi_whdentry); ++} ++ ++static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry) ++{ ++ struct dentry *wh = NULL; ++ ++ if (!dentry || IS_ERR(dentry)) { ++ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry)); ++ return -1; ++ } ++ /* do not call dget_parent() here */ ++ dpri("d%d: %.*s?/%.*s, %s, cnt %d, flags 0x%x\n", ++ bindex, ++ AuDLNPair(dentry->d_parent), AuDLNPair(dentry), ++ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??", ++ atomic_read(&dentry->d_count), dentry->d_flags); ++ if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) { ++ struct au_iinfo *iinfo = au_ii(dentry->d_inode); ++ if (iinfo) ++ wh = iinfo->ii_hinode[0 + bindex].hi_whdentry; ++ } ++ do_pri_inode(bindex, dentry->d_inode, wh); ++ return 0; ++} ++ ++void au_dpri_dentry(struct dentry *dentry) ++{ ++ struct au_dinfo *dinfo; ++ aufs_bindex_t bindex; ++ int err; ++ ++ err = do_pri_dentry(-1, dentry); ++ if (err || !au_test_aufs(dentry->d_sb)) ++ return; ++ ++ dinfo = au_di(dentry); ++ if (!dinfo) ++ return; ++ dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d\n", ++ dinfo->di_bstart, dinfo->di_bend, ++ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry)); ++ if (dinfo->di_bstart < 0) ++ return; ++ for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++) ++ do_pri_dentry(bindex, dinfo->di_hdentry[0 + bindex].hd_dentry); ++} ++ ++static int do_pri_file(aufs_bindex_t bindex, struct file *file) ++{ ++ char a[32]; ++ ++ if (!file || IS_ERR(file)) { ++ dpri("f%d: err %ld\n", bindex, PTR_ERR(file)); ++ return -1; ++ } ++ a[0] = 0; ++ if (bindex < 0 ++ && file->f_dentry ++ && au_test_aufs(file->f_dentry->d_sb) ++ && au_fi(file)) ++ snprintf(a, sizeof(a), ", mmapped %d", au_test_mmapped(file)); ++ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, pos %llu%s\n", ++ bindex, file->f_mode, file->f_flags, (long)file_count(file), ++ file->f_pos, a); ++ if (file->f_dentry) ++ do_pri_dentry(bindex, file->f_dentry); ++ return 0; ++} ++ ++void au_dpri_file(struct file *file) ++{ ++ struct au_finfo *finfo; ++ aufs_bindex_t bindex; ++ int err; ++ ++ err = do_pri_file(-1, file); ++ if (err || !file->f_dentry || !au_test_aufs(file->f_dentry->d_sb)) ++ return; ++ ++ finfo = au_fi(file); ++ if (!finfo) ++ return; ++ if (finfo->fi_bstart < 0) ++ return; ++ for (bindex = finfo->fi_bstart; bindex <= finfo->fi_bend; bindex++) { ++ struct au_hfile *hf; ++ ++ hf = finfo->fi_hfile + bindex; ++ do_pri_file(bindex, hf ? hf->hf_file : NULL); ++ } ++} ++ ++static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br) ++{ ++ struct vfsmount *mnt; ++ struct super_block *sb; ++ ++ if (!br || IS_ERR(br)) ++ goto out; ++ mnt = br->br_mnt; ++ if (!mnt || IS_ERR(mnt)) ++ goto out; ++ sb = mnt->mnt_sb; ++ if (!sb || IS_ERR(sb)) ++ goto out; ++ ++ dpri("s%d: {perm 0x%x, cnt %d, wbr %p}, " ++ "%s, dev 0x%02x%02x, flags 0x%lx, cnt(BIAS) %d, active %d, " ++ "xino %d\n", ++ bindex, br->br_perm, atomic_read(&br->br_count), br->br_wbr, ++ au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev), ++ sb->s_flags, sb->s_count - S_BIAS, ++ atomic_read(&sb->s_active), !!br->br_xino.xi_file); ++ return 0; ++ ++ out: ++ dpri("s%d: err %ld\n", bindex, PTR_ERR(br)); ++ return -1; ++} ++ ++void au_dpri_sb(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ aufs_bindex_t bindex; ++ int err; ++ /* to reuduce stack size */ ++ struct { ++ struct vfsmount mnt; ++ struct au_branch fake; ++ } *a; ++ ++ /* this function can be called from magic sysrq */ ++ a = kzalloc(sizeof(*a), GFP_ATOMIC); ++ if (unlikely(!a)) { ++ dpri("no memory\n"); ++ return; ++ } ++ ++ a->mnt.mnt_sb = sb; ++ a->fake.br_perm = 0; ++ a->fake.br_mnt = &a->mnt; ++ a->fake.br_xino.xi_file = NULL; ++ atomic_set(&a->fake.br_count, 0); ++ smp_mb(); /* atomic_set */ ++ err = do_pri_br(-1, &a->fake); ++ kfree(a); ++ dpri("dev 0x%x\n", sb->s_dev); ++ if (err || !au_test_aufs(sb)) ++ return; ++ ++ sbinfo = au_sbi(sb); ++ if (!sbinfo) ++ return; ++ dpri("nw %d, gen %u, kobj %d\n", ++ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation, ++ atomic_read(&sbinfo->si_kobj.kref.refcount)); ++ for (bindex = 0; bindex <= sbinfo->si_bend; bindex++) ++ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_dbg_sleep_jiffy(int jiffy) ++{ ++ while (jiffy) ++ jiffy = schedule_timeout_uninterruptible(jiffy); ++} ++ ++void au_dbg_iattr(struct iattr *ia) ++{ ++#define AuBit(name) if (ia->ia_valid & ATTR_ ## name) \ ++ dpri(#name "\n") ++ AuBit(MODE); ++ AuBit(UID); ++ AuBit(GID); ++ AuBit(SIZE); ++ AuBit(ATIME); ++ AuBit(MTIME); ++ AuBit(CTIME); ++ AuBit(ATIME_SET); ++ AuBit(MTIME_SET); ++ AuBit(FORCE); ++ AuBit(ATTR_FLAG); ++ AuBit(KILL_SUID); ++ AuBit(KILL_SGID); ++ AuBit(FILE); ++ AuBit(KILL_PRIV); ++ AuBit(OPEN); ++ AuBit(TIMES_SET); ++#undef AuBit ++ dpri("ia_file %p\n", ia->ia_file); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen) ++{ ++ struct dentry *parent; ++ ++ parent = dget_parent(dentry); ++ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode) ++ || IS_ROOT(dentry) ++ || au_digen(parent) != sigen); ++ dput(parent); ++} ++ ++void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen) ++{ ++ struct dentry *parent; ++ ++ parent = dget_parent(dentry); ++ AuDebugOn(S_ISDIR(dentry->d_inode->i_mode) ++ || au_digen(parent) != sigen); ++ dput(parent); ++} ++ ++void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen) ++{ ++ int err, i, j; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry **dentries; ++ ++ err = au_dpages_init(&dpages, GFP_NOFS); ++ AuDebugOn(err); ++ err = au_dcsub_pages_rev(&dpages, parent, /*do_include*/1, NULL, NULL); ++ AuDebugOn(err); ++ for (i = dpages.ndpage - 1; !err && i >= 0; i--) { ++ dpage = dpages.dpages + i; ++ dentries = dpage->dentries; ++ for (j = dpage->ndentry - 1; !err && j >= 0; j--) ++ AuDebugOn(au_digen(dentries[j]) != sigen); ++ } ++ au_dpages_free(&dpages); ++} ++ ++void au_dbg_verify_hf(struct au_finfo *finfo) ++{ ++ struct au_hfile *hf; ++ aufs_bindex_t bend, bindex; ++ ++ if (finfo->fi_bstart >= 0) { ++ bend = finfo->fi_bend; ++ for (bindex = finfo->fi_bstart; bindex <= bend; bindex++) { ++ hf = finfo->fi_hfile + bindex; ++ AuDebugOn(hf->hf_file || hf->hf_br); ++ } ++ } ++} ++ ++void au_dbg_verify_kthread(void) ++{ ++ if (au_test_wkq(current)) { ++ au_dbg_blocked(); ++ BUG(); ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_debug_sbinfo_init(struct au_sbinfo *sbinfo __maybe_unused) ++{ ++#ifdef AuForceNoPlink ++ au_opt_clr(sbinfo->si_mntflags, PLINK); ++#endif ++#ifdef AuForceNoXino ++ au_opt_clr(sbinfo->si_mntflags, XINO); ++#endif ++#ifdef AuForceNoRefrof ++ au_opt_clr(sbinfo->si_mntflags, REFROF); ++#endif ++#ifdef AuForceHinotify ++ au_opt_set_udba(sbinfo->si_mntflags, UDBA_HINOTIFY); ++#endif ++} ++ ++int __init au_debug_init(void) ++{ ++ aufs_bindex_t bindex; ++ struct au_vdir_destr destr; ++ ++ bindex = -1; ++ AuDebugOn(bindex >= 0); ++ ++ destr.len = -1; ++ AuDebugOn(destr.len < NAME_MAX); ++ ++#ifdef CONFIG_4KSTACKS ++ AuWarn("CONFIG_4KSTACKS is defined.\n"); ++#endif ++ ++#ifdef AuForceNoBrs ++ sysaufs_brs = 0; ++#endif ++ ++ return 0; ++} +diff -Naur a/fs/aufs/debug.h b/fs/aufs/debug.h +--- a/fs/aufs/debug.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/debug.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,260 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * debug print functions ++ */ ++ ++#ifndef __AUFS_DEBUG_H__ ++#define __AUFS_DEBUG_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++/* #include */ ++/* #include */ ++/* #include */ ++#include ++/* #include */ ++/* #include */ ++#include ++#include ++ ++#ifdef CONFIG_AUFS_DEBUG ++#define AuDebugOn(a) BUG_ON(a) ++ ++/* module parameter */ ++extern int aufs_debug; ++static inline void au_debug(int n) ++{ ++ aufs_debug = n; ++ smp_mb(); ++} ++ ++static inline int au_debug_test(void) ++{ ++ return aufs_debug; ++} ++#else ++#define AuDebugOn(a) do {} while (0) ++#define au_debug() do {} while (0) ++static inline int au_debug_test(void) ++{ ++ return 0; ++} ++#endif /* CONFIG_AUFS_DEBUG */ ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* debug print */ ++ ++#define AuDpri(lvl, fmt, arg...) \ ++ printk(lvl AUFS_NAME " %s:%d:%s[%d]: " fmt, \ ++ __func__, __LINE__, current->comm, current->pid, ##arg) ++#define AuDbg(fmt, arg...) do { \ ++ if (au_debug_test()) \ ++ AuDpri(KERN_DEBUG, fmt, ##arg); \ ++} while (0) ++#define AuLabel(l) AuDbg(#l "\n") ++#define AuInfo(fmt, arg...) AuDpri(KERN_INFO, fmt, ##arg) ++#define AuWarn(fmt, arg...) AuDpri(KERN_WARNING, fmt, ##arg) ++#define AuErr(fmt, arg...) AuDpri(KERN_ERR, fmt, ##arg) ++#define AuIOErr(fmt, arg...) AuErr("I/O Error, " fmt, ##arg) ++#define AuWarn1(fmt, arg...) do { \ ++ static unsigned char _c; \ ++ if (!_c++) \ ++ AuWarn(fmt, ##arg); \ ++} while (0) ++ ++#define AuErr1(fmt, arg...) do { \ ++ static unsigned char _c; \ ++ if (!_c++) \ ++ AuErr(fmt, ##arg); \ ++} while (0) ++ ++#define AuIOErr1(fmt, arg...) do { \ ++ static unsigned char _c; \ ++ if (!_c++) \ ++ AuIOErr(fmt, ##arg); \ ++} while (0) ++ ++#define AuUnsupportMsg "This operation is not supported." \ ++ " Please report this application to aufs-users ML." ++#define AuUnsupport(fmt, args...) do { \ ++ AuErr(AuUnsupportMsg "\n" fmt, ##args); \ ++ dump_stack(); \ ++} while (0) ++ ++#define AuTraceErr(e) do { \ ++ if (unlikely((e) < 0)) \ ++ AuDbg("err %d\n", (int)(e)); \ ++} while (0) ++ ++#define AuTraceErrPtr(p) do { \ ++ if (IS_ERR(p)) \ ++ AuDbg("err %ld\n", PTR_ERR(p)); \ ++} while (0) ++ ++/* dirty macros for debug print, use with "%.*s" and caution */ ++#define AuLNPair(qstr) (qstr)->len, (qstr)->name ++#define AuDLNPair(d) AuLNPair(&(d)->d_name) ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_sbinfo; ++struct au_finfo; ++struct dentry; ++#ifdef CONFIG_AUFS_DEBUG ++extern char *au_plevel; ++struct au_nhash; ++void au_dpri_whlist(struct au_nhash *whlist); ++struct au_vdir; ++void au_dpri_vdir(struct au_vdir *vdir); ++struct inode; ++void au_dpri_inode(struct inode *inode); ++void au_dpri_dentry(struct dentry *dentry); ++struct file; ++void au_dpri_file(struct file *filp); ++struct super_block; ++void au_dpri_sb(struct super_block *sb); ++ ++void au_dbg_sleep_jiffy(int jiffy); ++struct iattr; ++void au_dbg_iattr(struct iattr *ia); ++ ++void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen); ++void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen); ++void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen); ++void au_dbg_verify_hf(struct au_finfo *finfo); ++void au_dbg_verify_kthread(void); ++ ++int __init au_debug_init(void); ++void au_debug_sbinfo_init(struct au_sbinfo *sbinfo); ++#define AuDbgWhlist(w) do { \ ++ AuDbg(#w "\n"); \ ++ au_dpri_whlist(w); \ ++} while (0) ++ ++#define AuDbgVdir(v) do { \ ++ AuDbg(#v "\n"); \ ++ au_dpri_vdir(v); \ ++} while (0) ++ ++#define AuDbgInode(i) do { \ ++ AuDbg(#i "\n"); \ ++ au_dpri_inode(i); \ ++} while (0) ++ ++#define AuDbgDentry(d) do { \ ++ AuDbg(#d "\n"); \ ++ au_dpri_dentry(d); \ ++} while (0) ++ ++#define AuDbgFile(f) do { \ ++ AuDbg(#f "\n"); \ ++ au_dpri_file(f); \ ++} while (0) ++ ++#define AuDbgSb(sb) do { \ ++ AuDbg(#sb "\n"); \ ++ au_dpri_sb(sb); \ ++} while (0) ++ ++#define AuDbgSleep(sec) do { \ ++ AuDbg("sleep %d sec\n", sec); \ ++ ssleep(sec); \ ++} while (0) ++ ++#define AuDbgSleepJiffy(jiffy) do { \ ++ AuDbg("sleep %d jiffies\n", jiffy); \ ++ au_dbg_sleep_jiffy(jiffy); \ ++} while (0) ++ ++#define AuDbgIAttr(ia) do { \ ++ AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \ ++ au_dbg_iattr(ia); \ ++} while (0) ++#else ++static inline void au_dbg_verify_dir_parent(struct dentry *dentry, ++ unsigned int sigen) ++{ ++ /* empty */ ++} ++static inline void au_dbg_verify_nondir_parent(struct dentry *dentry, ++ unsigned int sigen) ++{ ++ /* empty */ ++} ++static inline void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen) ++{ ++ /* empty */ ++} ++static inline void au_dbg_verify_hf(struct au_finfo *finfo) ++{ ++ /* empty */ ++} ++static inline void au_dbg_verify_kthread(void) ++{ ++ /* empty */ ++} ++ ++static inline int au_debug_init(void) ++{ ++ return 0; ++} ++static inline void au_debug_sbinfo_init(struct au_sbinfo *sbinfo) ++{ ++ /* empty */ ++} ++#define AuDbgWhlist(w) do {} while (0) ++#define AuDbgVdir(v) do {} while (0) ++#define AuDbgInode(i) do {} while (0) ++#define AuDbgDentry(d) do {} while (0) ++#define AuDbgFile(f) do {} while (0) ++#define AuDbgSb(sb) do {} while (0) ++#define AuDbgSleep(sec) do {} while (0) ++#define AuDbgSleepJiffy(jiffy) do {} while (0) ++#define AuDbgIAttr(ia) do {} while (0) ++#endif /* CONFIG_AUFS_DEBUG */ ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_MAGIC_SYSRQ ++int __init au_sysrq_init(void); ++void au_sysrq_fin(void); ++ ++#ifdef CONFIG_HW_CONSOLE ++#define au_dbg_blocked() do { \ ++ WARN_ON(1); \ ++ handle_sysrq('w', vc_cons[fg_console].d->vc_tty); \ ++} while (0) ++#else ++#define au_dbg_blocked() do {} while (0) ++#endif ++ ++#else ++static inline int au_sysrq_init(void) ++{ ++ return 0; ++} ++#define au_sysrq_fin() do {} while (0) ++#define au_dbg_blocked() do {} while (0) ++#endif /* CONFIG_AUFS_MAGIC_SYSRQ */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_DEBUG_H__ */ +diff -Naur a/fs/aufs/dentry.c b/fs/aufs/dentry.c +--- a/fs/aufs/dentry.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/dentry.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,876 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * lookup and dentry operations ++ */ ++ ++#include ++#include "aufs.h" ++ ++static void au_h_nd(struct nameidata *h_nd, struct nameidata *nd) ++{ ++ if (nd) { ++ *h_nd = *nd; ++ ++ /* ++ * gave up supporting LOOKUP_CREATE/OPEN for lower fs, ++ * due to whiteout and branch permission. ++ */ ++ h_nd->flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE ++ | LOOKUP_FOLLOW); ++ /* unnecessary? */ ++ h_nd->intent.open.file = NULL; ++ } else ++ memset(h_nd, 0, sizeof(*h_nd)); ++} ++ ++struct au_lkup_one_args { ++ struct dentry **errp; ++ struct qstr *name; ++ struct dentry *h_parent; ++ struct au_branch *br; ++ struct nameidata *nd; ++}; ++ ++struct dentry *au_lkup_one(struct qstr *name, struct dentry *h_parent, ++ struct au_branch *br, struct nameidata *nd) ++{ ++ struct dentry *h_dentry; ++ int err; ++ struct nameidata h_nd; ++ ++ if (au_test_fs_null_nd(h_parent->d_sb)) ++ return vfsub_lookup_one_len(name->name, h_parent, name->len); ++ ++ au_h_nd(&h_nd, nd); ++ h_nd.path.dentry = h_parent; ++ h_nd.path.mnt = br->br_mnt; ++ ++ err = __lookup_one_len(name->name, &h_nd.last, NULL, name->len); ++ h_dentry = ERR_PTR(err); ++ if (!err) { ++ path_get(&h_nd.path); ++ h_dentry = vfsub_lookup_hash(&h_nd); ++ path_put(&h_nd.path); ++ } ++ ++ return h_dentry; ++} ++ ++static void au_call_lkup_one(void *args) ++{ ++ struct au_lkup_one_args *a = args; ++ *a->errp = au_lkup_one(a->name, a->h_parent, a->br, a->nd); ++} ++ ++#define AuLkup_ALLOW_NEG 1 ++#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name) ++#define au_fset_lkup(flags, name) { (flags) |= AuLkup_##name; } ++#define au_fclr_lkup(flags, name) { (flags) &= ~AuLkup_##name; } ++ ++struct au_do_lookup_args { ++ unsigned int flags; ++ mode_t type; ++ struct nameidata *nd; ++}; ++ ++/* ++ * returns positive/negative dentry, NULL or an error. ++ * NULL means whiteout-ed or not-found. ++ */ ++static struct dentry* ++au_do_lookup(struct dentry *h_parent, struct dentry *dentry, ++ aufs_bindex_t bindex, struct qstr *wh_name, ++ struct au_do_lookup_args *args) ++{ ++ struct dentry *h_dentry; ++ struct inode *h_inode, *inode; ++ struct qstr *name; ++ struct au_branch *br; ++ int wh_found, opq; ++ unsigned char wh_able; ++ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG); ++ ++ name = &dentry->d_name; ++ wh_found = 0; ++ br = au_sbr(dentry->d_sb, bindex); ++ wh_able = !!au_br_whable(br->br_perm); ++ if (wh_able) ++ wh_found = au_wh_test(h_parent, wh_name, br, /*try_sio*/0); ++ h_dentry = ERR_PTR(wh_found); ++ if (!wh_found) ++ goto real_lookup; ++ if (unlikely(wh_found < 0)) ++ goto out; ++ ++ /* We found a whiteout */ ++ /* au_set_dbend(dentry, bindex); */ ++ au_set_dbwh(dentry, bindex); ++ if (!allow_neg) ++ return NULL; /* success */ ++ ++ real_lookup: ++ h_dentry = au_lkup_one(name, h_parent, br, args->nd); ++ if (IS_ERR(h_dentry)) ++ goto out; ++ ++ h_inode = h_dentry->d_inode; ++ if (!h_inode) { ++ if (!allow_neg) ++ goto out_neg; ++ } else if (wh_found ++ || (args->type && args->type != (h_inode->i_mode & S_IFMT))) ++ goto out_neg; ++ ++ if (au_dbend(dentry) <= bindex) ++ au_set_dbend(dentry, bindex); ++ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry)) ++ au_set_dbstart(dentry, bindex); ++ au_set_h_dptr(dentry, bindex, h_dentry); ++ ++ inode = dentry->d_inode; ++ if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able ++ || (inode && !S_ISDIR(inode->i_mode))) ++ goto out; /* success */ ++ ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ opq = au_diropq_test(h_dentry, br); ++ mutex_unlock(&h_inode->i_mutex); ++ if (opq > 0) ++ au_set_dbdiropq(dentry, bindex); ++ else if (unlikely(opq < 0)) { ++ au_set_h_dptr(dentry, bindex, NULL); ++ h_dentry = ERR_PTR(opq); ++ } ++ goto out; ++ ++ out_neg: ++ dput(h_dentry); ++ h_dentry = NULL; ++ out: ++ return h_dentry; ++} ++ ++static int au_test_shwh(struct super_block *sb, const struct qstr *name) ++{ ++ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH) ++ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))) ++ return -EPERM; ++ return 0; ++} ++ ++/* ++ * returns the number of lower positive dentries, ++ * otherwise an error. ++ * can be called at unlinking with @type is zero. ++ */ ++int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type, ++ struct nameidata *nd) ++{ ++ int npositive, err; ++ aufs_bindex_t bindex, btail, bdiropq; ++ unsigned char isdir; ++ struct qstr whname; ++ struct au_do_lookup_args args = { ++ .flags = 0, ++ .type = type, ++ .nd = nd ++ }; ++ const struct qstr *name = &dentry->d_name; ++ struct dentry *parent; ++ struct inode *inode; ++ ++ parent = dget_parent(dentry); ++ err = au_test_shwh(dentry->d_sb, name); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_wh_name_alloc(&whname, name); ++ if (unlikely(err)) ++ goto out; ++ ++ inode = dentry->d_inode; ++ isdir = !!(inode && S_ISDIR(inode->i_mode)); ++ if (!type) ++ au_fset_lkup(args.flags, ALLOW_NEG); ++ ++ npositive = 0; ++ btail = au_dbtaildir(parent); ++ for (bindex = bstart; bindex <= btail; bindex++) { ++ struct dentry *h_parent, *h_dentry; ++ struct inode *h_inode, *h_dir; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry) { ++ if (h_dentry->d_inode) ++ npositive++; ++ if (type != S_IFDIR) ++ break; ++ continue; ++ } ++ h_parent = au_h_dptr(parent, bindex); ++ if (!h_parent) ++ continue; ++ h_dir = h_parent->d_inode; ++ if (!h_dir || !S_ISDIR(h_dir->i_mode)) ++ continue; ++ ++ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); ++ h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname, ++ &args); ++ mutex_unlock(&h_dir->i_mutex); ++ err = PTR_ERR(h_dentry); ++ if (IS_ERR(h_dentry)) ++ goto out_wh; ++ au_fclr_lkup(args.flags, ALLOW_NEG); ++ ++ if (au_dbwh(dentry) >= 0) ++ break; ++ if (!h_dentry) ++ continue; ++ h_inode = h_dentry->d_inode; ++ if (!h_inode) ++ continue; ++ npositive++; ++ if (!args.type) ++ args.type = h_inode->i_mode & S_IFMT; ++ if (args.type != S_IFDIR) ++ break; ++ else if (isdir) { ++ /* the type of lower may be different */ ++ bdiropq = au_dbdiropq(dentry); ++ if (bdiropq >= 0 && bdiropq <= bindex) ++ break; ++ } ++ } ++ ++ if (npositive) { ++ AuLabel(positive); ++ au_update_dbstart(dentry); ++ } ++ err = npositive; ++ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE) ++ && au_dbstart(dentry) < 0)) ++ /* both of real entry and whiteout found */ ++ err = -EIO; ++ ++ out_wh: ++ kfree(whname.name); ++ out: ++ dput(parent); ++ return err; ++} ++ ++struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent, ++ struct au_branch *br) ++{ ++ struct dentry *dentry; ++ int wkq_err; ++ ++ if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC)) ++ dentry = au_lkup_one(name, parent, br, /*nd*/NULL); ++ else { ++ struct au_lkup_one_args args = { ++ .errp = &dentry, ++ .name = name, ++ .h_parent = parent, ++ .br = br, ++ .nd = NULL ++ }; ++ ++ wkq_err = au_wkq_wait(au_call_lkup_one, &args); ++ if (unlikely(wkq_err)) ++ dentry = ERR_PTR(wkq_err); ++ } ++ ++ return dentry; ++} ++ ++/* ++ * lookup @dentry on @bindex which should be negative. ++ */ ++int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ int err; ++ struct dentry *parent, *h_parent, *h_dentry; ++ struct qstr *name; ++ ++ name = &dentry->d_name; ++ parent = dget_parent(dentry); ++ h_parent = au_h_dptr(parent, bindex); ++ h_dentry = au_sio_lkup_one(name, h_parent, ++ au_sbr(dentry->d_sb, bindex)); ++ err = PTR_ERR(h_dentry); ++ if (IS_ERR(h_dentry)) ++ goto out; ++ if (unlikely(h_dentry->d_inode)) { ++ err = -EIO; ++ AuIOErr("b%d %.*s should be negative.\n", ++ bindex, AuDLNPair(h_dentry)); ++ dput(h_dentry); ++ goto out; ++ } ++ ++ if (bindex < au_dbstart(dentry)) ++ au_set_dbstart(dentry, bindex); ++ if (au_dbend(dentry) < bindex) ++ au_set_dbend(dentry, bindex); ++ au_set_h_dptr(dentry, bindex, h_dentry); ++ err = 0; ++ ++ out: ++ dput(parent); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* subset of struct inode */ ++struct au_iattr { ++ unsigned long i_ino; ++ /* unsigned int i_nlink; */ ++ uid_t i_uid; ++ gid_t i_gid; ++ u64 i_version; ++/* ++ loff_t i_size; ++ blkcnt_t i_blocks; ++*/ ++ umode_t i_mode; ++}; ++ ++static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode) ++{ ++ ia->i_ino = h_inode->i_ino; ++ /* ia->i_nlink = h_inode->i_nlink; */ ++ ia->i_uid = h_inode->i_uid; ++ ia->i_gid = h_inode->i_gid; ++ ia->i_version = h_inode->i_version; ++/* ++ ia->i_size = h_inode->i_size; ++ ia->i_blocks = h_inode->i_blocks; ++*/ ++ ia->i_mode = (h_inode->i_mode & S_IFMT); ++} ++ ++static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode) ++{ ++ return ia->i_ino != h_inode->i_ino ++ /* || ia->i_nlink != h_inode->i_nlink */ ++ || ia->i_uid != h_inode->i_uid ++ || ia->i_gid != h_inode->i_gid ++ || ia->i_version != h_inode->i_version ++/* ++ || ia->i_size != h_inode->i_size ++ || ia->i_blocks != h_inode->i_blocks ++*/ ++ || ia->i_mode != (h_inode->i_mode & S_IFMT); ++} ++ ++static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent, ++ struct au_branch *br) ++{ ++ int err; ++ struct au_iattr ia; ++ struct inode *h_inode; ++ struct dentry *h_d; ++ struct super_block *h_sb; ++ ++ err = 0; ++ memset(&ia, -1, sizeof(ia)); ++ h_sb = h_dentry->d_sb; ++ h_inode = h_dentry->d_inode; ++ if (h_inode) ++ au_iattr_save(&ia, h_inode); ++ else if (au_test_nfs(h_sb) || au_test_fuse(h_sb)) ++ /* nfs d_revalidate may return 0 for negative dentry */ ++ /* fuse d_revalidate always return 0 for negative dentry */ ++ goto out; ++ ++ /* main purpose is namei.c:cached_lookup() and d_revalidate */ ++ h_d = au_lkup_one(&h_dentry->d_name, h_parent, br, /*nd*/NULL); ++ err = PTR_ERR(h_d); ++ if (IS_ERR(h_d)) ++ goto out; ++ ++ err = 0; ++ if (unlikely(h_d != h_dentry ++ || h_d->d_inode != h_inode ++ || (h_inode && au_iattr_test(&ia, h_inode)))) ++ err = au_busy_or_stale(); ++ dput(h_d); ++ ++ out: ++ AuTraceErr(err); ++ return err; ++} ++ ++int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir, ++ struct dentry *h_parent, struct au_branch *br) ++{ ++ int err; ++ ++ err = 0; ++ if (udba == AuOpt_UDBA_REVAL) { ++ IMustLock(h_dir); ++ err = (h_dentry->d_parent->d_inode != h_dir); ++ } else if (udba == AuOpt_UDBA_HINOTIFY) ++ err = au_h_verify_dentry(h_dentry, h_parent, br); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void au_do_refresh_hdentry(struct au_hdentry *p, struct au_dinfo *dinfo, ++ struct dentry *parent) ++{ ++ struct dentry *h_d, *h_dp; ++ struct au_hdentry tmp, *q; ++ struct super_block *sb; ++ aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq; ++ ++ bend = dinfo->di_bend; ++ bwh = dinfo->di_bwh; ++ bdiropq = dinfo->di_bdiropq; ++ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) { ++ h_d = p->hd_dentry; ++ if (!h_d) ++ continue; ++ ++ h_dp = dget_parent(h_d); ++ if (h_dp == au_h_dptr(parent, bindex)) { ++ dput(h_dp); ++ continue; ++ } ++ ++ new_bindex = au_find_dbindex(parent, h_dp); ++ dput(h_dp); ++ if (dinfo->di_bwh == bindex) ++ bwh = new_bindex; ++ if (dinfo->di_bdiropq == bindex) ++ bdiropq = new_bindex; ++ if (new_bindex < 0) { ++ au_hdput(p); ++ p->hd_dentry = NULL; ++ continue; ++ } ++ ++ /* swap two lower dentries, and loop again */ ++ q = dinfo->di_hdentry + new_bindex; ++ tmp = *q; ++ *q = *p; ++ *p = tmp; ++ if (tmp.hd_dentry) { ++ bindex--; ++ p--; ++ } ++ } ++ ++ sb = parent->d_sb; ++ dinfo->di_bwh = -1; ++ if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh)) ++ dinfo->di_bwh = bwh; ++ ++ dinfo->di_bdiropq = -1; ++ if (bdiropq >= 0 ++ && bdiropq <= au_sbend(sb) ++ && au_sbr_whable(sb, bdiropq)) ++ dinfo->di_bdiropq = bdiropq; ++ ++ bend = au_dbend(parent); ++ p = dinfo->di_hdentry; ++ for (bindex = 0; bindex <= bend; bindex++, p++) ++ if (p->hd_dentry) { ++ dinfo->di_bstart = bindex; ++ break; ++ } ++ ++ p = dinfo->di_hdentry + bend; ++ for (bindex = bend; bindex >= 0; bindex--, p--) ++ if (p->hd_dentry) { ++ dinfo->di_bend = bindex; ++ break; ++ } ++} ++ ++/* ++ * returns the number of found lower positive dentries, ++ * otherwise an error. ++ */ ++int au_refresh_hdentry(struct dentry *dentry, mode_t type) ++{ ++ int npositive, err; ++ unsigned int sigen; ++ aufs_bindex_t bstart; ++ struct au_dinfo *dinfo; ++ struct super_block *sb; ++ struct dentry *parent; ++ ++ sb = dentry->d_sb; ++ AuDebugOn(IS_ROOT(dentry)); ++ sigen = au_sigen(sb); ++ parent = dget_parent(dentry); ++ AuDebugOn(au_digen(parent) != sigen ++ || au_iigen(parent->d_inode) != sigen); ++ ++ dinfo = au_di(dentry); ++ err = au_di_realloc(dinfo, au_sbend(sb) + 1); ++ npositive = err; ++ if (unlikely(err)) ++ goto out; ++ au_do_refresh_hdentry(dinfo->di_hdentry + dinfo->di_bstart, dinfo, ++ parent); ++ ++ npositive = 0; ++ bstart = au_dbstart(parent); ++ if (type != S_IFDIR && dinfo->di_bstart == bstart) ++ goto out_dgen; /* success */ ++ ++ npositive = au_lkup_dentry(dentry, bstart, type, /*nd*/NULL); ++ if (npositive < 0) ++ goto out; ++ if (dinfo->di_bwh >= 0 && dinfo->di_bwh <= dinfo->di_bstart) ++ d_drop(dentry); ++ ++ out_dgen: ++ au_update_digen(dentry); ++ out: ++ dput(parent); ++ AuTraceErr(npositive); ++ return npositive; ++} ++ ++static noinline_for_stack ++int au_do_h_d_reval(struct dentry *h_dentry, struct nameidata *nd, ++ struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ int err, valid; ++ int (*reval)(struct dentry *, struct nameidata *); ++ ++ err = 0; ++ reval = NULL; ++ if (h_dentry->d_op) ++ reval = h_dentry->d_op->d_revalidate; ++ if (!reval) ++ goto out; ++ ++ AuDbg("b%d\n", bindex); ++ if (au_test_fs_null_nd(h_dentry->d_sb)) ++ /* it may return tri-state */ ++ valid = reval(h_dentry, NULL); ++ else { ++ struct nameidata h_nd; ++ int locked; ++ struct dentry *parent; ++ ++ au_h_nd(&h_nd, nd); ++ parent = nd->path.dentry; ++ locked = (nd && nd->path.dentry != dentry); ++ if (locked) ++ di_read_lock_parent(parent, AuLock_IR); ++ BUG_ON(bindex > au_dbend(parent)); ++ h_nd.path.dentry = au_h_dptr(parent, bindex); ++ BUG_ON(!h_nd.path.dentry); ++ h_nd.path.mnt = au_sbr(parent->d_sb, bindex)->br_mnt; ++ path_get(&h_nd.path); ++ valid = reval(h_dentry, &h_nd); ++ path_put(&h_nd.path); ++ if (locked) ++ di_read_unlock(parent, AuLock_IR); ++ } ++ ++ if (unlikely(valid < 0)) ++ err = valid; ++ else if (!valid) ++ err = -EINVAL; ++ ++ out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* todo: remove this */ ++static int h_d_revalidate(struct dentry *dentry, struct inode *inode, ++ struct nameidata *nd, int do_udba) ++{ ++ int err; ++ umode_t mode, h_mode; ++ aufs_bindex_t bindex, btail, bstart, ibs, ibe; ++ unsigned char plus, unhashed, is_root, h_plus; ++ struct inode *first, *h_inode, *h_cached_inode; ++ struct dentry *h_dentry; ++ struct qstr *name, *h_name; ++ ++ err = 0; ++ plus = 0; ++ mode = 0; ++ first = NULL; ++ ibs = -1; ++ ibe = -1; ++ unhashed = !!d_unhashed(dentry); ++ is_root = !!IS_ROOT(dentry); ++ name = &dentry->d_name; ++ ++ /* ++ * Theoretically, REVAL test should be unnecessary in case of INOTIFY. ++ * But inotify doesn't fire some necessary events, ++ * IN_ATTRIB for atime/nlink/pageio ++ * IN_DELETE for NFS dentry ++ * Let's do REVAL test too. ++ */ ++ if (do_udba && inode) { ++ mode = (inode->i_mode & S_IFMT); ++ plus = (inode->i_nlink > 0); ++ first = au_h_iptr(inode, au_ibstart(inode)); ++ ibs = au_ibstart(inode); ++ ibe = au_ibend(inode); ++ } ++ ++ bstart = au_dbstart(dentry); ++ btail = bstart; ++ if (inode && S_ISDIR(inode->i_mode)) ++ btail = au_dbtaildir(dentry); ++ for (bindex = bstart; bindex <= btail; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ ++ AuDbg("b%d, %.*s\n", bindex, AuDLNPair(h_dentry)); ++ h_name = &h_dentry->d_name; ++ if (unlikely(do_udba ++ && !is_root ++ && (unhashed != !!d_unhashed(h_dentry) ++ || name->len != h_name->len ++ || memcmp(name->name, h_name->name, name->len)) ++ )) { ++ AuDbg("unhash 0x%x 0x%x, %.*s %.*s\n", ++ unhashed, d_unhashed(h_dentry), ++ AuDLNPair(dentry), AuDLNPair(h_dentry)); ++ goto err; ++ } ++ ++ err = au_do_h_d_reval(h_dentry, nd, dentry, bindex); ++ if (unlikely(err)) ++ /* do not goto err, to keep the errno */ ++ break; ++ ++ /* todo: plink too? */ ++ if (!do_udba) ++ continue; ++ ++ /* UDBA tests */ ++ h_inode = h_dentry->d_inode; ++ if (unlikely(!!inode != !!h_inode)) ++ goto err; ++ ++ h_plus = plus; ++ h_mode = mode; ++ h_cached_inode = h_inode; ++ if (h_inode) { ++ h_mode = (h_inode->i_mode & S_IFMT); ++ h_plus = (h_inode->i_nlink > 0); ++ } ++ if (inode && ibs <= bindex && bindex <= ibe) ++ h_cached_inode = au_h_iptr(inode, bindex); ++ ++ if (unlikely(plus != h_plus ++ || mode != h_mode ++ || h_cached_inode != h_inode)) ++ goto err; ++ continue; ++ ++ err: ++ err = -EINVAL; ++ break; ++ } ++ ++ return err; ++} ++ ++static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen) ++{ ++ int err; ++ struct dentry *parent; ++ struct inode *inode; ++ ++ inode = dentry->d_inode; ++ if (au_digen(dentry) == sigen && au_iigen(inode) == sigen) ++ return 0; ++ ++ parent = dget_parent(dentry); ++ di_read_lock_parent(parent, AuLock_IR); ++ AuDebugOn(au_digen(parent) != sigen ++ || au_iigen(parent->d_inode) != sigen); ++ au_dbg_verify_gen(parent, sigen); ++ ++ /* returns a number of positive dentries */ ++ err = au_refresh_hdentry(dentry, inode->i_mode & S_IFMT); ++ if (err >= 0) ++ err = au_refresh_hinode(inode, dentry); ++ ++ di_read_unlock(parent, AuLock_IR); ++ dput(parent); ++ return err; ++} ++ ++int au_reval_dpath(struct dentry *dentry, unsigned int sigen) ++{ ++ int err; ++ struct dentry *d, *parent; ++ struct inode *inode; ++ ++ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS)) ++ return simple_reval_dpath(dentry, sigen); ++ ++ /* slow loop, keep it simple and stupid */ ++ /* cf: au_cpup_dirs() */ ++ err = 0; ++ parent = NULL; ++ while (au_digen(dentry) != sigen ++ || au_iigen(dentry->d_inode) != sigen) { ++ d = dentry; ++ while (1) { ++ dput(parent); ++ parent = dget_parent(d); ++ if (au_digen(parent) == sigen ++ && au_iigen(parent->d_inode) == sigen) ++ break; ++ d = parent; ++ } ++ ++ inode = d->d_inode; ++ if (d != dentry) ++ di_write_lock_child(d); ++ ++ /* someone might update our dentry while we were sleeping */ ++ if (au_digen(d) != sigen || au_iigen(d->d_inode) != sigen) { ++ di_read_lock_parent(parent, AuLock_IR); ++ /* returns a number of positive dentries */ ++ err = au_refresh_hdentry(d, inode->i_mode & S_IFMT); ++ if (err >= 0) ++ err = au_refresh_hinode(inode, d); ++ di_read_unlock(parent, AuLock_IR); ++ } ++ ++ if (d != dentry) ++ di_write_unlock(d); ++ dput(parent); ++ if (unlikely(err)) ++ break; ++ } ++ ++ return err; ++} ++ ++/* ++ * if valid returns 1, otherwise 0. ++ */ ++static int aufs_d_revalidate(struct dentry *dentry, struct nameidata *nd) ++{ ++ int valid, err; ++ unsigned int sigen; ++ unsigned char do_udba; ++ struct super_block *sb; ++ struct inode *inode; ++ ++ err = -EINVAL; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW); ++ sigen = au_sigen(sb); ++ if (au_digen(dentry) != sigen) { ++ AuDebugOn(IS_ROOT(dentry)); ++ if (inode) ++ err = au_reval_dpath(dentry, sigen); ++ if (unlikely(err)) ++ goto out_dgrade; ++ AuDebugOn(au_digen(dentry) != sigen); ++ } ++ if (inode && au_iigen(inode) != sigen) { ++ AuDebugOn(IS_ROOT(dentry)); ++ err = au_refresh_hinode(inode, dentry); ++ if (unlikely(err)) ++ goto out_dgrade; ++ AuDebugOn(au_iigen(inode) != sigen); ++ } ++ di_downgrade_lock(dentry, AuLock_IR); ++ ++ AuDebugOn(au_digen(dentry) != sigen); ++ AuDebugOn(inode && au_iigen(inode) != sigen); ++ err = -EINVAL; ++ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE); ++ if (do_udba && inode) { ++ aufs_bindex_t bstart = au_ibstart(inode); ++ ++ if (bstart >= 0 ++ && au_test_higen(inode, au_h_iptr(inode, bstart))) ++ goto out; ++ } ++ ++ err = h_d_revalidate(dentry, inode, nd, do_udba); ++ if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) ++ /* both of real entry and whiteout found */ ++ err = -EIO; ++ goto out; ++ ++ out_dgrade: ++ di_downgrade_lock(dentry, AuLock_IR); ++ out: ++ au_store_oflag(nd, inode); ++ aufs_read_unlock(dentry, AuLock_IR); ++ AuTraceErr(err); ++ valid = !err; ++ if (!valid) ++ AuDbg("%.*s invalid\n", AuDLNPair(dentry)); ++ return valid; ++} ++ ++static void aufs_d_release(struct dentry *dentry) ++{ ++ struct au_dinfo *dinfo; ++ aufs_bindex_t bend, bindex; ++ ++ dinfo = dentry->d_fsdata; ++ if (!dinfo) ++ return; ++ ++ /* dentry may not be revalidated */ ++ bindex = dinfo->di_bstart; ++ if (bindex >= 0) { ++ struct au_hdentry *p; ++ ++ bend = dinfo->di_bend; ++ p = dinfo->di_hdentry + bindex; ++ while (bindex++ <= bend) { ++ if (p->hd_dentry) ++ au_hdput(p); ++ p++; ++ } ++ } ++ kfree(dinfo->di_hdentry); ++ au_rwsem_destroy(&dinfo->di_rwsem); ++ au_cache_free_dinfo(dinfo); ++ au_hin_di_reinit(dentry); ++} ++ ++struct dentry_operations aufs_dop = { ++ .d_revalidate = aufs_d_revalidate, ++ .d_release = aufs_d_release ++}; +diff -Naur a/fs/aufs/dentry.h b/fs/aufs/dentry.h +--- a/fs/aufs/dentry.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/dentry.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,221 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * lookup and dentry operations ++ */ ++ ++#ifndef __AUFS_DENTRY_H__ ++#define __AUFS_DENTRY_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include "rwsem.h" ++ ++/* make a single member structure for future use */ ++/* todo: remove this structure */ ++struct au_hdentry { ++ struct dentry *hd_dentry; ++}; ++ ++struct au_dinfo { ++ atomic_t di_generation; ++ ++ struct rw_semaphore di_rwsem; ++ aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq; ++ struct au_hdentry *di_hdentry; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* dentry.c */ ++extern struct dentry_operations aufs_dop; ++struct au_branch; ++struct dentry *au_lkup_one(struct qstr *name, struct dentry *h_parent, ++ struct au_branch *br, struct nameidata *nd); ++struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent, ++ struct au_branch *br); ++int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir, ++ struct dentry *h_parent, struct au_branch *br); ++ ++int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type, ++ struct nameidata *nd); ++int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex); ++int au_refresh_hdentry(struct dentry *dentry, mode_t type); ++int au_reval_dpath(struct dentry *dentry, unsigned int sigen); ++ ++/* dinfo.c */ ++int au_alloc_dinfo(struct dentry *dentry); ++int au_di_realloc(struct au_dinfo *dinfo, int nbr); ++ ++void di_read_lock(struct dentry *d, int flags, unsigned int lsc); ++void di_read_unlock(struct dentry *d, int flags); ++void di_downgrade_lock(struct dentry *d, int flags); ++void di_write_lock(struct dentry *d, unsigned int lsc); ++void di_write_unlock(struct dentry *d); ++void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir); ++void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir); ++void di_write_unlock2(struct dentry *d1, struct dentry *d2); ++ ++struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex); ++aufs_bindex_t au_dbtail(struct dentry *dentry); ++aufs_bindex_t au_dbtaildir(struct dentry *dentry); ++ ++void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_dentry); ++void au_update_digen(struct dentry *dentry); ++void au_update_dbrange(struct dentry *dentry, int do_put_zero); ++void au_update_dbstart(struct dentry *dentry); ++void au_update_dbend(struct dentry *dentry); ++int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct au_dinfo *au_di(struct dentry *dentry) ++{ ++ return dentry->d_fsdata; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* lock subclass for dinfo */ ++enum { ++ AuLsc_DI_CHILD, /* child first */ ++ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hinotify */ ++ AuLsc_DI_CHILD3, /* copyup dirs */ ++ AuLsc_DI_PARENT, ++ AuLsc_DI_PARENT2, ++ AuLsc_DI_PARENT3 ++}; ++ ++/* ++ * di_read_lock_child, di_write_lock_child, ++ * di_read_lock_child2, di_write_lock_child2, ++ * di_read_lock_child3, di_write_lock_child3, ++ * di_read_lock_parent, di_write_lock_parent, ++ * di_read_lock_parent2, di_write_lock_parent2, ++ * di_read_lock_parent3, di_write_lock_parent3, ++ */ ++#define AuReadLockFunc(name, lsc) \ ++static inline void di_read_lock_##name(struct dentry *d, int flags) \ ++{ di_read_lock(d, flags, AuLsc_DI_##lsc); } ++ ++#define AuWriteLockFunc(name, lsc) \ ++static inline void di_write_lock_##name(struct dentry *d) \ ++{ di_write_lock(d, AuLsc_DI_##lsc); } ++ ++#define AuRWLockFuncs(name, lsc) \ ++ AuReadLockFunc(name, lsc) \ ++ AuWriteLockFunc(name, lsc) ++ ++AuRWLockFuncs(child, CHILD); ++AuRWLockFuncs(child2, CHILD2); ++AuRWLockFuncs(child3, CHILD3); ++AuRWLockFuncs(parent, PARENT); ++AuRWLockFuncs(parent2, PARENT2); ++AuRWLockFuncs(parent3, PARENT3); ++ ++#undef AuReadLockFunc ++#undef AuWriteLockFunc ++#undef AuRWLockFuncs ++ ++#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem) ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* todo: memory barrier? */ ++static inline unsigned int au_digen(struct dentry *d) ++{ ++ return atomic_read(&au_di(d)->di_generation); ++} ++ ++static inline void au_h_dentry_init(struct au_hdentry *hdentry) ++{ ++ hdentry->hd_dentry = NULL; ++} ++ ++static inline void au_hdput(struct au_hdentry *hd) ++{ ++ dput(hd->hd_dentry); ++} ++ ++static inline aufs_bindex_t au_dbstart(struct dentry *dentry) ++{ ++ return au_di(dentry)->di_bstart; ++} ++ ++static inline aufs_bindex_t au_dbend(struct dentry *dentry) ++{ ++ return au_di(dentry)->di_bend; ++} ++ ++static inline aufs_bindex_t au_dbwh(struct dentry *dentry) ++{ ++ return au_di(dentry)->di_bwh; ++} ++ ++static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry) ++{ ++ return au_di(dentry)->di_bdiropq; ++} ++ ++/* todo: hard/soft set? */ ++static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ au_di(dentry)->di_bstart = bindex; ++} ++ ++static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ au_di(dentry)->di_bend = bindex; ++} ++ ++static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ /* dbwh can be outside of bstart - bend range */ ++ au_di(dentry)->di_bwh = bindex; ++} ++ ++static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ au_di(dentry)->di_bdiropq = bindex; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_HINOTIFY ++static inline void au_digen_dec(struct dentry *d) ++{ ++ atomic_dec(&au_di(d)->di_generation); ++} ++ ++static inline void au_hin_di_reinit(struct dentry *dentry) ++{ ++ dentry->d_fsdata = NULL; ++} ++#else ++static inline void au_hin_di_reinit(struct dentry *dentry __maybe_unused) ++{ ++ /* empty */ ++} ++#endif /* CONFIG_AUFS_HINOTIFY */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_DENTRY_H__ */ +diff -Naur a/fs/aufs/dinfo.c b/fs/aufs/dinfo.c +--- a/fs/aufs/dinfo.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/dinfo.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,360 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * dentry private data ++ */ ++ ++#include "aufs.h" ++ ++int au_alloc_dinfo(struct dentry *dentry) ++{ ++ struct au_dinfo *dinfo; ++ struct super_block *sb; ++ int nbr; ++ ++ dinfo = au_cache_alloc_dinfo(); ++ if (unlikely(!dinfo)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ nbr = au_sbend(sb) + 1; ++ if (nbr <= 0) ++ nbr = 1; ++ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS); ++ if (unlikely(!dinfo->di_hdentry)) ++ goto out_dinfo; ++ ++ atomic_set(&dinfo->di_generation, au_sigen(sb)); ++ /* smp_mb(); */ /* atomic_set */ ++ init_rwsem(&dinfo->di_rwsem); ++ down_write_nested(&dinfo->di_rwsem, AuLsc_DI_CHILD); ++ dinfo->di_bstart = -1; ++ dinfo->di_bend = -1; ++ dinfo->di_bwh = -1; ++ dinfo->di_bdiropq = -1; ++ ++ dentry->d_fsdata = dinfo; ++ dentry->d_op = &aufs_dop; ++ return 0; /* success */ ++ ++ out_dinfo: ++ au_cache_free_dinfo(dinfo); ++ out: ++ return -ENOMEM; ++} ++ ++int au_di_realloc(struct au_dinfo *dinfo, int nbr) ++{ ++ int err, sz; ++ struct au_hdentry *hdp; ++ ++ err = -ENOMEM; ++ sz = sizeof(*hdp) * (dinfo->di_bend + 1); ++ if (!sz) ++ sz = sizeof(*hdp); ++ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS); ++ if (hdp) { ++ dinfo->di_hdentry = hdp; ++ err = 0; ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void do_ii_write_lock(struct inode *inode, unsigned int lsc) ++{ ++ switch (lsc) { ++ case AuLsc_DI_CHILD: ++ ii_write_lock_child(inode); ++ break; ++ case AuLsc_DI_CHILD2: ++ ii_write_lock_child2(inode); ++ break; ++ case AuLsc_DI_CHILD3: ++ ii_write_lock_child3(inode); ++ break; ++ case AuLsc_DI_PARENT: ++ ii_write_lock_parent(inode); ++ break; ++ case AuLsc_DI_PARENT2: ++ ii_write_lock_parent2(inode); ++ break; ++ case AuLsc_DI_PARENT3: ++ ii_write_lock_parent3(inode); ++ break; ++ default: ++ BUG(); ++ } ++} ++ ++static void do_ii_read_lock(struct inode *inode, unsigned int lsc) ++{ ++ switch (lsc) { ++ case AuLsc_DI_CHILD: ++ ii_read_lock_child(inode); ++ break; ++ case AuLsc_DI_CHILD2: ++ ii_read_lock_child2(inode); ++ break; ++ case AuLsc_DI_CHILD3: ++ ii_read_lock_child3(inode); ++ break; ++ case AuLsc_DI_PARENT: ++ ii_read_lock_parent(inode); ++ break; ++ case AuLsc_DI_PARENT2: ++ ii_read_lock_parent2(inode); ++ break; ++ case AuLsc_DI_PARENT3: ++ ii_read_lock_parent3(inode); ++ break; ++ default: ++ BUG(); ++ } ++} ++ ++void di_read_lock(struct dentry *d, int flags, unsigned int lsc) ++{ ++ down_read_nested(&au_di(d)->di_rwsem, lsc); ++ if (d->d_inode) { ++ if (au_ftest_lock(flags, IW)) ++ do_ii_write_lock(d->d_inode, lsc); ++ else if (au_ftest_lock(flags, IR)) ++ do_ii_read_lock(d->d_inode, lsc); ++ } ++} ++ ++void di_read_unlock(struct dentry *d, int flags) ++{ ++ if (d->d_inode) { ++ if (au_ftest_lock(flags, IW)) ++ ii_write_unlock(d->d_inode); ++ else if (au_ftest_lock(flags, IR)) ++ ii_read_unlock(d->d_inode); ++ } ++ up_read(&au_di(d)->di_rwsem); ++} ++ ++void di_downgrade_lock(struct dentry *d, int flags) ++{ ++ downgrade_write(&au_di(d)->di_rwsem); ++ if (d->d_inode && au_ftest_lock(flags, IR)) ++ ii_downgrade_lock(d->d_inode); ++} ++ ++void di_write_lock(struct dentry *d, unsigned int lsc) ++{ ++ down_write_nested(&au_di(d)->di_rwsem, lsc); ++ if (d->d_inode) ++ do_ii_write_lock(d->d_inode, lsc); ++} ++ ++void di_write_unlock(struct dentry *d) ++{ ++ if (d->d_inode) ++ ii_write_unlock(d->d_inode); ++ up_write(&au_di(d)->di_rwsem); ++} ++ ++void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir) ++{ ++ AuDebugOn(d1 == d2 ++ || d1->d_inode == d2->d_inode ++ || d1->d_sb != d2->d_sb); ++ ++ if (isdir && au_test_subdir(d1, d2)) { ++ di_write_lock_child(d1); ++ di_write_lock_child2(d2); ++ } else { ++ /* there should be no races */ ++ di_write_lock_child(d2); ++ di_write_lock_child2(d1); ++ } ++} ++ ++void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir) ++{ ++ AuDebugOn(d1 == d2 ++ || d1->d_inode == d2->d_inode ++ || d1->d_sb != d2->d_sb); ++ ++ if (isdir && au_test_subdir(d1, d2)) { ++ di_write_lock_parent(d1); ++ di_write_lock_parent2(d2); ++ } else { ++ /* there should be no races */ ++ di_write_lock_parent(d2); ++ di_write_lock_parent2(d1); ++ } ++} ++ ++void di_write_unlock2(struct dentry *d1, struct dentry *d2) ++{ ++ di_write_unlock(d1); ++ if (d1->d_inode == d2->d_inode) ++ up_write(&au_di(d2)->di_rwsem); ++ else ++ di_write_unlock(d2); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ struct dentry *d; ++ ++ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry)) ++ return NULL; ++ AuDebugOn(bindex < 0); ++ d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry; ++ AuDebugOn(d && (atomic_read(&d->d_count) <= 0)); ++ return d; ++} ++ ++aufs_bindex_t au_dbtail(struct dentry *dentry) ++{ ++ aufs_bindex_t bend, bwh; ++ ++ bend = au_dbend(dentry); ++ if (0 <= bend) { ++ bwh = au_dbwh(dentry); ++ if (!bwh) ++ return bwh; ++ if (0 < bwh && bwh < bend) ++ return bwh - 1; ++ } ++ return bend; ++} ++ ++aufs_bindex_t au_dbtaildir(struct dentry *dentry) ++{ ++ aufs_bindex_t bend, bopq; ++ ++ bend = au_dbtail(dentry); ++ if (0 <= bend) { ++ bopq = au_dbdiropq(dentry); ++ if (0 <= bopq && bopq < bend) ++ bend = bopq; ++ } ++ return bend; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_dentry) ++{ ++ struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex; ++ ++ if (hd->hd_dentry) ++ au_hdput(hd); ++ hd->hd_dentry = h_dentry; ++} ++ ++void au_update_digen(struct dentry *dentry) ++{ ++ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb)); ++ /* smp_mb(); */ /* atomic_set */ ++} ++ ++void au_update_dbrange(struct dentry *dentry, int do_put_zero) ++{ ++ struct au_dinfo *dinfo; ++ struct dentry *h_d; ++ ++ dinfo = au_di(dentry); ++ if (!dinfo || dinfo->di_bstart < 0) ++ return; ++ ++ if (do_put_zero) { ++ aufs_bindex_t bindex, bend; ++ ++ bend = dinfo->di_bend; ++ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) { ++ h_d = dinfo->di_hdentry[0 + bindex].hd_dentry; ++ if (h_d && !h_d->d_inode) ++ au_set_h_dptr(dentry, bindex, NULL); ++ } ++ } ++ ++ dinfo->di_bstart = -1; ++ while (++dinfo->di_bstart <= dinfo->di_bend) ++ if (dinfo->di_hdentry[0 + dinfo->di_bstart].hd_dentry) ++ break; ++ if (dinfo->di_bstart > dinfo->di_bend) { ++ dinfo->di_bstart = -1; ++ dinfo->di_bend = -1; ++ return; ++ } ++ ++ dinfo->di_bend++; ++ while (0 <= --dinfo->di_bend) ++ if (dinfo->di_hdentry[0 + dinfo->di_bend].hd_dentry) ++ break; ++ AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0); ++} ++ ++void au_update_dbstart(struct dentry *dentry) ++{ ++ aufs_bindex_t bindex, bend; ++ struct dentry *h_dentry; ++ ++ bend = au_dbend(dentry); ++ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ if (h_dentry->d_inode) { ++ au_set_dbstart(dentry, bindex); ++ return; ++ } ++ au_set_h_dptr(dentry, bindex, NULL); ++ } ++} ++ ++void au_update_dbend(struct dentry *dentry) ++{ ++ aufs_bindex_t bindex, bstart; ++ struct dentry *h_dentry; ++ ++ bstart = au_dbstart(dentry); ++ for (bindex = au_dbend(dentry); bindex <= bstart; bindex--) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ if (h_dentry->d_inode) { ++ au_set_dbend(dentry, bindex); ++ return; ++ } ++ au_set_h_dptr(dentry, bindex, NULL); ++ } ++} ++ ++int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry) ++{ ++ aufs_bindex_t bindex, bend; ++ ++ bend = au_dbend(dentry); ++ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) ++ if (au_h_dptr(dentry, bindex) == h_dentry) ++ return bindex; ++ return -1; ++} +diff -Naur a/fs/aufs/dir.c b/fs/aufs/dir.c +--- a/fs/aufs/dir.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/dir.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,532 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * directory operations ++ */ ++ ++#include ++#include ++#include "aufs.h" ++ ++void au_add_nlink(struct inode *dir, struct inode *h_dir) ++{ ++ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); ++ ++ dir->i_nlink += h_dir->i_nlink - 2; ++ if (h_dir->i_nlink < 2) ++ dir->i_nlink += 2; ++} ++ ++void au_sub_nlink(struct inode *dir, struct inode *h_dir) ++{ ++ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); ++ ++ dir->i_nlink -= h_dir->i_nlink - 2; ++ if (h_dir->i_nlink < 2) ++ dir->i_nlink -= 2; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int reopen_dir(struct file *file) ++{ ++ int err; ++ unsigned int flags; ++ aufs_bindex_t bindex, btail, bstart; ++ struct dentry *dentry, *h_dentry; ++ struct file *h_file; ++ ++ /* open all lower dirs */ ++ dentry = file->f_dentry; ++ bstart = au_dbstart(dentry); ++ for (bindex = au_fbstart(file); bindex < bstart; bindex++) ++ au_set_h_fptr(file, bindex, NULL); ++ au_set_fbstart(file, bstart); ++ ++ btail = au_dbtaildir(dentry); ++ for (bindex = au_fbend(file); btail < bindex; bindex--) ++ au_set_h_fptr(file, bindex, NULL); ++ au_set_fbend(file, btail); ++ ++ flags = file->f_flags; ++ for (bindex = bstart; bindex <= btail; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ h_file = au_h_fptr(file, bindex); ++ if (h_file) ++ continue; ++ ++ h_file = au_h_open(dentry, bindex, flags, file); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; /* close all? */ ++ au_set_h_fptr(file, bindex, h_file); ++ } ++ au_update_figen(file); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ err = 0; ++ ++ out: ++ return err; ++} ++ ++static int do_open_dir(struct file *file, int flags) ++{ ++ int err; ++ aufs_bindex_t bindex, btail; ++ struct dentry *dentry, *h_dentry; ++ struct file *h_file; ++ ++ err = 0; ++ dentry = file->f_dentry; ++ au_set_fvdir_cache(file, NULL); ++ au_fi(file)->fi_maintain_plink = 0; ++ file->f_version = dentry->d_inode->i_version; ++ bindex = au_dbstart(dentry); ++ au_set_fbstart(file, bindex); ++ btail = au_dbtaildir(dentry); ++ au_set_fbend(file, btail); ++ for (; !err && bindex <= btail; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ ++ h_file = au_h_open(dentry, bindex, flags, file); ++ if (IS_ERR(h_file)) { ++ err = PTR_ERR(h_file); ++ break; ++ } ++ au_set_h_fptr(file, bindex, h_file); ++ } ++ au_update_figen(file); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ if (!err) ++ return 0; /* success */ ++ ++ /* close all */ ++ for (bindex = au_fbstart(file); bindex <= btail; bindex++) ++ au_set_h_fptr(file, bindex, NULL); ++ au_set_fbstart(file, -1); ++ au_set_fbend(file, -1); ++ return err; ++} ++ ++static int aufs_open_dir(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ return au_do_open(file, do_open_dir); ++} ++ ++static int aufs_release_dir(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ struct au_vdir *vdir_cache; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ ++ sb = file->f_dentry->d_sb; ++ si_noflush_read_lock(sb); ++ fi_write_lock(file); ++ vdir_cache = au_fvdir_cache(file); ++ if (vdir_cache) ++ au_vdir_free(vdir_cache); ++ if (au_fi(file)->fi_maintain_plink) { ++ sbinfo = au_sbi(sb); ++ au_fclr_si(sbinfo, MAINTAIN_PLINK); ++ wake_up_all(&sbinfo->si_plink_wq); ++ } ++ fi_write_unlock(file); ++ au_finfo_fin(file); ++ si_read_unlock(sb); ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct inode *inode; ++ struct super_block *sb; ++ ++ err = 0; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ IMustLock(inode); ++ bend = au_dbend(dentry); ++ for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) { ++ struct path h_path; ++ struct inode *h_inode; ++ ++ if (au_test_ro(sb, bindex, inode)) ++ continue; ++ h_path.dentry = au_h_dptr(dentry, bindex); ++ if (!h_path.dentry) ++ continue; ++ h_inode = h_path.dentry->d_inode; ++ if (!h_inode) ++ continue; ++ ++ /* no mnt_want_write() */ ++ /* cf. fs/nsfd/vfs.c and fs/nfsd/nfs4recover.c */ ++ /* todo: inotiry fired? */ ++ h_path.mnt = au_sbr_mnt(sb, bindex); ++ mutex_lock(&h_inode->i_mutex); ++ err = filemap_fdatawrite(h_inode->i_mapping); ++ AuDebugOn(!h_inode->i_fop); ++ if (!err && h_inode->i_fop->fsync) ++ err = h_inode->i_fop->fsync(NULL, h_path.dentry, ++ datasync); ++ if (!err) ++ err = filemap_fdatawrite(h_inode->i_mapping); ++ if (!err) ++ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/ ++ mutex_unlock(&h_inode->i_mutex); ++ } ++ ++ return err; ++} ++ ++static int au_do_fsync_dir(struct file *file, int datasync) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct file *h_file; ++ struct super_block *sb; ++ struct inode *inode; ++ struct mutex *h_mtx; ++ ++ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ sb = file->f_dentry->d_sb; ++ inode = file->f_dentry->d_inode; ++ bend = au_fbend(file); ++ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) { ++ h_file = au_h_fptr(file, bindex); ++ if (!h_file || au_test_ro(sb, bindex, inode)) ++ continue; ++ ++ err = vfs_fsync(h_file, h_file->f_dentry, datasync); ++ if (!err) { ++ h_mtx = &h_file->f_dentry->d_inode->i_mutex; ++ mutex_lock(h_mtx); ++ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); ++ /*ignore*/ ++ mutex_unlock(h_mtx); ++ } ++ } ++ ++ out: ++ return err; ++} ++ ++/* ++ * @file may be NULL ++ */ ++static int aufs_fsync_dir(struct file *file, struct dentry *dentry, ++ int datasync) ++{ ++ int err; ++ struct super_block *sb; ++ ++ IMustLock(dentry->d_inode); ++ ++ err = 0; ++ sb = dentry->d_sb; ++ si_noflush_read_lock(sb); ++ if (file) ++ err = au_do_fsync_dir(file, datasync); ++ else { ++ di_write_lock_child(dentry); ++ err = au_do_fsync_dir_no_file(dentry, datasync); ++ } ++ au_cpup_attr_timesizes(dentry->d_inode); ++ di_write_unlock(dentry); ++ if (file) ++ fi_write_unlock(file); ++ ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int aufs_readdir(struct file *file, void *dirent, filldir_t filldir) ++{ ++ int err; ++ struct dentry *dentry; ++ struct inode *inode; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ inode = dentry->d_inode; ++ IMustLock(inode); ++ ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ err = au_vdir_init(file); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ if (!au_test_nfsd(current)) { ++ err = au_vdir_fill_de(file, dirent, filldir); ++ fsstack_copy_attr_atime(inode, ++ au_h_iptr(inode, au_ibstart(inode))); ++ } else { ++ /* ++ * nfsd filldir may call lookup_one_len(), vfs_getattr(), ++ * encode_fh() and others. ++ */ ++ struct inode *h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ ++ di_read_unlock(dentry, AuLock_IR); ++ si_read_unlock(sb); ++ lockdep_off(); ++ err = au_vdir_fill_de(file, dirent, filldir); ++ lockdep_on(); ++ fsstack_copy_attr_atime(inode, h_inode); ++ fi_write_unlock(file); ++ ++ AuTraceErr(err); ++ return err; ++ } ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define AuTestEmpty_WHONLY 1 ++#define AuTestEmpty_CALLED (1 << 1) ++#define AuTestEmpty_SHWH (1 << 2) ++#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name) ++#define au_fset_testempty(flags, name) { (flags) |= AuTestEmpty_##name; } ++#define au_fclr_testempty(flags, name) { (flags) &= ~AuTestEmpty_##name; } ++ ++#ifndef CONFIG_AUFS_SHWH ++#undef AuTestEmpty_SHWH ++#define AuTestEmpty_SHWH 0 ++#endif ++ ++struct test_empty_arg { ++ struct au_nhash whlist; ++ unsigned int flags; ++ int err; ++ aufs_bindex_t bindex; ++}; ++ ++static int test_empty_cb(void *__arg, const char *__name, int namelen, ++ loff_t offset __maybe_unused, u64 ino, ++ unsigned int d_type) ++{ ++ struct test_empty_arg *arg = __arg; ++ char *name = (void *)__name; ++ ++ arg->err = 0; ++ au_fset_testempty(arg->flags, CALLED); ++ /* smp_mb(); */ ++ if (name[0] == '.' ++ && (namelen == 1 || (name[1] == '.' && namelen == 2))) ++ goto out; /* success */ ++ ++ if (namelen <= AUFS_WH_PFX_LEN ++ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { ++ if (au_ftest_testempty(arg->flags, WHONLY) ++ && !au_nhash_test_known_wh(&arg->whlist, name, namelen)) ++ arg->err = -ENOTEMPTY; ++ goto out; ++ } ++ ++ name += AUFS_WH_PFX_LEN; ++ namelen -= AUFS_WH_PFX_LEN; ++ if (!au_nhash_test_known_wh(&arg->whlist, name, namelen)) ++ arg->err = au_nhash_append_wh ++ (&arg->whlist, name, namelen, ino, d_type, arg->bindex, ++ au_ftest_testempty(arg->flags, SHWH)); ++ ++ out: ++ /* smp_mb(); */ ++ AuTraceErr(arg->err); ++ return arg->err; ++} ++ ++static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg) ++{ ++ int err; ++ struct file *h_file; ++ ++ h_file = au_h_open(dentry, arg->bindex, ++ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE, ++ /*file*/NULL); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; ++ ++ err = 0; ++ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE) ++ && !h_file->f_dentry->d_inode->i_nlink) ++ goto out_put; ++ ++ do { ++ arg->err = 0; ++ au_fclr_testempty(arg->flags, CALLED); ++ /* smp_mb(); */ ++ err = vfsub_readdir(h_file, test_empty_cb, arg); ++ if (err >= 0) ++ err = arg->err; ++ } while (!err && au_ftest_testempty(arg->flags, CALLED)); ++ ++ out_put: ++ fput(h_file); ++ au_sbr_put(dentry->d_sb, arg->bindex); ++ out: ++ return err; ++} ++ ++struct do_test_empty_args { ++ int *errp; ++ struct dentry *dentry; ++ struct test_empty_arg *arg; ++}; ++ ++static void call_do_test_empty(void *args) ++{ ++ struct do_test_empty_args *a = args; ++ *a->errp = do_test_empty(a->dentry, a->arg); ++} ++ ++static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg) ++{ ++ int err, wkq_err; ++ struct dentry *h_dentry; ++ struct inode *h_inode; ++ ++ h_dentry = au_h_dptr(dentry, arg->bindex); ++ h_inode = h_dentry->d_inode; ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ); ++ mutex_unlock(&h_inode->i_mutex); ++ if (!err) ++ err = do_test_empty(dentry, arg); ++ else { ++ struct do_test_empty_args args = { ++ .errp = &err, ++ .dentry = dentry, ++ .arg = arg ++ }; ++ unsigned int flags = arg->flags; ++ ++ wkq_err = au_wkq_wait(call_do_test_empty, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ arg->flags = flags; ++ } ++ ++ return err; ++} ++ ++int au_test_empty_lower(struct dentry *dentry) ++{ ++ int err; ++ aufs_bindex_t bindex, bstart, btail; ++ struct test_empty_arg arg; ++ ++ err = au_nhash_alloc(&arg.whlist, au_sbi(dentry->d_sb)->si_rdhash, ++ GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ ++ bstart = au_dbstart(dentry); ++ arg.flags = 0; ++ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)) ++ au_fset_testempty(arg.flags, SHWH); ++ arg.bindex = bstart; ++ err = do_test_empty(dentry, &arg); ++ if (unlikely(err)) ++ goto out_whlist; ++ ++ au_fset_testempty(arg.flags, WHONLY); ++ btail = au_dbtaildir(dentry); ++ for (bindex = bstart + 1; !err && bindex <= btail; bindex++) { ++ struct dentry *h_dentry; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry && h_dentry->d_inode) { ++ arg.bindex = bindex; ++ err = do_test_empty(dentry, &arg); ++ } ++ } ++ ++ out_whlist: ++ au_nhash_wh_free(&arg.whlist); ++ out: ++ return err; ++} ++ ++int au_test_empty(struct dentry *dentry, struct au_nhash *whlist) ++{ ++ int err; ++ struct test_empty_arg arg; ++ aufs_bindex_t bindex, btail; ++ ++ err = 0; ++ arg.whlist = *whlist; ++ arg.flags = AuTestEmpty_WHONLY; ++ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)) ++ au_fset_testempty(arg.flags, SHWH); ++ btail = au_dbtaildir(dentry); ++ for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) { ++ struct dentry *h_dentry; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry && h_dentry->d_inode) { ++ arg.bindex = bindex; ++ err = sio_test_empty(dentry, &arg); ++ } ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++const struct file_operations aufs_dir_fop = { ++ .read = generic_read_dir, ++ .readdir = aufs_readdir, ++ .unlocked_ioctl = aufs_ioctl_dir, ++ .open = aufs_open_dir, ++ .release = aufs_release_dir, ++ .flush = aufs_flush, ++ .fsync = aufs_fsync_dir ++}; +diff -Naur a/fs/aufs/dir.h b/fs/aufs/dir.h +--- a/fs/aufs/dir.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/dir.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,114 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * directory operations ++ */ ++ ++#ifndef __AUFS_DIR_H__ ++#define __AUFS_DIR_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* need to be faster and smaller */ ++ ++struct au_nhash { ++ unsigned int nh_num; ++ struct hlist_head *nh_head; ++}; ++ ++struct au_vdir_destr { ++ unsigned char len; ++ unsigned char name[0]; ++} __packed; ++ ++struct au_vdir_dehstr { ++ struct hlist_node hash; ++ struct au_vdir_destr *str; ++}; ++ ++struct au_vdir_de { ++ ino_t de_ino; ++ unsigned char de_type; ++ /* caution: packed */ ++ struct au_vdir_destr de_str; ++} __packed; ++ ++struct au_vdir_wh { ++ struct hlist_node wh_hash; ++#ifdef CONFIG_AUFS_SHWH ++ ino_t wh_ino; ++ aufs_bindex_t wh_bindex; ++ unsigned char wh_type; ++#else ++ aufs_bindex_t wh_bindex; ++#endif ++ /* caution: packed */ ++ struct au_vdir_destr wh_str; ++} __packed; ++ ++union au_vdir_deblk_p { ++ unsigned char *deblk; ++ struct au_vdir_de *de; ++}; ++ ++struct au_vdir { ++ unsigned char **vd_deblk; ++ unsigned long vd_nblk; ++ struct { ++ unsigned long ul; ++ union au_vdir_deblk_p p; ++ } vd_last; ++ ++ unsigned long vd_version; ++ unsigned int vd_deblk_sz; ++ unsigned long vd_jiffy; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* dir.c */ ++extern const struct file_operations aufs_dir_fop; ++void au_add_nlink(struct inode *dir, struct inode *h_dir); ++void au_sub_nlink(struct inode *dir, struct inode *h_dir); ++int au_test_empty_lower(struct dentry *dentry); ++int au_test_empty(struct dentry *dentry, struct au_nhash *whlist); ++ ++/* vdir.c */ ++int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp); ++void au_nhash_wh_free(struct au_nhash *whlist); ++int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt, ++ int limit); ++int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen); ++int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino, ++ unsigned int d_type, aufs_bindex_t bindex, ++ unsigned char shwh); ++void au_vdir_free(struct au_vdir *vdir); ++int au_vdir_init(struct file *file); ++int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir); ++ ++/* ioctl.c */ ++long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg); ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_DIR_H__ */ +diff -Naur a/fs/aufs/export.c b/fs/aufs/export.c +--- a/fs/aufs/export.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/export.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,736 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * export via nfs ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++union conv { ++#ifdef CONFIG_AUFS_INO_T_64 ++ __u32 a[2]; ++#else ++ __u32 a[1]; ++#endif ++ ino_t ino; ++}; ++ ++static ino_t decode_ino(__u32 *a) ++{ ++ union conv u; ++ ++ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a)); ++ u.a[0] = a[0]; ++#ifdef CONFIG_AUFS_INO_T_64 ++ u.a[1] = a[1]; ++#endif ++ return u.ino; ++} ++ ++static void encode_ino(__u32 *a, ino_t ino) ++{ ++ union conv u; ++ ++ u.ino = ino; ++ a[0] = u.a[0]; ++#ifdef CONFIG_AUFS_INO_T_64 ++ a[1] = u.a[1]; ++#endif ++} ++ ++/* NFS file handle */ ++enum { ++ Fh_br_id, ++ Fh_sigen, ++#ifdef CONFIG_AUFS_INO_T_64 ++ /* support 64bit inode number */ ++ Fh_ino1, ++ Fh_ino2, ++ Fh_dir_ino1, ++ Fh_dir_ino2, ++#else ++ Fh_ino1, ++ Fh_dir_ino1, ++#endif ++ Fh_igen, ++ Fh_h_type, ++ Fh_tail, ++ ++ Fh_ino = Fh_ino1, ++ Fh_dir_ino = Fh_dir_ino1 ++}; ++ ++static int au_test_anon(struct dentry *dentry) ++{ ++ return !!(dentry->d_flags & DCACHE_DISCONNECTED); ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* inode generation external table */ ++ ++int au_xigen_inc(struct inode *inode) ++{ ++ int err; ++ loff_t pos; ++ ssize_t sz; ++ __u32 igen; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ ++ err = 0; ++ sb = inode->i_sb; ++ if (unlikely(!au_opt_test(au_mntflags(sb), XINO))) ++ goto out; ++ ++ pos = inode->i_ino; ++ pos *= sizeof(igen); ++ igen = inode->i_generation + 1; ++ sbinfo = au_sbi(sb); ++ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen, ++ sizeof(igen), &pos); ++ if (sz == sizeof(igen)) ++ goto out; /* success */ ++ ++ err = sz; ++ if (unlikely(sz >= 0)) { ++ err = -EIO; ++ AuIOErr("xigen error (%zd)\n", sz); ++ } ++ ++ out: ++ return err; ++} ++ ++int au_xigen_new(struct inode *inode) ++{ ++ int err; ++ loff_t pos; ++ ssize_t sz; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ ++ err = 0; ++ /* todo: dirty, at mount time */ ++ if (inode->i_ino == AUFS_ROOT_INO) ++ goto out; ++ sb = inode->i_sb; ++ if (unlikely(!au_opt_test(au_mntflags(sb), XINO))) ++ goto out; ++ ++ err = -EFBIG; ++ pos = inode->i_ino; ++ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) { ++ AuIOErr1("too large i%lld\n", pos); ++ goto out; ++ } ++ pos *= sizeof(inode->i_generation); ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ file = sbinfo->si_xigen; ++ BUG_ON(!file); ++ ++ if (i_size_read(file->f_dentry->d_inode) ++ < pos + sizeof(inode->i_generation)) { ++ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next); ++ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation, ++ sizeof(inode->i_generation), &pos); ++ } else ++ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation, ++ sizeof(inode->i_generation), &pos); ++ if (sz == sizeof(inode->i_generation)) ++ goto out; /* success */ ++ ++ err = sz; ++ if (unlikely(sz >= 0)) { ++ err = -EIO; ++ AuIOErr("xigen error (%zd)\n", sz); ++ } ++ ++ out: ++ return err; ++} ++ ++int au_xigen_set(struct super_block *sb, struct file *base) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ ++ sbinfo = au_sbi(sb); ++ file = au_xino_create2(base, sbinfo->si_xigen); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ err = 0; ++ if (sbinfo->si_xigen) ++ fput(sbinfo->si_xigen); ++ sbinfo->si_xigen = file; ++ ++ out: ++ return err; ++} ++ ++void au_xigen_clr(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ sbinfo = au_sbi(sb); ++ if (sbinfo->si_xigen) { ++ fput(sbinfo->si_xigen); ++ sbinfo->si_xigen = NULL; ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino, ++ ino_t dir_ino) ++{ ++ struct dentry *dentry, *d; ++ struct inode *inode; ++ unsigned int sigen; ++ ++ dentry = NULL; ++ inode = ilookup(sb, ino); ++ if (!inode) ++ goto out; ++ ++ dentry = ERR_PTR(-ESTALE); ++ sigen = au_sigen(sb); ++ if (unlikely(is_bad_inode(inode) ++ || IS_DEADDIR(inode) ++ || sigen != au_iigen(inode))) ++ goto out_iput; ++ ++ dentry = NULL; ++ if (!dir_ino || S_ISDIR(inode->i_mode)) ++ dentry = d_find_alias(inode); ++ else { ++ spin_lock(&dcache_lock); ++ list_for_each_entry(d, &inode->i_dentry, d_alias) ++ if (!au_test_anon(d) ++ && d->d_parent->d_inode->i_ino == dir_ino) { ++ dentry = dget_locked(d); ++ break; ++ } ++ spin_unlock(&dcache_lock); ++ } ++ if (unlikely(dentry && sigen != au_digen(dentry))) { ++ dput(dentry); ++ dentry = ERR_PTR(-ESTALE); ++ } ++ ++ out_iput: ++ iput(inode); ++ out: ++ return dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* todo: dirty? */ ++/* if exportfs_decode_fh() passed vfsmount*, we could be happy */ ++static struct vfsmount *au_mnt_get(struct super_block *sb) ++{ ++ struct mnt_namespace *ns; ++ struct vfsmount *pos, *mnt; ++ ++ spin_lock(&vfsmount_lock); ++ /* no get/put ?? */ ++ AuDebugOn(!current->nsproxy); ++ ns = current->nsproxy->mnt_ns; ++ AuDebugOn(!ns); ++ mnt = NULL; ++ /* the order (reverse) will not be a problem */ ++ list_for_each_entry(pos, &ns->list, mnt_list) ++ if (pos->mnt_sb == sb) { ++ mnt = mntget(pos); ++ break; ++ } ++ spin_unlock(&vfsmount_lock); ++ AuDebugOn(!mnt); ++ ++ return mnt; ++} ++ ++struct au_nfsd_si_lock { ++ const unsigned int sigen; ++ const aufs_bindex_t br_id; ++ unsigned char force_lock; ++}; ++ ++static aufs_bindex_t si_nfsd_read_lock(struct super_block *sb, ++ struct au_nfsd_si_lock *nsi_lock) ++{ ++ aufs_bindex_t bindex; ++ ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ /* branch id may be wrapped around */ ++ bindex = au_br_index(sb, nsi_lock->br_id); ++ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb)) ++ goto out; /* success */ ++ ++ if (!nsi_lock->force_lock) ++ si_read_unlock(sb); ++ bindex = -1; ++ ++ out: ++ return bindex; ++} ++ ++struct find_name_by_ino { ++ int called, found; ++ ino_t ino; ++ char *name; ++ int namelen; ++}; ++ ++static int ++find_name_by_ino(void *arg, const char *name, int namelen, loff_t offset, ++ u64 ino, unsigned int d_type) ++{ ++ struct find_name_by_ino *a = arg; ++ ++ a->called++; ++ if (a->ino != ino) ++ return 0; ++ ++ memcpy(a->name, name, namelen); ++ a->namelen = namelen; ++ a->found = 1; ++ return 1; ++} ++ ++static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino, ++ struct au_nfsd_si_lock *nsi_lock) ++{ ++ struct dentry *dentry, *parent; ++ struct file *file; ++ struct inode *dir; ++ struct find_name_by_ino arg; ++ int err; ++ ++ parent = path->dentry; ++ if (nsi_lock) ++ si_read_unlock(parent->d_sb); ++ path_get(path); ++ file = dentry_open(parent, path->mnt, au_dir_roflags, current_cred()); ++ dentry = (void *)file; ++ if (IS_ERR(file)) ++ goto out; ++ ++ dentry = ERR_PTR(-ENOMEM); ++ arg.name = __getname(); ++ if (unlikely(!arg.name)) ++ goto out_file; ++ arg.ino = ino; ++ arg.found = 0; ++ do { ++ arg.called = 0; ++ /* smp_mb(); */ ++ err = vfsub_readdir(file, find_name_by_ino, &arg); ++ } while (!err && !arg.found && arg.called); ++ dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out_name; ++ dentry = ERR_PTR(-ENOENT); ++ if (!arg.found) ++ goto out_name; ++ ++ /* do not call au_lkup_one() */ ++ dir = parent->d_inode; ++ mutex_lock(&dir->i_mutex); ++ dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen); ++ mutex_unlock(&dir->i_mutex); ++ AuTraceErrPtr(dentry); ++ if (IS_ERR(dentry)) ++ goto out_name; ++ AuDebugOn(au_test_anon(dentry)); ++ if (unlikely(!dentry->d_inode)) { ++ dput(dentry); ++ dentry = ERR_PTR(-ENOENT); ++ } ++ ++ out_name: ++ __putname(arg.name); ++ out_file: ++ fput(file); ++ out: ++ if (unlikely(nsi_lock ++ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0)) ++ if (!IS_ERR(dentry)) { ++ dput(dentry); ++ dentry = ERR_PTR(-ESTALE); ++ } ++ AuTraceErrPtr(dentry); ++ return dentry; ++} ++ ++static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino, ++ ino_t dir_ino, ++ struct au_nfsd_si_lock *nsi_lock) ++{ ++ struct dentry *dentry; ++ struct path path; ++ ++ if (dir_ino != AUFS_ROOT_INO) { ++ path.dentry = decode_by_ino(sb, dir_ino, 0); ++ dentry = path.dentry; ++ if (!path.dentry || IS_ERR(path.dentry)) ++ goto out; ++ AuDebugOn(au_test_anon(path.dentry)); ++ } else ++ path.dentry = dget(sb->s_root); ++ ++ path.mnt = au_mnt_get(sb); ++ dentry = au_lkup_by_ino(&path, ino, nsi_lock); ++ path_put(&path); ++ ++ out: ++ AuTraceErrPtr(dentry); ++ return dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int h_acceptable(void *expv, struct dentry *dentry) ++{ ++ return 1; ++} ++ ++static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath, ++ char *buf, int len, struct super_block *sb) ++{ ++ char *p; ++ int n; ++ struct path path; ++ ++ p = d_path(h_rootpath, buf, len); ++ if (IS_ERR(p)) ++ goto out; ++ n = strlen(p); ++ ++ path.mnt = h_rootpath->mnt; ++ path.dentry = h_parent; ++ p = d_path(&path, buf, len); ++ if (IS_ERR(p)) ++ goto out; ++ if (n != 1) ++ p += n; ++ ++ path.mnt = au_mnt_get(sb); ++ path.dentry = sb->s_root; ++ p = d_path(&path, buf, len - strlen(p)); ++ mntput(path.mnt); ++ if (IS_ERR(p)) ++ goto out; ++ if (n != 1) ++ p[strlen(p)] = '/'; ++ ++ out: ++ AuTraceErrPtr(p); ++ return p; ++} ++ ++static ++struct dentry *decode_by_path(struct super_block *sb, aufs_bindex_t bindex, ++ ino_t ino, __u32 *fh, int fh_len, ++ struct au_nfsd_si_lock *nsi_lock) ++{ ++ struct dentry *dentry, *h_parent, *root; ++ struct super_block *h_sb; ++ char *pathname, *p; ++ struct vfsmount *h_mnt; ++ struct au_branch *br; ++ int err; ++ struct path path; ++ ++ br = au_sbr(sb, bindex); ++ /* au_br_get(br); */ ++ h_mnt = br->br_mnt; ++ h_sb = h_mnt->mnt_sb; ++ /* todo: call lower fh_to_dentry()? fh_to_parent()? */ ++ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail), ++ fh_len - Fh_tail, fh[Fh_h_type], ++ h_acceptable, /*context*/NULL); ++ dentry = h_parent; ++ if (unlikely(!h_parent || IS_ERR(h_parent))) { ++ AuWarn1("%s decode_fh failed, %ld\n", ++ au_sbtype(h_sb), PTR_ERR(h_parent)); ++ goto out; ++ } ++ dentry = NULL; ++ if (unlikely(au_test_anon(h_parent))) { ++ AuWarn1("%s decode_fh returned a disconnected dentry\n", ++ au_sbtype(h_sb)); ++ goto out_h_parent; ++ } ++ ++ dentry = ERR_PTR(-ENOMEM); ++ pathname = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!pathname)) ++ goto out_h_parent; ++ ++ root = sb->s_root; ++ path.mnt = h_mnt; ++ di_read_lock_parent(root, !AuLock_IR); ++ path.dentry = au_h_dptr(root, bindex); ++ di_read_unlock(root, !AuLock_IR); ++ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb); ++ dentry = (void *)p; ++ if (IS_ERR(p)) ++ goto out_pathname; ++ ++ si_read_unlock(sb); ++ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path); ++ dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out_relock; ++ ++ dentry = ERR_PTR(-ENOENT); ++ AuDebugOn(au_test_anon(path.dentry)); ++ if (unlikely(!path.dentry->d_inode)) ++ goto out_path; ++ ++ if (ino != path.dentry->d_inode->i_ino) ++ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL); ++ else ++ dentry = dget(path.dentry); ++ ++ out_path: ++ path_put(&path); ++ out_relock: ++ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0)) ++ if (!IS_ERR(dentry)) { ++ dput(dentry); ++ dentry = ERR_PTR(-ESTALE); ++ } ++ out_pathname: ++ free_page((unsigned long)pathname); ++ out_h_parent: ++ dput(h_parent); ++ out: ++ /* au_br_put(br); */ ++ AuTraceErrPtr(dentry); ++ return dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct dentry * ++aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, ++ int fh_type) ++{ ++ struct dentry *dentry; ++ __u32 *fh = fid->raw; ++ ino_t ino, dir_ino; ++ aufs_bindex_t bindex; ++ struct au_nfsd_si_lock nsi_lock = { ++ .sigen = fh[Fh_sigen], ++ .br_id = fh[Fh_br_id], ++ .force_lock = 0 ++ }; ++ ++ AuDebugOn(fh_len < Fh_tail); ++ ++ dentry = ERR_PTR(-ESTALE); ++ /* branch id may be wrapped around */ ++ bindex = si_nfsd_read_lock(sb, &nsi_lock); ++ if (unlikely(bindex < 0)) ++ goto out; ++ nsi_lock.force_lock = 1; ++ ++ /* is this inode still cached? */ ++ ino = decode_ino(fh + Fh_ino); ++ AuDebugOn(ino == AUFS_ROOT_INO); ++ dir_ino = decode_ino(fh + Fh_dir_ino); ++ dentry = decode_by_ino(sb, ino, dir_ino); ++ if (IS_ERR(dentry)) ++ goto out_unlock; ++ if (dentry) ++ goto accept; ++ ++ /* is the parent dir cached? */ ++ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock); ++ if (IS_ERR(dentry)) ++ goto out_unlock; ++ if (dentry) ++ goto accept; ++ ++ /* lookup path */ ++ dentry = decode_by_path(sb, bindex, ino, fh, fh_len, &nsi_lock); ++ if (IS_ERR(dentry)) ++ goto out_unlock; ++ if (unlikely(!dentry)) ++ /* todo?: make it ESTALE */ ++ goto out_unlock; ++ ++ accept: ++ if (dentry->d_inode->i_generation == fh[Fh_igen]) ++ goto out_unlock; /* success */ ++ ++ dput(dentry); ++ dentry = ERR_PTR(-ESTALE); ++ out_unlock: ++ si_read_unlock(sb); ++ out: ++ AuTraceErrPtr(dentry); ++ return dentry; ++} ++ ++#if 0 /* reserved for future use */ ++/* support subtreecheck option */ ++static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid, ++ int fh_len, int fh_type) ++{ ++ struct dentry *parent; ++ __u32 *fh = fid->raw; ++ ino_t dir_ino; ++ ++ dir_ino = decode_ino(fh + Fh_dir_ino); ++ parent = decode_by_ino(sb, dir_ino, 0); ++ if (IS_ERR(parent)) ++ goto out; ++ if (!parent) ++ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]), ++ dir_ino, fh, fh_len); ++ ++ out: ++ AuTraceErrPtr(parent); ++ return parent; ++} ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int aufs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len, ++ int connectable) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ struct super_block *sb, *h_sb; ++ struct inode *inode; ++ struct dentry *parent, *h_parent; ++ struct au_branch *br; ++ ++ AuDebugOn(au_test_anon(dentry)); ++ ++ parent = NULL; ++ err = -ENOSPC; ++ if (unlikely(*max_len <= Fh_tail)) { ++ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len); ++ goto out; ++ } ++ ++ err = FILEID_ROOT; ++ if (IS_ROOT(dentry)) { ++ AuDebugOn(dentry->d_inode->i_ino != AUFS_ROOT_INO); ++ goto out; ++ } ++ ++ err = -EIO; ++ h_parent = NULL; ++ sb = dentry->d_sb; ++ aufs_read_lock(dentry, AuLock_FLUSH | AuLock_IR); ++ parent = dget_parent(dentry); ++ di_read_lock_parent(parent, !AuLock_IR); ++ inode = dentry->d_inode; ++ AuDebugOn(!inode); ++#ifdef CONFIG_AUFS_DEBUG ++ if (unlikely(!au_opt_test(au_mntflags(sb), XINO))) ++ AuWarn1("NFS-exporting requires xino\n"); ++#endif ++ ++ bend = au_dbtaildir(parent); ++ for (bindex = au_dbstart(parent); bindex <= bend; bindex++) { ++ h_parent = au_h_dptr(parent, bindex); ++ if (h_parent) { ++ dget(h_parent); ++ break; ++ } ++ } ++ if (unlikely(!h_parent)) ++ goto out_unlock; ++ ++ err = -EPERM; ++ br = au_sbr(sb, bindex); ++ h_sb = br->br_mnt->mnt_sb; ++ if (unlikely(!h_sb->s_export_op)) { ++ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb)); ++ goto out_dput; ++ } ++ ++ fh[Fh_br_id] = br->br_id; ++ fh[Fh_sigen] = au_sigen(sb); ++ encode_ino(fh + Fh_ino, inode->i_ino); ++ encode_ino(fh + Fh_dir_ino, parent->d_inode->i_ino); ++ fh[Fh_igen] = inode->i_generation; ++ ++ *max_len -= Fh_tail; ++ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail), ++ max_len, ++ /*connectable or subtreecheck*/0); ++ err = fh[Fh_h_type]; ++ *max_len += Fh_tail; ++ /* todo: macros? */ ++ if (err != 255) ++ err = 99; ++ else ++ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb)); ++ ++ out_dput: ++ dput(h_parent); ++ out_unlock: ++ di_read_unlock(parent, !AuLock_IR); ++ dput(parent); ++ aufs_read_unlock(dentry, AuLock_IR); ++ out: ++ if (unlikely(err < 0)) ++ err = 255; ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct export_operations aufs_export_op = { ++ .fh_to_dentry = aufs_fh_to_dentry, ++ /* .fh_to_parent = aufs_fh_to_parent, */ ++ .encode_fh = aufs_encode_fh ++}; ++ ++void au_export_init(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ __u32 u; ++ ++ sb->s_export_op = &aufs_export_op; ++ sbinfo = au_sbi(sb); ++ sbinfo->si_xigen = NULL; ++ get_random_bytes(&u, sizeof(u)); ++ BUILD_BUG_ON(sizeof(u) != sizeof(int)); ++ atomic_set(&sbinfo->si_xigen_next, u); ++} +diff -Naur a/fs/aufs/file.c b/fs/aufs/file.c +--- a/fs/aufs/file.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/file.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,568 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * handling file/dir, and address_space operation ++ */ ++ ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++/* ++ * a dirty trick for handling deny_write_access(). ++ * because FMODE_EXEC flag is not passed to f_op->open(), ++ * set it to file->private_data temporary. ++ */ ++void au_store_oflag(struct nameidata *nd, struct inode *inode) ++{ ++ if (nd ++ /* && !(nd->flags & LOOKUP_CONTINUE) */ ++ && (nd->flags & LOOKUP_OPEN) ++ && (nd->intent.open.flags & vfsub_fmode_to_uint(FMODE_EXEC)) ++ && inode ++ && S_ISREG(inode->i_mode)) { ++ /* suppress a warning in lp64 */ ++ unsigned long flags = nd->intent.open.flags; ++ nd->intent.open.file->private_data = (void *)flags; ++ /* smp_mb(); */ ++ } ++} ++ ++/* drop flags for writing */ ++unsigned int au_file_roflags(unsigned int flags) ++{ ++ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC); ++ flags |= O_RDONLY | O_NOATIME; ++ return flags; ++} ++ ++/* common functions to regular file and dir */ ++struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, ++ struct file *file) ++{ ++ struct file *h_file; ++ struct dentry *h_dentry; ++ struct inode *h_inode; ++ struct super_block *sb; ++ struct au_branch *br; ++ int err; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ h_inode = h_dentry->d_inode; ++ /* a race condition can happen between open and unlink/rmdir */ ++ h_file = ERR_PTR(-ENOENT); ++ if (unlikely((!d_unhashed(dentry) && d_unhashed(h_dentry)) ++ || !h_inode)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ br = au_sbr(sb, bindex); ++ h_file = ERR_PTR(-EACCES); ++ if (file && (file->f_mode & FMODE_EXEC) ++ && (br->br_mnt->mnt_flags & MNT_NOEXEC)) ++ goto out; ++ ++ /* drop flags for writing */ ++ if (au_test_ro(sb, bindex, dentry->d_inode)) ++ flags = au_file_roflags(flags); ++ flags &= ~O_CREAT; ++ atomic_inc(&br->br_count); ++ h_file = dentry_open(dget(h_dentry), mntget(br->br_mnt), flags, ++ current_cred()); ++ if (IS_ERR(h_file)) ++ goto out_br; ++ ++ if (file && (file->f_mode & FMODE_EXEC)) { ++ h_file->f_mode |= FMODE_EXEC; ++ err = deny_write_access(h_file); ++ if (unlikely(err)) { ++ fput(h_file); ++ h_file = ERR_PTR(err); ++ goto out_br; ++ } ++ } ++ fsnotify_open(h_dentry); ++ goto out; /* success */ ++ ++ out_br: ++ atomic_dec(&br->br_count); ++ out: ++ return h_file; ++} ++ ++int au_do_open(struct file *file, int (*open)(struct file *file, int flags)) ++{ ++ int err; ++ struct dentry *dentry; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_finfo_init(file); ++ if (unlikely(err)) ++ goto out; ++ ++ di_read_lock_child(dentry, AuLock_IR); ++ err = open(file, file->f_flags); ++ di_read_unlock(dentry, AuLock_IR); ++ ++ fi_write_unlock(file); ++ if (unlikely(err)) ++ au_finfo_fin(file); ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++int au_reopen_nondir(struct file *file) ++{ ++ int err; ++ aufs_bindex_t bstart, bindex, bend; ++ struct dentry *dentry; ++ struct file *h_file, *h_file_tmp; ++ ++ dentry = file->f_dentry; ++ bstart = au_dbstart(dentry); ++ h_file_tmp = NULL; ++ if (au_fbstart(file) == bstart) { ++ h_file = au_h_fptr(file, bstart); ++ if (file->f_mode == h_file->f_mode) ++ return 0; /* success */ ++ h_file_tmp = h_file; ++ get_file(h_file_tmp); ++ au_set_h_fptr(file, bstart, NULL); ++ } ++ AuDebugOn(au_fbstart(file) < bstart ++ || au_fi(file)->fi_hfile[0 + bstart].hf_file); ++ ++ h_file = au_h_open(dentry, bstart, file->f_flags & ~O_TRUNC, file); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; /* todo: close all? */ ++ ++ err = 0; ++ au_set_fbstart(file, bstart); ++ au_set_h_fptr(file, bstart, h_file); ++ au_update_figen(file); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ ++ /* close lower files */ ++ bend = au_fbend(file); ++ for (bindex = bstart + 1; bindex <= bend; bindex++) ++ au_set_h_fptr(file, bindex, NULL); ++ au_set_fbend(file, bstart); ++ ++ out: ++ if (h_file_tmp) ++ fput(h_file_tmp); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_reopen_wh(struct file *file, aufs_bindex_t btgt, ++ struct dentry *hi_wh) ++{ ++ int err; ++ aufs_bindex_t bstart; ++ struct au_dinfo *dinfo; ++ struct dentry *h_dentry; ++ ++ dinfo = au_di(file->f_dentry); ++ bstart = dinfo->di_bstart; ++ dinfo->di_bstart = btgt; ++ h_dentry = dinfo->di_hdentry[0 + btgt].hd_dentry; ++ dinfo->di_hdentry[0 + btgt].hd_dentry = hi_wh; ++ err = au_reopen_nondir(file); ++ dinfo->di_hdentry[0 + btgt].hd_dentry = h_dentry; ++ dinfo->di_bstart = bstart; ++ ++ return err; ++} ++ ++static int au_ready_to_write_wh(struct file *file, loff_t len, ++ aufs_bindex_t bcpup) ++{ ++ int err; ++ struct inode *inode; ++ struct dentry *dentry, *hi_wh; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ inode = dentry->d_inode; ++ hi_wh = au_hi_wh(inode, bcpup); ++ if (!hi_wh) ++ err = au_sio_cpup_wh(dentry, bcpup, len, file); ++ else ++ /* already copied-up after unlink */ ++ err = au_reopen_wh(file, bcpup, hi_wh); ++ ++ sb = dentry->d_sb; ++ if (!err && inode->i_nlink > 1 && au_opt_test(au_mntflags(sb), PLINK)) ++ au_plink_append(inode, bcpup, au_h_dptr(dentry, bcpup)); ++ ++ return err; ++} ++ ++/* ++ * prepare the @file for writing. ++ */ ++int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin) ++{ ++ int err; ++ aufs_bindex_t bstart, bcpup; ++ struct dentry *dentry, *parent, *h_dentry; ++ struct inode *h_inode, *inode; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ bstart = au_fbstart(file); ++ inode = dentry->d_inode; ++ err = au_test_ro(sb, bstart, inode); ++ if (!err && (au_h_fptr(file, bstart)->f_mode & FMODE_WRITE)) { ++ err = au_pin(pin, dentry, bstart, AuOpt_UDBA_NONE, /*flags*/0); ++ goto out; ++ } ++ ++ /* need to cpup */ ++ parent = dget_parent(dentry); ++ di_write_lock_parent(parent); ++ err = AuWbrCopyup(au_sbi(sb), dentry); ++ bcpup = err; ++ if (unlikely(err < 0)) ++ goto out_dgrade; ++ err = 0; ++ ++ if (!au_h_dptr(parent, bcpup)) { ++ err = au_cpup_dirs(dentry, bcpup); ++ if (unlikely(err)) ++ goto out_dgrade; ++ } ++ ++ err = au_pin(pin, dentry, bcpup, AuOpt_UDBA_NONE, ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (unlikely(err)) ++ goto out_dgrade; ++ ++ h_dentry = au_h_fptr(file, bstart)->f_dentry; ++ h_inode = h_dentry->d_inode; ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ if (d_unhashed(dentry) /* || d_unhashed(h_dentry) */ ++ /* || !h_inode->i_nlink */) { ++ err = au_ready_to_write_wh(file, len, bcpup); ++ di_downgrade_lock(parent, AuLock_IR); ++ } else { ++ di_downgrade_lock(parent, AuLock_IR); ++ if (!au_h_dptr(dentry, bcpup)) ++ err = au_sio_cpup_simple(dentry, bcpup, len, ++ AuCpup_DTIME); ++ if (!err) ++ err = au_reopen_nondir(file); ++ } ++ mutex_unlock(&h_inode->i_mutex); ++ ++ if (!err) { ++ au_pin_set_parent_lflag(pin, /*lflag*/0); ++ goto out_dput; /* success */ ++ } ++ au_unpin(pin); ++ goto out_unlock; ++ ++ out_dgrade: ++ di_downgrade_lock(parent, AuLock_IR); ++ out_unlock: ++ di_read_unlock(parent, AuLock_IR); ++ out_dput: ++ dput(parent); ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_file_refresh_by_inode(struct file *file, int *need_reopen) ++{ ++ int err; ++ aufs_bindex_t bstart; ++ struct au_pin pin; ++ struct au_finfo *finfo; ++ struct dentry *dentry, *parent, *hi_wh; ++ struct inode *inode; ++ struct super_block *sb; ++ ++ err = 0; ++ finfo = au_fi(file); ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ bstart = au_ibstart(inode); ++ if (bstart == finfo->fi_bstart) ++ goto out; ++ ++ parent = dget_parent(dentry); ++ if (au_test_ro(sb, bstart, inode)) { ++ di_read_lock_parent(parent, !AuLock_IR); ++ err = AuWbrCopyup(au_sbi(sb), dentry); ++ bstart = err; ++ di_read_unlock(parent, !AuLock_IR); ++ if (unlikely(err < 0)) ++ goto out_parent; ++ err = 0; ++ } ++ ++ di_read_lock_parent(parent, AuLock_IR); ++ hi_wh = au_hi_wh(inode, bstart); ++ if (au_opt_test(au_mntflags(sb), PLINK) ++ && au_plink_test(inode) ++ && !d_unhashed(dentry)) { ++ err = au_test_and_cpup_dirs(dentry, bstart); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ /* always superio. */ ++ err = au_pin(&pin, dentry, bstart, AuOpt_UDBA_NONE, ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (!err) ++ err = au_sio_cpup_simple(dentry, bstart, -1, ++ AuCpup_DTIME); ++ au_unpin(&pin); ++ } else if (hi_wh) { ++ /* already copied-up after unlink */ ++ err = au_reopen_wh(file, bstart, hi_wh); ++ *need_reopen = 0; ++ } ++ ++ out_unlock: ++ di_read_unlock(parent, AuLock_IR); ++ out_parent: ++ dput(parent); ++ out: ++ return err; ++} ++ ++static void au_do_refresh_file(struct file *file) ++{ ++ aufs_bindex_t bindex, bend, new_bindex, brid; ++ struct au_hfile *p, tmp, *q; ++ struct au_finfo *finfo; ++ struct super_block *sb; ++ ++ sb = file->f_dentry->d_sb; ++ finfo = au_fi(file); ++ p = finfo->fi_hfile + finfo->fi_bstart; ++ brid = p->hf_br->br_id; ++ bend = finfo->fi_bend; ++ for (bindex = finfo->fi_bstart; bindex <= bend; bindex++, p++) { ++ if (!p->hf_file) ++ continue; ++ ++ new_bindex = au_br_index(sb, p->hf_br->br_id); ++ if (new_bindex == bindex) ++ continue; ++ if (new_bindex < 0) { ++ au_set_h_fptr(file, bindex, NULL); ++ continue; ++ } ++ ++ /* swap two lower inode, and loop again */ ++ q = finfo->fi_hfile + new_bindex; ++ tmp = *q; ++ *q = *p; ++ *p = tmp; ++ if (tmp.hf_file) { ++ bindex--; ++ p--; ++ } ++ } ++ ++ p = finfo->fi_hfile; ++ if (!au_test_mmapped(file) && !d_unhashed(file->f_dentry)) { ++ bend = au_sbend(sb); ++ for (finfo->fi_bstart = 0; finfo->fi_bstart <= bend; ++ finfo->fi_bstart++, p++) ++ if (p->hf_file) { ++ if (p->hf_file->f_dentry ++ && p->hf_file->f_dentry->d_inode) ++ break; ++ else ++ au_hfput(p, file); ++ } ++ } else { ++ bend = au_br_index(sb, brid); ++ for (finfo->fi_bstart = 0; finfo->fi_bstart < bend; ++ finfo->fi_bstart++, p++) ++ if (p->hf_file) ++ au_hfput(p, file); ++ bend = au_sbend(sb); ++ } ++ ++ p = finfo->fi_hfile + bend; ++ for (finfo->fi_bend = bend; finfo->fi_bend >= finfo->fi_bstart; ++ finfo->fi_bend--, p--) ++ if (p->hf_file) { ++ if (p->hf_file->f_dentry ++ && p->hf_file->f_dentry->d_inode) ++ break; ++ else ++ au_hfput(p, file); ++ } ++ AuDebugOn(finfo->fi_bend < finfo->fi_bstart); ++} ++ ++/* ++ * after branch manipulating, refresh the file. ++ */ ++static int refresh_file(struct file *file, int (*reopen)(struct file *file)) ++{ ++ int err, need_reopen; ++ struct dentry *dentry; ++ aufs_bindex_t bend, bindex; ++ ++ dentry = file->f_dentry; ++ err = au_fi_realloc(au_fi(file), au_sbend(dentry->d_sb) + 1); ++ if (unlikely(err)) ++ goto out; ++ au_do_refresh_file(file); ++ ++ err = 0; ++ need_reopen = 1; ++ if (!au_test_mmapped(file)) ++ err = au_file_refresh_by_inode(file, &need_reopen); ++ if (!err && need_reopen && !d_unhashed(dentry)) ++ err = reopen(file); ++ if (!err) { ++ au_update_figen(file); ++ return 0; /* success */ ++ } ++ ++ /* error, close all lower files */ ++ bend = au_fbend(file); ++ for (bindex = au_fbstart(file); bindex <= bend; bindex++) ++ au_set_h_fptr(file, bindex, NULL); ++ ++ out: ++ return err; ++} ++ ++/* common function to regular file and dir */ ++int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file), ++ int wlock) ++{ ++ int err; ++ unsigned int sigen, figen; ++ aufs_bindex_t bstart; ++ unsigned char pseudo_link; ++ struct dentry *dentry; ++ ++ err = 0; ++ dentry = file->f_dentry; ++ sigen = au_sigen(dentry->d_sb); ++ fi_write_lock(file); ++ figen = au_figen(file); ++ di_write_lock_child(dentry); ++ bstart = au_dbstart(dentry); ++ pseudo_link = (bstart != au_ibstart(dentry->d_inode)); ++ if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) { ++ if (!wlock) { ++ di_downgrade_lock(dentry, AuLock_IR); ++ fi_downgrade_lock(file); ++ } ++ goto out; /* success */ ++ } ++ ++ AuDbg("sigen %d, figen %d\n", sigen, figen); ++ if (sigen != au_digen(dentry) ++ || sigen != au_iigen(dentry->d_inode)) { ++ err = au_reval_dpath(dentry, sigen); ++ if (unlikely(err < 0)) ++ goto out; ++ AuDebugOn(au_digen(dentry) != sigen ++ || au_iigen(dentry->d_inode) != sigen); ++ } ++ ++ err = refresh_file(file, reopen); ++ if (!err) { ++ if (!wlock) { ++ di_downgrade_lock(dentry, AuLock_IR); ++ fi_downgrade_lock(file); ++ } ++ } else { ++ di_write_unlock(dentry); ++ fi_write_unlock(file); ++ } ++ ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* cf. aufs_nopage() */ ++/* for madvise(2) */ ++static int aufs_readpage(struct file *file __maybe_unused, struct page *page) ++{ ++ unlock_page(page); ++ return 0; ++} ++ ++/* they will never be called. */ ++#ifdef CONFIG_AUFS_DEBUG ++static int aufs_write_begin(struct file *file, struct address_space *mapping, ++ loff_t pos, unsigned len, unsigned flags, ++ struct page **pagep, void **fsdata) ++{ AuUnsupport(); return 0; } ++static int aufs_write_end(struct file *file, struct address_space *mapping, ++ loff_t pos, unsigned len, unsigned copied, ++ struct page *page, void *fsdata) ++{ AuUnsupport(); return 0; } ++static int aufs_writepage(struct page *page, struct writeback_control *wbc) ++{ AuUnsupport(); return 0; } ++static void aufs_sync_page(struct page *page) ++{ AuUnsupport(); } ++ ++static int aufs_set_page_dirty(struct page *page) ++{ AuUnsupport(); return 0; } ++static void aufs_invalidatepage(struct page *page, unsigned long offset) ++{ AuUnsupport(); } ++static int aufs_releasepage(struct page *page, gfp_t gfp) ++{ AuUnsupport(); return 0; } ++static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb, ++ const struct iovec *iov, loff_t offset, ++ unsigned long nr_segs) ++{ AuUnsupport(); return 0; } ++#endif /* CONFIG_AUFS_DEBUG */ ++ ++struct address_space_operations aufs_aop = { ++ .readpage = aufs_readpage, ++#ifdef CONFIG_AUFS_DEBUG ++ .writepage = aufs_writepage, ++ .sync_page = aufs_sync_page, ++ .set_page_dirty = aufs_set_page_dirty, ++ .write_begin = aufs_write_begin, ++ .write_end = aufs_write_end, ++ .invalidatepage = aufs_invalidatepage, ++ .releasepage = aufs_releasepage, ++ .direct_IO = aufs_direct_IO, ++#endif /* CONFIG_AUFS_DEBUG */ ++}; +diff -Naur a/fs/aufs/file.h b/fs/aufs/file.h +--- a/fs/aufs/file.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/file.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,159 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * file operations ++ */ ++ ++#ifndef __AUFS_FILE_H__ ++#define __AUFS_FILE_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include "rwsem.h" ++ ++struct au_branch; ++struct au_hfile { ++ struct file *hf_file; ++ struct au_branch *hf_br; ++}; ++ ++struct au_vdir; ++struct au_finfo { ++ atomic_t fi_generation; ++ ++ struct rw_semaphore fi_rwsem; ++ struct au_hfile *fi_hfile; ++ aufs_bindex_t fi_bstart, fi_bend; ++ ++ union { ++ /* non-dir only */ ++ struct { ++ struct vm_operations_struct *fi_h_vm_ops; ++ struct vm_operations_struct *fi_vm_ops; ++ }; ++ ++ /* dir only */ ++ struct { ++ struct au_vdir *fi_vdir_cache; ++ int fi_maintain_plink; ++ }; ++ }; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* file.c */ ++extern struct address_space_operations aufs_aop; ++void au_store_oflag(struct nameidata *nd, struct inode *inode); ++unsigned int au_file_roflags(unsigned int flags); ++struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, ++ struct file *file); ++int au_do_open(struct file *file, int (*open)(struct file *file, int flags)); ++int au_reopen_nondir(struct file *file); ++struct au_pin; ++int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin); ++int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file), ++ int wlock); ++ ++/* f_op.c */ ++extern const struct file_operations aufs_file_fop; ++int aufs_flush(struct file *file, fl_owner_t id); ++ ++/* finfo.c */ ++void au_hfput(struct au_hfile *hf, struct file *file); ++void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, ++ struct file *h_file); ++ ++void au_update_figen(struct file *file); ++ ++void au_finfo_fin(struct file *file); ++int au_finfo_init(struct file *file); ++int au_fi_realloc(struct au_finfo *finfo, int nbr); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct au_finfo *au_fi(struct file *file) ++{ ++ return file->private_data; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * fi_read_lock, fi_write_lock, ++ * fi_read_unlock, fi_write_unlock, fi_downgrade_lock ++ */ ++AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem); ++ ++#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem) ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* todo: hard/soft set? */ ++static inline aufs_bindex_t au_fbstart(struct file *file) ++{ ++ return au_fi(file)->fi_bstart; ++} ++ ++static inline aufs_bindex_t au_fbend(struct file *file) ++{ ++ return au_fi(file)->fi_bend; ++} ++ ++static inline struct au_vdir *au_fvdir_cache(struct file *file) ++{ ++ return au_fi(file)->fi_vdir_cache; ++} ++ ++static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex) ++{ ++ au_fi(file)->fi_bstart = bindex; ++} ++ ++static inline void au_set_fbend(struct file *file, aufs_bindex_t bindex) ++{ ++ au_fi(file)->fi_bend = bindex; ++} ++ ++static inline void au_set_fvdir_cache(struct file *file, ++ struct au_vdir *vdir_cache) ++{ ++ au_fi(file)->fi_vdir_cache = vdir_cache; ++} ++ ++static inline struct file *au_h_fptr(struct file *file, aufs_bindex_t bindex) ++{ ++ return au_fi(file)->fi_hfile[0 + bindex].hf_file; ++} ++ ++/* todo: memory barrier? */ ++static inline unsigned int au_figen(struct file *f) ++{ ++ return atomic_read(&au_fi(f)->fi_generation); ++} ++ ++static inline int au_test_mmapped(struct file *f) ++{ ++ return !!(au_fi(f)->fi_h_vm_ops); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_FILE_H__ */ +diff -Naur a/fs/aufs/finfo.c b/fs/aufs/finfo.c +--- a/fs/aufs/finfo.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/finfo.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,134 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * file private data ++ */ ++ ++#include ++#include "aufs.h" ++ ++void au_hfput(struct au_hfile *hf, struct file *file) ++{ ++ if (file->f_mode & FMODE_EXEC) ++ allow_write_access(hf->hf_file); ++ fput(hf->hf_file); ++ hf->hf_file = NULL; ++ atomic_dec(&hf->hf_br->br_count); ++ hf->hf_br = NULL; ++} ++ ++void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val) ++{ ++ struct au_finfo *finfo = au_fi(file); ++ struct au_hfile *hf; ++ ++ hf = finfo->fi_hfile + bindex; ++ if (hf->hf_file) ++ au_hfput(hf, file); ++ if (val) { ++ hf->hf_file = val; ++ hf->hf_br = au_sbr(file->f_dentry->d_sb, bindex); ++ } ++} ++ ++void au_update_figen(struct file *file) ++{ ++ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_dentry)); ++ /* smp_mb(); */ /* atomic_set */ ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_finfo_fin(struct file *file) ++{ ++ struct au_finfo *finfo; ++ aufs_bindex_t bindex, bend; ++ ++ fi_write_lock(file); ++ bend = au_fbend(file); ++ bindex = au_fbstart(file); ++ if (bindex >= 0) ++ /* ++ * calls fput() instead of filp_close(), ++ * since no dnotify or lock for the lower file. ++ */ ++ for (; bindex <= bend; bindex++) ++ au_set_h_fptr(file, bindex, NULL); ++ ++ finfo = au_fi(file); ++ au_dbg_verify_hf(finfo); ++ kfree(finfo->fi_hfile); ++ fi_write_unlock(file); ++ au_rwsem_destroy(&finfo->fi_rwsem); ++ au_cache_free_finfo(finfo); ++} ++ ++int au_finfo_init(struct file *file) ++{ ++ struct au_finfo *finfo; ++ struct dentry *dentry; ++ unsigned long ul; ++ ++ dentry = file->f_dentry; ++ finfo = au_cache_alloc_finfo(); ++ if (unlikely(!finfo)) ++ goto out; ++ ++ finfo->fi_hfile = kcalloc(au_sbend(dentry->d_sb) + 1, ++ sizeof(*finfo->fi_hfile), GFP_NOFS); ++ if (unlikely(!finfo->fi_hfile)) ++ goto out_finfo; ++ ++ init_rwsem(&finfo->fi_rwsem); ++ down_write(&finfo->fi_rwsem); ++ finfo->fi_bstart = -1; ++ finfo->fi_bend = -1; ++ atomic_set(&finfo->fi_generation, au_digen(dentry)); ++ /* smp_mb(); */ /* atomic_set */ ++ ++ /* cf. au_store_oflag() */ ++ /* suppress a warning in lp64 */ ++ ul = (unsigned long)file->private_data; ++ file->f_mode |= (vfsub_uint_to_fmode(ul) & FMODE_EXEC); ++ file->private_data = finfo; ++ return 0; /* success */ ++ ++ out_finfo: ++ au_cache_free_finfo(finfo); ++ out: ++ return -ENOMEM; ++} ++ ++int au_fi_realloc(struct au_finfo *finfo, int nbr) ++{ ++ int err, sz; ++ struct au_hfile *hfp; ++ ++ err = -ENOMEM; ++ sz = sizeof(*hfp) * (finfo->fi_bend + 1); ++ if (!sz) ++ sz = sizeof(*hfp); ++ hfp = au_kzrealloc(finfo->fi_hfile, sz, sizeof(*hfp) * nbr, GFP_NOFS); ++ if (hfp) { ++ finfo->fi_hfile = hfp; ++ err = 0; ++ } ++ ++ return err; ++} +diff -Naur a/fs/aufs/f_op.c b/fs/aufs/f_op.c +--- a/fs/aufs/f_op.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/f_op.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,648 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * file and vm operations ++ */ ++ ++#include ++#include ++#include ++#include "aufs.h" ++ ++/* common function to regular file and dir */ ++int aufs_flush(struct file *file, fl_owner_t id) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ struct dentry *dentry; ++ struct file *h_file; ++ ++ dentry = file->f_dentry; ++ si_noflush_read_lock(dentry->d_sb); ++ fi_read_lock(file); ++ di_read_lock_child(dentry, AuLock_IW); ++ ++ err = 0; ++ bend = au_fbend(file); ++ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) { ++ h_file = au_h_fptr(file, bindex); ++ if (!h_file || !h_file->f_op || !h_file->f_op->flush) ++ continue; ++ ++ err = h_file->f_op->flush(h_file, id); ++ if (!err) ++ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); ++ /*ignore*/ ++ } ++ au_cpup_attr_timesizes(dentry->d_inode); ++ ++ di_read_unlock(dentry, AuLock_IW); ++ fi_read_unlock(file); ++ si_read_unlock(dentry->d_sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int do_open_nondir(struct file *file, int flags) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ struct file *h_file; ++ struct dentry *dentry; ++ struct au_finfo *finfo; ++ ++ err = 0; ++ dentry = file->f_dentry; ++ finfo = au_fi(file); ++ finfo->fi_h_vm_ops = NULL; ++ finfo->fi_vm_ops = NULL; ++ bindex = au_dbstart(dentry); ++ /* O_TRUNC is processed already */ ++ BUG_ON(au_test_ro(dentry->d_sb, bindex, dentry->d_inode) ++ && (flags & O_TRUNC)); ++ ++ h_file = au_h_open(dentry, bindex, flags, file); ++ if (IS_ERR(h_file)) ++ err = PTR_ERR(h_file); ++ else { ++ au_set_fbstart(file, bindex); ++ au_set_fbend(file, bindex); ++ au_set_h_fptr(file, bindex, h_file); ++ au_update_figen(file); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ } ++ return err; ++} ++ ++static int aufs_open_nondir(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ return au_do_open(file, do_open_nondir); ++} ++ ++static int aufs_release_nondir(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ struct super_block *sb = file->f_dentry->d_sb; ++ ++ si_noflush_read_lock(sb); ++ kfree(au_fi(file)->fi_vm_ops); ++ au_finfo_fin(file); ++ si_read_unlock(sb); ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static ssize_t aufs_read(struct file *file, char __user *buf, size_t count, ++ loff_t *ppos) ++{ ++ ssize_t err; ++ struct dentry *dentry; ++ struct file *h_file; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ err = vfsub_read_u(h_file, buf, count, ppos); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode); ++ ++ di_read_unlock(dentry, AuLock_IR); ++ fi_read_unlock(file); ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++static ssize_t aufs_write(struct file *file, const char __user *ubuf, ++ size_t count, loff_t *ppos) ++{ ++ ssize_t err; ++ aufs_bindex_t bstart; ++ struct au_pin pin; ++ struct dentry *dentry; ++ struct inode *inode; ++ struct super_block *sb; ++ struct file *h_file; ++ char __user *buf = (char __user *)ubuf; ++ ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ mutex_lock(&inode->i_mutex); ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ bstart = au_fbstart(file); ++ h_file = au_h_fptr(file, bstart); ++ au_unpin(&pin); ++ err = vfsub_write_u(h_file, buf, count, ppos); ++ au_cpup_attr_timesizes(inode); ++ inode->i_mode = h_file->f_dentry->d_inode->i_mode; ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ out: ++ si_read_unlock(sb); ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++ ++static ssize_t aufs_splice_read(struct file *file, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags) ++{ ++ ssize_t err; ++ struct file *h_file; ++ struct dentry *dentry; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ err = -EINVAL; ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ if (au_test_loopback_kthread()) { ++ file->f_mapping = h_file->f_mapping; ++ smp_mb(); /* unnecessary? */ ++ } ++ err = vfsub_splice_to(h_file, ppos, pipe, len, flags); ++ /* todo: necessasry? */ ++ /* file->f_ra = h_file->f_ra; */ ++ fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode); ++ ++ di_read_unlock(dentry, AuLock_IR); ++ fi_read_unlock(file); ++ ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++static ssize_t ++aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos, ++ size_t len, unsigned int flags) ++{ ++ ssize_t err; ++ struct au_pin pin; ++ struct dentry *dentry; ++ struct inode *inode; ++ struct super_block *sb; ++ struct file *h_file; ++ ++ dentry = file->f_dentry; ++ inode = dentry->d_inode; ++ mutex_lock(&inode->i_mutex); ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ au_unpin(&pin); ++ err = vfsub_splice_from(pipe, h_file, ppos, len, flags); ++ au_cpup_attr_timesizes(inode); ++ inode->i_mode = h_file->f_dentry->d_inode->i_mode; ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ out: ++ si_read_unlock(sb); ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct file *au_safe_file(struct vm_area_struct *vma) ++{ ++ struct file *file; ++ ++ file = vma->vm_file; ++ if (file->private_data && au_test_aufs(file->f_dentry->d_sb)) ++ return file; ++ return NULL; ++} ++ ++static void au_reset_file(struct vm_area_struct *vma, struct file *file) ++{ ++ vma->vm_file = file; ++ /* smp_mb(); */ /* flush vm_file */ ++} ++ ++static int aufs_fault(struct vm_area_struct *vma, struct vm_fault *vmf) ++{ ++ int err; ++ static DECLARE_WAIT_QUEUE_HEAD(wq); ++ struct file *file, *h_file; ++ struct au_finfo *finfo; ++ ++ /* todo: non-robr mode, user vm_file as it is? */ ++ wait_event(wq, (file = au_safe_file(vma))); ++ ++ /* do not revalidate, no si lock */ ++ finfo = au_fi(file); ++ h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file; ++ AuDebugOn(!h_file || !au_test_mmapped(file)); ++ ++ fi_write_lock(file); ++ vma->vm_file = h_file; ++ err = finfo->fi_h_vm_ops->fault(vma, vmf); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ au_reset_file(vma, file); ++ fi_write_unlock(file); ++#if 0 /* def CONFIG_SMP */ ++ /* wake_up_nr(&wq, online_cpu - 1); */ ++ wake_up_all(&wq); ++#else ++ wake_up(&wq); ++#endif ++ ++ return err; ++} ++ ++static int aufs_page_mkwrite(struct vm_area_struct *vma, struct page *page) ++{ ++ int err; ++ static DECLARE_WAIT_QUEUE_HEAD(wq); ++ struct file *file, *h_file; ++ struct au_finfo *finfo; ++ ++ wait_event(wq, (file = au_safe_file(vma))); ++ ++ finfo = au_fi(file); ++ h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file; ++ AuDebugOn(!h_file || !au_test_mmapped(file)); ++ ++ fi_write_lock(file); ++ vma->vm_file = h_file; ++ err = finfo->fi_h_vm_ops->page_mkwrite(vma, page); ++ au_reset_file(vma, file); ++ fi_write_unlock(file); ++ wake_up(&wq); ++ ++ return err; ++} ++ ++static void aufs_vm_close(struct vm_area_struct *vma) ++{ ++ static DECLARE_WAIT_QUEUE_HEAD(wq); ++ struct file *file, *h_file; ++ struct au_finfo *finfo; ++ ++ wait_event(wq, (file = au_safe_file(vma))); ++ ++ finfo = au_fi(file); ++ h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file; ++ AuDebugOn(!h_file || !au_test_mmapped(file)); ++ ++ fi_write_lock(file); ++ vma->vm_file = h_file; ++ finfo->fi_h_vm_ops->close(vma); ++ au_reset_file(vma, file); ++ fi_write_unlock(file); ++ wake_up(&wq); ++} ++ ++static struct vm_operations_struct aufs_vm_ops = { ++ /* .close and .page_mkwrite are not set by default */ ++ .fault = aufs_fault, ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct vm_operations_struct *au_vm_ops(struct file *h_file, ++ struct vm_area_struct *vma) ++{ ++ struct vm_operations_struct *vm_ops; ++ int err; ++ ++ vm_ops = ERR_PTR(-ENODEV); ++ if (!h_file->f_op || !h_file->f_op->mmap) ++ goto out; ++ ++ err = h_file->f_op->mmap(h_file, vma); ++ vm_ops = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ ++ vm_ops = vma->vm_ops; ++ err = do_munmap(current->mm, vma->vm_start, ++ vma->vm_end - vma->vm_start); ++ if (unlikely(err)) { ++ AuIOErr("failed internal unmapping %.*s, %d\n", ++ AuDLNPair(h_file->f_dentry), err); ++ vm_ops = ERR_PTR(-EIO); ++ } ++ ++ out: ++ return vm_ops; ++} ++ ++static int au_custom_vm_ops(struct au_finfo *finfo, struct vm_area_struct *vma) ++{ ++ int err; ++ struct vm_operations_struct *h_ops; ++ ++ err = 0; ++ h_ops = finfo->fi_h_vm_ops; ++ AuDebugOn(!h_ops); ++ if ((!h_ops->page_mkwrite && !h_ops->close) ++ || finfo->fi_vm_ops) ++ goto out; ++ ++ err = -ENOMEM; ++ finfo->fi_vm_ops = kmemdup(&aufs_vm_ops, sizeof(aufs_vm_ops), GFP_NOFS); ++ if (unlikely(!finfo->fi_vm_ops)) ++ goto out; ++ ++ err = 0; ++ if (h_ops->page_mkwrite) ++ finfo->fi_vm_ops->page_mkwrite = aufs_page_mkwrite; ++ if (h_ops->close) ++ finfo->fi_vm_ops->close = aufs_vm_close; ++ ++ vma->vm_ops = finfo->fi_vm_ops; ++ ++ out: ++ return err; ++} ++ ++static int aufs_mmap(struct file *file, struct vm_area_struct *vma) ++{ ++ int err; ++ unsigned char wlock, mmapped; ++ struct dentry *dentry; ++ struct super_block *sb; ++ struct file *h_file; ++ struct vm_operations_struct *vm_ops; ++ ++ dentry = file->f_dentry; ++ mmapped = !!au_test_mmapped(file); /* can be harmless race condition */ ++ wlock = !!(file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED); ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, wlock | !mmapped); ++ if (unlikely(err)) ++ goto out; ++ ++ if (wlock) { ++ struct au_pin pin; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ au_unpin(&pin); ++ } else if (!mmapped) ++ di_downgrade_lock(dentry, AuLock_IR); ++ ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ if (au_test_fs_bad_mapping(h_file->f_dentry->d_sb)) { ++ /* ++ * by this assignment, f_mapping will differs from aufs inode ++ * i_mapping. ++ * if someone else mixes the use of f_dentry->d_inode and ++ * f_mapping->host, then a problem may arise. ++ */ ++ file->f_mapping = h_file->f_mapping; ++ } ++ ++ vm_ops = NULL; ++ if (!mmapped) { ++ vm_ops = au_vm_ops(h_file, vma); ++ err = PTR_ERR(vm_ops); ++ if (IS_ERR(vm_ops)) ++ goto out_unlock; ++ } ++ ++ /* ++ * unnecessary to handle MAP_DENYWRITE and deny_write_access()? ++ * currently MAP_DENYWRITE from userspace is ignored, but elf loader ++ * sets it. when FMODE_EXEC is set (by open_exec() or sys_uselib()), ++ * both of the aufs file and the lower file is deny_write_access()-ed. ++ * finally I hope we can skip handlling MAP_DENYWRITE here. ++ */ ++ err = generic_file_mmap(file, vma); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ vma->vm_ops = &aufs_vm_ops; ++ /* test again */ ++ if (!au_test_mmapped(file)) ++ au_fi(file)->fi_h_vm_ops = vm_ops; ++ ++ err = au_custom_vm_ops(au_fi(file), vma); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ vfsub_file_accessed(h_file); ++ fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode); ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ if (!wlock && mmapped) ++ fi_read_unlock(file); ++ else ++ fi_write_unlock(file); ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static unsigned int aufs_poll(struct file *file, poll_table *wait) ++{ ++ unsigned int mask; ++ int err; ++ struct file *h_file; ++ struct dentry *dentry; ++ struct super_block *sb; ++ ++ /* We should pretend an error happened. */ ++ mask = POLLERR /* | POLLIN | POLLOUT */; ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ /* it is not an error if h_file has no operation */ ++ mask = DEFAULT_POLLMASK; ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ if (h_file->f_op && h_file->f_op->poll) ++ mask = h_file->f_op->poll(h_file, wait); ++ ++ di_read_unlock(dentry, AuLock_IR); ++ fi_read_unlock(file); ++ ++ out: ++ si_read_unlock(sb); ++ AuTraceErr((int)mask); ++ return mask; ++} ++ ++static int aufs_fsync_nondir(struct file *file, struct dentry *dentry, ++ int datasync) ++{ ++ int err; ++ struct au_pin pin; ++ struct inode *inode; ++ struct file *h_file; ++ struct super_block *sb; ++ ++ inode = dentry->d_inode; ++ IMustLock(file->f_mapping->host); ++ if (inode != file->f_mapping->host) { ++ mutex_unlock(&file->f_mapping->host->i_mutex); ++ mutex_lock(&inode->i_mutex); ++ } ++ IMustLock(inode); ++ ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ err = 0; /* -EBADF; */ /* posix? */ ++ if (unlikely(!(file->f_mode & FMODE_WRITE))) ++ goto out; ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ au_unpin(&pin); ++ ++ err = -EINVAL; ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ if (h_file->f_op && h_file->f_op->fsync) { ++ struct dentry *h_d; ++ struct mutex *h_mtx; ++ ++ /* ++ * no filemap_fdatawrite() since aufs file has no its own ++ * mapping, but dir. ++ */ ++ h_d = h_file->f_dentry; ++ h_mtx = &h_d->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ err = h_file->f_op->fsync(h_file, h_d, datasync); ++ if (!err) ++ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); ++ /*ignore*/ ++ au_cpup_attr_timesizes(inode); ++ mutex_unlock(h_mtx); ++ } ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ out: ++ si_read_unlock(sb); ++ if (inode != file->f_mapping->host) { ++ mutex_unlock(&inode->i_mutex); ++ mutex_lock(&file->f_mapping->host->i_mutex); ++ } ++ return err; ++} ++ ++static int aufs_fasync(int fd, struct file *file, int flag) ++{ ++ int err; ++ struct file *h_file; ++ struct dentry *dentry; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ if (h_file->f_op && h_file->f_op->fasync) ++ err = h_file->f_op->fasync(fd, h_file, flag); ++ ++ di_read_unlock(dentry, AuLock_IR); ++ fi_read_unlock(file); ++ ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++const struct file_operations aufs_file_fop = { ++ /* ++ * while generic_file_llseek/_unlocked() don't use BKL, ++ * don't use it since it operates file->f_mapping->host. ++ * in aufs, it may be a real file and may confuse users by UDBA. ++ */ ++ /* .llseek = generic_file_llseek, */ ++ ++ .read = aufs_read, ++ .write = aufs_write, ++ .poll = aufs_poll, ++ .mmap = aufs_mmap, ++ .open = aufs_open_nondir, ++ .flush = aufs_flush, ++ .release = aufs_release_nondir, ++ .fsync = aufs_fsync_nondir, ++ .fasync = aufs_fasync, ++ .splice_write = aufs_splice_write, ++ .splice_read = aufs_splice_read ++}; +diff -Naur a/fs/aufs/fstype.h b/fs/aufs/fstype.h +--- a/fs/aufs/fstype.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/fstype.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,474 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * judging filesystem type ++ */ ++ ++#ifndef __AUFS_FSTYPE_H__ ++#define __AUFS_FSTYPE_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static inline int au_test_aufs(struct super_block *sb) ++{ ++ return sb->s_magic == AUFS_SUPER_MAGIC; ++} ++ ++static inline const char *au_sbtype(struct super_block *sb) ++{ ++ return sb->s_type->name; ++} ++ ++static inline int au_test_iso9660(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE) ++ return sb->s_magic == ROMFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_romfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE) ++ return sb->s_magic == ISOFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_cramfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE) ++ return sb->s_magic == CRAMFS_MAGIC; ++#endif ++ return 0; ++} ++ ++static inline int au_test_nfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE) ++ return sb->s_magic == NFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_fuse(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE) ++ return sb->s_magic == FUSE_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_xfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE) ++ return sb->s_magic == XFS_SB_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_tmpfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_TMPFS ++ return sb->s_magic == TMPFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE) ++ return !strcmp(au_sbtype(sb), "ecryptfs"); ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_smbfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_SMB_FS) || defined(CONFIG_SMB_FS_MODULE) ++ return sb->s_magic == SMB_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ocfs2(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE) ++ return sb->s_magic == OCFS2_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_OCFS2_FS_O2CB) || defined(CONFIG_OCFS2_FS_O2CB_MODULE) ++ return sb->s_magic == DLMFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_coda(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_CODA_FS) || defined(CONFIG_CODA_FS_MODULE) ++ return sb->s_magic == CODA_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_v9fs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_9P_FS) || defined(CONFIG_9P_FS_MODULE) ++ return sb->s_magic == V9FS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ext4(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_EXT4DEV_FS) || defined(CONFIG_EXT4DEV_FS_MODULE) ++ return sb->s_magic == EXT4_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_sysv(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_SYSV_FS) || defined(CONFIG_SYSV_FS_MODULE) ++ return !strcmp(au_sbtype(sb), "sysv"); ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ramfs(struct super_block *sb) ++{ ++ return sb->s_magic == RAMFS_MAGIC; ++} ++ ++static inline int au_test_ubifs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE) ++ return sb->s_magic == UBIFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_procfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_PROC_FS ++ return sb->s_magic == PROC_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_sysfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_SYSFS ++ return sb->s_magic == SYSFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_configfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE) ++ return sb->s_magic == CONFIGFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_minix(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE) ++ return sb->s_magic == MINIX3_SUPER_MAGIC ++ || sb->s_magic == MINIX2_SUPER_MAGIC ++ || sb->s_magic == MINIX2_SUPER_MAGIC2 ++ || sb->s_magic == MINIX_SUPER_MAGIC ++ || sb->s_magic == MINIX_SUPER_MAGIC2; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_cifs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_CIFS_FS) || defined(CONFIGCIFS_FS_MODULE) ++ return sb->s_magic == CIFS_MAGIC_NUMBER; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_fat(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE) ++ return sb->s_magic == MSDOS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_msdos(struct super_block *sb) ++{ ++ return au_test_fat(sb); ++} ++ ++static inline int au_test_vfat(struct super_block *sb) ++{ ++ return au_test_fat(sb); ++} ++ ++static inline int au_test_securityfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_SECURITYFS ++ return sb->s_magic == SECURITYFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_squashfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE) ++ return sb->s_magic == SQUASHFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_btrfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE) ++ return sb->s_magic == BTRFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_xenfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE) ++ return sb->s_magic == XENFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_debugfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_DEBUG_FS ++ return sb->s_magic == DEBUGFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* ++ * they can't be an aufs branch. ++ */ ++static inline int au_test_fs_unsuppoted(struct super_block *sb) ++{ ++ return ++#ifndef CONFIG_AUFS_BR_RAMFS ++ au_test_ramfs(sb) || ++#endif ++ au_test_procfs(sb) ++ || au_test_sysfs(sb) ++ || au_test_configfs(sb) ++ || au_test_debugfs(sb) ++ || au_test_securityfs(sb) ++ || au_test_xenfs(sb) ++ /* || !strcmp(au_sbtype(sb), "unionfs") */ ++ || au_test_aufs(sb); /* will be supported in next version */ ++} ++ ++/* ++ * If the filesystem supports NFS-export, then it has to support NULL as ++ * a nameidata parameter for ->create(), ->lookup() and ->d_revalidate(). ++ * We can apply this principle when we handle a lower filesystem. ++ */ ++static inline int au_test_fs_null_nd(struct super_block *sb) ++{ ++ return !!sb->s_export_op; ++} ++ ++static inline int au_test_fs_remote(struct super_block *sb) ++{ ++ return !au_test_tmpfs(sb) ++#ifdef CONFIG_AUFS_BR_RAMFS ++ && !au_test_ramfs(sb) ++#endif ++ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * Note: these functions (below) are created after reading ->getattr() in all ++ * filesystems under linux/fs. it means we have to do so in every update... ++ */ ++ ++/* ++ * some filesystems require getattr to refresh the inode attributes before ++ * referencing. ++ * in most cases, we can rely on the inode attribute in NFS (or every remote fs) ++ * and leave the work for d_revalidate() ++ */ ++static inline int au_test_fs_refresh_iattr(struct super_block *sb) ++{ ++ return au_test_nfs(sb) ++ || au_test_fuse(sb) ++ /* || au_test_smbfs(sb) */ /* untested */ ++ /* || au_test_ocfs2(sb) */ /* untested */ ++ /* || au_test_btrfs(sb) */ /* untested */ ++ /* || au_test_coda(sb) */ /* untested */ ++ /* || au_test_v9fs(sb) */ /* untested */ ++ ; ++} ++ ++/* ++ * filesystems which don't maintain i_size or i_blocks. ++ */ ++static inline int au_test_fs_bad_iattr_size(struct super_block *sb) ++{ ++ return au_test_xfs(sb) ++ /* || au_test_ext4(sb) */ /* untested */ ++ /* || au_test_ocfs2(sb) */ /* untested */ ++ /* || au_test_ocfs2_dlmfs(sb) */ /* untested */ ++ /* || au_test_sysv(sb) */ /* untested */ ++ /* || au_test_ubifs(sb) */ /* untested */ ++ /* || au_test_minix(sb) */ /* untested */ ++ ; ++} ++ ++/* ++ * filesystems which don't store the correct value in some of their inode ++ * attributes. ++ */ ++static inline int au_test_fs_bad_iattr(struct super_block *sb) ++{ ++ return au_test_fs_bad_iattr_size(sb) ++ /* || au_test_cifs(sb) */ /* untested */ ++ || au_test_fat(sb) ++ || au_test_msdos(sb) ++ || au_test_vfat(sb); ++} ++ ++/* they don't check i_nlink in link(2) */ ++static inline int au_test_fs_no_limit_nlink(struct super_block *sb) ++{ ++ return au_test_tmpfs(sb) ++#ifdef CONFIG_AUFS_BR_RAMFS ++ || au_test_ramfs(sb) ++#endif ++ || au_test_ubifs(sb); ++} ++ ++/* ++ * filesystems which sets S_NOATIME and S_NOCMTIME. ++ */ ++static inline int au_test_fs_notime(struct super_block *sb) ++{ ++ return au_test_nfs(sb) ++ || au_test_fuse(sb) ++ || au_test_ubifs(sb) ++ /* || au_test_cifs(sb) */ /* untested */ ++ ; ++} ++ ++/* ++ * filesystems which requires replacing i_mapping. ++ */ ++static inline int au_test_fs_bad_mapping(struct super_block *sb) ++{ ++ return au_test_fuse(sb) ++ || au_test_ubifs(sb); ++} ++ ++/* temporary support for i#1 in cramfs */ ++static inline int au_test_fs_unique_ino(struct inode *inode) ++{ ++ if (au_test_cramfs(inode->i_sb)) ++ return inode->i_ino != 1; ++ return 1; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * the filesystem where the xino files placed must support i/o after unlink and ++ * maintain i_size and i_blocks. ++ */ ++static inline int au_test_fs_bad_xino(struct super_block *sb) ++{ ++ return au_test_fs_remote(sb) ++ || au_test_fs_bad_iattr_size(sb) ++#ifdef CONFIG_AUFS_BR_RAMFS ++ || !(au_test_ramfs(sb) || au_test_fs_null_nd(sb)) ++#else ++ || !au_test_fs_null_nd(sb) /* to keep xino code simple */ ++#endif ++ /* don't want unnecessary work for xino */ ++ || au_test_aufs(sb) ++ || au_test_ecryptfs(sb); ++} ++ ++static inline int au_test_fs_trunc_xino(struct super_block *sb) ++{ ++ return au_test_tmpfs(sb) ++ || au_test_ramfs(sb); ++} ++ ++/* ++ * test if the @sb is real-readonly. ++ */ ++static inline int au_test_fs_rr(struct super_block *sb) ++{ ++ return au_test_squashfs(sb) ++ || au_test_iso9660(sb) ++ || au_test_cramfs(sb) ++ || au_test_romfs(sb); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_FSTYPE_H__ */ +diff -Naur a/fs/aufs/hinotify.c b/fs/aufs/hinotify.c +--- a/fs/aufs/hinotify.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/hinotify.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,755 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * inotify for the lower directories ++ */ ++ ++#include "aufs.h" ++ ++static const __u32 AuHinMask = (IN_MOVE | IN_DELETE | IN_CREATE); ++static struct inotify_handle *au_hin_handle; ++ ++AuCacheFuncs(hinotify, HINOTIFY); ++ ++int au_hin_alloc(struct au_hinode *hinode, struct inode *inode, ++ struct inode *h_inode) ++{ ++ int err; ++ struct au_hinotify *hin; ++ s32 wd; ++ ++ err = -ENOMEM; ++ hin = au_cache_alloc_hinotify(); ++ if (hin) { ++ AuDebugOn(hinode->hi_notify); ++ hinode->hi_notify = hin; ++ hin->hin_aufs_inode = inode; ++ ++ inotify_init_watch(&hin->hin_watch); ++ wd = inotify_add_watch(au_hin_handle, &hin->hin_watch, h_inode, ++ AuHinMask); ++ if (wd >= 0) ++ return 0; /* success */ ++ ++ err = wd; ++ put_inotify_watch(&hin->hin_watch); ++ au_cache_free_hinotify(hin); ++ hinode->hi_notify = NULL; ++ } ++ ++ return err; ++} ++ ++void au_hin_free(struct au_hinode *hinode) ++{ ++ int err; ++ struct au_hinotify *hin; ++ ++ hin = hinode->hi_notify; ++ if (hin) { ++ err = 0; ++ if (atomic_read(&hin->hin_watch.count)) ++ err = inotify_rm_watch(au_hin_handle, &hin->hin_watch); ++ if (unlikely(err)) ++ /* it means the watch is already removed */ ++ AuWarn("failed inotify_rm_watch() %d\n", err); ++ au_cache_free_hinotify(hin); ++ hinode->hi_notify = NULL; ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_hin_ctl(struct au_hinode *hinode, int do_set) ++{ ++ struct inode *h_inode; ++ struct inotify_watch *watch; ++ ++ if (!hinode->hi_notify) ++ return; ++ ++ h_inode = hinode->hi_inode; ++ IMustLock(h_inode); ++ ++ /* todo: try inotify_find_update_watch()? */ ++ watch = &hinode->hi_notify->hin_watch; ++ mutex_lock(&h_inode->inotify_mutex); ++ /* mutex_lock(&watch->ih->mutex); */ ++ if (do_set) { ++ AuDebugOn(watch->mask & AuHinMask); ++ watch->mask |= AuHinMask; ++ } else { ++ AuDebugOn(!(watch->mask & AuHinMask)); ++ watch->mask &= ~AuHinMask; ++ } ++ /* mutex_unlock(&watch->ih->mutex); */ ++ mutex_unlock(&h_inode->inotify_mutex); ++} ++ ++void au_reset_hinotify(struct inode *inode, unsigned int flags) ++{ ++ aufs_bindex_t bindex, bend; ++ struct inode *hi; ++ struct dentry *iwhdentry; ++ ++ bend = au_ibend(inode); ++ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) { ++ hi = au_h_iptr(inode, bindex); ++ if (!hi) ++ continue; ++ ++ /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */ ++ iwhdentry = au_hi_wh(inode, bindex); ++ if (iwhdentry) ++ dget(iwhdentry); ++ au_igrab(hi); ++ au_set_h_iptr(inode, bindex, NULL, 0); ++ au_set_h_iptr(inode, bindex, au_igrab(hi), ++ flags & ~AuHi_XINO); ++ iput(hi); ++ dput(iwhdentry); ++ /* mutex_unlock(&hi->i_mutex); */ ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int hin_xino(struct inode *inode, struct inode *h_inode) ++{ ++ int err; ++ aufs_bindex_t bindex, bend, bfound, bstart; ++ struct inode *h_i; ++ ++ err = 0; ++ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { ++ AuWarn("branch root dir was changed\n"); ++ goto out; ++ } ++ ++ bfound = -1; ++ bend = au_ibend(inode); ++ bstart = au_ibstart(inode); ++#if 0 /* reserved for future use */ ++ if (bindex == bend) { ++ /* keep this ino in rename case */ ++ goto out; ++ } ++#endif ++ for (bindex = bstart; bindex <= bend; bindex++) { ++ if (au_h_iptr(inode, bindex) == h_inode) { ++ bfound = bindex; ++ break; ++ } ++ } ++ if (bfound < 0) ++ goto out; ++ ++ for (bindex = bstart; bindex <= bend; bindex++) { ++ h_i = au_h_iptr(inode, bindex); ++ if (!h_i) ++ continue; ++ ++ err = au_xino_write0(inode->i_sb, bindex, h_i->i_ino, 0); ++ /* ignore this error */ ++ /* bad action? */ ++ } ++ ++ /* children inode number will be broken */ ++ ++ out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int hin_gen_tree(struct dentry *dentry) ++{ ++ int err, i, j, ndentry; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry **dentries; ++ ++ err = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_dcsub_pages(&dpages, dentry, NULL, NULL); ++ if (unlikely(err)) ++ goto out_dpages; ++ ++ for (i = 0; i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ dentries = dpage->dentries; ++ ndentry = dpage->ndentry; ++ for (j = 0; j < ndentry; j++) { ++ struct dentry *d; ++ ++ d = dentries[j]; ++ if (IS_ROOT(d)) ++ continue; ++ ++ d_drop(d); ++ au_digen_dec(d); ++ if (d->d_inode) ++ /* todo: reset children xino? ++ cached children only? */ ++ au_iigen_dec(d->d_inode); ++ } ++ } ++ ++ out_dpages: ++ au_dpages_free(&dpages); ++ ++ /* discard children */ ++ dentry_unhash(dentry); ++ dput(dentry); ++ out: ++ return err; ++} ++ ++/* ++ * return 0 if processed. ++ */ ++static int hin_gen_by_inode(char *name, unsigned int nlen, struct inode *inode, ++ const unsigned int isdir) ++{ ++ int err; ++ struct dentry *d; ++ struct qstr *dname; ++ ++ err = 1; ++ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { ++ AuWarn("branch root dir was changed\n"); ++ err = 0; ++ goto out; ++ } ++ ++ if (!isdir) { ++ AuDebugOn(!name); ++ au_iigen_dec(inode); ++ spin_lock(&dcache_lock); ++ list_for_each_entry(d, &inode->i_dentry, d_alias) { ++ dname = &d->d_name; ++ if (dname->len != nlen ++ && memcmp(dname->name, name, nlen)) ++ continue; ++ err = 0; ++ spin_lock(&d->d_lock); ++ __d_drop(d); ++ au_digen_dec(d); ++ spin_unlock(&d->d_lock); ++ break; ++ } ++ spin_unlock(&dcache_lock); ++ } else { ++ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIRS); ++ d = d_find_alias(inode); ++ if (!d) { ++ au_iigen_dec(inode); ++ goto out; ++ } ++ ++ dname = &d->d_name; ++ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) ++ err = hin_gen_tree(d); ++ dput(d); ++ } ++ ++ out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int hin_gen_by_name(struct dentry *dentry, const unsigned int isdir) ++{ ++ int err; ++ struct inode *inode; ++ ++ inode = dentry->d_inode; ++ if (IS_ROOT(dentry) ++ /* || (inode && inode->i_ino == AUFS_ROOT_INO) */ ++ ) { ++ AuWarn("branch root dir was changed\n"); ++ return 0; ++ } ++ ++ err = 0; ++ if (!isdir) { ++ d_drop(dentry); ++ au_digen_dec(dentry); ++ if (inode) ++ au_iigen_dec(inode); ++ } else { ++ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS); ++ if (inode) ++ err = hin_gen_tree(dentry); ++ } ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* hinotify job flags */ ++#define AuHinJob_XINO0 1 ++#define AuHinJob_GEN (1 << 1) ++#define AuHinJob_DIRENT (1 << 2) ++#define AuHinJob_ISDIR (1 << 3) ++#define AuHinJob_TRYXINO0 (1 << 4) ++#define AuHinJob_MNTPNT (1 << 5) ++#define au_ftest_hinjob(flags, name) ((flags) & AuHinJob_##name) ++#define au_fset_hinjob(flags, name) { (flags) |= AuHinJob_##name; } ++#define au_fclr_hinjob(flags, name) { (flags) &= ~AuHinJob_##name; } ++ ++struct hin_job_args { ++ unsigned int flags; ++ struct inode *inode, *h_inode, *dir, *h_dir; ++ struct dentry *dentry; ++ char *h_name; ++ int h_nlen; ++}; ++ ++static int hin_job(struct hin_job_args *a) ++{ ++ const unsigned int isdir = au_ftest_hinjob(a->flags, ISDIR); ++ ++ /* reset xino */ ++ if (au_ftest_hinjob(a->flags, XINO0) && a->inode) ++ hin_xino(a->inode, a->h_inode); /* ignore this error */ ++ ++ if (au_ftest_hinjob(a->flags, TRYXINO0) ++ && a->inode ++ && a->h_inode) { ++ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ if (!a->h_inode->i_nlink) ++ hin_xino(a->inode, a->h_inode); /* ignore this error */ ++ mutex_unlock(&a->h_inode->i_mutex); ++ } ++ ++ /* make the generation obsolete */ ++ if (au_ftest_hinjob(a->flags, GEN)) { ++ int err = -1; ++ if (a->inode) ++ err = hin_gen_by_inode(a->h_name, a->h_nlen, a->inode, ++ isdir); ++ if (err && a->dentry) ++ hin_gen_by_name(a->dentry, isdir); ++ /* ignore this error */ ++ } ++ ++ /* make dir entries obsolete */ ++ if (au_ftest_hinjob(a->flags, DIRENT) && a->inode) { ++ struct au_vdir *vdir; ++ ++ vdir = au_ivdir(a->inode); ++ if (vdir) ++ vdir->vd_jiffy = 0; ++ /* IMustLock(a->inode); */ ++ /* a->inode->i_version++; */ ++ } ++ ++ /* can do nothing but warn */ ++ if (au_ftest_hinjob(a->flags, MNTPNT) ++ && a->dentry ++ && d_mountpoint(a->dentry)) ++ AuWarn("mount-point %.*s is removed or renamed\n", ++ AuDLNPair(a->dentry)); ++ ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static char *in_name(u32 mask) ++{ ++#ifdef CONFIG_AUFS_DEBUG ++#define test_ret(flag) if (mask & flag) \ ++ return #flag; ++ test_ret(IN_ACCESS); ++ test_ret(IN_MODIFY); ++ test_ret(IN_ATTRIB); ++ test_ret(IN_CLOSE_WRITE); ++ test_ret(IN_CLOSE_NOWRITE); ++ test_ret(IN_OPEN); ++ test_ret(IN_MOVED_FROM); ++ test_ret(IN_MOVED_TO); ++ test_ret(IN_CREATE); ++ test_ret(IN_DELETE); ++ test_ret(IN_DELETE_SELF); ++ test_ret(IN_MOVE_SELF); ++ test_ret(IN_UNMOUNT); ++ test_ret(IN_Q_OVERFLOW); ++ test_ret(IN_IGNORED); ++ return ""; ++#undef test_ret ++#else ++ return "??"; ++#endif ++} ++ ++static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen, ++ struct inode *dir) ++{ ++ struct dentry *dentry, *d, *parent; ++ struct qstr *dname; ++ ++ parent = d_find_alias(dir); ++ if (!parent) ++ return NULL; ++ ++ dentry = NULL; ++ spin_lock(&dcache_lock); ++ list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) { ++ /* AuDbg("%.*s\n", AuDLNPair(d)); */ ++ dname = &d->d_name; ++ if (dname->len != nlen || memcmp(dname->name, name, nlen)) ++ continue; ++ if (!atomic_read(&d->d_count) || !d->d_fsdata) { ++ spin_lock(&d->d_lock); ++ __d_drop(d); ++ spin_unlock(&d->d_lock); ++ continue; ++ } ++ ++ dentry = dget(d); ++ break; ++ } ++ spin_unlock(&dcache_lock); ++ dput(parent); ++ ++ if (dentry) ++ di_write_lock_child(dentry); ++ ++ return dentry; ++} ++ ++static struct inode *lookup_wlock_by_ino(struct super_block *sb, ++ aufs_bindex_t bindex, ino_t h_ino) ++{ ++ struct inode *inode; ++ ino_t ino; ++ int err; ++ ++ inode = NULL; ++ err = au_xino_read(sb, bindex, h_ino, &ino); ++ if (!err && ino) ++ inode = ilookup(sb, ino); ++ if (!inode) ++ goto out; ++ ++ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { ++ AuWarn("wrong root branch\n"); ++ iput(inode); ++ inode = NULL; ++ goto out; ++ } ++ ++ ii_write_lock_child(inode); ++ ++ out: ++ return inode; ++} ++ ++enum { CHILD, PARENT }; ++struct postproc_args { ++ struct inode *h_dir, *dir, *h_child_inode; ++ u32 mask; ++ unsigned int flags[2]; ++ unsigned int h_child_nlen; ++ char h_child_name[]; ++}; ++ ++static void postproc(void *_args) ++{ ++ struct postproc_args *a = _args; ++ struct super_block *sb; ++ aufs_bindex_t bindex, bend, bfound; ++ unsigned char xino, try_iput; ++ int err; ++ struct inode *inode; ++ ino_t h_ino; ++ struct hin_job_args args; ++ struct dentry *dentry; ++ struct au_sbinfo *sbinfo; ++ ++ AuDebugOn(!_args); ++ AuDebugOn(!a->h_dir); ++ AuDebugOn(!a->dir); ++ AuDebugOn(!a->mask); ++ AuDbg("mask 0x%x %s, i%lu, hi%lu, hci%lu\n", ++ a->mask, in_name(a->mask), a->dir->i_ino, a->h_dir->i_ino, ++ a->h_child_inode ? a->h_child_inode->i_ino : 0); ++ ++ inode = NULL; ++ dentry = NULL; ++ /* ++ * do not lock a->dir->i_mutex here ++ * because of d_revalidate() may cause a deadlock. ++ */ ++ sb = a->dir->i_sb; ++ AuDebugOn(!sb); ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!sbinfo); ++ /* big aufs lock */ ++ si_noflush_write_lock(sb); ++ ++ ii_read_lock_parent(a->dir); ++ bfound = -1; ++ bend = au_ibend(a->dir); ++ for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++) ++ if (au_h_iptr(a->dir, bindex) == a->h_dir) { ++ bfound = bindex; ++ break; ++ } ++ ii_read_unlock(a->dir); ++ if (unlikely(bfound < 0)) ++ goto out; ++ ++ xino = !!au_opt_test(au_mntflags(sb), XINO); ++ h_ino = 0; ++ if (a->h_child_inode) ++ h_ino = a->h_child_inode->i_ino; ++ ++ if (a->h_child_nlen ++ && (au_ftest_hinjob(a->flags[CHILD], GEN) ++ || au_ftest_hinjob(a->flags[CHILD], MNTPNT))) ++ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen, ++ a->dir); ++ try_iput = 0; ++ if (dentry) ++ inode = dentry->d_inode; ++ if (xino && !inode && h_ino ++ && (au_ftest_hinjob(a->flags[CHILD], XINO0) ++ || au_ftest_hinjob(a->flags[CHILD], TRYXINO0) ++ || au_ftest_hinjob(a->flags[CHILD], GEN))) { ++ inode = lookup_wlock_by_ino(sb, bfound, h_ino); ++ try_iput = 1; ++ } ++ ++ args.flags = a->flags[CHILD]; ++ args.dentry = dentry; ++ args.inode = inode; ++ args.h_inode = a->h_child_inode; ++ args.dir = a->dir; ++ args.h_dir = a->h_dir; ++ args.h_name = a->h_child_name; ++ args.h_nlen = a->h_child_nlen; ++ err = hin_job(&args); ++ if (dentry) { ++ if (dentry->d_fsdata) ++ di_write_unlock(dentry); ++ dput(dentry); ++ } ++ if (inode && try_iput) { ++ ii_write_unlock(inode); ++ iput(inode); ++ } ++ ++ ii_write_lock_parent(a->dir); ++ args.flags = a->flags[PARENT]; ++ args.dentry = NULL; ++ args.inode = a->dir; ++ args.h_inode = a->h_dir; ++ args.dir = NULL; ++ args.h_dir = NULL; ++ args.h_name = NULL; ++ args.h_nlen = 0; ++ err = hin_job(&args); ++ ii_write_unlock(a->dir); ++ ++ out: ++ au_nwt_done(&sbinfo->si_nowait); ++ si_write_unlock(sb); ++ ++ iput(a->h_child_inode); ++ iput(a->h_dir); ++ iput(a->dir); ++ kfree(a); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void aufs_inotify(struct inotify_watch *watch, u32 wd __maybe_unused, ++ u32 mask, u32 cookie __maybe_unused, ++ const char *h_child_name, struct inode *h_child_inode) ++{ ++ struct au_hinotify *hinotify; ++ struct postproc_args *args; ++ int len, wkq_err; ++ unsigned char isdir, isroot, wh; ++ char *p; ++ struct inode *dir; ++ unsigned int flags[2]; ++ ++ /* if IN_UNMOUNT happens, there must be another bug */ ++ AuDebugOn(mask & IN_UNMOUNT); ++ if (mask & (IN_IGNORED | IN_UNMOUNT)) { ++ put_inotify_watch(watch); ++ return; ++ } ++#ifdef AuDbgHinotify ++ au_debug(1); ++ if (1 || !h_child_name || strcmp(h_child_name, AUFS_XINO_FNAME)) { ++ AuDbg("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s," ++ " hi%lu\n", ++ watch->inode->i_ino, wd, mask, in_name(mask), cookie, ++ h_child_name ? h_child_name : "", ++ h_child_inode ? h_child_inode->i_ino : 0); ++ WARN_ON(1); ++ } ++ au_debug(0); ++#endif ++ ++ hinotify = container_of(watch, struct au_hinotify, hin_watch); ++ AuDebugOn(!hinotify || !hinotify->hin_aufs_inode); ++ dir = igrab(hinotify->hin_aufs_inode); ++ if (!dir) ++ return; ++ ++ isroot = (dir->i_ino == AUFS_ROOT_INO); ++ len = 0; ++ wh = 0; ++ if (h_child_name) { ++ len = strlen(h_child_name); ++ if (!memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { ++ h_child_name += AUFS_WH_PFX_LEN; ++ len -= AUFS_WH_PFX_LEN; ++ wh = 1; ++ } ++ } ++ ++ isdir = 0; ++ if (h_child_inode) ++ isdir = !!S_ISDIR(h_child_inode->i_mode); ++ flags[PARENT] = AuHinJob_ISDIR; ++ flags[CHILD] = 0; ++ if (isdir) ++ flags[CHILD] = AuHinJob_ISDIR; ++ switch (mask & IN_ALL_EVENTS) { ++ case IN_MOVED_FROM: ++ case IN_MOVED_TO: ++ AuDebugOn(!h_child_name || !h_child_inode); ++ au_fset_hinjob(flags[CHILD], GEN); ++ au_fset_hinjob(flags[CHILD], XINO0); ++ au_fset_hinjob(flags[CHILD], MNTPNT); ++ au_fset_hinjob(flags[PARENT], DIRENT); ++ break; ++ ++ case IN_CREATE: ++ AuDebugOn(!h_child_name || !h_child_inode); ++ au_fset_hinjob(flags[PARENT], DIRENT); ++ au_fset_hinjob(flags[CHILD], GEN); ++ break; ++ ++ case IN_DELETE: ++ /* ++ * aufs never be able to get this child inode. ++ * revalidation should be in d_revalidate() ++ * by checking i_nlink, i_generation or d_unhashed(). ++ */ ++ AuDebugOn(!h_child_name); ++ au_fset_hinjob(flags[PARENT], DIRENT); ++ au_fset_hinjob(flags[CHILD], GEN); ++ au_fset_hinjob(flags[CHILD], TRYXINO0); ++ au_fset_hinjob(flags[CHILD], MNTPNT); ++ break; ++ ++ default: ++ AuDebugOn(1); ++ } ++ ++ if (wh) ++ h_child_inode = NULL; ++ ++ /* iput() and kfree() will be called in postproc() */ ++ /* ++ * inotify_mutex is already acquired and kmalloc/prune_icache may lock ++ * iprune_mutex. strange. ++ */ ++ lockdep_off(); ++ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS); ++ lockdep_on(); ++ if (unlikely(!args)) { ++ AuErr1("no memory\n"); ++ iput(dir); ++ return; ++ } ++ args->flags[PARENT] = flags[PARENT]; ++ args->flags[CHILD] = flags[CHILD]; ++ args->mask = mask; ++ args->dir = dir; ++ args->h_dir = igrab(watch->inode); ++ if (h_child_inode) ++ h_child_inode = igrab(h_child_inode); /* can be NULL */ ++ args->h_child_inode = h_child_inode; ++ args->h_child_nlen = len; ++ if (len) { ++ p = (void *)args; ++ p += sizeof(*args); ++ memcpy(p, h_child_name, len + 1); ++ } ++ ++ lockdep_off(); ++ wkq_err = au_wkq_nowait(postproc, args, dir->i_sb); ++ lockdep_on(); ++ if (unlikely(wkq_err)) ++ AuErr("wkq %d\n", wkq_err); ++} ++ ++static void aufs_inotify_destroy(struct inotify_watch *watch __maybe_unused) ++{ ++ return; ++} ++ ++static struct inotify_operations aufs_inotify_ops = { ++ .handle_event = aufs_inotify, ++ .destroy_watch = aufs_inotify_destroy ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void au_hin_destroy_cache(void) ++{ ++ kmem_cache_destroy(au_cachep[AuCache_HINOTIFY]); ++ au_cachep[AuCache_HINOTIFY] = NULL; ++} ++ ++int __init au_hinotify_init(void) ++{ ++ int err; ++ ++ err = -ENOMEM; ++ au_cachep[AuCache_HINOTIFY] = AuCache(au_hinotify); ++ if (au_cachep[AuCache_HINOTIFY]) { ++ err = 0; ++ au_hin_handle = inotify_init(&aufs_inotify_ops); ++ if (IS_ERR(au_hin_handle)) { ++ err = PTR_ERR(au_hin_handle); ++ au_hin_destroy_cache(); ++ } ++ } ++ AuTraceErr(err); ++ return err; ++} ++ ++void au_hinotify_fin(void) ++{ ++ inotify_destroy(au_hin_handle); ++ if (au_cachep[AuCache_HINOTIFY]) ++ au_hin_destroy_cache(); ++} +diff -Naur a/fs/aufs/iinfo.c b/fs/aufs/iinfo.c +--- a/fs/aufs/iinfo.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/iinfo.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,271 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * inode private data ++ */ ++ ++#include "aufs.h" ++ ++struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex) ++{ ++ struct inode *h_inode; ++ ++ h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode; ++ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); ++ return h_inode; ++} ++ ++/* todo: hard/soft set? */ ++void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex) ++{ ++ struct au_iinfo *iinfo = au_ii(inode); ++ struct inode *h_inode; ++ ++ iinfo->ii_bstart = bindex; ++ h_inode = iinfo->ii_hinode[bindex + 0].hi_inode; ++ if (h_inode) ++ au_cpup_igen(inode, h_inode); ++} ++ ++void au_hiput(struct au_hinode *hinode) ++{ ++ au_hin_free(hinode); ++ dput(hinode->hi_whdentry); ++ iput(hinode->hi_inode); ++} ++ ++unsigned int au_hi_flags(struct inode *inode, int isdir) ++{ ++ unsigned int flags; ++ const unsigned int mnt_flags = au_mntflags(inode->i_sb); ++ ++ flags = 0; ++ if (au_opt_test(mnt_flags, XINO)) ++ au_fset_hi(flags, XINO); ++ if (isdir && au_opt_test(mnt_flags, UDBA_HINOTIFY)) ++ au_fset_hi(flags, HINOTIFY); ++ return flags; ++} ++ ++void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, ++ struct inode *h_inode, unsigned int flags) ++{ ++ struct au_hinode *hinode; ++ struct inode *hi; ++ struct au_iinfo *iinfo = au_ii(inode); ++ ++ hinode = iinfo->ii_hinode + bindex; ++ hi = hinode->hi_inode; ++ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); ++ AuDebugOn(h_inode && hi); ++ ++ if (hi) ++ au_hiput(hinode); ++ hinode->hi_inode = h_inode; ++ if (h_inode) { ++ int err; ++ struct super_block *sb = inode->i_sb; ++ struct au_branch *br; ++ ++ if (bindex == iinfo->ii_bstart) ++ au_cpup_igen(inode, h_inode); ++ br = au_sbr(sb, bindex); ++ hinode->hi_id = br->br_id; ++ if (au_ftest_hi(flags, XINO)) { ++ err = au_xino_write(sb, bindex, h_inode->i_ino, ++ inode->i_ino); ++ if (unlikely(err)) ++ AuIOErr1("failed au_xino_write() %d\n", err); ++ } ++ ++ if (au_ftest_hi(flags, HINOTIFY) ++ && au_br_hinotifyable(br->br_perm)) { ++ err = au_hin_alloc(hinode, inode, h_inode); ++ if (unlikely(err)) ++ AuIOErr1("au_hin_alloc() %d\n", err); ++ } ++ } ++} ++ ++void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_wh) ++{ ++ struct au_hinode *hinode; ++ ++ hinode = au_ii(inode)->ii_hinode + bindex; ++ AuDebugOn(hinode->hi_whdentry); ++ hinode->hi_whdentry = h_wh; ++} ++ ++void au_update_iigen(struct inode *inode) ++{ ++ atomic_set(&au_ii(inode)->ii_generation, au_sigen(inode->i_sb)); ++ /* smp_mb(); */ /* atomic_set */ ++} ++ ++/* it may be called at remount time, too */ ++void au_update_brange(struct inode *inode, int do_put_zero) ++{ ++ struct au_iinfo *iinfo; ++ ++ iinfo = au_ii(inode); ++ if (!iinfo || iinfo->ii_bstart < 0) ++ return; ++ ++ if (do_put_zero) { ++ aufs_bindex_t bindex; ++ ++ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; ++ bindex++) { ++ struct inode *h_i; ++ ++ h_i = iinfo->ii_hinode[0 + bindex].hi_inode; ++ if (h_i && !h_i->i_nlink) ++ au_set_h_iptr(inode, bindex, NULL, 0); ++ } ++ } ++ ++ iinfo->ii_bstart = -1; ++ while (++iinfo->ii_bstart <= iinfo->ii_bend) ++ if (iinfo->ii_hinode[0 + iinfo->ii_bstart].hi_inode) ++ break; ++ if (iinfo->ii_bstart > iinfo->ii_bend) { ++ iinfo->ii_bstart = -1; ++ iinfo->ii_bend = -1; ++ return; ++ } ++ ++ iinfo->ii_bend++; ++ while (0 <= --iinfo->ii_bend) ++ if (iinfo->ii_hinode[0 + iinfo->ii_bend].hi_inode) ++ break; ++ AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend || iinfo->ii_bend < 0); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_iinfo_init(struct inode *inode) ++{ ++ struct au_iinfo *iinfo; ++ struct super_block *sb; ++ int nbr, i; ++ ++ sb = inode->i_sb; ++ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo); ++ nbr = au_sbend(sb) + 1; ++ if (unlikely(nbr <= 0)) ++ nbr = 1; ++ iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS); ++ if (iinfo->ii_hinode) { ++ for (i = 0; i < nbr; i++) ++ iinfo->ii_hinode[i].hi_id = -1; ++ ++ atomic_set(&iinfo->ii_generation, au_sigen(sb)); ++ /* smp_mb(); */ /* atomic_set */ ++ init_rwsem(&iinfo->ii_rwsem); ++ iinfo->ii_bstart = -1; ++ iinfo->ii_bend = -1; ++ iinfo->ii_vdir = NULL; ++ return 0; ++ } ++ return -ENOMEM; ++} ++ ++int au_ii_realloc(struct au_iinfo *iinfo, int nbr) ++{ ++ int err, sz; ++ struct au_hinode *hip; ++ ++ err = -ENOMEM; ++ sz = sizeof(*hip) * (iinfo->ii_bend + 1); ++ if (!sz) ++ sz = sizeof(*hip); ++ hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS); ++ if (hip) { ++ iinfo->ii_hinode = hip; ++ err = 0; ++ } ++ ++ return err; ++} ++ ++static int au_iinfo_write0(struct super_block *sb, struct au_hinode *hinode, ++ ino_t ino) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ unsigned char locked; ++ ++ err = 0; ++ locked = !!si_noflush_read_trylock(sb); ++ bindex = au_br_index(sb, hinode->hi_id); ++ if (bindex >= 0) ++ err = au_xino_write0(sb, bindex, hinode->hi_inode->i_ino, ino); ++ /* error action? */ ++ if (locked) ++ si_read_unlock(sb); ++ return err; ++} ++ ++void au_iinfo_fin(struct inode *inode) ++{ ++ ino_t ino; ++ aufs_bindex_t bend; ++ unsigned char unlinked = !inode->i_nlink; ++ struct au_iinfo *iinfo; ++ struct au_hinode *hi; ++ struct super_block *sb; ++ ++ if (unlinked) { ++ int err = au_xigen_inc(inode); ++ if (unlikely(err)) ++ AuWarn1("failed resetting i_generation, %d\n", err); ++ } ++ ++ iinfo = au_ii(inode); ++ /* bad_inode case */ ++ if (!iinfo) ++ return; ++ ++ if (iinfo->ii_vdir) ++ au_vdir_free(iinfo->ii_vdir); ++ ++ if (iinfo->ii_bstart >= 0) { ++ sb = inode->i_sb; ++ ino = 0; ++ if (unlinked) ++ ino = inode->i_ino; ++ hi = iinfo->ii_hinode + iinfo->ii_bstart; ++ bend = iinfo->ii_bend; ++ while (iinfo->ii_bstart++ <= bend) { ++ if (hi->hi_inode) { ++ if (unlinked || !hi->hi_inode->i_nlink) { ++ au_iinfo_write0(sb, hi, ino); ++ /* ignore this error */ ++ ino = 0; ++ } ++ au_hiput(hi); ++ } ++ hi++; ++ } ++ } ++ ++ kfree(iinfo->ii_hinode); ++ au_rwsem_destroy(&iinfo->ii_rwsem); ++} +diff -Naur a/fs/aufs/inode.c b/fs/aufs/inode.c +--- a/fs/aufs/inode.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/inode.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,376 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * inode functions ++ */ ++ ++#include "aufs.h" ++ ++struct inode *au_igrab(struct inode *inode) ++{ ++ if (inode) { ++ AuDebugOn(!atomic_read(&inode->i_count)); ++ atomic_inc(&inode->i_count); ++ } ++ return inode; ++} ++ ++static void au_refresh_hinode_attr(struct inode *inode, int do_version) ++{ ++ au_cpup_attr_all(inode, /*force*/0); ++ au_update_iigen(inode); ++ if (do_version) ++ inode->i_version++; ++} ++ ++int au_refresh_hinode_self(struct inode *inode, int do_attr) ++{ ++ int err; ++ aufs_bindex_t bindex, new_bindex; ++ unsigned char update; ++ struct inode *first; ++ struct au_hinode *p, *q, tmp; ++ struct super_block *sb; ++ struct au_iinfo *iinfo; ++ ++ update = 0; ++ sb = inode->i_sb; ++ iinfo = au_ii(inode); ++ err = au_ii_realloc(iinfo, au_sbend(sb) + 1); ++ if (unlikely(err)) ++ goto out; ++ ++ p = iinfo->ii_hinode + iinfo->ii_bstart; ++ first = p->hi_inode; ++ err = 0; ++ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; ++ bindex++, p++) { ++ if (!p->hi_inode) ++ continue; ++ ++ new_bindex = au_br_index(sb, p->hi_id); ++ if (new_bindex == bindex) ++ continue; ++ ++ if (new_bindex < 0) { ++ update++; ++ au_hiput(p); ++ p->hi_inode = NULL; ++ continue; ++ } ++ ++ if (new_bindex < iinfo->ii_bstart) ++ iinfo->ii_bstart = new_bindex; ++ if (iinfo->ii_bend < new_bindex) ++ iinfo->ii_bend = new_bindex; ++ /* swap two lower inode, and loop again */ ++ q = iinfo->ii_hinode + new_bindex; ++ tmp = *q; ++ *q = *p; ++ *p = tmp; ++ if (tmp.hi_inode) { ++ bindex--; ++ p--; ++ } ++ } ++ au_update_brange(inode, /*do_put_zero*/0); ++ if (do_attr) ++ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode)); ++ ++ out: ++ return err; ++} ++ ++int au_refresh_hinode(struct inode *inode, struct dentry *dentry) ++{ ++ int err, update; ++ unsigned int flags; ++ aufs_bindex_t bindex, bend; ++ unsigned char isdir; ++ struct inode *first; ++ struct au_hinode *p; ++ struct au_iinfo *iinfo; ++ ++ err = au_refresh_hinode_self(inode, /*do_attr*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ update = 0; ++ iinfo = au_ii(inode); ++ p = iinfo->ii_hinode + iinfo->ii_bstart; ++ first = p->hi_inode; ++ isdir = S_ISDIR(inode->i_mode); ++ flags = au_hi_flags(inode, isdir); ++ bend = au_dbend(dentry); ++ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) { ++ struct inode *h_i; ++ struct dentry *h_d; ++ ++ h_d = au_h_dptr(dentry, bindex); ++ if (!h_d || !h_d->d_inode) ++ continue; ++ ++ if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) { ++ h_i = au_h_iptr(inode, bindex); ++ if (h_i) { ++ if (h_i == h_d->d_inode) ++ continue; ++ err = -EIO; ++ break; ++ } ++ } ++ if (bindex < iinfo->ii_bstart) ++ iinfo->ii_bstart = bindex; ++ if (iinfo->ii_bend < bindex) ++ iinfo->ii_bend = bindex; ++ au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags); ++ update = 1; ++ } ++ au_update_brange(inode, /*do_put_zero*/0); ++ ++ if (unlikely(err)) ++ goto out; ++ ++ au_refresh_hinode_attr(inode, update && isdir); ++ ++ out: ++ return err; ++} ++ ++static int set_inode(struct inode *inode, struct dentry *dentry) ++{ ++ int err; ++ unsigned int flags; ++ umode_t mode; ++ aufs_bindex_t bindex, bstart, btail; ++ unsigned char isdir; ++ struct dentry *h_dentry; ++ struct inode *h_inode; ++ struct au_iinfo *iinfo; ++ ++ err = 0; ++ isdir = 0; ++ bstart = au_dbstart(dentry); ++ h_inode = au_h_dptr(dentry, bstart)->d_inode; ++ mode = h_inode->i_mode; ++ switch (mode & S_IFMT) { ++ case S_IFREG: ++ btail = au_dbtail(dentry); ++ inode->i_op = &aufs_iop; ++ inode->i_fop = &aufs_file_fop; ++ inode->i_mapping->a_ops = &aufs_aop; ++ break; ++ case S_IFDIR: ++ isdir = 1; ++ btail = au_dbtaildir(dentry); ++ inode->i_op = &aufs_dir_iop; ++ inode->i_fop = &aufs_dir_fop; ++ break; ++ case S_IFLNK: ++ btail = au_dbtail(dentry); ++ inode->i_op = &aufs_symlink_iop; ++ break; ++ case S_IFBLK: ++ case S_IFCHR: ++ case S_IFIFO: ++ case S_IFSOCK: ++ btail = au_dbtail(dentry); ++ inode->i_op = &aufs_iop; ++ init_special_inode(inode, mode, h_inode->i_rdev); ++ break; ++ default: ++ AuIOErr("Unknown file type 0%o\n", mode); ++ err = -EIO; ++ goto out; ++ } ++ ++ /* do not set inotify for whiteouted dirs (SHWH mode) */ ++ flags = au_hi_flags(inode, isdir); ++ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH) ++ && au_ftest_hi(flags, HINOTIFY) ++ && dentry->d_name.len > AUFS_WH_PFX_LEN ++ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) ++ au_fclr_hi(flags, HINOTIFY); ++ iinfo = au_ii(inode); ++ iinfo->ii_bstart = bstart; ++ iinfo->ii_bend = btail; ++ for (bindex = bstart; bindex <= btail; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry) ++ au_set_h_iptr(inode, bindex, ++ au_igrab(h_dentry->d_inode), flags); ++ } ++ au_cpup_attr_all(inode, /*force*/1); ++ ++ out: ++ return err; ++} ++ ++/* successful returns with iinfo write_locked */ ++static int reval_inode(struct inode *inode, struct dentry *dentry, int *matched) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ struct inode *h_inode, *h_dinode; ++ ++ *matched = 0; ++ ++ /* ++ * before this function, if aufs got any iinfo lock, it must be only ++ * one, the parent dir. ++ * it can happen by UDBA and the obsoleted inode number. ++ */ ++ err = -EIO; ++ if (unlikely(inode->i_ino == parent_ino(dentry))) ++ goto out; ++ ++ err = 0; ++ ii_write_lock_new_child(inode); ++ h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode; ++ bend = au_ibend(inode); ++ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) { ++ h_inode = au_h_iptr(inode, bindex); ++ if (h_inode && h_inode == h_dinode) { ++ *matched = 1; ++ err = 0; ++ if (au_iigen(inode) != au_digen(dentry)) ++ err = au_refresh_hinode(inode, dentry); ++ break; ++ } ++ } ++ ++ if (unlikely(err)) ++ ii_write_unlock(inode); ++ out: ++ return err; ++} ++ ++/* successful returns with iinfo write_locked */ ++/* todo: return with unlocked? */ ++struct inode *au_new_inode(struct dentry *dentry, int must_new) ++{ ++ struct inode *inode; ++ struct dentry *h_dentry; ++ struct super_block *sb; ++ ino_t h_ino, ino; ++ int err, match; ++ aufs_bindex_t bstart; ++ ++ sb = dentry->d_sb; ++ bstart = au_dbstart(dentry); ++ h_dentry = au_h_dptr(dentry, bstart); ++ h_ino = h_dentry->d_inode->i_ino; ++ err = au_xino_read(sb, bstart, h_ino, &ino); ++ inode = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ new_ino: ++ if (!ino) { ++ ino = au_xino_new_ino(sb); ++ if (unlikely(!ino)) { ++ inode = ERR_PTR(-EIO); ++ goto out; ++ } ++ } ++ ++ AuDbg("i%lu\n", (unsigned long)ino); ++ inode = au_iget_locked(sb, ino); ++ err = PTR_ERR(inode); ++ if (IS_ERR(inode)) ++ goto out; ++ ++ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW)); ++ if (inode->i_state & I_NEW) { ++ ii_write_lock_new_child(inode); ++ err = set_inode(inode, dentry); ++ unlock_new_inode(inode); ++ if (!err) ++ goto out; /* success */ ++ ++ iget_failed(inode); ++ ii_write_unlock(inode); ++ goto out_iput; ++ } else if (!must_new) { ++ err = reval_inode(inode, dentry, &match); ++ if (!err) ++ goto out; /* success */ ++ else if (match) ++ goto out_iput; ++ } ++ ++ if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode))) ++ AuWarn1("Un-notified UDBA or repeatedly renamed dir," ++ " b%d, %s, %.*s, hi%lu, i%lu.\n", ++ bstart, au_sbtype(h_dentry->d_sb), AuDLNPair(dentry), ++ (unsigned long)h_ino, (unsigned long)ino); ++ ino = 0; ++ err = au_xino_write0(sb, bstart, h_ino, 0); ++ if (!err) { ++ iput(inode); ++ goto new_ino; ++ } ++ ++ out_iput: ++ iput(inode); ++ inode = ERR_PTR(err); ++ out: ++ return inode; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, ++ struct inode *inode) ++{ ++ int err; ++ ++ err = au_br_rdonly(au_sbr(sb, bindex)); ++ ++ /* pseudo-link after flushed may happen out of bounds */ ++ if (!err ++ && inode ++ && au_ibstart(inode) <= bindex ++ && bindex <= au_ibend(inode)) { ++ /* ++ * permission check is unnecessary since vfsub routine ++ * will be called later ++ */ ++ struct inode *hi = au_h_iptr(inode, bindex); ++ if (hi) ++ err = IS_IMMUTABLE(hi) ? -EROFS : 0; ++ } ++ ++ return err; ++} ++ ++int au_test_h_perm(struct inode *h_inode, int mask) ++{ ++ if (!current_fsuid()) ++ return 0; ++ return inode_permission(h_inode, mask); ++} ++ ++int au_test_h_perm_sio(struct inode *h_inode, int mask) ++{ ++ if (au_test_nfs(h_inode->i_sb) ++ && (mask & MAY_WRITE) ++ && S_ISDIR(h_inode->i_mode)) ++ mask |= MAY_READ; /* force permission check */ ++ return au_test_h_perm(h_inode, mask); ++} +diff -Naur a/fs/aufs/inode.h b/fs/aufs/inode.h +--- a/fs/aufs/inode.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/inode.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,473 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * inode operations ++ */ ++ ++#ifndef __AUFS_INODE_H__ ++#define __AUFS_INODE_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++#include "rwsem.h" ++ ++struct vfsmount; ++ ++struct au_hinotify { ++#ifdef CONFIG_AUFS_HINOTIFY ++ struct inotify_watch hin_watch; ++ struct inode *hin_aufs_inode; /* no get/put */ ++#endif ++}; ++ ++struct au_hinode { ++ struct inode *hi_inode; ++ aufs_bindex_t hi_id; ++#ifdef CONFIG_AUFS_HINOTIFY ++ struct au_hinotify *hi_notify; ++#endif ++ ++ /* reference to the copied-up whiteout with get/put */ ++ struct dentry *hi_whdentry; ++}; ++ ++struct au_vdir; ++struct au_iinfo { ++ atomic_t ii_generation; ++ struct super_block *ii_hsb1; /* no get/put */ ++ ++ struct rw_semaphore ii_rwsem; ++ aufs_bindex_t ii_bstart, ii_bend; ++ __u32 ii_higen; ++ struct au_hinode *ii_hinode; ++ struct au_vdir *ii_vdir; ++}; ++ ++struct au_icntnr { ++ struct au_iinfo iinfo; ++ struct inode vfs_inode; ++}; ++ ++/* au_pin flags */ ++#define AuPin_DI_LOCKED 1 ++#define AuPin_MNT_WRITE (1 << 1) ++#define au_ftest_pin(flags, name) ((flags) & AuPin_##name) ++#define au_fset_pin(flags, name) { (flags) |= AuPin_##name; } ++#define au_fclr_pin(flags, name) { (flags) &= ~AuPin_##name; } ++ ++struct au_pin { ++ /* input */ ++ struct dentry *dentry; ++ unsigned int udba; ++ unsigned char lsc_di, lsc_hi, flags; ++ aufs_bindex_t bindex; ++ ++ /* output */ ++ struct dentry *parent; ++ struct au_hinode *hdir; ++ struct vfsmount *h_mnt; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct au_iinfo *au_ii(struct inode *inode) ++{ ++ struct au_iinfo *iinfo; ++ ++ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo); ++ if (iinfo->ii_hinode) ++ return iinfo; ++ return NULL; /* debugging bad_inode case */ ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* inode.c */ ++struct inode *au_igrab(struct inode *inode); ++int au_refresh_hinode_self(struct inode *inode, int do_attr); ++int au_refresh_hinode(struct inode *inode, struct dentry *dentry); ++struct inode *au_new_inode(struct dentry *dentry, int must_new); ++int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, ++ struct inode *inode); ++int au_test_h_perm(struct inode *h_inode, int mask); ++int au_test_h_perm_sio(struct inode *h_inode, int mask); ++ ++/* i_op.c */ ++extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop; ++ ++/* au_wr_dir flags */ ++#define AuWrDir_ADD_ENTRY 1 ++#define AuWrDir_ISDIR (1 << 1) ++#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name) ++#define au_fset_wrdir(flags, name) { (flags) |= AuWrDir_##name; } ++#define au_fclr_wrdir(flags, name) { (flags) &= ~AuWrDir_##name; } ++ ++struct au_wr_dir_args { ++ aufs_bindex_t force_btgt; ++ unsigned char flags; ++}; ++int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, ++ struct au_wr_dir_args *args); ++ ++struct dentry *au_pinned_h_parent(struct au_pin *pin); ++void au_pin_init(struct au_pin *pin, struct dentry *dentry, ++ aufs_bindex_t bindex, int lsc_di, int lsc_hi, ++ unsigned int udba, unsigned char flags); ++int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int udba, unsigned char flags) __must_check; ++int au_do_pin(struct au_pin *pin) __must_check; ++void au_unpin(struct au_pin *pin); ++ ++/* i_op_add.c */ ++int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent, int isdir); ++int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev); ++int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname); ++int aufs_create(struct inode *dir, struct dentry *dentry, int mode, ++ struct nameidata *nd); ++int aufs_link(struct dentry *src_dentry, struct inode *dir, ++ struct dentry *dentry); ++int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode); ++ ++/* i_op_del.c */ ++int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup); ++int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent, int isdir); ++int aufs_unlink(struct inode *dir, struct dentry *dentry); ++int aufs_rmdir(struct inode *dir, struct dentry *dentry); ++ ++/* i_op_ren.c */ ++int au_wbr(struct dentry *dentry, aufs_bindex_t btgt); ++int aufs_rename(struct inode *src_dir, struct dentry *src_dentry, ++ struct inode *dir, struct dentry *dentry); ++ ++/* iinfo.c */ ++struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex); ++void au_hiput(struct au_hinode *hinode); ++void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex); ++void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_wh); ++unsigned int au_hi_flags(struct inode *inode, int isdir); ++ ++/* hinode flags */ ++#define AuHi_XINO 1 ++#define AuHi_HINOTIFY (1 << 1) ++#define au_ftest_hi(flags, name) ((flags) & AuHi_##name) ++#define au_fset_hi(flags, name) { (flags) |= AuHi_##name; } ++#define au_fclr_hi(flags, name) { (flags) &= ~AuHi_##name; } ++ ++#ifndef CONFIG_AUFS_HINOTIFY ++#undef AuHi_HINOTIFY ++#define AuHi_HINOTIFY 0 ++#endif ++ ++void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, ++ struct inode *h_inode, unsigned int flags); ++ ++void au_update_iigen(struct inode *inode); ++void au_update_brange(struct inode *inode, int do_put_zero); ++ ++int au_iinfo_init(struct inode *inode); ++void au_iinfo_fin(struct inode *inode); ++int au_ii_realloc(struct au_iinfo *iinfo, int nbr); ++ ++/* plink.c */ ++void au_plink_block_maintain(struct super_block *sb); ++#ifdef CONFIG_AUFS_DEBUG ++void au_plink_list(struct super_block *sb); ++#else ++static inline void au_plink_list(struct super_block *sb) ++{ ++ /* nothing */ ++} ++#endif ++int au_plink_test(struct inode *inode); ++struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex); ++void au_plink_append(struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_dentry); ++void au_plink_put(struct super_block *sb); ++void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* lock subclass for iinfo */ ++enum { ++ AuLsc_II_CHILD, /* child first */ ++ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hinotify */ ++ AuLsc_II_CHILD3, /* copyup dirs */ ++ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */ ++ AuLsc_II_PARENT2, ++ AuLsc_II_PARENT3, /* copyup dirs */ ++ AuLsc_II_NEW_CHILD ++}; ++ ++/* ++ * ii_read_lock_child, ii_write_lock_child, ++ * ii_read_lock_child2, ii_write_lock_child2, ++ * ii_read_lock_child3, ii_write_lock_child3, ++ * ii_read_lock_parent, ii_write_lock_parent, ++ * ii_read_lock_parent2, ii_write_lock_parent2, ++ * ii_read_lock_parent3, ii_write_lock_parent3, ++ * ii_read_lock_new_child, ii_write_lock_new_child, ++ */ ++#define AuReadLockFunc(name, lsc) \ ++static inline void ii_read_lock_##name(struct inode *i) \ ++{ \ ++ down_read_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \ ++} ++ ++#define AuWriteLockFunc(name, lsc) \ ++static inline void ii_write_lock_##name(struct inode *i) \ ++{ \ ++ down_write_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \ ++} ++ ++#define AuRWLockFuncs(name, lsc) \ ++ AuReadLockFunc(name, lsc) \ ++ AuWriteLockFunc(name, lsc) ++ ++AuRWLockFuncs(child, CHILD); ++AuRWLockFuncs(child2, CHILD2); ++AuRWLockFuncs(child3, CHILD3); ++AuRWLockFuncs(parent, PARENT); ++AuRWLockFuncs(parent2, PARENT2); ++AuRWLockFuncs(parent3, PARENT3); ++AuRWLockFuncs(new_child, NEW_CHILD); ++ ++#undef AuReadLockFunc ++#undef AuWriteLockFunc ++#undef AuRWLockFuncs ++ ++/* ++ * ii_read_unlock, ii_write_unlock, ii_downgrade_lock ++ */ ++AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem); ++ ++#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem) ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline unsigned int au_iigen(struct inode *inode) ++{ ++ return atomic_read(&au_ii(inode)->ii_generation); ++} ++ ++/* tiny test for inode number */ ++/* tmpfs generation is too rough */ ++static inline int au_test_higen(struct inode *inode, struct inode *h_inode) ++{ ++ struct au_iinfo *iinfo; ++ ++ iinfo = au_ii(inode); ++ return !(iinfo->ii_hsb1 == h_inode->i_sb ++ && iinfo->ii_higen == h_inode->i_generation); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline aufs_bindex_t au_ii_br_id(struct inode *inode, ++ aufs_bindex_t bindex) ++{ ++ return au_ii(inode)->ii_hinode[0 + bindex].hi_id; ++} ++ ++static inline aufs_bindex_t au_ibstart(struct inode *inode) ++{ ++ return au_ii(inode)->ii_bstart; ++} ++ ++static inline aufs_bindex_t au_ibend(struct inode *inode) ++{ ++ return au_ii(inode)->ii_bend; ++} ++ ++static inline struct au_vdir *au_ivdir(struct inode *inode) ++{ ++ return au_ii(inode)->ii_vdir; ++} ++ ++static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex) ++{ ++ return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry; ++} ++ ++static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex) ++{ ++ au_ii(inode)->ii_bend = bindex; ++} ++ ++static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir) ++{ ++ au_ii(inode)->ii_vdir = vdir; ++} ++ ++static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex) ++{ ++ return au_ii(inode)->ii_hinode + bindex; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct dentry *au_pinned_parent(struct au_pin *pin) ++{ ++ if (pin) ++ return pin->parent; ++ return NULL; ++} ++ ++static inline struct inode *au_pinned_h_dir(struct au_pin *pin) ++{ ++ if (pin && pin->hdir) ++ return pin->hdir->hi_inode; ++ return NULL; ++} ++ ++static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin) ++{ ++ if (pin) ++ return pin->hdir; ++ return NULL; ++} ++ ++static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry) ++{ ++ if (pin) ++ pin->dentry = dentry; ++} ++ ++static inline void au_pin_set_parent_lflag(struct au_pin *pin, ++ unsigned char lflag) ++{ ++ if (pin) { ++ /* dirty macros require brackets */ ++ if (lflag) { ++ au_fset_pin(pin->flags, DI_LOCKED); ++ } else { ++ au_fclr_pin(pin->flags, DI_LOCKED); ++ } ++ } ++} ++ ++static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent) ++{ ++ if (pin) { ++ dput(pin->parent); ++ pin->parent = dget(parent); ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_HINOTIFY ++/* hinotify.c */ ++int au_hin_alloc(struct au_hinode *hinode, struct inode *inode, ++ struct inode *h_inode); ++void au_hin_free(struct au_hinode *hinode); ++void au_hin_ctl(struct au_hinode *hinode, int do_set); ++void au_reset_hinotify(struct inode *inode, unsigned int flags); ++ ++int __init au_hinotify_init(void); ++void au_hinotify_fin(void); ++ ++static inline ++void au_hin_init(struct au_hinode *hinode, struct au_hinotify *val) ++{ ++ hinode->hi_notify = val; ++} ++ ++static inline void au_iigen_dec(struct inode *inode) ++{ ++ atomic_dec(&au_ii(inode)->ii_generation); ++} ++ ++#else ++static inline ++int au_hin_alloc(struct au_hinode *hinode __maybe_unused, ++ struct inode *inode __maybe_unused, ++ struct inode *h_inode __maybe_unused) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static inline void au_hin_free(struct au_hinode *hinode __maybe_unused) ++{ ++ /* nothing */ ++} ++ ++static inline void au_hin_ctl(struct au_hinode *hinode __maybe_unused, ++ int do_set __maybe_unused) ++{ ++ /* nothing */ ++} ++ ++static inline void au_reset_hinotify(struct inode *inode __maybe_unused, ++ unsigned int flags __maybe_unused) ++{ ++ /* nothing */ ++} ++ ++static inline int au_hinotify_init(void) ++{ ++ return 0; ++} ++ ++#define au_hinotify_fin() do {} while (0) ++ ++static inline ++void au_hin_init(struct au_hinode *hinode __maybe_unused, ++ struct au_hinotify *val __maybe_unused) ++{ ++ /* empty */ ++} ++#endif /* CONFIG_AUFS_HINOTIFY */ ++ ++static inline void au_hin_suspend(struct au_hinode *hdir) ++{ ++ au_hin_ctl(hdir, /*do_set*/0); ++} ++ ++static inline void au_hin_resume(struct au_hinode *hdir) ++{ ++ au_hin_ctl(hdir, /*do_set*/1); ++} ++ ++static inline void au_hin_imtx_lock(struct au_hinode *hdir) ++{ ++ mutex_lock(&hdir->hi_inode->i_mutex); ++ au_hin_suspend(hdir); ++} ++ ++static inline void au_hin_imtx_lock_nested(struct au_hinode *hdir, ++ unsigned int sc __maybe_unused) ++{ ++ mutex_lock_nested(&hdir->hi_inode->i_mutex, sc); ++ au_hin_suspend(hdir); ++} ++ ++static inline void au_hin_imtx_unlock(struct au_hinode *hdir) ++{ ++ au_hin_resume(hdir); ++ mutex_unlock(&hdir->hi_inode->i_mutex); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_INODE_H__ */ +diff -Naur a/fs/aufs/ioctl.c b/fs/aufs/ioctl.c +--- a/fs/aufs/ioctl.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/ioctl.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,68 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * ioctl ++ * currently plink-management only. ++ */ ++ ++#include ++#include "aufs.h" ++ ++long aufs_ioctl_dir(struct file *file, unsigned int cmd, ++ unsigned long arg __maybe_unused) ++{ ++ long err; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ ++ err = -EACCES; ++ if (!capable(CAP_SYS_ADMIN)) ++ goto out; ++ ++ err = 0; ++ sb = file->f_dentry->d_sb; ++ sbinfo = au_sbi(sb); ++ switch (cmd) { ++ case AUFS_CTL_PLINK_MAINT: ++ /* ++ * pseudo-link maintenance mode, ++ * cleared by aufs_release_dir() ++ */ ++ si_write_lock(sb); ++ if (!au_ftest_si(sbinfo, MAINTAIN_PLINK)) { ++ au_fset_si(sbinfo, MAINTAIN_PLINK); ++ au_fi(file)->fi_maintain_plink = 1; ++ } else ++ err = -EBUSY; ++ si_write_unlock(sb); ++ break; ++ case AUFS_CTL_PLINK_CLEAN: ++ if (au_opt_test(sbinfo->si_mntflags, PLINK)) { ++ aufs_write_lock(sb->s_root); ++ au_plink_put(sb); ++ aufs_write_unlock(sb->s_root); ++ } ++ break; ++ default: ++ err = -EINVAL; ++ } ++ ++ out: ++ return err; ++} +diff -Naur a/fs/aufs/i_op_add.c b/fs/aufs/i_op_add.c +--- a/fs/aufs/i_op_add.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/i_op_add.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,638 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * inode operations (add entry) ++ */ ++ ++#include "aufs.h" ++ ++/* ++ * final procedure of adding a new entry, except link(2). ++ * remove whiteout, instantiate, copyup the parent dir's times and size ++ * and update version. ++ * if it failed, re-create the removed whiteout. ++ */ ++static int epilog(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct dentry *dentry) ++{ ++ int err, rerr; ++ aufs_bindex_t bwh; ++ struct path h_path; ++ struct inode *inode, *h_dir; ++ struct dentry *wh; ++ ++ bwh = -1; ++ if (wh_dentry) { ++ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */ ++ IMustLock(h_dir); ++ AuDebugOn(au_h_iptr(dir, bindex) != h_dir); ++ bwh = au_dbwh(dentry); ++ h_path.dentry = wh_dentry; ++ h_path.mnt = au_sbr_mnt(dir->i_sb, bindex); ++ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, ++ dentry); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ inode = au_new_inode(dentry, /*must_new*/1); ++ if (!IS_ERR(inode)) { ++ d_instantiate(dentry, inode); ++ dir = dentry->d_parent->d_inode; /* dir inode is locked */ ++ IMustLock(dir); ++ if (au_ibstart(dir) == au_dbstart(dentry)) ++ au_cpup_attr_timesizes(dir); ++ dir->i_version++; ++ return 0; /* success */ ++ } ++ ++ err = PTR_ERR(inode); ++ if (!wh_dentry) ++ goto out; ++ ++ /* revert */ ++ /* dir inode is locked */ ++ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent); ++ rerr = PTR_ERR(wh); ++ if (IS_ERR(wh)) { ++ AuIOErr("%.*s reverting whiteout failed(%d, %d)\n", ++ AuDLNPair(dentry), err, rerr); ++ err = -EIO; ++ } else ++ dput(wh); ++ ++ out: ++ return err; ++} ++ ++/* ++ * simple tests for the adding inode operations. ++ * following the checks in vfs, plus the parent-child relationship. ++ */ ++int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent, int isdir) ++{ ++ int err; ++ umode_t h_mode; ++ struct dentry *h_dentry; ++ struct inode *h_inode; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ h_inode = h_dentry->d_inode; ++ if (!dentry->d_inode) { ++ err = -EEXIST; ++ if (unlikely(h_inode)) ++ goto out; ++ } else { ++ /* rename(2) case */ ++ err = -EIO; ++ if (unlikely(!h_inode || !h_inode->i_nlink)) ++ goto out; ++ ++ h_mode = h_inode->i_mode; ++ if (!isdir) { ++ err = -EISDIR; ++ if (unlikely(S_ISDIR(h_mode))) ++ goto out; ++ } else if (unlikely(!S_ISDIR(h_mode))) { ++ err = -ENOTDIR; ++ goto out; ++ } ++ } ++ ++ err = -EIO; ++ /* expected parent dir is locked */ ++ if (unlikely(h_parent != h_dentry->d_parent)) ++ goto out; ++ err = 0; ++ ++ out: ++ return err; ++} ++ ++/* ++ * initial procedure of adding a new entry. ++ * prepare writable branch and the parent dir, lock it, ++ * and lookup whiteout for the new entry. ++ */ ++static struct dentry* ++lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt, ++ struct dentry *src_dentry, struct au_pin *pin, ++ struct au_wr_dir_args *wr_dir_args) ++{ ++ struct dentry *wh_dentry, *h_parent; ++ struct super_block *sb; ++ struct au_branch *br; ++ int err; ++ unsigned int udba; ++ aufs_bindex_t bcpup; ++ ++ err = au_wr_dir(dentry, src_dentry, wr_dir_args); ++ bcpup = err; ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err < 0)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ udba = au_opt_udba(sb); ++ err = au_pin(pin, dentry, bcpup, udba, ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ ++ h_parent = au_pinned_h_parent(pin); ++ if (udba != AuOpt_UDBA_NONE ++ && au_dbstart(dentry) == bcpup) { ++ err = au_may_add(dentry, bcpup, h_parent, ++ au_ftest_wrdir(wr_dir_args->flags, ISDIR)); ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out_unpin; ++ } ++ ++ br = au_sbr(sb, bcpup); ++ if (dt) { ++ struct path tmp = { ++ .dentry = h_parent, ++ .mnt = br->br_mnt ++ }; ++ au_dtime_store(dt, au_pinned_parent(pin), &tmp); ++ } ++ ++ wh_dentry = NULL; ++ if (bcpup != au_dbwh(dentry)) ++ goto out; /* success */ ++ ++ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br); ++ ++ out_unpin: ++ if (IS_ERR(wh_dentry)) ++ au_unpin(pin); ++ out: ++ return wh_dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++enum { Mknod, Symlink, Creat }; ++struct simple_arg { ++ int type; ++ union { ++ struct { ++ int mode; ++ struct nameidata *nd; ++ } c; ++ struct { ++ const char *symname; ++ } s; ++ struct { ++ int mode; ++ dev_t dev; ++ } m; ++ } u; ++}; ++ ++static int add_simple(struct inode *dir, struct dentry *dentry, ++ struct simple_arg *arg) ++{ ++ int err; ++ aufs_bindex_t bstart; ++ unsigned char created; ++ struct au_dtime dt; ++ struct au_pin pin; ++ struct path h_path; ++ struct dentry *wh_dentry, *parent; ++ struct inode *h_dir; ++ struct au_wr_dir_args wr_dir_args = { ++ .force_btgt = -1, ++ .flags = AuWrDir_ADD_ENTRY ++ }; ++ ++ IMustLock(dir); ++ ++ parent = dentry->d_parent; /* dir inode is locked */ ++ aufs_read_lock(dentry, AuLock_DW); ++ di_write_lock_parent(parent); ++ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL, &pin, ++ &wr_dir_args); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out; ++ ++ bstart = au_dbstart(dentry); ++ h_path.dentry = au_h_dptr(dentry, bstart); ++ h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart); ++ h_dir = au_pinned_h_dir(&pin); ++ switch (arg->type) { ++ case Creat: ++ err = vfsub_create(h_dir, &h_path, arg->u.c.mode); ++ break; ++ case Symlink: ++ err = vfsub_symlink(h_dir, &h_path, arg->u.s.symname); ++ break; ++ case Mknod: ++ err = vfsub_mknod(h_dir, &h_path, arg->u.m.mode, arg->u.m.dev); ++ break; ++ default: ++ BUG(); ++ } ++ created = !err; ++ if (!err) ++ err = epilog(dir, bstart, wh_dentry, dentry); ++ ++ /* revert */ ++ if (unlikely(created && err && h_path.dentry->d_inode)) { ++ int rerr; ++ rerr = vfsub_unlink(h_dir, &h_path, /*force*/0); ++ if (rerr) { ++ AuIOErr("%.*s revert failure(%d, %d)\n", ++ AuDLNPair(dentry), err, rerr); ++ err = -EIO; ++ } ++ au_dtime_revert(&dt); ++ d_drop(dentry); ++ } ++ ++ au_unpin(&pin); ++ dput(wh_dentry); ++ ++ out: ++ if (unlikely(err)) { ++ au_update_dbstart(dentry); ++ d_drop(dentry); ++ } ++ di_write_unlock(parent); ++ aufs_read_unlock(dentry, AuLock_DW); ++ return err; ++} ++ ++int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) ++{ ++ struct simple_arg arg = { ++ .type = Mknod, ++ .u.m = { ++ .mode = mode, ++ .dev = dev ++ } ++ }; ++ return add_simple(dir, dentry, &arg); ++} ++ ++int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) ++{ ++ struct simple_arg arg = { ++ .type = Symlink, ++ .u.s.symname = symname ++ }; ++ return add_simple(dir, dentry, &arg); ++} ++ ++int aufs_create(struct inode *dir, struct dentry *dentry, int mode, ++ struct nameidata *nd) ++{ ++ struct simple_arg arg = { ++ .type = Creat, ++ .u.c = { ++ .mode = mode, ++ .nd = nd ++ } ++ }; ++ return add_simple(dir, dentry, &arg); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_link_args { ++ aufs_bindex_t bdst, bsrc; ++ struct au_pin pin; ++ struct path h_path; ++ struct dentry *src_parent, *parent; ++}; ++ ++static int au_cpup_before_link(struct dentry *src_dentry, ++ struct au_link_args *a) ++{ ++ int err; ++ struct dentry *h_src_dentry; ++ struct mutex *h_mtx; ++ ++ di_read_lock_parent(a->src_parent, AuLock_IR); ++ err = au_test_and_cpup_dirs(src_dentry, a->bdst); ++ if (unlikely(err)) ++ goto out; ++ ++ h_src_dentry = au_h_dptr(src_dentry, a->bsrc); ++ h_mtx = &h_src_dentry->d_inode->i_mutex; ++ err = au_pin(&a->pin, src_dentry, a->bdst, ++ au_opt_udba(src_dentry->d_sb), ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (unlikely(err)) ++ goto out; ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ err = au_sio_cpup_simple(src_dentry, a->bdst, -1, ++ AuCpup_DTIME /* | AuCpup_KEEPLINO */); ++ mutex_unlock(h_mtx); ++ au_unpin(&a->pin); ++ ++ out: ++ di_read_unlock(a->src_parent, AuLock_IR); ++ return err; ++} ++ ++static int au_cpup_or_link(struct dentry *src_dentry, struct au_link_args *a) ++{ ++ int err; ++ unsigned char plink; ++ struct inode *h_inode, *inode; ++ struct dentry *h_src_dentry; ++ struct super_block *sb; ++ ++ plink = 0; ++ h_inode = NULL; ++ sb = src_dentry->d_sb; ++ inode = src_dentry->d_inode; ++ if (au_ibstart(inode) <= a->bdst) ++ h_inode = au_h_iptr(inode, a->bdst); ++ if (!h_inode || !h_inode->i_nlink) { ++ /* copyup src_dentry as the name of dentry. */ ++ au_set_dbstart(src_dentry, a->bdst); ++ au_set_h_dptr(src_dentry, a->bdst, dget(a->h_path.dentry)); ++ h_inode = au_h_dptr(src_dentry, a->bsrc)->d_inode; ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ err = au_sio_cpup_single(src_dentry, a->bdst, a->bsrc, -1, ++ AuCpup_KEEPLINO, a->parent); ++ mutex_unlock(&h_inode->i_mutex); ++ au_set_h_dptr(src_dentry, a->bdst, NULL); ++ au_set_dbstart(src_dentry, a->bsrc); ++ } else { ++ /* the inode of src_dentry already exists on a.bdst branch */ ++ h_src_dentry = d_find_alias(h_inode); ++ if (!h_src_dentry && au_plink_test(inode)) { ++ plink = 1; ++ h_src_dentry = au_plink_lkup(inode, a->bdst); ++ err = PTR_ERR(h_src_dentry); ++ if (IS_ERR(h_src_dentry)) ++ goto out; ++ ++ if (unlikely(!h_src_dentry->d_inode)) { ++ dput(h_src_dentry); ++ h_src_dentry = NULL; ++ } ++ ++ } ++ if (h_src_dentry) { ++ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), ++ &a->h_path); ++ dput(h_src_dentry); ++ } else { ++ AuIOErr("no dentry found for hi%lu on b%d\n", ++ h_inode->i_ino, a->bdst); ++ err = -EIO; ++ } ++ } ++ ++ if (!err && !plink) ++ au_plink_append(inode, a->bdst, a->h_path.dentry); ++ ++out: ++ return err; ++} ++ ++int aufs_link(struct dentry *src_dentry, struct inode *dir, ++ struct dentry *dentry) ++{ ++ int err, rerr; ++ struct au_dtime dt; ++ struct au_link_args *a; ++ struct dentry *wh_dentry, *h_src_dentry; ++ struct inode *inode; ++ struct super_block *sb; ++ struct au_wr_dir_args wr_dir_args = { ++ /* .force_btgt = -1, */ ++ .flags = AuWrDir_ADD_ENTRY ++ }; ++ ++ IMustLock(dir); ++ inode = src_dentry->d_inode; ++ IMustLock(inode); ++ ++ err = -ENOENT; ++ if (unlikely(!inode->i_nlink)) ++ goto out; ++ ++ err = -ENOMEM; ++ a = kzalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ a->parent = dentry->d_parent; /* dir inode is locked */ ++ aufs_read_and_write_lock2(dentry, src_dentry, /*AuLock_FLUSH*/0); ++ a->src_parent = dget_parent(src_dentry); ++ wr_dir_args.force_btgt = au_dbstart(src_dentry); ++ ++ di_write_lock_parent(a->parent); ++ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt); ++ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin, ++ &wr_dir_args); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out_unlock; ++ ++ err = 0; ++ sb = dentry->d_sb; ++ a->bdst = au_dbstart(dentry); ++ a->h_path.dentry = au_h_dptr(dentry, a->bdst); ++ a->h_path.mnt = au_sbr_mnt(sb, a->bdst); ++ a->bsrc = au_dbstart(src_dentry); ++ if (au_opt_test(au_mntflags(sb), PLINK)) { ++ if (a->bdst < a->bsrc ++ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) ++ err = au_cpup_or_link(src_dentry, a); ++ else { ++ h_src_dentry = au_h_dptr(src_dentry, a->bdst); ++ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), ++ &a->h_path); ++ } ++ } else { ++ /* ++ * copyup src_dentry to the branch we process, ++ * and then link(2) to it. ++ */ ++ if (a->bdst < a->bsrc ++ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) { ++ au_unpin(&a->pin); ++ di_write_unlock(a->parent); ++ err = au_cpup_before_link(src_dentry, a); ++ if (!err) { ++ di_write_lock_parent(a->parent); ++ err = au_pin(&a->pin, dentry, a->bdst, ++ au_opt_udba(sb), ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (unlikely(err)) ++ goto out_wh; ++ } ++ } ++ if (!err) { ++ h_src_dentry = au_h_dptr(src_dentry, a->bdst); ++ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), ++ &a->h_path); ++ } ++ } ++ if (unlikely(err)) ++ goto out_unpin; ++ ++ if (wh_dentry) { ++ a->h_path.dentry = wh_dentry; ++ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path, ++ dentry); ++ if (unlikely(err)) ++ goto out_revert; ++ } ++ ++ dir->i_version++; ++ if (au_ibstart(dir) == au_dbstart(dentry)) ++ au_cpup_attr_timesizes(dir); ++ inc_nlink(inode); ++ inode->i_ctime = dir->i_ctime; ++ if (!d_unhashed(a->h_path.dentry)) ++ d_instantiate(dentry, au_igrab(inode)); ++ else ++ /* some filesystem calls d_drop() */ ++ d_drop(dentry); ++ goto out_unpin; /* success */ ++ ++ out_revert: ++ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path, /*force*/0); ++ if (!rerr) ++ goto out_dt; ++ AuIOErr("%.*s reverting failed(%d, %d)\n", ++ AuDLNPair(dentry), err, rerr); ++ err = -EIO; ++ out_dt: ++ d_drop(dentry); ++ au_dtime_revert(&dt); ++ out_unpin: ++ au_unpin(&a->pin); ++ out_wh: ++ dput(wh_dentry); ++ out_unlock: ++ if (unlikely(err)) { ++ au_update_dbstart(dentry); ++ d_drop(dentry); ++ } ++ di_write_unlock(a->parent); ++ dput(a->src_parent); ++ aufs_read_and_write_unlock2(dentry, src_dentry); ++ kfree(a); ++ out: ++ return err; ++} ++ ++int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ++{ ++ int err, rerr; ++ aufs_bindex_t bindex; ++ unsigned char diropq; ++ struct au_pin pin; ++ struct path h_path; ++ struct dentry *wh_dentry, *parent, *opq_dentry; ++ struct mutex *h_mtx; ++ struct super_block *sb; ++ struct au_dtime dt; ++ struct au_wr_dir_args wr_dir_args = { ++ .force_btgt = -1, ++ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR ++ }; ++ ++ IMustLock(dir); ++ ++ aufs_read_lock(dentry, AuLock_DW); ++ parent = dentry->d_parent; /* dir inode is locked */ ++ di_write_lock_parent(parent); ++ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL, &pin, ++ &wr_dir_args); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ bindex = au_dbstart(dentry); ++ h_path.dentry = au_h_dptr(dentry, bindex); ++ h_path.mnt = au_sbr_mnt(sb, bindex); ++ err = vfsub_mkdir(au_pinned_h_dir(&pin), &h_path, mode); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ /* make the dir opaque */ ++ diropq = 0; ++ h_mtx = &h_path.dentry->d_inode->i_mutex; ++ if (wh_dentry ++ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) { ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ opq_dentry = au_diropq_create(dentry, bindex); ++ mutex_unlock(h_mtx); ++ err = PTR_ERR(opq_dentry); ++ if (IS_ERR(opq_dentry)) ++ goto out_dir; ++ dput(opq_dentry); ++ diropq = 1; ++ } ++ ++ err = epilog(dir, bindex, wh_dentry, dentry); ++ if (!err) { ++ inc_nlink(dir); ++ goto out_unlock; /* success */ ++ } ++ ++ /* revert */ ++ if (diropq) { ++ AuLabel(revert opq); ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ rerr = au_diropq_remove(dentry, bindex); ++ mutex_unlock(h_mtx); ++ if (rerr) { ++ AuIOErr("%.*s reverting diropq failed(%d, %d)\n", ++ AuDLNPair(dentry), err, rerr); ++ err = -EIO; ++ } ++ } ++ ++ out_dir: ++ AuLabel(revert dir); ++ rerr = vfsub_rmdir(au_pinned_h_dir(&pin), &h_path); ++ if (rerr) { ++ AuIOErr("%.*s reverting dir failed(%d, %d)\n", ++ AuDLNPair(dentry), err, rerr); ++ err = -EIO; ++ } ++ d_drop(dentry); ++ au_dtime_revert(&dt); ++ out_unlock: ++ au_unpin(&pin); ++ dput(wh_dentry); ++ out: ++ if (unlikely(err)) { ++ au_update_dbstart(dentry); ++ d_drop(dentry); ++ } ++ di_write_unlock(parent); ++ aufs_read_unlock(dentry, AuLock_DW); ++ return err; ++} +diff -Naur a/fs/aufs/i_op.c b/fs/aufs/i_op.c +--- a/fs/aufs/i_op.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/i_op.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,874 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * inode operations (except add/del/rename) ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++static int h_permission(struct inode *h_inode, int mask, ++ struct vfsmount *h_mnt, int brperm) ++{ ++ int err; ++ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND)); ++ ++ err = -EACCES; ++ if ((write_mask && IS_IMMUTABLE(h_inode)) ++ || ((mask & MAY_EXEC) ++ && S_ISREG(h_inode->i_mode) ++ && ((h_mnt->mnt_flags & MNT_NOEXEC) ++ || !(h_inode->i_mode & S_IXUGO)))) ++ goto out; ++ ++ /* ++ * - skip the lower fs test in the case of write to ro branch. ++ * - nfs dir permission write check is optimized, but a policy for ++ * link/rename requires a real check. ++ */ ++ if ((write_mask && !au_br_writable(brperm)) ++ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode) ++ && write_mask && !(mask & MAY_READ)) ++ || !h_inode->i_op->permission) { ++ /* AuLabel(generic_permission); */ ++ err = generic_permission(h_inode, mask, NULL); ++ } else { ++ /* AuLabel(h_inode->permission); */ ++ err = h_inode->i_op->permission(h_inode, mask); ++ AuTraceErr(err); ++ } ++ ++ if (!err) ++ err = devcgroup_inode_permission(h_inode, mask); ++ if (!err) ++ err = security_inode_permission ++ (h_inode, mask & (MAY_READ | MAY_WRITE | MAY_EXEC ++ | MAY_APPEND)); ++ ++ out: ++ return err; ++} ++ ++static int aufs_permission(struct inode *inode, int mask) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ const unsigned char isdir = !!S_ISDIR(inode->i_mode); ++ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND)); ++ struct inode *h_inode; ++ struct super_block *sb; ++ struct au_branch *br; ++ ++ sb = inode->i_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ ii_read_lock_child(inode); ++ ++ if (!isdir || write_mask) { ++ h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ AuDebugOn(!h_inode ++ || ((h_inode->i_mode & S_IFMT) ++ != (inode->i_mode & S_IFMT))); ++ err = 0; ++ bindex = au_ibstart(inode); ++ br = au_sbr(sb, bindex); ++ err = h_permission(h_inode, mask, br->br_mnt, br->br_perm); ++ ++ if (write_mask && !err) { ++ /* test whether the upper writable branch exists */ ++ err = -EROFS; ++ for (; bindex >= 0; bindex--) ++ if (!au_br_rdonly(au_sbr(sb, bindex))) { ++ err = 0; ++ break; ++ } ++ } ++ goto out; ++ } ++ ++ /* non-write to dir */ ++ err = 0; ++ bend = au_ibend(inode); ++ for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) { ++ h_inode = au_h_iptr(inode, bindex); ++ if (h_inode) { ++ AuDebugOn(!S_ISDIR(h_inode->i_mode)); ++ br = au_sbr(sb, bindex); ++ err = h_permission(h_inode, mask, br->br_mnt, ++ br->br_perm); ++ } ++ } ++ ++ out: ++ ii_read_unlock(inode); ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry, ++ struct nameidata *nd) ++{ ++ struct dentry *ret, *parent; ++ struct inode *inode, *h_inode; ++ struct mutex *mtx; ++ struct super_block *sb; ++ int err, npositive; ++ aufs_bindex_t bstart; ++ ++ /* temporary workaround for a bug in NFSD readdir */ ++ if (!au_test_nfsd(current)) ++ IMustLock(dir); ++ else ++ WARN_ONCE(!mutex_is_locked(&dir->i_mutex), ++ "a known problem of NFSD readdir since 2.6.28\n"); ++ ++ sb = dir->i_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_alloc_dinfo(dentry); ++ ret = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ ++ parent = dentry->d_parent; /* dir inode is locked */ ++ di_read_lock_parent(parent, AuLock_IR); ++ npositive = au_lkup_dentry(dentry, au_dbstart(parent), /*type*/0, nd); ++ di_read_unlock(parent, AuLock_IR); ++ err = npositive; ++ ret = ERR_PTR(err); ++ if (unlikely(err < 0)) ++ goto out_unlock; ++ ++ inode = NULL; ++ if (npositive) { ++ bstart = au_dbstart(dentry); ++ h_inode = au_h_dptr(dentry, bstart)->d_inode; ++ if (!S_ISDIR(h_inode->i_mode)) { ++ /* ++ * stop 'race'-ing between hardlinks under different ++ * parents. ++ */ ++ mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx; ++ mutex_lock(mtx); ++ inode = au_new_inode(dentry, /*must_new*/0); ++ mutex_unlock(mtx); ++ } else ++ inode = au_new_inode(dentry, /*must_new*/0); ++ ret = (void *)inode; ++ } ++ if (IS_ERR(inode)) ++ goto out_unlock; ++ ++ ret = d_splice_alias(inode, dentry); ++ if (unlikely(IS_ERR(ret) && inode)) ++ ii_write_unlock(inode); ++ au_store_oflag(nd, inode); ++ ++ out_unlock: ++ di_write_unlock(dentry); ++ out: ++ si_read_unlock(sb); ++ return ret; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent, ++ const unsigned char add_entry, aufs_bindex_t bcpup, ++ aufs_bindex_t bstart) ++{ ++ int err; ++ struct dentry *h_parent; ++ struct inode *h_dir; ++ ++ if (add_entry) { ++ au_update_dbstart(dentry); ++ IMustLock(parent->d_inode); ++ } else ++ di_write_lock_parent(parent); ++ ++ err = 0; ++ if (!au_h_dptr(parent, bcpup)) { ++ if (bstart < bcpup) ++ err = au_cpdown_dirs(dentry, bcpup); ++ else ++ err = au_cpup_dirs(dentry, bcpup); ++ } ++ if (!err && add_entry) { ++ h_parent = au_h_dptr(parent, bcpup); ++ h_dir = h_parent->d_inode; ++ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); ++ err = au_lkup_neg(dentry, bcpup); ++ /* todo: no unlock here */ ++ mutex_unlock(&h_dir->i_mutex); ++ if (bstart < bcpup && au_dbstart(dentry) < 0) { ++ au_set_dbstart(dentry, 0); ++ au_update_dbrange(dentry, /*do_put_zero*/0); ++ } ++ } ++ ++ if (!add_entry) ++ di_write_unlock(parent); ++ if (!err) ++ err = bcpup; /* success */ ++ ++ return err; ++} ++ ++/* ++ * decide the branch and the parent dir where we will create a new entry. ++ * returns new bindex or an error. ++ * copyup the parent dir if needed. ++ */ ++int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, ++ struct au_wr_dir_args *args) ++{ ++ int err; ++ aufs_bindex_t bcpup, bstart, src_bstart; ++ const unsigned char add_entry = !!au_ftest_wrdir(args->flags, ++ ADD_ENTRY); ++ struct super_block *sb; ++ struct dentry *parent; ++ struct au_sbinfo *sbinfo; ++ ++ sb = dentry->d_sb; ++ sbinfo = au_sbi(sb); ++ parent = dget_parent(dentry); ++ bstart = au_dbstart(dentry); ++ bcpup = bstart; ++ if (args->force_btgt < 0) { ++ if (src_dentry) { ++ src_bstart = au_dbstart(src_dentry); ++ if (src_bstart < bstart) ++ bcpup = src_bstart; ++ } else if (add_entry) { ++ err = AuWbrCreate(sbinfo, dentry, ++ au_ftest_wrdir(args->flags, ISDIR)); ++ bcpup = err; ++ } ++ ++ if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) { ++ if (add_entry) ++ err = AuWbrCopyup(sbinfo, dentry); ++ else { ++ if (!IS_ROOT(dentry)) { ++ di_read_lock_parent(parent, !AuLock_IR); ++ err = AuWbrCopyup(sbinfo, dentry); ++ di_read_unlock(parent, !AuLock_IR); ++ } else ++ err = AuWbrCopyup(sbinfo, dentry); ++ } ++ bcpup = err; ++ if (unlikely(err < 0)) ++ goto out; ++ } ++ } else { ++ bcpup = args->force_btgt; ++ AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode)); ++ } ++ AuDbg("bstart %d, bcpup %d\n", bstart, bcpup); ++ if (bstart < bcpup) ++ au_update_dbrange(dentry, /*do_put_zero*/1); ++ ++ err = bcpup; ++ if (bcpup == bstart) ++ goto out; /* success */ ++ ++ /* copyup the new parent into the branch we process */ ++ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart); ++ ++ out: ++ dput(parent); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct dentry *au_pinned_h_parent(struct au_pin *pin) ++{ ++ if (pin && pin->parent) ++ return au_h_dptr(pin->parent, pin->bindex); ++ return NULL; ++} ++ ++void au_unpin(struct au_pin *p) ++{ ++ if (au_ftest_pin(p->flags, MNT_WRITE)) ++ mnt_drop_write(p->h_mnt); ++ if (!p->hdir) ++ return; ++ ++ au_hin_imtx_unlock(p->hdir); ++ if (!au_ftest_pin(p->flags, DI_LOCKED)) ++ di_read_unlock(p->parent, AuLock_IR); ++ iput(p->hdir->hi_inode); ++ dput(p->parent); ++ p->parent = NULL; ++ p->hdir = NULL; ++ p->h_mnt = NULL; ++} ++ ++int au_do_pin(struct au_pin *p) ++{ ++ int err; ++ struct super_block *sb; ++ struct dentry *h_dentry, *h_parent; ++ struct au_branch *br; ++ struct inode *h_dir; ++ ++ err = 0; ++ sb = p->dentry->d_sb; ++ br = au_sbr(sb, p->bindex); ++ if (IS_ROOT(p->dentry)) { ++ if (au_ftest_pin(p->flags, MNT_WRITE)) { ++ p->h_mnt = br->br_mnt; ++ err = mnt_want_write(p->h_mnt); ++ if (unlikely(err)) { ++ au_fclr_pin(p->flags, MNT_WRITE); ++ goto out_err; ++ } ++ } ++ goto out; ++ } ++ ++ h_dentry = NULL; ++ if (p->bindex <= au_dbend(p->dentry)) ++ h_dentry = au_h_dptr(p->dentry, p->bindex); ++ ++ p->parent = dget_parent(p->dentry); ++ if (!au_ftest_pin(p->flags, DI_LOCKED)) ++ di_read_lock(p->parent, AuLock_IR, p->lsc_di); ++ ++ h_dir = NULL; ++ h_parent = au_h_dptr(p->parent, p->bindex); ++ p->hdir = au_hi(p->parent->d_inode, p->bindex); ++ if (p->hdir) ++ h_dir = p->hdir->hi_inode; ++ ++ /* udba case */ ++ if (unlikely(!p->hdir || !h_dir)) { ++ err = au_busy_or_stale(); ++ if (!au_ftest_pin(p->flags, DI_LOCKED)) ++ di_read_unlock(p->parent, AuLock_IR); ++ dput(p->parent); ++ p->parent = NULL; ++ goto out_err; ++ } ++ ++ au_igrab(h_dir); ++ au_hin_imtx_lock_nested(p->hdir, p->lsc_hi); ++ ++ if (h_dentry) { ++ err = au_h_verify(h_dentry, p->udba, h_dir, h_parent, br); ++ if (unlikely(err)) { ++ au_fclr_pin(p->flags, MNT_WRITE); ++ goto out_unpin; ++ } ++ } ++ ++ if (au_ftest_pin(p->flags, MNT_WRITE)) { ++ p->h_mnt = br->br_mnt; ++ err = mnt_want_write(p->h_mnt); ++ if (unlikely(err)) { ++ au_fclr_pin(p->flags, MNT_WRITE); ++ goto out_unpin; ++ } ++ } ++ goto out; /* success */ ++ ++ out_unpin: ++ au_unpin(p); ++ out_err: ++ AuErr("err %d\n", err); ++ err = au_busy_or_stale(); ++ out: ++ return err; ++} ++ ++void au_pin_init(struct au_pin *p, struct dentry *dentry, ++ aufs_bindex_t bindex, int lsc_di, int lsc_hi, ++ unsigned int udba, unsigned char flags) ++{ ++ p->dentry = dentry; ++ p->udba = udba; ++ p->lsc_di = lsc_di; ++ p->lsc_hi = lsc_hi; ++ p->flags = flags; ++ p->bindex = bindex; ++ ++ p->parent = NULL; ++ p->hdir = NULL; ++ p->h_mnt = NULL; ++} ++ ++int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int udba, unsigned char flags) ++{ ++ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2, ++ udba, flags); ++ return au_do_pin(pin); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define AuIcpup_DID_CPUP 1 ++#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name) ++#define au_fset_icpup(flags, name) { (flags) |= AuIcpup_##name; } ++#define au_fclr_icpup(flags, name) { (flags) &= ~AuIcpup_##name; } ++ ++struct au_icpup_args { ++ unsigned char flags; ++ unsigned char pin_flags; ++ aufs_bindex_t btgt; ++ struct au_pin pin; ++ struct path h_path; ++ struct inode *h_inode; ++}; ++ ++static int au_lock_and_icpup(struct dentry *dentry, struct iattr *ia, ++ struct au_icpup_args *a) ++{ ++ int err; ++ unsigned int udba; ++ loff_t sz; ++ aufs_bindex_t bstart; ++ struct dentry *hi_wh, *parent; ++ struct inode *inode; ++ struct au_wr_dir_args wr_dir_args = { ++ .force_btgt = -1, ++ .flags = 0 ++ }; ++ ++ di_write_lock_child(dentry); ++ bstart = au_dbstart(dentry); ++ inode = dentry->d_inode; ++ if (S_ISDIR(inode->i_mode)) ++ au_fset_wrdir(wr_dir_args.flags, ISDIR); ++ /* plink or hi_wh() case */ ++ if (bstart != au_ibstart(inode)) ++ wr_dir_args.force_btgt = au_ibstart(inode); ++ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args); ++ if (unlikely(err < 0)) ++ goto out_dentry; ++ a->btgt = err; ++ if (err != bstart) ++ au_fset_icpup(a->flags, DID_CPUP); ++ ++ err = 0; ++ a->pin_flags = AuPin_MNT_WRITE; ++ parent = NULL; ++ if (!IS_ROOT(dentry)) { ++ au_fset_pin(a->pin_flags, DI_LOCKED); ++ parent = dget_parent(dentry); ++ di_write_lock_parent(parent); ++ } ++ ++ udba = au_opt_udba(dentry->d_sb); ++ if (d_unhashed(dentry) || (ia->ia_valid & ATTR_FILE)) ++ udba = AuOpt_UDBA_NONE; ++ err = au_pin(&a->pin, dentry, a->btgt, udba, a->pin_flags); ++ if (unlikely(err)) { ++ if (parent) { ++ di_write_unlock(parent); ++ dput(parent); ++ } ++ goto out_dentry; ++ } ++ a->h_path.dentry = au_h_dptr(dentry, bstart); ++ a->h_inode = a->h_path.dentry->d_inode; ++ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ sz = -1; ++ if ((ia->ia_valid & ATTR_SIZE) && ia->ia_size < i_size_read(a->h_inode)) ++ sz = ia->ia_size; ++ ++ hi_wh = NULL; ++ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unhashed(dentry)) { ++ hi_wh = au_hi_wh(inode, a->btgt); ++ if (!hi_wh) { ++ err = au_sio_cpup_wh(dentry, a->btgt, sz, /*file*/NULL); ++ if (unlikely(err)) ++ goto out_unlock; ++ hi_wh = au_hi_wh(inode, a->btgt); ++ /* todo: revalidate hi_wh? */ ++ } ++ } ++ ++ if (parent) { ++ au_pin_set_parent_lflag(&a->pin, /*lflag*/0); ++ di_downgrade_lock(parent, AuLock_IR); ++ dput(parent); ++ } ++ if (!au_ftest_icpup(a->flags, DID_CPUP)) ++ goto out; /* success */ ++ ++ if (!d_unhashed(dentry)) { ++ err = au_sio_cpup_simple(dentry, a->btgt, sz, AuCpup_DTIME); ++ if (!err) ++ a->h_path.dentry = au_h_dptr(dentry, a->btgt); ++ } else if (!hi_wh) ++ a->h_path.dentry = au_h_dptr(dentry, a->btgt); ++ else ++ a->h_path.dentry = hi_wh; /* do not dget here */ ++ ++ out_unlock: ++ mutex_unlock(&a->h_inode->i_mutex); ++ a->h_inode = a->h_path.dentry->d_inode; ++ if (!err) { ++ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ goto out; /* success */ ++ } ++ ++ au_unpin(&a->pin); ++ ++ out_dentry: ++ di_write_unlock(dentry); ++ out: ++ return err; ++} ++ ++static int aufs_setattr(struct dentry *dentry, struct iattr *ia) ++{ ++ int err; ++ struct inode *inode; ++ struct super_block *sb; ++ struct file *file; ++ struct au_icpup_args *a; ++ ++ err = -ENOMEM; ++ a = kzalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ inode = dentry->d_inode; ++ IMustLock(inode); ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ file = NULL; ++ if (ia->ia_valid & ATTR_FILE) { ++ /* currently ftruncate(2) only */ ++ file = ia->ia_file; ++ fi_write_lock(file); ++ ia->ia_file = au_h_fptr(file, au_fbstart(file)); ++ } ++ ++ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) ++ ia->ia_valid &= ~ATTR_MODE; ++ ++ err = au_lock_and_icpup(dentry, ia, a); ++ if (unlikely(err < 0)) ++ goto out_si; ++ if (au_ftest_icpup(a->flags, DID_CPUP)) { ++ ia->ia_file = NULL; ++ ia->ia_valid &= ~ATTR_FILE; ++ } ++ ++ a->h_path.mnt = au_sbr_mnt(sb, a->btgt); ++ if (ia->ia_valid & ATTR_SIZE) { ++ struct file *f; ++ ++ if (ia->ia_size < i_size_read(inode)) { ++ /* unmap only */ ++ err = vmtruncate(inode, ia->ia_size); ++ if (unlikely(err)) ++ goto out_unlock; ++ } ++ ++ f = NULL; ++ if (ia->ia_valid & ATTR_FILE) ++ f = ia->ia_file; ++ mutex_unlock(&a->h_inode->i_mutex); ++ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f); ++ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ } else ++ err = vfsub_notify_change(&a->h_path, ia); ++ if (!err) ++ au_cpup_attr_changeable(inode); ++ ++ out_unlock: ++ mutex_unlock(&a->h_inode->i_mutex); ++ au_unpin(&a->pin); ++ di_write_unlock(dentry); ++ out_si: ++ if (file) { ++ fi_write_unlock(file); ++ ia->ia_file = file; ++ ia->ia_valid |= ATTR_FILE; ++ } ++ si_read_unlock(sb); ++ kfree(a); ++ out: ++ return err; ++} ++ ++static int au_getattr_lock_reval(struct dentry *dentry, unsigned int sigen) ++{ ++ int err; ++ struct inode *inode; ++ struct dentry *parent; ++ ++ err = 0; ++ inode = dentry->d_inode; ++ di_write_lock_child(dentry); ++ if (au_digen(dentry) != sigen || au_iigen(inode) != sigen) { ++ parent = dget_parent(dentry); ++ di_read_lock_parent(parent, AuLock_IR); ++ /* returns a number of positive dentries */ ++ err = au_refresh_hdentry(dentry, inode->i_mode & S_IFMT); ++ if (err > 0) ++ err = au_refresh_hinode(inode, dentry); ++ di_read_unlock(parent, AuLock_IR); ++ dput(parent); ++ if (unlikely(!err)) ++ err = -EIO; ++ } ++ di_downgrade_lock(dentry, AuLock_IR); ++ ++ return err; ++} ++ ++static void au_refresh_iattr(struct inode *inode, struct kstat *st, ++ unsigned int nlink) ++{ ++ inode->i_mode = st->mode; ++ inode->i_uid = st->uid; ++ inode->i_gid = st->gid; ++ inode->i_atime = st->atime; ++ inode->i_mtime = st->mtime; ++ inode->i_ctime = st->ctime; ++ ++ au_cpup_attr_nlink(inode, /*force*/0); ++ if (S_ISDIR(inode->i_mode)) { ++ inode->i_nlink -= nlink; ++ inode->i_nlink += st->nlink; ++ } ++ ++ spin_lock(&inode->i_lock); ++ inode->i_blocks = st->blocks; ++ i_size_write(inode, st->size); ++ spin_unlock(&inode->i_lock); ++} ++ ++static int aufs_getattr(struct vfsmount *mnt __maybe_unused, ++ struct dentry *dentry, struct kstat *st) ++{ ++ int err; ++ unsigned int mnt_flags; ++ aufs_bindex_t bindex; ++ unsigned char udba_none, positive, did_lock; ++ struct super_block *sb, *h_sb; ++ struct inode *inode; ++ struct vfsmount *h_mnt; ++ struct dentry *h_dentry; ++ ++ err = 0; ++ did_lock = 0; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ si_read_lock(sb, AuLock_FLUSH); ++ if (IS_ROOT(dentry)) { ++ /* lock free root dinfo */ ++ h_dentry = dget(au_di(dentry)->di_hdentry->hd_dentry); ++ h_mnt = au_sbr_mnt(sb, 0); ++ goto getattr; ++ } ++ ++ did_lock = 1; ++ mnt_flags = au_mntflags(sb); ++ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE); ++ ++ /* support fstat(2) */ ++ if (!d_unhashed(dentry) && !udba_none) { ++ unsigned int sigen = au_sigen(sb); ++ if (au_digen(dentry) == sigen && au_iigen(inode) == sigen) ++ di_read_lock_child(dentry, AuLock_IR); ++ else { ++ err = au_getattr_lock_reval(dentry, sigen); ++ if (unlikely(err)) ++ goto out; ++ } ++ } else ++ di_read_lock_child(dentry, AuLock_IR); ++ ++ bindex = au_ibstart(inode); ++ h_mnt = au_sbr_mnt(sb, bindex); ++ h_sb = h_mnt->mnt_sb; ++ if (!au_test_fs_bad_iattr(h_sb) && udba_none) ++ goto out_fill; /* success */ ++ ++ if (au_dbstart(dentry) == bindex) ++ h_dentry = dget(au_h_dptr(dentry, bindex)); ++ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) { ++ h_dentry = au_plink_lkup(inode, bindex); ++ if (IS_ERR(h_dentry)) ++ goto out_fill; /* pretending success */ ++ } else ++ /* illegally overlapped or something */ ++ goto out_fill; /* pretending success */ ++ ++ getattr: ++ positive = !!h_dentry->d_inode; ++ if (positive) ++ err = vfs_getattr(h_mnt, h_dentry, st); ++ dput(h_dentry); ++ if (!err) { ++ if (positive) ++ au_refresh_iattr(inode, st, h_dentry->d_inode->i_nlink); ++ goto out_fill; /* success */ ++ } ++ goto out; ++ ++ out_fill: ++ generic_fillattr(inode, st); ++ out: ++ if (did_lock) ++ di_read_unlock(dentry, AuLock_IR); ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int h_readlink(struct dentry *dentry, int bindex, char __user *buf, ++ int bufsiz) ++{ ++ int err; ++ struct super_block *sb; ++ struct dentry *h_dentry; ++ ++ err = -EINVAL; ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (unlikely(/* !h_dentry ++ || !h_dentry->d_inode ++ || !h_dentry->d_inode->i_op ++ || */ !h_dentry->d_inode->i_op->readlink)) ++ goto out; ++ ++ err = security_inode_readlink(h_dentry); ++ if (unlikely(err)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ if (!au_test_ro(sb, bindex, dentry->d_inode)) { ++ vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry); ++ fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode); ++ } ++ err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz); ++ ++ out: ++ return err; ++} ++ ++static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) ++{ ++ int err; ++ ++ aufs_read_lock(dentry, AuLock_IR); ++ err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz); ++ aufs_read_unlock(dentry, AuLock_IR); ++ ++ return err; ++} ++ ++static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd) ++{ ++ int err; ++ char *buf; ++ mm_segment_t old_fs; ++ ++ err = -ENOMEM; ++ buf = __getname(); ++ if (unlikely(!buf)) ++ goto out; ++ ++ aufs_read_lock(dentry, AuLock_IR); ++ old_fs = get_fs(); ++ set_fs(KERNEL_DS); ++ err = h_readlink(dentry, au_dbstart(dentry), (char __user *)buf, ++ PATH_MAX); ++ set_fs(old_fs); ++ aufs_read_unlock(dentry, AuLock_IR); ++ ++ if (err >= 0) { ++ buf[err] = 0; ++ /* will be freed by put_link */ ++ nd_set_link(nd, buf); ++ return NULL; /* success */ ++ } ++ __putname(buf); ++ ++ out: ++ path_put(&nd->path); ++ AuTraceErr(err); ++ return ERR_PTR(err); ++} ++ ++static void aufs_put_link(struct dentry *dentry __maybe_unused, ++ struct nameidata *nd, void *cookie __maybe_unused) ++{ ++ __putname(nd_get_link(nd)); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void aufs_truncate_range(struct inode *inode __maybe_unused, ++ loff_t start __maybe_unused, ++ loff_t end __maybe_unused) ++{ ++ AuUnsupport(); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct inode_operations aufs_symlink_iop = { ++ .permission = aufs_permission, ++ .setattr = aufs_setattr, ++ .getattr = aufs_getattr, ++ .readlink = aufs_readlink, ++ .follow_link = aufs_follow_link, ++ .put_link = aufs_put_link ++}; ++ ++struct inode_operations aufs_dir_iop = { ++ .create = aufs_create, ++ .lookup = aufs_lookup, ++ .link = aufs_link, ++ .unlink = aufs_unlink, ++ .symlink = aufs_symlink, ++ .mkdir = aufs_mkdir, ++ .rmdir = aufs_rmdir, ++ .mknod = aufs_mknod, ++ .rename = aufs_rename, ++ ++ .permission = aufs_permission, ++ .setattr = aufs_setattr, ++ .getattr = aufs_getattr ++}; ++ ++struct inode_operations aufs_iop = { ++ .permission = aufs_permission, ++ .setattr = aufs_setattr, ++ .getattr = aufs_getattr, ++ .truncate_range = aufs_truncate_range ++}; +diff -Naur a/fs/aufs/i_op_del.c b/fs/aufs/i_op_del.c +--- a/fs/aufs/i_op_del.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/i_op_del.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,466 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * inode operations (del entry) ++ */ ++ ++#include "aufs.h" ++ ++/* ++ * decide if a new whiteout for @dentry is necessary or not. ++ * when it is necessary, prepare the parent dir for the upper branch whose ++ * branch index is @bcpup for creation. the actual creation of the whiteout will ++ * be done by caller. ++ * return value: ++ * 0: wh is unnecessary ++ * plus: wh is necessary ++ * minus: error ++ */ ++int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup) ++{ ++ int need_wh, err; ++ aufs_bindex_t bstart; ++ struct super_block *sb; ++ ++ sb = dentry->d_sb; ++ bstart = au_dbstart(dentry); ++ if (*bcpup < 0) { ++ *bcpup = bstart; ++ if (au_test_ro(sb, bstart, dentry->d_inode)) { ++ err = AuWbrCopyup(au_sbi(sb), dentry); ++ *bcpup = err; ++ if (unlikely(err < 0)) ++ goto out; ++ } ++ } else ++ AuDebugOn(bstart < *bcpup ++ || au_test_ro(sb, *bcpup, dentry->d_inode)); ++ AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart); ++ ++ if (*bcpup != bstart) { ++ err = au_cpup_dirs(dentry, *bcpup); ++ if (unlikely(err)) ++ goto out; ++ need_wh = 1; ++ } else { ++ aufs_bindex_t old_bend, new_bend, bdiropq = -1; ++ ++ old_bend = au_dbend(dentry); ++ if (isdir) { ++ bdiropq = au_dbdiropq(dentry); ++ au_set_dbdiropq(dentry, -1); ++ } ++ need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0, ++ /*nd*/NULL); ++ err = need_wh; ++ if (isdir) ++ au_set_dbdiropq(dentry, bdiropq); ++ if (unlikely(err < 0)) ++ goto out; ++ new_bend = au_dbend(dentry); ++ if (!need_wh && old_bend != new_bend) { ++ au_set_h_dptr(dentry, new_bend, NULL); ++ au_set_dbend(dentry, old_bend); ++ } ++ } ++ AuDbg("need_wh %d\n", need_wh); ++ err = need_wh; ++ ++ out: ++ return err; ++} ++ ++/* ++ * simple tests for the del-entry operations. ++ * following the checks in vfs, plus the parent-child relationship. ++ */ ++int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent, int isdir) ++{ ++ int err; ++ umode_t h_mode; ++ struct dentry *h_dentry, *h_latest; ++ struct inode *h_inode; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ h_inode = h_dentry->d_inode; ++ if (dentry->d_inode) { ++ err = -ENOENT; ++ if (unlikely(!h_inode || !h_inode->i_nlink)) ++ goto out; ++ ++ h_mode = h_inode->i_mode; ++ if (!isdir) { ++ err = -EISDIR; ++ if (unlikely(S_ISDIR(h_mode))) ++ goto out; ++ } else if (unlikely(!S_ISDIR(h_mode))) { ++ err = -ENOTDIR; ++ goto out; ++ } ++ } else { ++ /* rename(2) case */ ++ err = -EIO; ++ if (unlikely(h_inode)) ++ goto out; ++ } ++ ++ err = -ENOENT; ++ /* expected parent dir is locked */ ++ if (unlikely(h_parent != h_dentry->d_parent)) ++ goto out; ++ err = 0; ++ ++ /* ++ * rmdir a dir may break the consistency on some filesystem. ++ * let's try heavy test. ++ */ ++ err = -EACCES; ++ if (unlikely(au_test_h_perm(h_parent->d_inode, MAY_EXEC | MAY_WRITE))) ++ goto out; ++ ++ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent, ++ au_sbr(dentry->d_sb, bindex)); ++ err = -EIO; ++ if (IS_ERR(h_latest)) ++ goto out; ++ if (h_latest == h_dentry) ++ err = 0; ++ dput(h_latest); ++ ++ out: ++ return err; ++} ++ ++/* ++ * decide the branch where we operate for @dentry. the branch index will be set ++ * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent ++ * dir for reverting. ++ * when a new whiteout is necessary, create it. ++ */ ++static struct dentry* ++lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup, ++ struct au_dtime *dt, struct au_pin *pin) ++{ ++ struct dentry *wh_dentry; ++ struct super_block *sb; ++ struct path h_path; ++ int err, need_wh; ++ unsigned int udba; ++ aufs_bindex_t bcpup; ++ ++ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup); ++ wh_dentry = ERR_PTR(need_wh); ++ if (unlikely(need_wh < 0)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ udba = au_opt_udba(sb); ++ bcpup = *rbcpup; ++ err = au_pin(pin, dentry, bcpup, udba, ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ ++ h_path.dentry = au_pinned_h_parent(pin); ++ if (udba != AuOpt_UDBA_NONE ++ && au_dbstart(dentry) == bcpup) { ++ err = au_may_del(dentry, bcpup, h_path.dentry, isdir); ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out_unpin; ++ } ++ ++ h_path.mnt = au_sbr_mnt(sb, bcpup); ++ au_dtime_store(dt, au_pinned_parent(pin), &h_path); ++ wh_dentry = NULL; ++ if (!need_wh) ++ goto out; /* success, no need to create whiteout */ ++ ++ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry); ++ if (!IS_ERR(wh_dentry)) ++ goto out; /* success */ ++ /* returns with the parent is locked and wh_dentry is dget-ed */ ++ ++ out_unpin: ++ au_unpin(pin); ++ out: ++ return wh_dentry; ++} ++ ++/* ++ * when removing a dir, rename it to a unique temporary whiteout-ed name first ++ * in order to be revertible and save time for removing many child whiteouts ++ * under the dir. ++ * returns 1 when there are too many child whiteout and caller should remove ++ * them asynchronously. returns 0 when the number of children is enough small to ++ * remove now or the branch fs is a remote fs. ++ * otherwise return an error. ++ */ ++static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex, ++ struct au_nhash *whlist, struct inode *dir) ++{ ++ int rmdir_later, err, dirwh; ++ struct dentry *h_dentry; ++ struct super_block *sb; ++ ++ sb = dentry->d_sb; ++ h_dentry = au_h_dptr(dentry, bindex); ++ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex)); ++ if (unlikely(err)) ++ goto out; ++ ++ /* stop monitoring */ ++ au_hin_free(au_hi(dentry->d_inode, bindex)); ++ ++ if (!au_test_fs_remote(h_dentry->d_sb)) { ++ dirwh = au_sbi(sb)->si_dirwh; ++ rmdir_later = (dirwh <= 1); ++ if (!rmdir_later) ++ rmdir_later = au_nhash_test_longer_wh(whlist, bindex, ++ dirwh); ++ if (rmdir_later) ++ return rmdir_later; ++ } ++ ++ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist); ++ if (unlikely(err)) { ++ AuIOErr("rmdir %.*s, b%d failed, %d. ignored\n", ++ AuDLNPair(h_dentry), bindex, err); ++ err = 0; ++ } ++ ++ out: ++ return err; ++} ++ ++/* ++ * final procedure for deleting a entry. ++ * maintain dentry and iattr. ++ */ ++static void epilog(struct inode *dir, struct dentry *dentry, ++ aufs_bindex_t bindex) ++{ ++ struct inode *inode; ++ ++ inode = dentry->d_inode; ++ d_drop(dentry); ++ inode->i_ctime = dir->i_ctime; ++ ++ if (atomic_read(&dentry->d_count) == 1) { ++ au_set_h_dptr(dentry, au_dbstart(dentry), NULL); ++ au_update_dbstart(dentry); ++ } ++ if (au_ibstart(dir) == bindex) ++ au_cpup_attr_timesizes(dir); ++ dir->i_version++; ++} ++ ++/* ++ * when an error happened, remove the created whiteout and revert everything. ++ */ ++static int do_revert(int err, struct inode *dir, aufs_bindex_t bwh, ++ struct dentry *wh_dentry, struct dentry *dentry, ++ struct au_dtime *dt) ++{ ++ int rerr; ++ struct path h_path = { ++ .dentry = wh_dentry, ++ .mnt = au_sbr_mnt(dir->i_sb, bwh) ++ }; ++ ++ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bwh), &h_path, dentry); ++ if (!rerr) { ++ au_set_dbwh(dentry, bwh); ++ au_dtime_revert(dt); ++ return 0; ++ } ++ ++ AuIOErr("%.*s reverting whiteout failed(%d, %d)\n", ++ AuDLNPair(dentry), err, rerr); ++ return -EIO; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int aufs_unlink(struct inode *dir, struct dentry *dentry) ++{ ++ int err; ++ aufs_bindex_t bwh, bindex, bstart; ++ struct au_dtime dt; ++ struct au_pin pin; ++ struct path h_path; ++ struct inode *inode, *h_dir; ++ struct dentry *parent, *wh_dentry; ++ ++ IMustLock(dir); ++ inode = dentry->d_inode; ++ if (unlikely(!inode)) ++ return -ENOENT; /* possible? */ ++ IMustLock(inode); ++ ++ aufs_read_lock(dentry, AuLock_DW); ++ parent = dentry->d_parent; /* dir inode is locked */ ++ di_write_lock_parent(parent); ++ ++ bstart = au_dbstart(dentry); ++ bwh = au_dbwh(dentry); ++ bindex = -1; ++ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt, &pin); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out; ++ ++ h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart); ++ h_path.dentry = au_h_dptr(dentry, bstart); ++ dget(h_path.dentry); ++ if (bindex == bstart) { ++ h_dir = au_pinned_h_dir(&pin); ++ err = vfsub_unlink(h_dir, &h_path, /*force*/0); ++ } else { ++ /* dir inode is locked */ ++ h_dir = wh_dentry->d_parent->d_inode; ++ IMustLock(h_dir); ++ err = 0; ++ } ++ ++ if (!err) { ++ drop_nlink(inode); ++ epilog(dir, dentry, bindex); ++ ++ /* update target timestamps */ ++ if (bindex == bstart) { ++ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/ ++ inode->i_ctime = h_path.dentry->d_inode->i_ctime; ++ } else ++ /* todo: this timestamp may be reverted later */ ++ inode->i_ctime = h_dir->i_ctime; ++ goto out_unlock; /* success */ ++ } ++ ++ /* revert */ ++ if (wh_dentry) { ++ int rerr; ++ ++ rerr = do_revert(err, dir, bwh, wh_dentry, dentry, &dt); ++ if (rerr) ++ err = rerr; ++ } ++ ++ out_unlock: ++ au_unpin(&pin); ++ dput(wh_dentry); ++ dput(h_path.dentry); ++ out: ++ di_write_unlock(parent); ++ aufs_read_unlock(dentry, AuLock_DW); ++ return err; ++} ++ ++int aufs_rmdir(struct inode *dir, struct dentry *dentry) ++{ ++ int err, rmdir_later; ++ aufs_bindex_t bwh, bindex, bstart; ++ struct au_dtime dt; ++ struct au_pin pin; ++ struct inode *inode; ++ struct dentry *parent, *wh_dentry, *h_dentry; ++ struct au_whtmp_rmdir *args; ++ ++ IMustLock(dir); ++ inode = dentry->d_inode; ++ err = -ENOENT; /* possible? */ ++ if (unlikely(!inode)) ++ goto out; ++ IMustLock(inode); ++ ++ err = -ENOMEM; ++ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS); ++ if (unlikely(!args)) ++ goto out; ++ ++ aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH); ++ parent = dentry->d_parent; /* dir inode is locked */ ++ di_write_lock_parent(parent); ++ err = au_test_empty(dentry, &args->whlist); ++ if (unlikely(err)) ++ goto out_args; ++ ++ bstart = au_dbstart(dentry); ++ bwh = au_dbwh(dentry); ++ bindex = -1; ++ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &dt, &pin); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out_args; ++ ++ h_dentry = au_h_dptr(dentry, bstart); ++ dget(h_dentry); ++ rmdir_later = 0; ++ if (bindex == bstart) { ++ err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir); ++ if (err > 0) { ++ rmdir_later = err; ++ err = 0; ++ } ++ } else { ++ /* stop monitoring */ ++ au_hin_free(au_hi(inode, bstart)); ++ ++ /* dir inode is locked */ ++ IMustLock(wh_dentry->d_parent->d_inode); ++ err = 0; ++ } ++ ++ if (!err) { ++ clear_nlink(inode); ++ au_set_dbdiropq(dentry, -1); ++ epilog(dir, dentry, bindex); ++ ++ if (rmdir_later) { ++ au_whtmp_kick_rmdir(dir, bstart, h_dentry, args); ++ args = NULL; ++ } ++ ++ goto out_unlock; /* success */ ++ } ++ ++ /* revert */ ++ AuLabel(revert); ++ if (wh_dentry) { ++ int rerr; ++ ++ rerr = do_revert(err, dir, bwh, wh_dentry, dentry, &dt); ++ if (rerr) ++ err = rerr; ++ } ++ ++ out_unlock: ++ au_unpin(&pin); ++ dput(wh_dentry); ++ dput(h_dentry); ++ out_args: ++ di_write_unlock(parent); ++ aufs_read_unlock(dentry, AuLock_DW); ++ if (args) ++ au_whtmp_rmdir_free(args); ++ out: ++ return err; ++} +diff -Naur a/fs/aufs/i_op_ren.c b/fs/aufs/i_op_ren.c +--- a/fs/aufs/i_op_ren.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/i_op_ren.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,942 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * inode operation (rename entry) ++ * todo: this is crazy monster ++ */ ++ ++#include "aufs.h" ++ ++enum { AuSRC, AuDST, AuSrcDst }; ++enum { AuPARENT, AuCHILD, AuParentChild }; ++ ++#define AuRen_ISDIR 1 ++#define AuRen_ISSAMEDIR (1 << 1) ++#define AuRen_WHSRC (1 << 2) ++#define AuRen_WHDST (1 << 3) ++#define AuRen_MNT_WRITE (1 << 4) ++#define AuRen_DT_DSTDIR (1 << 5) ++#define AuRen_DIROPQ (1 << 6) ++#define AuRen_CPUP (1 << 7) ++#define au_ftest_ren(flags, name) ((flags) & AuRen_##name) ++#define au_fset_ren(flags, name) { (flags) |= AuRen_##name; } ++#define au_fclr_ren(flags, name) { (flags) &= ~AuRen_##name; } ++ ++struct au_ren_args { ++ struct { ++ struct dentry *dentry, *h_dentry, *parent, *h_parent, ++ *wh_dentry; ++ struct inode *dir, *inode; ++ struct au_hinode *hdir; ++ struct au_dtime dt[AuParentChild]; ++ aufs_bindex_t bstart; ++ } sd[AuSrcDst]; ++ ++#define src_dentry sd[AuSRC].dentry ++#define src_dir sd[AuSRC].dir ++#define src_inode sd[AuSRC].inode ++#define src_h_dentry sd[AuSRC].h_dentry ++#define src_parent sd[AuSRC].parent ++#define src_h_parent sd[AuSRC].h_parent ++#define src_wh_dentry sd[AuSRC].wh_dentry ++#define src_hdir sd[AuSRC].hdir ++#define src_h_dir sd[AuSRC].hdir->hi_inode ++#define src_dt sd[AuSRC].dt ++#define src_bstart sd[AuSRC].bstart ++ ++#define dst_dentry sd[AuDST].dentry ++#define dst_dir sd[AuDST].dir ++#define dst_inode sd[AuDST].inode ++#define dst_h_dentry sd[AuDST].h_dentry ++#define dst_parent sd[AuDST].parent ++#define dst_h_parent sd[AuDST].h_parent ++#define dst_wh_dentry sd[AuDST].wh_dentry ++#define dst_hdir sd[AuDST].hdir ++#define dst_h_dir sd[AuDST].hdir->hi_inode ++#define dst_dt sd[AuDST].dt ++#define dst_bstart sd[AuDST].bstart ++ ++ struct dentry *h_trap; ++ struct au_branch *br; ++ struct au_hinode *src_hinode; ++ struct path h_path; ++ struct au_nhash whlist; ++ aufs_bindex_t btgt; ++ ++ unsigned int flags; ++ ++ struct au_whtmp_rmdir *thargs; ++ struct dentry *h_dst; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * functions for reverting. ++ * when an error happened in a single rename systemcall, we should revert ++ * everything as if nothing happend. ++ * we don't need to revert the copied-up/down the parent dir since they are ++ * harmless. ++ */ ++ ++#define RevertFailure(fmt, args...) do { \ ++ AuIOErr("revert failure: " fmt " (%d, %d)\n", \ ++ ##args, err, rerr); \ ++ err = -EIO; \ ++} while (0) ++ ++static void au_ren_rev_diropq(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ ++ au_hin_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD); ++ rerr = au_diropq_remove(a->src_dentry, a->btgt); ++ au_hin_imtx_unlock(a->src_hinode); ++ if (rerr) ++ RevertFailure("remove diropq %.*s", AuDLNPair(a->src_dentry)); ++} ++ ++ ++static void au_ren_rev_rename(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ ++ a->h_path.dentry = au_lkup_one(&a->src_dentry->d_name, a->src_h_parent, ++ a->br, /*nd*/NULL); ++ rerr = PTR_ERR(a->h_path.dentry); ++ if (IS_ERR(a->h_path.dentry)) { ++ RevertFailure("au_lkup_one %.*s", AuDLNPair(a->src_dentry)); ++ return; ++ } ++ ++ rerr = vfsub_rename(a->dst_h_dir, ++ au_h_dptr(a->src_dentry, a->btgt), ++ a->src_h_dir, &a->h_path); ++ d_drop(a->h_path.dentry); ++ dput(a->h_path.dentry); ++ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */ ++ if (rerr) ++ RevertFailure("rename %.*s", AuDLNPair(a->src_dentry)); ++} ++ ++static void au_ren_rev_cpup(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ ++ a->h_path.dentry = a->dst_h_dentry; ++ rerr = vfsub_unlink(a->dst_h_dir, &a->h_path, /*force*/0); ++ au_set_h_dptr(a->src_dentry, a->btgt, NULL); ++ au_set_dbstart(a->src_dentry, a->src_bstart); ++ if (rerr) ++ RevertFailure("unlink %.*s", AuDLNPair(a->dst_h_dentry)); ++} ++ ++ ++static void au_ren_rev_whtmp(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ ++ a->h_path.dentry = au_lkup_one(&a->dst_dentry->d_name, a->dst_h_parent, ++ a->br, /*nd*/NULL); ++ rerr = PTR_ERR(a->h_path.dentry); ++ if (IS_ERR(a->h_path.dentry)) { ++ RevertFailure("lookup %.*s", AuDLNPair(a->dst_dentry)); ++ return; ++ } ++ if (a->h_path.dentry->d_inode) { ++ d_drop(a->h_path.dentry); ++ dput(a->h_path.dentry); ++ return; ++ } ++ ++ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path); ++ d_drop(a->h_path.dentry); ++ dput(a->h_path.dentry); ++ if (!rerr) { ++ au_set_h_dptr(a->dst_dentry, a->btgt, NULL); ++ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst)); ++ } else ++ RevertFailure("rename %.*s", AuDLNPair(a->h_dst)); ++} ++ ++static void au_ren_rev_whsrc(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ ++ a->h_path.dentry = a->src_wh_dentry; ++ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry); ++ if (rerr) ++ RevertFailure("unlink %.*s", AuDLNPair(a->src_wh_dentry)); ++} ++ ++static void au_ren_rev_drop(struct au_ren_args *a) ++{ ++ struct dentry *d, *h_d; ++ int i; ++ aufs_bindex_t bend, bindex; ++ ++ for (i = 0; i < AuSrcDst; i++) { ++ d = a->sd[i].dentry; ++ d_drop(d); ++ bend = au_dbend(d); ++ for (bindex = au_dbstart(d); bindex <= bend; bindex++) { ++ h_d = au_h_dptr(d, bindex); ++ if (h_d) ++ d_drop(h_d); ++ } ++ } ++ ++ au_update_dbstart(a->dst_dentry); ++ if (a->thargs) ++ d_drop(a->h_dst); ++} ++#undef RevertFailure ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * when we have to copyup the renaming entry, do it with the rename-target name ++ * in order to minimize the cost (the later actual rename is unnecessary). ++ * otherwise rename it on the target branch. ++ */ ++static int au_ren_or_cpup(struct au_ren_args *a) ++{ ++ int err; ++ struct dentry *d; ++ ++ d = a->src_dentry; ++ if (au_dbstart(d) == a->btgt) { ++ a->h_path.dentry = a->dst_h_dentry; ++ if (au_ftest_ren(a->flags, DIROPQ) ++ && au_dbdiropq(d) == a->btgt) ++ au_fclr_ren(a->flags, DIROPQ); ++ AuDebugOn(au_dbstart(d) != a->btgt); ++ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt), ++ a->dst_h_dir, &a->h_path); ++ } else { ++ struct mutex *h_mtx = &a->src_h_dentry->d_inode->i_mutex; ++ ++ au_fset_ren(a->flags, CPUP); ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ au_set_dbstart(d, a->btgt); ++ au_set_h_dptr(d, a->btgt, dget(a->dst_h_dentry)); ++ err = au_sio_cpup_single(d, a->btgt, a->src_bstart, -1, ++ !AuCpup_DTIME, a->dst_parent); ++ if (unlikely(err)) { ++ au_set_h_dptr(d, a->btgt, NULL); ++ au_set_dbstart(d, a->src_bstart); ++ } ++ mutex_unlock(h_mtx); ++ } ++ ++ return err; ++} ++ ++/* cf. aufs_rmdir() */ ++static int au_ren_del_whtmp(struct au_ren_args *a) ++{ ++ int err; ++ struct inode *dir; ++ ++ dir = a->dst_dir; ++ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt, ++ au_sbi(dir->i_sb)->si_dirwh) ++ || au_test_fs_remote(a->h_dst->d_sb)) { ++ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist); ++ if (unlikely(err)) ++ AuWarn("failed removing whtmp dir %.*s (%d), " ++ "ignored.\n", AuDLNPair(a->h_dst), err); ++ } else { ++ au_nhash_wh_free(&a->thargs->whlist); ++ a->thargs->whlist = a->whlist; ++ a->whlist.nh_num = 0; ++ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs); ++ dput(a->h_dst); ++ a->thargs = NULL; ++ } ++ ++ return 0; ++} ++ ++/* make it 'opaque' dir. */ ++static int au_ren_diropq(struct au_ren_args *a) ++{ ++ int err; ++ struct dentry *diropq; ++ ++ err = 0; ++ a->src_hinode = au_hi(a->src_inode, a->btgt); ++ au_hin_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD); ++ diropq = au_diropq_create(a->src_dentry, a->btgt); ++ au_hin_imtx_unlock(a->src_hinode); ++ if (IS_ERR(diropq)) ++ err = PTR_ERR(diropq); ++ dput(diropq); ++ ++ return err; ++} ++ ++static int do_rename(struct au_ren_args *a) ++{ ++ int err; ++ struct dentry *d, *h_d; ++ ++ /* prepare workqueue args for asynchronous rmdir */ ++ h_d = a->dst_h_dentry; ++ if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) { ++ err = -ENOMEM; ++ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS); ++ if (unlikely(!a->thargs)) ++ goto out; ++ a->h_dst = dget(h_d); ++ } ++ ++ /* create whiteout for src_dentry */ ++ if (au_ftest_ren(a->flags, WHSRC)) { ++ a->src_wh_dentry ++ = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent); ++ err = PTR_ERR(a->src_wh_dentry); ++ if (IS_ERR(a->src_wh_dentry)) ++ goto out_thargs; ++ } ++ ++ /* lookup whiteout for dentry */ ++ if (au_ftest_ren(a->flags, WHDST)) { ++ h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name, ++ a->br); ++ err = PTR_ERR(h_d); ++ if (IS_ERR(h_d)) ++ goto out_whsrc; ++ if (!h_d->d_inode) ++ dput(h_d); ++ else ++ a->dst_wh_dentry = h_d; ++ } ++ ++ /* rename dentry to tmpwh */ ++ if (a->thargs) { ++ err = au_whtmp_ren(a->dst_h_dentry, a->br); ++ if (unlikely(err)) ++ goto out_whdst; ++ ++ d = a->dst_dentry; ++ au_set_h_dptr(d, a->btgt, NULL); ++ err = au_lkup_neg(d, a->btgt); ++ if (unlikely(err)) ++ goto out_whtmp; ++ a->dst_h_dentry = au_h_dptr(d, a->btgt); ++ } ++ ++ /* cpup src */ ++ if (a->dst_h_dentry->d_inode && a->src_bstart != a->btgt) { ++ struct mutex *h_mtx = &a->src_h_dentry->d_inode->i_mutex; ++ ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ err = au_sio_cpup_simple(a->src_dentry, a->btgt, -1, ++ !AuCpup_DTIME); ++ mutex_unlock(h_mtx); ++ if (unlikely(err)) ++ goto out_whtmp; ++ } ++ ++ /* rename by vfs_rename or cpup */ ++ d = a->dst_dentry; ++ if (au_ftest_ren(a->flags, ISDIR) ++ && (a->dst_wh_dentry ++ || au_dbdiropq(d) == a->btgt ++ /* hide the lower to keep xino */ ++ || a->btgt < au_dbend(d) ++ || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ))) ++ au_fset_ren(a->flags, DIROPQ); ++ err = au_ren_or_cpup(a); ++ if (unlikely(err)) ++ /* leave the copied-up one */ ++ goto out_whtmp; ++ ++ /* make dir opaque */ ++ if (au_ftest_ren(a->flags, DIROPQ)) { ++ err = au_ren_diropq(a); ++ if (unlikely(err)) ++ goto out_rename; ++ } ++ ++ /* update target timestamps */ ++ AuDebugOn(au_dbstart(a->src_dentry) != a->btgt); ++ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt); ++ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/ ++ a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime; ++ ++ /* remove whiteout for dentry */ ++ if (a->dst_wh_dentry) { ++ a->h_path.dentry = a->dst_wh_dentry; ++ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path, ++ a->dst_dentry); ++ if (unlikely(err)) ++ goto out_diropq; ++ } ++ ++ /* remove whtmp */ ++ if (a->thargs) ++ au_ren_del_whtmp(a); /* ignore this error */ ++ ++ err = 0; ++ goto out_success; ++ ++ out_diropq: ++ if (au_ftest_ren(a->flags, DIROPQ)) ++ au_ren_rev_diropq(err, a); ++ out_rename: ++ if (!au_ftest_ren(a->flags, CPUP)) ++ au_ren_rev_rename(err, a); ++ else ++ au_ren_rev_cpup(err, a); ++ out_whtmp: ++ if (a->thargs) ++ au_ren_rev_whtmp(err, a); ++ out_whdst: ++ dput(a->dst_wh_dentry); ++ a->dst_wh_dentry = NULL; ++ out_whsrc: ++ if (a->src_wh_dentry) ++ au_ren_rev_whsrc(err, a); ++ au_ren_rev_drop(a); ++ out_success: ++ dput(a->src_wh_dentry); ++ dput(a->dst_wh_dentry); ++ out_thargs: ++ if (a->thargs) { ++ dput(a->h_dst); ++ au_whtmp_rmdir_free(a->thargs); ++ a->thargs = NULL; ++ } ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * test if @dentry dir can be rename destination or not. ++ * success means, it is a logically empty dir. ++ */ ++static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist) ++{ ++ return au_test_empty(dentry, whlist); ++} ++ ++/* ++ * test if @dentry dir can be rename source or not. ++ * if it can, return 0 and @children is filled. ++ * success means, ++ * - it is a logically empty dir. ++ * - or, it exists on writable branch and has no children including whiteouts ++ * on the lower branch. ++ */ ++static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt) ++{ ++ int err; ++ aufs_bindex_t bstart; ++ ++ bstart = au_dbstart(dentry); ++ if (bstart != btgt) { ++ struct au_nhash whlist; ++ ++ err = au_nhash_alloc(&whlist, au_sbi(dentry->d_sb)->si_rdhash, ++ GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_test_empty(dentry, &whlist); ++ au_nhash_wh_free(&whlist); ++ goto out; ++ } ++ ++ if (bstart == au_dbtaildir(dentry)) ++ return 0; /* success */ ++ ++ err = au_test_empty_lower(dentry); ++ ++ out: ++ if (err == -ENOTEMPTY) { ++ AuWarn1("renaming dir who has child(ren) on multiple branches," ++ " is not supported\n"); ++ err = -EXDEV; ++ } ++ return err; ++} ++ ++/* side effect: sets whlist and h_dentry */ ++static int au_ren_may_dir(struct au_ren_args *a) ++{ ++ int err; ++ struct dentry *d; ++ ++ d = a->dst_dentry; ++ err = au_nhash_alloc(&a->whlist, au_sbi(d->d_sb)->si_rdhash, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ ++ err = 0; ++ if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) { ++ au_set_dbstart(d, a->dst_bstart); ++ err = may_rename_dstdir(d, &a->whlist); ++ au_set_dbstart(d, a->btgt); ++ } ++ a->dst_h_dentry = au_h_dptr(d, au_dbstart(d)); ++ if (unlikely(err)) ++ goto out; ++ ++ d = a->src_dentry; ++ a->src_h_dentry = au_h_dptr(d, au_dbstart(d)); ++ if (au_ftest_ren(a->flags, ISDIR)) { ++ err = may_rename_srcdir(d, a->btgt); ++ if (unlikely(err)) { ++ au_nhash_wh_free(&a->whlist); ++ a->whlist.nh_num = 0; ++ } ++ } ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * simple tests for rename. ++ * following the checks in vfs, plus the parent-child relationship. ++ */ ++static int au_may_ren(struct au_ren_args *a) ++{ ++ int err, isdir; ++ struct inode *h_inode; ++ ++ if (a->src_bstart == a->btgt) { ++ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent, ++ au_ftest_ren(a->flags, ISDIR)); ++ if (unlikely(err)) ++ goto out; ++ err = -EINVAL; ++ if (unlikely(a->src_h_dentry == a->h_trap)) ++ goto out; ++ } ++ ++ err = 0; ++ if (a->dst_bstart != a->btgt) ++ goto out; ++ ++ err = -EIO; ++ h_inode = a->dst_h_dentry->d_inode; ++ isdir = !!au_ftest_ren(a->flags, ISDIR); ++ if (!a->dst_dentry->d_inode) { ++ if (unlikely(h_inode)) ++ goto out; ++ err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent, ++ isdir); ++ } else { ++ if (unlikely(!h_inode || !h_inode->i_nlink)) ++ goto out; ++ err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent, ++ isdir); ++ if (unlikely(err)) ++ goto out; ++ err = -ENOTEMPTY; ++ if (unlikely(a->dst_h_dentry == a->h_trap)) ++ goto out; ++ err = 0; ++ } ++ ++ out: ++ if (unlikely(err == -ENOENT || err == -EEXIST)) ++ err = -EIO; ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * locking order ++ * (VFS) ++ * - src_dir and dir by lock_rename() ++ * - inode if exitsts ++ * (aufs) ++ * - lock all ++ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls, ++ * + si_read_lock ++ * + di_write_lock2_child() ++ * + di_write_lock_child() ++ * + ii_write_lock_child() ++ * + di_write_lock_child2() ++ * + ii_write_lock_child2() ++ * + src_parent and parent ++ * + di_write_lock_parent() ++ * + ii_write_lock_parent() ++ * + di_write_lock_parent2() ++ * + ii_write_lock_parent2() ++ * + lower src_dir and dir by vfsub_lock_rename() ++ * + verify the every relationships between child and parent. if any ++ * of them failed, unlock all and return -EBUSY. ++ */ ++static void au_ren_unlock(struct au_ren_args *a) ++{ ++ struct super_block *sb; ++ ++ sb = a->dst_dentry->d_sb; ++ if (au_ftest_ren(a->flags, MNT_WRITE)) ++ mnt_drop_write(a->br->br_mnt); ++ vfsub_unlock_rename(a->src_h_parent, a->src_hdir, ++ a->dst_h_parent, a->dst_hdir); ++} ++ ++static int au_ren_lock(struct au_ren_args *a) ++{ ++ int err; ++ unsigned int udba; ++ ++ err = 0; ++ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt); ++ a->src_hdir = au_hi(a->src_dir, a->btgt); ++ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt); ++ a->dst_hdir = au_hi(a->dst_dir, a->btgt); ++ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir, ++ a->dst_h_parent, a->dst_hdir); ++ udba = au_opt_udba(a->src_dentry->d_sb); ++ if (au_dbstart(a->src_dentry) == a->btgt) ++ err = au_h_verify(a->src_h_dentry, udba, ++ a->src_h_parent->d_inode, a->src_h_parent, ++ a->br); ++ if (!err && au_dbstart(a->dst_dentry) == a->btgt) ++ err = au_h_verify(a->dst_h_dentry, udba, ++ a->dst_h_parent->d_inode, a->dst_h_parent, ++ a->br); ++ if (!err) { ++ err = mnt_want_write(a->br->br_mnt); ++ if (unlikely(err)) ++ goto out_unlock; ++ au_fset_ren(a->flags, MNT_WRITE); ++ goto out; /* success */ ++ } ++ ++ err = au_busy_or_stale(); ++ ++ out_unlock: ++ au_ren_unlock(a); ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void au_ren_refresh_dir(struct au_ren_args *a) ++{ ++ struct inode *dir; ++ ++ dir = a->dst_dir; ++ dir->i_version++; ++ if (au_ftest_ren(a->flags, ISDIR)) { ++ /* is this updating defined in POSIX? */ ++ au_cpup_attr_timesizes(a->src_inode); ++ au_cpup_attr_nlink(dir, /*force*/1); ++ if (a->dst_inode) { ++ clear_nlink(a->dst_inode); ++ au_cpup_attr_timesizes(a->dst_inode); ++ } ++ } ++ if (au_ibstart(dir) == a->btgt) ++ au_cpup_attr_timesizes(dir); ++ ++ if (au_ftest_ren(a->flags, ISSAMEDIR)) ++ return; ++ ++ dir = a->src_dir; ++ dir->i_version++; ++ if (au_ftest_ren(a->flags, ISDIR)) ++ au_cpup_attr_nlink(dir, /*force*/1); ++ if (au_ibstart(dir) == a->btgt) ++ au_cpup_attr_timesizes(dir); ++} ++ ++static void au_ren_refresh(struct au_ren_args *a) ++{ ++ aufs_bindex_t bend, bindex; ++ struct dentry *d, *h_d; ++ struct inode *i, *h_i; ++ struct super_block *sb; ++ ++ d = a->src_dentry; ++ au_set_dbwh(d, -1); ++ bend = au_dbend(d); ++ for (bindex = a->btgt + 1; bindex <= bend; bindex++) { ++ h_d = au_h_dptr(d, bindex); ++ if (h_d) ++ au_set_h_dptr(d, bindex, NULL); ++ } ++ au_set_dbend(d, a->btgt); ++ ++ sb = d->d_sb; ++ i = a->src_inode; ++ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i)) ++ return; /* success */ ++ ++ bend = au_ibend(i); ++ for (bindex = a->btgt + 1; bindex <= bend; bindex++) { ++ h_i = au_h_iptr(i, bindex); ++ if (h_i) { ++ au_xino_write0(sb, bindex, h_i->i_ino, 0); ++ /* ignore this error */ ++ au_set_h_iptr(i, bindex, NULL, 0); ++ } ++ } ++ au_set_ibend(i, a->btgt); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* mainly for link(2) and rename(2) */ ++int au_wbr(struct dentry *dentry, aufs_bindex_t btgt) ++{ ++ aufs_bindex_t bdiropq, bwh; ++ struct dentry *parent; ++ struct au_branch *br; ++ ++ parent = dentry->d_parent; ++ IMustLock(parent->d_inode); /* dir is locked */ ++ ++ bdiropq = au_dbdiropq(parent); ++ bwh = au_dbwh(dentry); ++ br = au_sbr(dentry->d_sb, btgt); ++ if (au_br_rdonly(br) ++ || (0 <= bdiropq && bdiropq < btgt) ++ || (0 <= bwh && bwh < btgt)) ++ btgt = -1; ++ ++ AuDbg("btgt %d\n", btgt); ++ return btgt; ++} ++ ++/* sets src_bstart, dst_bstart and btgt */ ++static int au_ren_wbr(struct au_ren_args *a) ++{ ++ int err; ++ struct au_wr_dir_args wr_dir_args = { ++ /* .force_btgt = -1, */ ++ .flags = AuWrDir_ADD_ENTRY ++ }; ++ ++ a->src_bstart = au_dbstart(a->src_dentry); ++ a->dst_bstart = au_dbstart(a->dst_dentry); ++ if (au_ftest_ren(a->flags, ISDIR)) ++ au_fset_wrdir(wr_dir_args.flags, ISDIR); ++ wr_dir_args.force_btgt = a->src_bstart; ++ if (a->dst_inode && a->dst_bstart < a->src_bstart) ++ wr_dir_args.force_btgt = a->dst_bstart; ++ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt); ++ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args); ++ a->btgt = err; ++ ++ return err; ++} ++ ++static void au_ren_dt(struct au_ren_args *a) ++{ ++ a->h_path.dentry = a->src_h_parent; ++ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path); ++ if (!au_ftest_ren(a->flags, ISSAMEDIR)) { ++ a->h_path.dentry = a->dst_h_parent; ++ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path); ++ } ++ ++ au_fclr_ren(a->flags, DT_DSTDIR); ++ if (!au_ftest_ren(a->flags, ISDIR)) ++ return; ++ ++ a->h_path.dentry = a->src_h_dentry; ++ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path); ++ if (a->dst_h_dentry->d_inode) { ++ au_fset_ren(a->flags, DT_DSTDIR); ++ a->h_path.dentry = a->dst_h_dentry; ++ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path); ++ } ++} ++ ++static void au_ren_rev_dt(int err, struct au_ren_args *a) ++{ ++ struct dentry *h_d; ++ struct mutex *h_mtx; ++ ++ au_dtime_revert(a->src_dt + AuPARENT); ++ if (!au_ftest_ren(a->flags, ISSAMEDIR)) ++ au_dtime_revert(a->dst_dt + AuPARENT); ++ ++ if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) { ++ h_d = a->src_dt[AuCHILD].dt_h_path.dentry; ++ h_mtx = &h_d->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ au_dtime_revert(a->src_dt + AuCHILD); ++ mutex_unlock(h_mtx); ++ ++ if (au_ftest_ren(a->flags, DT_DSTDIR)) { ++ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry; ++ h_mtx = &h_d->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ au_dtime_revert(a->dst_dt + AuCHILD); ++ mutex_unlock(h_mtx); ++ } ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry, ++ struct inode *_dst_dir, struct dentry *_dst_dentry) ++{ ++ int err; ++ /* reduce stack space */ ++ struct au_ren_args *a; ++ ++ IMustLock(_src_dir); ++ IMustLock(_dst_dir); ++ ++ err = -ENOMEM; ++ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE); ++ a = kzalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ a->src_dir = _src_dir; ++ a->src_dentry = _src_dentry; ++ a->src_inode = a->src_dentry->d_inode; ++ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */ ++ a->dst_dir = _dst_dir; ++ a->dst_dentry = _dst_dentry; ++ a->dst_inode = a->dst_dentry->d_inode; ++ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */ ++ if (a->dst_inode) { ++ IMustLock(a->dst_inode); ++ au_igrab(a->dst_inode); ++ } ++ ++ err = -ENOTDIR; ++ if (S_ISDIR(a->src_inode->i_mode)) { ++ au_fset_ren(a->flags, ISDIR); ++ if (unlikely(a->dst_inode && !S_ISDIR(a->dst_inode->i_mode))) ++ goto out_free; ++ aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry, ++ AuLock_DIR | AuLock_FLUSH); ++ } else ++ aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry, ++ AuLock_FLUSH); ++ ++ au_fset_ren(a->flags, ISSAMEDIR); /* temporary */ ++ di_write_lock_parent(a->dst_parent); ++ ++ /* which branch we process */ ++ err = au_ren_wbr(a); ++ if (unlikely(err < 0)) ++ goto out_unlock; ++ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt); ++ a->h_path.mnt = a->br->br_mnt; ++ ++ /* are they available to be renamed */ ++ err = au_ren_may_dir(a); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ /* prepare the writable parent dir on the same branch */ ++ if (a->dst_bstart == a->btgt) { ++ au_fset_ren(a->flags, WHDST); ++ } else { ++ err = au_cpup_dirs(a->dst_dentry, a->btgt); ++ if (unlikely(err)) ++ goto out_children; ++ } ++ ++ if (a->src_dir != a->dst_dir) { ++ /* ++ * this temporary unlock is safe, ++ * because both dir->i_mutex are locked. ++ */ ++ di_write_unlock(a->dst_parent); ++ di_write_lock_parent(a->src_parent); ++ err = au_wr_dir_need_wh(a->src_dentry, ++ au_ftest_ren(a->flags, ISDIR), ++ &a->btgt); ++ di_write_unlock(a->src_parent); ++ di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1); ++ au_fclr_ren(a->flags, ISSAMEDIR); ++ } else ++ err = au_wr_dir_need_wh(a->src_dentry, ++ au_ftest_ren(a->flags, ISDIR), ++ &a->btgt); ++ if (unlikely(err < 0)) ++ goto out_children; ++ if (err) ++ au_fset_ren(a->flags, WHSRC); ++ ++ /* lock them all */ ++ err = au_ren_lock(a); ++ if (unlikely(err)) ++ goto out_children; ++ ++ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE)) { ++ err = au_may_ren(a); ++ if (unlikely(err)) ++ goto out_hdir; ++ } ++ ++ /* store timestamps to be revertible */ ++ au_ren_dt(a); ++ ++ /* here we go */ ++ err = do_rename(a); ++ if (unlikely(err)) ++ goto out_dt; ++ ++ /* update dir attributes */ ++ au_ren_refresh_dir(a); ++ ++ /* dput/iput all lower dentries */ ++ au_ren_refresh(a); ++ ++ goto out_hdir; /* success */ ++ ++ out_dt: ++ au_ren_rev_dt(err, a); ++ out_hdir: ++ au_ren_unlock(a); ++ out_children: ++ au_nhash_wh_free(&a->whlist); ++ out_unlock: ++ if (unlikely(err && au_ftest_ren(a->flags, ISDIR))) { ++ au_update_dbstart(a->dst_dentry); ++ d_drop(a->dst_dentry); ++ } ++ if (!err) ++ d_move(a->src_dentry, a->dst_dentry); ++ if (au_ftest_ren(a->flags, ISSAMEDIR)) ++ di_write_unlock(a->dst_parent); ++ else ++ di_write_unlock2(a->src_parent, a->dst_parent); ++ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry); ++ out_free: ++ iput(a->dst_inode); ++ if (a->thargs) ++ au_whtmp_rmdir_free(a->thargs); ++ kfree(a); ++ out: ++ return err; ++} +diff -Naur a/fs/aufs/Kconfig b/fs/aufs/Kconfig +--- a/fs/aufs/Kconfig 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/Kconfig 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,117 @@ ++config AUFS_FS ++ tristate "Aufs (Advanced multi layered unification filesystem) support" ++ depends on EXPERIMENTAL ++ help ++ Aufs is a stackable unification filesystem such as Unionfs, ++ which unifies several directories and provides a merged single ++ directory. ++ In the early days, aufs was entirely re-designed and ++ re-implemented Unionfs Version 1.x series. Introducing many ++ original ideas, approaches and improvements, it becomes totally ++ different from Unionfs while keeping the basic features. ++ ++if AUFS_FS ++choice ++ prompt "Maximum number of branches" ++ default AUFS_BRANCH_MAX_127 ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_127 ++ bool "127" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_511 ++ bool "511" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_1023 ++ bool "1023" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_32767 ++ bool "32767" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++endchoice ++ ++config AUFS_HINOTIFY ++ bool "Use inotify to detect actions on a branch" ++ depends on INOTIFY ++ help ++ If you want to modify files on branches directly, eg. bypassing aufs, ++ and want aufs to detect the changes of them fully, then enable this ++ option and use 'udba=inotify' mount option. ++ It will have a negative impact to the performance. ++ See detail in aufs.5. ++ ++config AUFS_EXPORT ++ bool "NFS-exportable aufs" ++ depends on (AUFS_FS = y && EXPORTFS = y) || (AUFS_FS = m && EXPORTFS) ++ help ++ If you want to export your mounted aufs via NFS, then enable this ++ option. There are several requirements for this configuration. ++ See detail in aufs.5. ++ ++config AUFS_SHWH ++ bool "Show whiteouts" ++ help ++ If you want to make the whiteouts in aufs visible, then enable ++ this option and specify 'shwh' mount option. Although it may ++ sounds like philosophy or something, but in technically it ++ simply shows the name of whiteout with keeping its behaviour. ++ ++config AUFS_BR_RAMFS ++ bool "Ramfs (initramfs/rootfs) as an aufs branch" ++ help ++ If you want to use ramfs as an aufs branch fs, then enable this ++ option. Generally tmpfs is recommended. ++ Aufs prohibited them to be a branch fs by default, because ++ initramfs becomes unusable after switch_root or something ++ generally. If you sets initramfs as an aufs branch and boot your ++ system by switch_root, you will meet a problem easily since the ++ files in initramfs may be inaccessible. ++ Unless you are going to use ramfs as an aufs branch fs without ++ switch_root or something, leave it N. ++ ++config AUFS_DEBUG ++ bool "Debug aufs" ++ help ++ Enable this to compile aufs internal debug code. ++ It will have a negative impact to the performance. ++ ++config AUFS_MAGIC_SYSRQ ++ bool ++ depends on AUFS_DEBUG && MAGIC_SYSRQ ++ default y ++ help ++ Automatic configuration for internal use. ++ When aufs supports Magic SysRq, enabled automatically. ++ ++config AUFS_BDEV_LOOP ++ bool ++ depends on BLK_DEV_LOOP ++ default y ++ help ++ Automatic configuration for internal use. ++ Convert =[ym] into =y. ++ ++config AUFS_INO_T_64 ++ bool ++ depends on AUFS_EXPORT ++ depends on 64BIT && !(ALPHA || S390) ++ default y ++ help ++ Automatic configuration for internal use. ++ /* typedef unsigned long/int __kernel_ino_t */ ++ /* alpha and s390x are int */ ++endif +diff -Naur a/fs/aufs/loop.c b/fs/aufs/loop.c +--- a/fs/aufs/loop.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/loop.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * support for loopback block device as a branch ++ */ ++ ++#include ++#include "aufs.h" ++ ++/* ++ * test if two lower dentries have overlapping branches. ++ */ ++int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_d1, ++ struct dentry *h_d2) ++{ ++ struct inode *h_inode; ++ struct loop_device *l; ++ ++ h_inode = h_d1->d_inode; ++ if (MAJOR(h_inode->i_sb->s_dev) != LOOP_MAJOR) ++ return 0; ++ ++ l = h_inode->i_sb->s_bdev->bd_disk->private_data; ++ h_d1 = l->lo_backing_file->f_dentry; ++ /* h_d1 can be local NFS. in this case aufs cannot detect the loop */ ++ if (unlikely(h_d1->d_sb == sb)) ++ return 1; ++ return !!au_test_subdir(h_d1, h_d2); ++} ++ ++/* true if a kernel thread named 'loop[0-9].*' accesses a file */ ++int au_test_loopback_kthread(void) ++{ ++ const char c = current->comm[4]; ++ ++ return current->mm == NULL ++ && '0' <= c && c <= '9' ++ && strncmp(current->comm, "loop", 4) == 0; ++} +diff -Naur a/fs/aufs/loop.h b/fs/aufs/loop.h +--- a/fs/aufs/loop.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/loop.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,51 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * support for loopback mount as a branch ++ */ ++ ++#ifndef __AUFS_LOOP_H__ ++#define __AUFS_LOOP_H__ ++ ++#ifdef __KERNEL__ ++ ++struct dentry; ++struct super_block; ++ ++#ifdef CONFIG_AUFS_BDEV_LOOP ++/* loop.c */ ++int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_d1, ++ struct dentry *h_d2); ++int au_test_loopback_kthread(void); ++#else ++static inline ++int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_d1, ++ struct dentry *h_d2) ++{ ++ return 0; ++} ++ ++static inline int au_test_loopback_kthread(void) ++{ ++ return 0; ++} ++#endif /* BLK_DEV_LOOP */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_LOOP_H__ */ +diff -Naur a/fs/aufs/magic.mk b/fs/aufs/magic.mk +--- a/fs/aufs/magic.mk 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/magic.mk 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,52 @@ ++ ++# defined in ${srctree}/fs/fuse/inode.c ++# tristate ++ifdef CONFIG_FUSE_FS ++ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546 ++endif ++ ++# defined in ${srctree}/fs/ocfs2/ocfs2_fs.h ++# tristate ++ifdef CONFIG_OCFS2_FS ++ccflags-y += -DOCFS2_SUPER_MAGIC=0x7461636f ++endif ++ ++# defined in ${srctree}/fs/ocfs2/dlm/userdlm.h ++# tristate ++ifdef CONFIG_OCFS2_FS_O2CB ++ccflags-y += -DDLMFS_MAGIC=0x76a9f425 ++endif ++ ++# defined in ${srctree}/fs/ramfs/inode.c ++# always true ++ccflags-y += -DRAMFS_MAGIC=0x858458f6 ++ ++# defined in ${srctree}/fs/cifs/cifsfs.c ++# tristate ++ifdef CONFIG_CIFS_FS ++ccflags-y += -DCIFS_MAGIC_NUMBER=0xFF534D42 ++endif ++ ++# defined in ${srctree}/fs/xfs/xfs_sb.h ++# tristate ++ifdef CONFIG_XFS_FS ++ccflags-y += -DXFS_SB_MAGIC=0x58465342 ++endif ++ ++# defined in ${srctree}/fs/configfs/mount.c ++# tristate ++ifdef CONFIG_CONFIGFS_FS ++ccflags-y += -DCONFIGFS_MAGIC=0x62656570 ++endif ++ ++# defined in ${srctree}/fs/9p/v9fs.h ++# tristate ++ifdef CONFIG_9P_FS ++ccflags-y += -DV9FS_MAGIC=0x01021997 ++endif ++ ++# defined in ${srctree}/fs/ubifs/ubifs.h ++# tristate ++ifdef CONFIG_UBIFS_FS ++ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905 ++endif +diff -Naur a/fs/aufs/Makefile b/fs/aufs/Makefile +--- a/fs/aufs/Makefile 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/Makefile 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,22 @@ ++ ++include ${src}/magic.mk ++-include ${src}/priv_def.mk ++ ++obj-$(CONFIG_AUFS_FS) += aufs.o ++aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \ ++ wkq.o vfsub.o dcsub.o \ ++ cpup.o whout.o plink.o wbr_policy.o \ ++ dinfo.o dentry.o \ ++ finfo.o file.o f_op.o \ ++ dir.o vdir.o \ ++ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \ ++ ioctl.o ++ ++# all are boolean ++aufs-$(CONFIG_SYSFS) += sysfs.o ++aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o ++aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o ++aufs-$(CONFIG_AUFS_HINOTIFY) += hinotify.o ++aufs-$(CONFIG_AUFS_EXPORT) += export.o ++aufs-$(CONFIG_AUFS_DEBUG) += debug.o ++aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o +diff -Naur a/fs/aufs/module.c b/fs/aufs/module.c +--- a/fs/aufs/module.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/module.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,173 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * module global variables and operations ++ */ ++ ++#include ++#include ++#include "aufs.h" ++ ++void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp) ++{ ++ if (new_sz <= nused) ++ return p; ++ ++ p = krealloc(p, new_sz, gfp); ++ if (p) ++ memset(p + nused, 0, new_sz - nused); ++ return p; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * aufs caches ++ */ ++struct kmem_cache *au_cachep[AuCache_Last]; ++static int __init au_cache_init(void) ++{ ++ au_cachep[AuCache_DINFO] = AuCache(au_dinfo); ++ if (au_cachep[AuCache_DINFO]) ++ au_cachep[AuCache_ICNTNR] = AuCache(au_icntnr); ++ if (au_cachep[AuCache_ICNTNR]) ++ au_cachep[AuCache_FINFO] = AuCache(au_finfo); ++ if (au_cachep[AuCache_FINFO]) ++ au_cachep[AuCache_VDIR] = AuCache(au_vdir); ++ if (au_cachep[AuCache_VDIR]) ++ au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr); ++ if (au_cachep[AuCache_DEHSTR]) ++ return 0; ++ ++ return -ENOMEM; ++} ++ ++static void au_cache_fin(void) ++{ ++ int i; ++ for (i = 0; i < AuCache_Last; i++) ++ if (au_cachep[i]) { ++ kmem_cache_destroy(au_cachep[i]); ++ au_cachep[i] = NULL; ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_dir_roflags; ++ ++/* ++ * functions for module interface. ++ */ ++MODULE_LICENSE("GPL"); ++/* MODULE_LICENSE("GPL v2"); */ ++MODULE_AUTHOR("Junjiro R. Okajima "); ++MODULE_DESCRIPTION(AUFS_NAME ++ " -- Advanced multi layered unification filesystem"); ++MODULE_VERSION(AUFS_VERSION); ++ ++/* it should be 'byte', but param_set_byte() prints it by "%c" */ ++short aufs_nwkq = AUFS_NWKQ_DEF; ++MODULE_PARM_DESC(nwkq, "the number of workqueue thread, " AUFS_WKQ_NAME); ++module_param_named(nwkq, aufs_nwkq, short, S_IRUGO); ++ ++/* this module parameter has no meaning when SYSFS is disabled */ ++int sysaufs_brs = 1; ++MODULE_PARM_DESC(brs, "use /fs/aufs/si_*/brN"); ++module_param_named(brs, sysaufs_brs, int, S_IRUGO); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */ ++ ++int au_seq_path(struct seq_file *seq, struct path *path) ++{ ++ return seq_path(seq, path, au_esc_chars); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int __init aufs_init(void) ++{ ++ int err, i; ++ char *p; ++ ++ p = au_esc_chars; ++ for (i = 1; i <= ' '; i++) ++ *p++ = i; ++ *p++ = '\\'; ++ *p++ = '\x7f'; ++ *p = 0; ++ ++ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE); ++ ++ sysaufs_brs_init(); ++ au_debug_init(); ++ ++ err = -EINVAL; ++ if (unlikely(aufs_nwkq <= 0)) ++ goto out; ++ ++ err = sysaufs_init(); ++ if (unlikely(err)) ++ goto out; ++ err = au_wkq_init(); ++ if (unlikely(err)) ++ goto out_sysaufs; ++ err = au_hinotify_init(); ++ if (unlikely(err)) ++ goto out_wkq; ++ err = au_sysrq_init(); ++ if (unlikely(err)) ++ goto out_hin; ++ err = au_cache_init(); ++ if (unlikely(err)) ++ goto out_sysrq; ++ err = register_filesystem(&aufs_fs_type); ++ if (unlikely(err)) ++ goto out_cache; ++ pr_info(AUFS_NAME " " AUFS_VERSION "\n"); ++ goto out; /* success */ ++ ++ out_cache: ++ au_cache_fin(); ++ out_sysrq: ++ au_sysrq_fin(); ++ out_hin: ++ au_hinotify_fin(); ++ out_wkq: ++ au_wkq_fin(); ++ out_sysaufs: ++ sysaufs_fin(); ++ out: ++ return err; ++} ++ ++static void __exit aufs_exit(void) ++{ ++ unregister_filesystem(&aufs_fs_type); ++ au_cache_fin(); ++ au_sysrq_fin(); ++ au_hinotify_fin(); ++ au_wkq_fin(); ++ sysaufs_fin(); ++} ++ ++module_init(aufs_init); ++module_exit(aufs_exit); +diff -Naur a/fs/aufs/module.h b/fs/aufs/module.h +--- a/fs/aufs/module.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/module.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,78 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * module initialization and module-global ++ */ ++ ++#ifndef __AUFS_MODULE_H__ ++#define __AUFS_MODULE_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++ ++struct path; ++struct seq_file; ++ ++/* module parameters */ ++extern short aufs_nwkq; ++extern int sysaufs_brs; ++ ++/* ---------------------------------------------------------------------- */ ++ ++extern int au_dir_roflags; ++ ++void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp); ++int au_seq_path(struct seq_file *seq, struct path *path); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* kmem cache */ ++enum { ++ AuCache_DINFO, ++ AuCache_ICNTNR, ++ AuCache_FINFO, ++ AuCache_VDIR, ++ AuCache_DEHSTR, ++#ifdef CONFIG_AUFS_HINOTIFY ++ AuCache_HINOTIFY, ++#endif ++ AuCache_Last ++}; ++ ++#define AuCache(type) KMEM_CACHE(type, SLAB_RECLAIM_ACCOUNT) ++ ++extern struct kmem_cache *au_cachep[]; ++ ++#define AuCacheFuncs(name, index) \ ++static inline void *au_cache_alloc_##name(void) \ ++{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \ ++static inline void au_cache_free_##name(void *p) \ ++{ kmem_cache_free(au_cachep[AuCache_##index], p); } ++ ++AuCacheFuncs(dinfo, DINFO); ++AuCacheFuncs(icntnr, ICNTNR); ++AuCacheFuncs(finfo, FINFO); ++AuCacheFuncs(vdir, VDIR); ++AuCacheFuncs(dehstr, DEHSTR); ++ ++/* ---------------------------------------------------------------------- */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_MODULE_H__ */ +diff -Naur a/fs/aufs/opts.c b/fs/aufs/opts.c +--- a/fs/aufs/opts.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/opts.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,1533 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * mount options/flags ++ */ ++ ++#include ++#include ++#include /* a distribution requires */ ++#include ++#include "aufs.h" ++ ++/* ---------------------------------------------------------------------- */ ++ ++enum { ++ Opt_br, ++ Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend, ++ Opt_idel, Opt_imod, Opt_ireorder, ++ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir, ++ Opt_rdblk_def, Opt_rdhash_def, ++ Opt_xino, Opt_zxino, Opt_noxino, ++ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino, ++ Opt_trunc_xino_path, Opt_itrunc_xino, ++ Opt_trunc_xib, Opt_notrunc_xib, ++ Opt_shwh, Opt_noshwh, ++ Opt_plink, Opt_noplink, Opt_list_plink, ++ Opt_udba, ++ /* Opt_lock, Opt_unlock, */ ++ Opt_cmd, Opt_cmd_args, ++ Opt_diropq_a, Opt_diropq_w, ++ Opt_warn_perm, Opt_nowarn_perm, ++ Opt_wbr_copyup, Opt_wbr_create, ++ Opt_refrof, Opt_norefrof, ++ Opt_verbose, Opt_noverbose, ++ Opt_sum, Opt_nosum, Opt_wsum, ++ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err ++}; ++ ++static match_table_t options = { ++ {Opt_br, "br=%s"}, ++ {Opt_br, "br:%s"}, ++ ++ {Opt_add, "add=%d:%s"}, ++ {Opt_add, "add:%d:%s"}, ++ {Opt_add, "ins=%d:%s"}, ++ {Opt_add, "ins:%d:%s"}, ++ {Opt_append, "append=%s"}, ++ {Opt_append, "append:%s"}, ++ {Opt_prepend, "prepend=%s"}, ++ {Opt_prepend, "prepend:%s"}, ++ ++ {Opt_del, "del=%s"}, ++ {Opt_del, "del:%s"}, ++ /* {Opt_idel, "idel:%d"}, */ ++ {Opt_mod, "mod=%s"}, ++ {Opt_mod, "mod:%s"}, ++ /* {Opt_imod, "imod:%d:%s"}, */ ++ ++ {Opt_dirwh, "dirwh=%d"}, ++ ++ {Opt_xino, "xino=%s"}, ++ {Opt_noxino, "noxino"}, ++ {Opt_trunc_xino, "trunc_xino"}, ++ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"}, ++ {Opt_notrunc_xino, "notrunc_xino"}, ++ {Opt_trunc_xino_path, "trunc_xino=%s"}, ++ {Opt_itrunc_xino, "itrunc_xino=%d"}, ++ /* {Opt_zxino, "zxino=%s"}, */ ++ {Opt_trunc_xib, "trunc_xib"}, ++ {Opt_notrunc_xib, "notrunc_xib"}, ++ ++ {Opt_plink, "plink"}, ++ {Opt_noplink, "noplink"}, ++#ifdef CONFIG_AUFS_DEBUG ++ {Opt_list_plink, "list_plink"}, ++#endif ++ ++ {Opt_udba, "udba=%s"}, ++ ++ {Opt_diropq_a, "diropq=always"}, ++ {Opt_diropq_a, "diropq=a"}, ++ {Opt_diropq_w, "diropq=whiteouted"}, ++ {Opt_diropq_w, "diropq=w"}, ++ ++ {Opt_warn_perm, "warn_perm"}, ++ {Opt_nowarn_perm, "nowarn_perm"}, ++ ++ /* keep them temporary */ ++ {Opt_ignore_silent, "coo=%s"}, ++ {Opt_ignore_silent, "nodlgt"}, ++ {Opt_ignore_silent, "nodirperm1"}, ++ {Opt_ignore_silent, "clean_plink"}, ++ ++#ifdef CONFIG_AUFS_SHWH ++ {Opt_shwh, "shwh"}, ++#endif ++ {Opt_noshwh, "noshwh"}, ++ ++ {Opt_rendir, "rendir=%d"}, ++ ++ {Opt_refrof, "refrof"}, ++ {Opt_norefrof, "norefrof"}, ++ ++ {Opt_verbose, "verbose"}, ++ {Opt_verbose, "v"}, ++ {Opt_noverbose, "noverbose"}, ++ {Opt_noverbose, "quiet"}, ++ {Opt_noverbose, "q"}, ++ {Opt_noverbose, "silent"}, ++ ++ {Opt_sum, "sum"}, ++ {Opt_nosum, "nosum"}, ++ {Opt_wsum, "wsum"}, ++ ++ {Opt_rdcache, "rdcache=%d"}, ++ {Opt_rdblk, "rdblk=%d"}, ++ {Opt_rdblk_def, "rdblk=def"}, ++ {Opt_rdhash, "rdhash=%d"}, ++ {Opt_rdhash_def, "rdhash=def"}, ++ ++ {Opt_wbr_create, "create=%s"}, ++ {Opt_wbr_create, "create_policy=%s"}, ++ {Opt_wbr_copyup, "cpup=%s"}, ++ {Opt_wbr_copyup, "copyup=%s"}, ++ {Opt_wbr_copyup, "copyup_policy=%s"}, ++ ++ /* internal use for the scripts */ ++ {Opt_ignore_silent, "si=%s"}, ++ ++ {Opt_br, "dirs=%s"}, ++ {Opt_ignore, "debug=%d"}, ++ {Opt_ignore, "delete=whiteout"}, ++ {Opt_ignore, "delete=all"}, ++ {Opt_ignore, "imap=%s"}, ++ ++ {Opt_err, NULL} ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static const char *au_parser_pattern(int val, struct match_token *token) ++{ ++ while (token->pattern) { ++ if (token->token == val) ++ return token->pattern; ++ token++; ++ } ++ BUG(); ++ return "??"; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static match_table_t brperms = { ++ {AuBrPerm_RO, AUFS_BRPERM_RO}, ++ {AuBrPerm_RR, AUFS_BRPERM_RR}, ++ {AuBrPerm_RW, AUFS_BRPERM_RW}, ++ ++ {AuBrPerm_ROWH, AUFS_BRPERM_ROWH}, ++ {AuBrPerm_RRWH, AUFS_BRPERM_RRWH}, ++ {AuBrPerm_RWNoLinkWH, AUFS_BRPERM_RWNLWH}, ++ ++ {AuBrPerm_ROWH, "nfsro"}, ++ {AuBrPerm_RO, NULL} ++}; ++ ++static int br_perm_val(char *perm) ++{ ++ int val; ++ substring_t args[MAX_OPT_ARGS]; ++ ++ val = match_token(perm, brperms, args); ++ return val; ++} ++ ++const char *au_optstr_br_perm(int brperm) ++{ ++ return au_parser_pattern(brperm, (void *)brperms); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static match_table_t udbalevel = { ++ {AuOpt_UDBA_REVAL, "reval"}, ++ {AuOpt_UDBA_NONE, "none"}, ++#ifdef CONFIG_AUFS_HINOTIFY ++ {AuOpt_UDBA_HINOTIFY, "inotify"}, ++#endif ++ {-1, NULL} ++}; ++ ++static int udba_val(char *str) ++{ ++ substring_t args[MAX_OPT_ARGS]; ++ ++ return match_token(str, udbalevel, args); ++} ++ ++const char *au_optstr_udba(int udba) ++{ ++ return au_parser_pattern(udba, (void *)udbalevel); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static match_table_t au_wbr_create_policy = { ++ {AuWbrCreate_TDP, "tdp"}, ++ {AuWbrCreate_TDP, "top-down-parent"}, ++ {AuWbrCreate_RR, "rr"}, ++ {AuWbrCreate_RR, "round-robin"}, ++ {AuWbrCreate_MFS, "mfs"}, ++ {AuWbrCreate_MFS, "most-free-space"}, ++ {AuWbrCreate_MFSV, "mfs:%d"}, ++ {AuWbrCreate_MFSV, "most-free-space:%d"}, ++ ++ {AuWbrCreate_MFSRR, "mfsrr:%d"}, ++ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"}, ++ {AuWbrCreate_PMFS, "pmfs"}, ++ {AuWbrCreate_PMFSV, "pmfs:%d"}, ++ ++ {-1, NULL} ++}; ++ ++/* ++ * cf. linux/lib/parser.c and cmdline.c ++ * gave up calling memparse() since it uses simple_strtoull() instead of ++ * strict_...(). ++ */ ++static int au_match_ull(substring_t *s, unsigned long long *result) ++{ ++ int err; ++ unsigned int len; ++ char a[32]; ++ ++ err = -ERANGE; ++ len = s->to - s->from; ++ if (len + 1 <= sizeof(a)) { ++ memcpy(a, s->from, len); ++ a[len] = '\0'; ++ err = strict_strtoull(a, 0, result); ++ } ++ return err; ++} ++ ++static int au_wbr_mfs_wmark(substring_t *arg, char *str, ++ struct au_opt_wbr_create *create) ++{ ++ int err; ++ unsigned long long ull; ++ ++ err = 0; ++ if (!au_match_ull(arg, &ull)) ++ create->mfsrr_watermark = ull; ++ else { ++ AuErr("bad integer in %s\n", str); ++ err = -EINVAL; ++ } ++ ++ return err; ++} ++ ++static int au_wbr_mfs_sec(substring_t *arg, char *str, ++ struct au_opt_wbr_create *create) ++{ ++ int n, err; ++ ++ err = 0; ++ if (!match_int(arg, &n) && 0 <= n) ++ create->mfs_second = n; ++ else { ++ AuErr("bad integer in %s\n", str); ++ err = -EINVAL; ++ } ++ ++ return err; ++} ++ ++static int au_wbr_create_val(char *str, struct au_opt_wbr_create *create) ++{ ++ int err, e; ++ substring_t args[MAX_OPT_ARGS]; ++ ++ err = match_token(str, au_wbr_create_policy, args); ++ create->wbr_create = err; ++ switch (err) { ++ case AuWbrCreate_MFSRRV: ++ e = au_wbr_mfs_wmark(&args[0], str, create); ++ if (!e) ++ e = au_wbr_mfs_sec(&args[1], str, create); ++ if (unlikely(e)) ++ err = e; ++ break; ++ case AuWbrCreate_MFSRR: ++ e = au_wbr_mfs_wmark(&args[0], str, create); ++ if (unlikely(e)) { ++ err = e; ++ break; ++ } ++ /*FALLTHROUGH*/ ++ case AuWbrCreate_MFS: ++ case AuWbrCreate_PMFS: ++ create->mfs_second = AUFS_MFS_SECOND_DEF; ++ break; ++ case AuWbrCreate_MFSV: ++ case AuWbrCreate_PMFSV: ++ e = au_wbr_mfs_sec(&args[0], str, create); ++ if (unlikely(e)) ++ err = e; ++ break; ++ } ++ ++ return err; ++} ++ ++const char *au_optstr_wbr_create(int wbr_create) ++{ ++ return au_parser_pattern(wbr_create, (void *)au_wbr_create_policy); ++} ++ ++static match_table_t au_wbr_copyup_policy = { ++ {AuWbrCopyup_TDP, "tdp"}, ++ {AuWbrCopyup_TDP, "top-down-parent"}, ++ {AuWbrCopyup_BUP, "bup"}, ++ {AuWbrCopyup_BUP, "bottom-up-parent"}, ++ {AuWbrCopyup_BU, "bu"}, ++ {AuWbrCopyup_BU, "bottom-up"}, ++ {-1, NULL} ++}; ++ ++static int au_wbr_copyup_val(char *str) ++{ ++ substring_t args[MAX_OPT_ARGS]; ++ ++ return match_token(str, au_wbr_copyup_policy, args); ++} ++ ++const char *au_optstr_wbr_copyup(int wbr_copyup) ++{ ++ return au_parser_pattern(wbr_copyup, (void *)au_wbr_copyup_policy); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY; ++ ++static void dump_opts(struct au_opts *opts) ++{ ++#ifdef CONFIG_AUFS_DEBUG ++ /* reduce stack space */ ++ union { ++ struct au_opt_add *add; ++ struct au_opt_del *del; ++ struct au_opt_mod *mod; ++ struct au_opt_xino *xino; ++ struct au_opt_xino_itrunc *xino_itrunc; ++ struct au_opt_wbr_create *create; ++ } u; ++ struct au_opt *opt; ++ ++ opt = opts->opt; ++ while (opt->type != Opt_tail) { ++ switch (opt->type) { ++ case Opt_add: ++ u.add = &opt->add; ++ AuDbg("add {b%d, %s, 0x%x, %p}\n", ++ u.add->bindex, u.add->pathname, u.add->perm, ++ u.add->path.dentry); ++ break; ++ case Opt_del: ++ case Opt_idel: ++ u.del = &opt->del; ++ AuDbg("del {%s, %p}\n", ++ u.del->pathname, u.del->h_path.dentry); ++ break; ++ case Opt_mod: ++ case Opt_imod: ++ u.mod = &opt->mod; ++ AuDbg("mod {%s, 0x%x, %p}\n", ++ u.mod->path, u.mod->perm, u.mod->h_root); ++ break; ++ case Opt_append: ++ u.add = &opt->add; ++ AuDbg("append {b%d, %s, 0x%x, %p}\n", ++ u.add->bindex, u.add->pathname, u.add->perm, ++ u.add->path.dentry); ++ break; ++ case Opt_prepend: ++ u.add = &opt->add; ++ AuDbg("prepend {b%d, %s, 0x%x, %p}\n", ++ u.add->bindex, u.add->pathname, u.add->perm, ++ u.add->path.dentry); ++ break; ++ case Opt_dirwh: ++ AuDbg("dirwh %d\n", opt->dirwh); ++ break; ++ case Opt_rdcache: ++ AuDbg("rdcache %d\n", opt->rdcache); ++ break; ++ case Opt_rdblk: ++ AuDbg("rdblk %u\n", opt->rdblk); ++ break; ++ case Opt_rdblk_def: ++ AuDbg("rdblk_def\n"); ++ break; ++ case Opt_rdhash: ++ AuDbg("rdhash %u\n", opt->rdhash); ++ break; ++ case Opt_rdhash_def: ++ AuDbg("rdhash_def\n"); ++ break; ++ case Opt_xino: ++ u.xino = &opt->xino; ++ AuDbg("xino {%s %.*s}\n", ++ u.xino->path, ++ AuDLNPair(u.xino->file->f_dentry)); ++ break; ++ case Opt_trunc_xino: ++ AuLabel(trunc_xino); ++ break; ++ case Opt_notrunc_xino: ++ AuLabel(notrunc_xino); ++ break; ++ case Opt_trunc_xino_path: ++ case Opt_itrunc_xino: ++ u.xino_itrunc = &opt->xino_itrunc; ++ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex); ++ break; ++ ++ case Opt_noxino: ++ AuLabel(noxino); ++ break; ++ case Opt_trunc_xib: ++ AuLabel(trunc_xib); ++ break; ++ case Opt_notrunc_xib: ++ AuLabel(notrunc_xib); ++ break; ++ case Opt_shwh: ++ AuLabel(shwh); ++ break; ++ case Opt_noshwh: ++ AuLabel(noshwh); ++ break; ++ case Opt_plink: ++ AuLabel(plink); ++ break; ++ case Opt_noplink: ++ AuLabel(noplink); ++ break; ++ case Opt_list_plink: ++ AuLabel(list_plink); ++ break; ++ case Opt_udba: ++ AuDbg("udba %d, %s\n", ++ opt->udba, au_optstr_udba(opt->udba)); ++ break; ++ case Opt_diropq_a: ++ AuLabel(diropq_a); ++ break; ++ case Opt_diropq_w: ++ AuLabel(diropq_w); ++ break; ++ case Opt_warn_perm: ++ AuLabel(warn_perm); ++ break; ++ case Opt_nowarn_perm: ++ AuLabel(nowarn_perm); ++ break; ++ case Opt_refrof: ++ AuLabel(refrof); ++ break; ++ case Opt_norefrof: ++ AuLabel(norefrof); ++ break; ++ case Opt_verbose: ++ AuLabel(verbose); ++ break; ++ case Opt_noverbose: ++ AuLabel(noverbose); ++ break; ++ case Opt_sum: ++ AuLabel(sum); ++ break; ++ case Opt_nosum: ++ AuLabel(nosum); ++ break; ++ case Opt_wsum: ++ AuLabel(wsum); ++ break; ++ case Opt_wbr_create: ++ u.create = &opt->wbr_create; ++ AuDbg("create %d, %s\n", u.create->wbr_create, ++ au_optstr_wbr_create(u.create->wbr_create)); ++ switch (u.create->wbr_create) { ++ case AuWbrCreate_MFSV: ++ case AuWbrCreate_PMFSV: ++ AuDbg("%d sec\n", u.create->mfs_second); ++ break; ++ case AuWbrCreate_MFSRR: ++ AuDbg("%llu watermark\n", ++ u.create->mfsrr_watermark); ++ break; ++ case AuWbrCreate_MFSRRV: ++ AuDbg("%llu watermark, %d sec\n", ++ u.create->mfsrr_watermark, ++ u.create->mfs_second); ++ break; ++ } ++ break; ++ case Opt_wbr_copyup: ++ AuDbg("copyup %d, %s\n", opt->wbr_copyup, ++ au_optstr_wbr_copyup(opt->wbr_copyup)); ++ break; ++ default: ++ BUG(); ++ } ++ opt++; ++ } ++#endif ++} ++ ++void au_opts_free(struct au_opts *opts) ++{ ++ struct au_opt *opt; ++ ++ opt = opts->opt; ++ while (opt->type != Opt_tail) { ++ switch (opt->type) { ++ case Opt_add: ++ case Opt_append: ++ case Opt_prepend: ++ path_put(&opt->add.path); ++ break; ++ case Opt_del: ++ case Opt_idel: ++ path_put(&opt->del.h_path); ++ break; ++ case Opt_mod: ++ case Opt_imod: ++ dput(opt->mod.h_root); ++ break; ++ case Opt_xino: ++ fput(opt->xino.file); ++ break; ++ } ++ opt++; ++ } ++} ++ ++static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags, ++ aufs_bindex_t bindex) ++{ ++ int err; ++ struct au_opt_add *add = &opt->add; ++ char *p; ++ ++ add->bindex = bindex; ++ add->perm = AuBrPerm_Last; ++ add->pathname = opt_str; ++ p = strchr(opt_str, '='); ++ if (p) { ++ *p++ = 0; ++ if (*p) ++ add->perm = br_perm_val(p); ++ } ++ ++ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path); ++ if (!err) { ++ if (!p) { ++ add->perm = AuBrPerm_RO; ++ if (au_test_fs_rr(add->path.dentry->d_sb)) ++ add->perm = AuBrPerm_RR; ++ else if (!bindex && !(sb_flags & MS_RDONLY)) ++ add->perm = AuBrPerm_RW; ++ } ++ opt->type = Opt_add; ++ goto out; ++ } ++ AuErr("lookup failed %s (%d)\n", add->pathname, err); ++ err = -EINVAL; ++ ++ out: ++ return err; ++} ++ ++static int au_opts_parse_del(struct au_opt_del *del, substring_t args[]) ++{ ++ int err; ++ ++ del->pathname = args[0].from; ++ AuDbg("del path %s\n", del->pathname); ++ ++ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path); ++ if (unlikely(err)) ++ AuErr("lookup failed %s (%d)\n", del->pathname, err); ++ ++ return err; ++} ++ ++#if 0 /* reserved for future use */ ++static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex, ++ struct au_opt_del *del, substring_t args[]) ++{ ++ int err; ++ struct dentry *root; ++ ++ err = -EINVAL; ++ root = sb->s_root; ++ aufs_read_lock(root, AuLock_FLUSH); ++ if (bindex < 0 || au_sbend(sb) < bindex) { ++ AuErr("out of bounds, %d\n", bindex); ++ goto out; ++ } ++ ++ err = 0; ++ del->h_path.dentry = dget(au_h_dptr(root, bindex)); ++ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex)); ++ ++ out: ++ aufs_read_unlock(root, !AuLock_IR); ++ return err; ++} ++#endif ++ ++static int au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[]) ++{ ++ int err; ++ struct path path; ++ char *p; ++ ++ err = -EINVAL; ++ mod->path = args[0].from; ++ p = strchr(mod->path, '='); ++ if (unlikely(!p)) { ++ AuErr("no permssion %s\n", args[0].from); ++ goto out; ++ } ++ ++ *p++ = 0; ++ err = vfsub_kern_path(mod->path, lkup_dirflags, &path); ++ if (unlikely(err)) { ++ AuErr("lookup failed %s (%d)\n", mod->path, err); ++ goto out; ++ } ++ ++ mod->perm = br_perm_val(p); ++ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p); ++ mod->h_root = dget(path.dentry); ++ path_put(&path); ++ ++ out: ++ return err; ++} ++ ++#if 0 /* reserved for future use */ ++static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex, ++ struct au_opt_mod *mod, substring_t args[]) ++{ ++ int err; ++ struct dentry *root; ++ ++ err = -EINVAL; ++ root = sb->s_root; ++ aufs_read_lock(root, AuLock_FLUSH); ++ if (bindex < 0 || au_sbend(sb) < bindex) { ++ AuErr("out of bounds, %d\n", bindex); ++ goto out; ++ } ++ ++ err = 0; ++ mod->perm = br_perm_val(args[1].from); ++ AuDbg("mod path %s, perm 0x%x, %s\n", ++ mod->path, mod->perm, args[1].from); ++ mod->h_root = dget(au_h_dptr(root, bindex)); ++ ++ out: ++ aufs_read_unlock(root, !AuLock_IR); ++ return err; ++} ++#endif ++ ++static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino, ++ substring_t args[]) ++{ ++ int err; ++ struct file *file; ++ ++ file = au_xino_create(sb, args[0].from, /*silent*/0); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ ++ err = -EINVAL; ++ if (unlikely(file->f_dentry->d_sb == sb)) { ++ fput(file); ++ AuErr("%s must be outside\n", args[0].from); ++ goto out; ++ } ++ ++ err = 0; ++ xino->file = file; ++ xino->path = args[0].from; ++ ++ out: ++ return err; ++} ++ ++static ++int au_opts_parse_xino_itrunc_path(struct super_block *sb, ++ struct au_opt_xino_itrunc *xino_itrunc, ++ substring_t args[]) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct path path; ++ struct dentry *root; ++ ++ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path); ++ if (unlikely(err)) { ++ AuErr("lookup failed %s (%d)\n", args[0].from, err); ++ goto out; ++ } ++ ++ xino_itrunc->bindex = -1; ++ root = sb->s_root; ++ aufs_read_lock(root, AuLock_FLUSH); ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ if (au_h_dptr(root, bindex) == path.dentry) { ++ xino_itrunc->bindex = bindex; ++ break; ++ } ++ } ++ aufs_read_unlock(root, !AuLock_IR); ++ path_put(&path); ++ ++ if (unlikely(xino_itrunc->bindex < 0)) { ++ AuErr("no such branch %s\n", args[0].from); ++ err = -EINVAL; ++ } ++ ++ out: ++ return err; ++} ++ ++/* called without aufs lock */ ++int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts) ++{ ++ int err, n, token; ++ aufs_bindex_t bindex; ++ unsigned char skipped; ++ struct dentry *root; ++ struct au_opt *opt, *opt_tail; ++ char *opt_str; ++ /* reduce the stack space */ ++ union { ++ struct au_opt_xino_itrunc *xino_itrunc; ++ struct au_opt_wbr_create *create; ++ } u; ++ struct { ++ substring_t args[MAX_OPT_ARGS]; ++ } *a; ++ ++ err = -ENOMEM; ++ a = kmalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ root = sb->s_root; ++ err = 0; ++ bindex = 0; ++ opt = opts->opt; ++ opt_tail = opt + opts->max_opt - 1; ++ opt->type = Opt_tail; ++ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) { ++ err = -EINVAL; ++ skipped = 0; ++ token = match_token(opt_str, options, a->args); ++ switch (token) { ++ case Opt_br: ++ err = 0; ++ while (!err && (opt_str = strsep(&a->args[0].from, ":")) ++ && *opt_str) { ++ err = opt_add(opt, opt_str, opts->sb_flags, ++ bindex++); ++ if (unlikely(!err && ++opt > opt_tail)) { ++ err = -E2BIG; ++ break; ++ } ++ opt->type = Opt_tail; ++ skipped = 1; ++ } ++ break; ++ case Opt_add: ++ if (unlikely(match_int(&a->args[0], &n))) { ++ AuErr("bad integer in %s\n", opt_str); ++ break; ++ } ++ bindex = n; ++ err = opt_add(opt, a->args[1].from, opts->sb_flags, ++ bindex); ++ if (!err) ++ opt->type = token; ++ break; ++ case Opt_append: ++ err = opt_add(opt, a->args[0].from, opts->sb_flags, ++ /*dummy bindex*/1); ++ if (!err) ++ opt->type = token; ++ break; ++ case Opt_prepend: ++ err = opt_add(opt, a->args[0].from, opts->sb_flags, ++ /*bindex*/0); ++ if (!err) ++ opt->type = token; ++ break; ++ case Opt_del: ++ err = au_opts_parse_del(&opt->del, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++#if 0 /* reserved for future use */ ++ case Opt_idel: ++ del->pathname = "(indexed)"; ++ if (unlikely(match_int(&args[0], &n))) { ++ AuErr("bad integer in %s\n", opt_str); ++ break; ++ } ++ err = au_opts_parse_idel(sb, n, &opt->del, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++#endif ++ case Opt_mod: ++ err = au_opts_parse_mod(&opt->mod, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++#ifdef IMOD /* reserved for future use */ ++ case Opt_imod: ++ u.mod->path = "(indexed)"; ++ if (unlikely(match_int(&a->args[0], &n))) { ++ AuErr("bad integer in %s\n", opt_str); ++ break; ++ } ++ err = au_opts_parse_imod(sb, n, &opt->mod, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++#endif ++ case Opt_xino: ++ err = au_opts_parse_xino(sb, &opt->xino, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++ ++ case Opt_trunc_xino_path: ++ err = au_opts_parse_xino_itrunc_path ++ (sb, &opt->xino_itrunc, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++ ++ case Opt_itrunc_xino: ++ u.xino_itrunc = &opt->xino_itrunc; ++ if (unlikely(match_int(&a->args[0], &n))) { ++ AuErr("bad integer in %s\n", opt_str); ++ break; ++ } ++ u.xino_itrunc->bindex = n; ++ aufs_read_lock(root, AuLock_FLUSH); ++ if (n < 0 || au_sbend(sb) < n) { ++ AuErr("out of bounds, %d\n", n); ++ aufs_read_unlock(root, !AuLock_IR); ++ break; ++ } ++ aufs_read_unlock(root, !AuLock_IR); ++ err = 0; ++ opt->type = token; ++ break; ++ ++ case Opt_dirwh: ++ if (unlikely(match_int(&a->args[0], &opt->dirwh))) ++ break; ++ err = 0; ++ opt->type = token; ++ break; ++ ++ case Opt_rdcache: ++ if (unlikely(match_int(&a->args[0], &opt->rdcache))) ++ break; ++ err = 0; ++ opt->type = token; ++ break; ++ case Opt_rdblk: ++ if (unlikely(match_int(&a->args[0], &n) ++ || n <= 0 ++ || n > KMALLOC_MAX_SIZE)) { ++ AuErr("bad integer in %s\n", opt_str); ++ break; ++ } ++ if (unlikely(n < NAME_MAX)) { ++ AuErr("rdblk must be larger than %d\n", ++ NAME_MAX); ++ break; ++ } ++ opt->rdblk = n; ++ err = 0; ++ opt->type = token; ++ break; ++ case Opt_rdhash: ++ if (unlikely(match_int(&a->args[0], &n) ++ || n <= 0 ++ || n * sizeof(struct hlist_head) ++ > KMALLOC_MAX_SIZE)) { ++ AuErr("bad integer in %s\n", opt_str); ++ break; ++ } ++ opt->rdhash = n; ++ err = 0; ++ opt->type = token; ++ break; ++ ++ case Opt_trunc_xino: ++ case Opt_notrunc_xino: ++ case Opt_noxino: ++ case Opt_trunc_xib: ++ case Opt_notrunc_xib: ++ case Opt_shwh: ++ case Opt_noshwh: ++ case Opt_plink: ++ case Opt_noplink: ++ case Opt_list_plink: ++ case Opt_diropq_a: ++ case Opt_diropq_w: ++ case Opt_warn_perm: ++ case Opt_nowarn_perm: ++ case Opt_refrof: ++ case Opt_norefrof: ++ case Opt_verbose: ++ case Opt_noverbose: ++ case Opt_sum: ++ case Opt_nosum: ++ case Opt_wsum: ++ case Opt_rdblk_def: ++ case Opt_rdhash_def: ++ err = 0; ++ opt->type = token; ++ break; ++ ++ case Opt_udba: ++ opt->udba = udba_val(a->args[0].from); ++ if (opt->udba >= 0) { ++ err = 0; ++ opt->type = token; ++ } else ++ AuErr("wrong value, %s\n", opt_str); ++ break; ++ ++ case Opt_wbr_create: ++ u.create = &opt->wbr_create; ++ u.create->wbr_create ++ = au_wbr_create_val(a->args[0].from, u.create); ++ if (u.create->wbr_create >= 0) { ++ err = 0; ++ opt->type = token; ++ } else ++ AuErr("wrong value, %s\n", opt_str); ++ break; ++ case Opt_wbr_copyup: ++ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from); ++ if (opt->wbr_copyup >= 0) { ++ err = 0; ++ opt->type = token; ++ } else ++ AuErr("wrong value, %s\n", opt_str); ++ break; ++ ++ case Opt_ignore: ++ AuWarn("ignored %s\n", opt_str); ++ /*FALLTHROUGH*/ ++ case Opt_ignore_silent: ++ skipped = 1; ++ err = 0; ++ break; ++ case Opt_err: ++ AuErr("unknown option %s\n", opt_str); ++ break; ++ } ++ ++ if (!err && !skipped) { ++ if (unlikely(++opt > opt_tail)) { ++ err = -E2BIG; ++ opt--; ++ opt->type = Opt_tail; ++ break; ++ } ++ opt->type = Opt_tail; ++ } ++ } ++ ++ kfree(a); ++ dump_opts(opts); ++ if (unlikely(err)) ++ au_opts_free(opts); ++ ++ out: ++ return err; ++} ++ ++static int au_opt_wbr_create(struct super_block *sb, ++ struct au_opt_wbr_create *create) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ ++ err = 1; /* handled */ ++ sbinfo = au_sbi(sb); ++ if (sbinfo->si_wbr_create_ops->fin) { ++ err = sbinfo->si_wbr_create_ops->fin(sb); ++ if (!err) ++ err = 1; ++ } ++ ++ sbinfo->si_wbr_create = create->wbr_create; ++ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create; ++ switch (create->wbr_create) { ++ case AuWbrCreate_MFSRRV: ++ case AuWbrCreate_MFSRR: ++ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark; ++ /*FALLTHROUGH*/ ++ case AuWbrCreate_MFS: ++ case AuWbrCreate_MFSV: ++ case AuWbrCreate_PMFS: ++ case AuWbrCreate_PMFSV: ++ sbinfo->si_wbr_mfs.mfs_expire = create->mfs_second * HZ; ++ break; ++ } ++ ++ if (sbinfo->si_wbr_create_ops->init) ++ sbinfo->si_wbr_create_ops->init(sb); /* ignore */ ++ ++ return err; ++} ++ ++/* ++ * returns, ++ * plus: processed without an error ++ * zero: unprocessed ++ */ ++static int au_opt_simple(struct super_block *sb, struct au_opt *opt, ++ struct au_opts *opts) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ ++ err = 1; /* handled */ ++ sbinfo = au_sbi(sb); ++ switch (opt->type) { ++ case Opt_udba: ++ sbinfo->si_mntflags &= ~AuOptMask_UDBA; ++ sbinfo->si_mntflags |= opt->udba; ++ opts->given_udba |= opt->udba; ++ break; ++ ++ case Opt_plink: ++ au_opt_set(sbinfo->si_mntflags, PLINK); ++ break; ++ case Opt_noplink: ++ if (au_opt_test(sbinfo->si_mntflags, PLINK)) ++ au_plink_put(sb); ++ au_opt_clr(sbinfo->si_mntflags, PLINK); ++ break; ++ case Opt_list_plink: ++ if (au_opt_test(sbinfo->si_mntflags, PLINK)) ++ au_plink_list(sb); ++ break; ++ ++ case Opt_diropq_a: ++ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ); ++ break; ++ case Opt_diropq_w: ++ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ); ++ break; ++ ++ case Opt_warn_perm: ++ au_opt_set(sbinfo->si_mntflags, WARN_PERM); ++ break; ++ case Opt_nowarn_perm: ++ au_opt_clr(sbinfo->si_mntflags, WARN_PERM); ++ break; ++ ++ case Opt_refrof: ++ au_opt_set(sbinfo->si_mntflags, REFROF); ++ break; ++ case Opt_norefrof: ++ au_opt_clr(sbinfo->si_mntflags, REFROF); ++ break; ++ ++ case Opt_verbose: ++ au_opt_set(sbinfo->si_mntflags, VERBOSE); ++ break; ++ case Opt_noverbose: ++ au_opt_clr(sbinfo->si_mntflags, VERBOSE); ++ break; ++ ++ case Opt_sum: ++ au_opt_set(sbinfo->si_mntflags, SUM); ++ break; ++ case Opt_wsum: ++ au_opt_clr(sbinfo->si_mntflags, SUM); ++ au_opt_set(sbinfo->si_mntflags, SUM_W); ++ case Opt_nosum: ++ au_opt_clr(sbinfo->si_mntflags, SUM); ++ au_opt_clr(sbinfo->si_mntflags, SUM_W); ++ break; ++ ++ case Opt_wbr_create: ++ err = au_opt_wbr_create(sb, &opt->wbr_create); ++ break; ++ case Opt_wbr_copyup: ++ sbinfo->si_wbr_copyup = opt->wbr_copyup; ++ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup; ++ break; ++ ++ case Opt_dirwh: ++ sbinfo->si_dirwh = opt->dirwh; ++ break; ++ ++ case Opt_rdcache: ++ sbinfo->si_rdcache = opt->rdcache * HZ; ++ break; ++ case Opt_rdblk: ++ sbinfo->si_rdblk = opt->rdblk; ++ break; ++ case Opt_rdblk_def: ++ sbinfo->si_rdblk = AUFS_RDBLK_DEF; ++ break; ++ case Opt_rdhash: ++ sbinfo->si_rdhash = opt->rdhash; ++ break; ++ case Opt_rdhash_def: ++ sbinfo->si_rdhash = AUFS_RDHASH_DEF; ++ break; ++ ++ case Opt_shwh: ++ au_opt_set(sbinfo->si_mntflags, SHWH); ++ break; ++ case Opt_noshwh: ++ au_opt_clr(sbinfo->si_mntflags, SHWH); ++ break; ++ ++ case Opt_trunc_xino: ++ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO); ++ break; ++ case Opt_notrunc_xino: ++ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO); ++ break; ++ ++ case Opt_trunc_xino_path: ++ case Opt_itrunc_xino: ++ err = au_xino_trunc(sb, opt->xino_itrunc.bindex); ++ if (!err) ++ err = 1; ++ break; ++ ++ case Opt_trunc_xib: ++ au_fset_opts(opts->flags, TRUNC_XIB); ++ break; ++ case Opt_notrunc_xib: ++ au_fclr_opts(opts->flags, TRUNC_XIB); ++ break; ++ ++ default: ++ err = 0; ++ break; ++ } ++ ++ return err; ++} ++ ++/* ++ * returns tri-state. ++ * plus: processed without an error ++ * zero: unprocessed ++ * minus: error ++ */ ++static int au_opt_br(struct super_block *sb, struct au_opt *opt, ++ struct au_opts *opts) ++{ ++ int err, do_refresh; ++ ++ err = 0; ++ switch (opt->type) { ++ case Opt_append: ++ opt->add.bindex = au_sbend(sb) + 1; ++ if (opt->add.bindex < 0) ++ opt->add.bindex = 0; ++ goto add; ++ case Opt_prepend: ++ opt->add.bindex = 0; ++ add: ++ case Opt_add: ++ err = au_br_add(sb, &opt->add, ++ au_ftest_opts(opts->flags, REMOUNT)); ++ if (!err) { ++ err = 1; ++ au_fset_opts(opts->flags, REFRESH_DIR); ++ if (au_br_whable(opt->add.perm)) ++ au_fset_opts(opts->flags, REFRESH_NONDIR); ++ } ++ break; ++ ++ case Opt_del: ++ case Opt_idel: ++ err = au_br_del(sb, &opt->del, ++ au_ftest_opts(opts->flags, REMOUNT)); ++ if (!err) { ++ err = 1; ++ au_fset_opts(opts->flags, TRUNC_XIB); ++ au_fset_opts(opts->flags, REFRESH_DIR); ++ au_fset_opts(opts->flags, REFRESH_NONDIR); ++ } ++ break; ++ ++ case Opt_mod: ++ case Opt_imod: ++ err = au_br_mod(sb, &opt->mod, ++ au_ftest_opts(opts->flags, REMOUNT), ++ &do_refresh); ++ if (!err) { ++ err = 1; ++ if (do_refresh) { ++ au_fset_opts(opts->flags, REFRESH_DIR); ++ au_fset_opts(opts->flags, REFRESH_NONDIR); ++ } ++ } ++ break; ++ } ++ ++ return err; ++} ++ ++static int au_opt_xino(struct super_block *sb, struct au_opt *opt, ++ struct au_opt_xino **opt_xino, ++ struct au_opts *opts) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct dentry *root, *parent, *h_root; ++ ++ err = 0; ++ switch (opt->type) { ++ case Opt_xino: ++ err = au_xino_set(sb, &opt->xino, ++ !!au_ftest_opts(opts->flags, REMOUNT)); ++ if (unlikely(err)) ++ break; ++ ++ *opt_xino = &opt->xino; ++ au_xino_brid_set(sb, -1); ++ ++ /* safe d_parent access */ ++ parent = opt->xino.file->f_dentry->d_parent; ++ root = sb->s_root; ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ h_root = au_h_dptr(root, bindex); ++ if (h_root == parent) { ++ au_xino_brid_set(sb, au_sbr_id(sb, bindex)); ++ break; ++ } ++ } ++ break; ++ ++ case Opt_noxino: ++ au_xino_clr(sb); ++ au_xino_brid_set(sb, -1); ++ *opt_xino = (void *)-1; ++ break; ++ } ++ ++ return err; ++} ++ ++int au_opts_verify(struct super_block *sb, unsigned long sb_flags, ++ unsigned int pending) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ unsigned char do_plink, skip, do_free; ++ struct au_branch *br; ++ struct au_wbr *wbr; ++ struct dentry *root; ++ struct inode *dir, *h_dir; ++ struct au_sbinfo *sbinfo; ++ struct au_hinode *hdir; ++ ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA)); ++ ++ if (!(sb_flags & MS_RDONLY)) { ++ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0)))) ++ AuWarn("first branch should be rw\n"); ++ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH))) ++ AuWarn("shwh should be used with ro\n"); ++ } ++ ++ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HINOTIFY) ++ && !au_opt_test(sbinfo->si_mntflags, XINO)) ++ AuWarn("udba=inotify requires xino\n"); ++ ++ err = 0; ++ root = sb->s_root; ++ dir = sb->s_root->d_inode; ++ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK); ++ bend = au_sbend(sb); ++ for (bindex = 0; !err && bindex <= bend; bindex++) { ++ skip = 0; ++ h_dir = au_h_iptr(dir, bindex); ++ br = au_sbr(sb, bindex); ++ do_free = 0; ++ ++ wbr = br->br_wbr; ++ if (wbr) ++ wbr_wh_read_lock(wbr); ++ ++ switch (br->br_perm) { ++ case AuBrPerm_RO: ++ case AuBrPerm_ROWH: ++ case AuBrPerm_RR: ++ case AuBrPerm_RRWH: ++ do_free = !!wbr; ++ skip = (!wbr ++ || (!wbr->wbr_whbase ++ && !wbr->wbr_plink ++ && !wbr->wbr_orph)); ++ break; ++ ++ case AuBrPerm_RWNoLinkWH: ++ /* skip = (!br->br_whbase && !br->br_orph); */ ++ skip = (!wbr || !wbr->wbr_whbase); ++ if (skip && wbr) { ++ if (do_plink) ++ skip = !!wbr->wbr_plink; ++ else ++ skip = !wbr->wbr_plink; ++ } ++ break; ++ ++ case AuBrPerm_RW: ++ /* skip = (br->br_whbase && br->br_ohph); */ ++ skip = (wbr && wbr->wbr_whbase); ++ if (skip) { ++ if (do_plink) ++ skip = !!wbr->wbr_plink; ++ else ++ skip = !wbr->wbr_plink; ++ } ++ break; ++ ++ default: ++ BUG(); ++ } ++ if (wbr) ++ wbr_wh_read_unlock(wbr); ++ ++ if (skip) ++ continue; ++ ++ hdir = au_hi(dir, bindex); ++ au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT); ++ if (wbr) ++ wbr_wh_write_lock(wbr); ++ err = au_wh_init(au_h_dptr(root, bindex), br, sb); ++ if (wbr) ++ wbr_wh_write_unlock(wbr); ++ au_hin_imtx_unlock(hdir); ++ ++ if (!err && do_free) { ++ kfree(wbr); ++ br->br_wbr = NULL; ++ } ++ } ++ ++ return err; ++} ++ ++int au_opts_mount(struct super_block *sb, struct au_opts *opts) ++{ ++ int err; ++ unsigned int tmp; ++ aufs_bindex_t bend; ++ struct au_opt *opt; ++ struct au_opt_xino *opt_xino, xino; ++ struct au_sbinfo *sbinfo; ++ ++ err = 0; ++ opt_xino = NULL; ++ opt = opts->opt; ++ while (err >= 0 && opt->type != Opt_tail) ++ err = au_opt_simple(sb, opt++, opts); ++ if (err > 0) ++ err = 0; ++ else if (unlikely(err < 0)) ++ goto out; ++ ++ /* disable xino and udba temporary */ ++ sbinfo = au_sbi(sb); ++ tmp = sbinfo->si_mntflags; ++ au_opt_clr(sbinfo->si_mntflags, XINO); ++ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL); ++ ++ opt = opts->opt; ++ while (err >= 0 && opt->type != Opt_tail) ++ err = au_opt_br(sb, opt++, opts); ++ if (err > 0) ++ err = 0; ++ else if (unlikely(err < 0)) ++ goto out; ++ ++ bend = au_sbend(sb); ++ if (unlikely(bend < 0)) { ++ err = -EINVAL; ++ AuErr("no branches\n"); ++ goto out; ++ } ++ ++ if (au_opt_test(tmp, XINO)) ++ au_opt_set(sbinfo->si_mntflags, XINO); ++ opt = opts->opt; ++ while (!err && opt->type != Opt_tail) ++ err = au_opt_xino(sb, opt++, &opt_xino, opts); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_opts_verify(sb, sb->s_flags, tmp); ++ if (unlikely(err)) ++ goto out; ++ ++ /* restore xino */ ++ if (au_opt_test(tmp, XINO) && !opt_xino) { ++ xino.file = au_xino_def(sb); ++ err = PTR_ERR(xino.file); ++ if (IS_ERR(xino.file)) ++ goto out; ++ ++ err = au_xino_set(sb, &xino, /*remount*/0); ++ fput(xino.file); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ /* restore udba */ ++ sbinfo->si_mntflags &= ~AuOptMask_UDBA; ++ sbinfo->si_mntflags |= (tmp & AuOptMask_UDBA); ++ if (au_opt_test(tmp, UDBA_HINOTIFY)) { ++ struct inode *dir = sb->s_root->d_inode; ++ au_reset_hinotify(dir, ++ au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO); ++ } ++ ++ out: ++ return err; ++} ++ ++int au_opts_remount(struct super_block *sb, struct au_opts *opts) ++{ ++ int err, rerr; ++ struct inode *dir; ++ struct au_opt_xino *opt_xino; ++ struct au_opt *opt; ++ struct au_sbinfo *sbinfo; ++ ++ dir = sb->s_root->d_inode; ++ sbinfo = au_sbi(sb); ++ err = 0; ++ opt_xino = NULL; ++ opt = opts->opt; ++ while (err >= 0 && opt->type != Opt_tail) { ++ err = au_opt_simple(sb, opt, opts); ++ if (!err) ++ err = au_opt_br(sb, opt, opts); ++ if (!err) ++ err = au_opt_xino(sb, opt, &opt_xino, opts); ++ opt++; ++ } ++ if (err > 0) ++ err = 0; ++ AuTraceErr(err); ++ /* go on even err */ ++ ++ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0); ++ if (unlikely(rerr && !err)) ++ err = rerr; ++ ++ if (au_ftest_opts(opts->flags, TRUNC_XIB)) { ++ rerr = au_xib_trunc(sb); ++ if (unlikely(rerr && !err)) ++ err = rerr; ++ } ++ ++ /* will be handled by the caller */ ++ if (!au_ftest_opts(opts->flags, REFRESH_DIR) ++ && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO))) ++ au_fset_opts(opts->flags, REFRESH_DIR); ++ ++ AuDbg("status 0x%x\n", opts->flags); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++unsigned int au_opt_udba(struct super_block *sb) ++{ ++ return au_mntflags(sb) & AuOptMask_UDBA; ++} +diff -Naur a/fs/aufs/opts.h b/fs/aufs/opts.h +--- a/fs/aufs/opts.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/opts.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,196 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * mount options/flags ++ */ ++ ++#ifndef __AUFS_OPTS_H__ ++#define __AUFS_OPTS_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++ ++struct file; ++struct super_block; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* mount flags */ ++#define AuOpt_XINO 1 /* external inode number bitmap ++ and translation table */ ++#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */ ++#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */ ++#define AuOpt_UDBA_REVAL (1 << 3) ++#define AuOpt_UDBA_HINOTIFY (1 << 4) ++#define AuOpt_SHWH (1 << 5) /* show whiteout */ ++#define AuOpt_PLINK (1 << 6) /* pseudo-link */ ++#define AuOpt_DIRPERM1 (1 << 7) /* unimplemented */ ++#define AuOpt_REFROF (1 << 8) /* unimplemented */ ++#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */ ++#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */ ++#define AuOpt_SUM_W (1 << 11) /* unimplemented */ ++#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */ ++#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */ ++ ++#ifndef CONFIG_AUFS_HINOTIFY ++#undef AuOpt_UDBA_HINOTIFY ++#define AuOpt_UDBA_HINOTIFY 0 ++#endif ++#ifndef CONFIG_AUFS_SHWH ++#undef AuOpt_SHWH ++#define AuOpt_SHWH 0 ++#endif ++ ++#define AuOpt_Def (AuOpt_XINO \ ++ | AuOpt_UDBA_REVAL \ ++ | AuOpt_PLINK \ ++ /* | AuOpt_DIRPERM1 */ \ ++ | AuOpt_WARN_PERM) ++#define AuOptMask_UDBA (AuOpt_UDBA_NONE \ ++ | AuOpt_UDBA_REVAL \ ++ | AuOpt_UDBA_HINOTIFY) ++ ++#define au_opt_test(flags, name) (flags & AuOpt_##name) ++#define au_opt_set(flags, name) do { \ ++ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \ ++ ((flags) |= AuOpt_##name); \ ++} while (0) ++#define au_opt_set_udba(flags, name) do { \ ++ (flags) &= ~AuOptMask_UDBA; \ ++ ((flags) |= AuOpt_##name); \ ++} while (0) ++#define au_opt_clr(flags, name) { ((flags) &= ~AuOpt_##name); } ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* policies to select one among multiple writable branches */ ++enum { ++ AuWbrCreate_TDP, /* top down parent */ ++ AuWbrCreate_RR, /* round robin */ ++ AuWbrCreate_MFS, /* most free space */ ++ AuWbrCreate_MFSV, /* mfs with seconds */ ++ AuWbrCreate_MFSRR, /* mfs then rr */ ++ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */ ++ AuWbrCreate_PMFS, /* parent and mfs */ ++ AuWbrCreate_PMFSV, /* parent and mfs with seconds */ ++ ++ AuWbrCreate_Def = AuWbrCreate_TDP ++}; ++ ++enum { ++ AuWbrCopyup_TDP, /* top down parent */ ++ AuWbrCopyup_BUP, /* bottom up parent */ ++ AuWbrCopyup_BU, /* bottom up */ ++ ++ AuWbrCopyup_Def = AuWbrCopyup_TDP ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_opt_add { ++ aufs_bindex_t bindex; ++ char *pathname; ++ int perm; ++ struct path path; ++}; ++ ++struct au_opt_del { ++ char *pathname; ++ struct path h_path; ++}; ++ ++struct au_opt_mod { ++ char *path; ++ int perm; ++ struct dentry *h_root; ++}; ++ ++struct au_opt_xino { ++ char *path; ++ struct file *file; ++}; ++ ++struct au_opt_xino_itrunc { ++ aufs_bindex_t bindex; ++}; ++ ++struct au_opt_wbr_create { ++ int wbr_create; ++ int mfs_second; ++ unsigned long long mfsrr_watermark; ++}; ++ ++struct au_opt { ++ int type; ++ union { ++ struct au_opt_xino xino; ++ struct au_opt_xino_itrunc xino_itrunc; ++ struct au_opt_add add; ++ struct au_opt_del del; ++ struct au_opt_mod mod; ++ int dirwh; ++ int rdcache; ++ unsigned int rdblk; ++ unsigned int rdhash; ++ int udba; ++ struct au_opt_wbr_create wbr_create; ++ int wbr_copyup; ++ }; ++}; ++ ++/* opts flags */ ++#define AuOpts_REMOUNT 1 ++#define AuOpts_REFRESH_DIR (1 << 1) ++#define AuOpts_REFRESH_NONDIR (1 << 2) ++#define AuOpts_TRUNC_XIB (1 << 3) ++#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name) ++#define au_fset_opts(flags, name) { (flags) |= AuOpts_##name; } ++#define au_fclr_opts(flags, name) { (flags) &= ~AuOpts_##name; } ++ ++struct au_opts { ++ struct au_opt *opt; ++ int max_opt; ++ ++ unsigned int given_udba; ++ unsigned int flags; ++ unsigned long sb_flags; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++const char *au_optstr_br_perm(int brperm); ++const char *au_optstr_udba(int udba); ++const char *au_optstr_wbr_copyup(int wbr_copyup); ++const char *au_optstr_wbr_create(int wbr_create); ++ ++void au_opts_free(struct au_opts *opts); ++int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts); ++int au_opts_verify(struct super_block *sb, unsigned long sb_flags, ++ unsigned int pending); ++int au_opts_mount(struct super_block *sb, struct au_opts *opts); ++int au_opts_remount(struct super_block *sb, struct au_opts *opts); ++ ++unsigned int au_opt_udba(struct super_block *sb); ++ ++/* ---------------------------------------------------------------------- */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_OPTS_H__ */ +diff -Naur a/fs/aufs/plink.c b/fs/aufs/plink.c +--- a/fs/aufs/plink.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/plink.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,344 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * pseudo-link ++ */ ++ ++#include "aufs.h" ++ ++/* ++ * during a user process maintains the pseudo-links, ++ * prohibit adding a new plink and branch manipulation. ++ */ ++void au_plink_block_maintain(struct super_block *sb) ++{ ++ struct au_sbinfo *sbi = au_sbi(sb); ++ /* gave up wake_up_bit() */ ++ wait_event(sbi->si_plink_wq, !au_ftest_si(sbi, MAINTAIN_PLINK)); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct pseudo_link { ++ struct list_head list; ++ struct inode *inode; ++}; ++ ++#ifdef CONFIG_AUFS_DEBUG ++void au_plink_list(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ struct list_head *plink_list; ++ struct pseudo_link *plink; ++ ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); ++ ++ plink_list = &sbinfo->si_plink.head; ++ spin_lock(&sbinfo->si_plink.spin); ++ list_for_each_entry(plink, plink_list, list) ++ AuDbg("%lu\n", plink->inode->i_ino); ++ spin_unlock(&sbinfo->si_plink.spin); ++} ++#endif ++ ++/* is the inode pseudo-linked? */ ++int au_plink_test(struct inode *inode) ++{ ++ int found; ++ struct au_sbinfo *sbinfo; ++ struct list_head *plink_list; ++ struct pseudo_link *plink; ++ ++ sbinfo = au_sbi(inode->i_sb); ++ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK)); ++ ++ found = 0; ++ plink_list = &sbinfo->si_plink.head; ++ spin_lock(&sbinfo->si_plink.spin); ++ list_for_each_entry(plink, plink_list, list) ++ if (plink->inode == inode) { ++ found = 1; ++ break; ++ } ++ spin_unlock(&sbinfo->si_plink.spin); ++ return found; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * generate a name for plink. ++ * the file will be stored under AUFS_WH_PLINKDIR. ++ */ ++/* 20 is max digits length of ulong 64 */ ++#define PLINK_NAME_LEN ((20 + 1) * 2) ++ ++static int plink_name(char *name, int len, struct inode *inode, ++ aufs_bindex_t bindex) ++{ ++ int rlen; ++ struct inode *h_inode; ++ ++ h_inode = au_h_iptr(inode, bindex); ++ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino); ++ return rlen; ++} ++ ++/* lookup the plink-ed @inode under the branch at @bindex */ ++struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex) ++{ ++ struct dentry *h_dentry, *h_parent; ++ struct au_branch *br; ++ struct inode *h_dir; ++ char a[PLINK_NAME_LEN]; ++ struct qstr tgtname = { ++ .name = a ++ }; ++ ++ br = au_sbr(inode->i_sb, bindex); ++ h_parent = br->br_wbr->wbr_plink; ++ h_dir = h_parent->d_inode; ++ tgtname.len = plink_name(a, sizeof(a), inode, bindex); ++ ++ /* always superio. */ ++ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2); ++ h_dentry = au_sio_lkup_one(&tgtname, h_parent, br); ++ mutex_unlock(&h_dir->i_mutex); ++ return h_dentry; ++} ++ ++/* create a pseudo-link */ ++static int do_whplink(struct qstr *tgt, struct dentry *h_parent, ++ struct dentry *h_dentry, struct au_branch *br) ++{ ++ int err; ++ struct path h_path = { ++ .mnt = br->br_mnt ++ }; ++ struct inode *h_dir; ++ ++ h_dir = h_parent->d_inode; ++ again: ++ h_path.dentry = au_lkup_one(tgt, h_parent, br, /*nd*/NULL); ++ err = PTR_ERR(h_path.dentry); ++ if (IS_ERR(h_path.dentry)) ++ goto out; ++ ++ err = 0; ++ /* wh.plink dir is not monitored */ ++ if (h_path.dentry->d_inode ++ && h_path.dentry->d_inode != h_dentry->d_inode) { ++ err = vfsub_unlink(h_dir, &h_path, /*force*/0); ++ dput(h_path.dentry); ++ h_path.dentry = NULL; ++ if (!err) ++ goto again; ++ } ++ if (!err && !h_path.dentry->d_inode) ++ err = vfsub_link(h_dentry, h_dir, &h_path); ++ dput(h_path.dentry); ++ ++ out: ++ return err; ++} ++ ++struct do_whplink_args { ++ int *errp; ++ struct qstr *tgt; ++ struct dentry *h_parent; ++ struct dentry *h_dentry; ++ struct au_branch *br; ++}; ++ ++static void call_do_whplink(void *args) ++{ ++ struct do_whplink_args *a = args; ++ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br); ++} ++ ++static int whplink(struct dentry *h_dentry, struct inode *inode, ++ aufs_bindex_t bindex, struct au_branch *br) ++{ ++ int err, wkq_err; ++ struct au_wbr *wbr; ++ struct dentry *h_parent; ++ struct inode *h_dir; ++ char a[PLINK_NAME_LEN]; ++ struct qstr tgtname = { ++ .name = a ++ }; ++ ++ wbr = au_sbr(inode->i_sb, bindex)->br_wbr; ++ h_parent = wbr->wbr_plink; ++ h_dir = h_parent->d_inode; ++ tgtname.len = plink_name(a, sizeof(a), inode, bindex); ++ ++ /* always superio. */ ++ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2); ++ if (!au_test_wkq(current)) { ++ struct do_whplink_args args = { ++ .errp = &err, ++ .tgt = &tgtname, ++ .h_parent = h_parent, ++ .h_dentry = h_dentry, ++ .br = br ++ }; ++ wkq_err = au_wkq_wait(call_do_whplink, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } else ++ err = do_whplink(&tgtname, h_parent, h_dentry, br); ++ mutex_unlock(&h_dir->i_mutex); ++ ++ return err; ++} ++ ++/* free a single plink */ ++static void do_put_plink(struct pseudo_link *plink, int do_del) ++{ ++ iput(plink->inode); ++ if (do_del) ++ list_del(&plink->list); ++ kfree(plink); ++} ++ ++/* ++ * create a new pseudo-link for @h_dentry on @bindex. ++ * the linked inode is held in aufs @inode. ++ */ ++void au_plink_append(struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_dentry) ++{ ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ struct list_head *plink_list; ++ struct pseudo_link *plink; ++ int found, err, cnt; ++ ++ sb = inode->i_sb; ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); ++ ++ err = 0; ++ cnt = 0; ++ found = 0; ++ plink_list = &sbinfo->si_plink.head; ++ spin_lock(&sbinfo->si_plink.spin); ++ list_for_each_entry(plink, plink_list, list) { ++ cnt++; ++ if (plink->inode == inode) { ++ found = 1; ++ break; ++ } ++ } ++ if (found) { ++ spin_unlock(&sbinfo->si_plink.spin); ++ return; ++ } ++ ++ plink = NULL; ++ if (!found) { ++ plink = kmalloc(sizeof(*plink), GFP_ATOMIC); ++ if (plink) { ++ plink->inode = au_igrab(inode); ++ list_add(&plink->list, plink_list); ++ cnt++; ++ } else ++ err = -ENOMEM; ++ } ++ spin_unlock(&sbinfo->si_plink.spin); ++ ++ if (!err) { ++ au_plink_block_maintain(sb); ++ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex)); ++ } ++ ++ if (unlikely(cnt > AUFS_PLINK_WARN)) ++ AuWarn1("unexpectedly many pseudo links, %d\n", cnt); ++ if (unlikely(err)) { ++ AuWarn("err %d, damaged pseudo link.\n", err); ++ if (!found && plink) ++ do_put_plink(plink, /*do_del*/1); ++ } ++} ++ ++/* free all plinks */ ++void au_plink_put(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ struct list_head *plink_list; ++ struct pseudo_link *plink, *tmp; ++ ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); ++ ++ plink_list = &sbinfo->si_plink.head; ++ /* no spin_lock since sbinfo is write-locked */ ++ list_for_each_entry_safe(plink, tmp, plink_list, list) ++ do_put_plink(plink, 0); ++ INIT_LIST_HEAD(plink_list); ++} ++ ++/* free the plinks on a branch specified by @br_id */ ++void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id) ++{ ++ struct au_sbinfo *sbinfo; ++ struct list_head *plink_list; ++ struct pseudo_link *plink, *tmp; ++ struct inode *inode; ++ aufs_bindex_t bstart, bend, bindex; ++ unsigned char do_put; ++ ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); ++ ++ plink_list = &sbinfo->si_plink.head; ++ /* no spin_lock since sbinfo is write-locked */ ++ list_for_each_entry_safe(plink, tmp, plink_list, list) { ++ do_put = 0; ++ inode = au_igrab(plink->inode); ++ ii_write_lock_child(inode); ++ bstart = au_ibstart(inode); ++ bend = au_ibend(inode); ++ if (bstart >= 0) { ++ for (bindex = bstart; bindex <= bend; bindex++) { ++ if (!au_h_iptr(inode, bindex) ++ || au_ii_br_id(inode, bindex) != br_id) ++ continue; ++ au_set_h_iptr(inode, bindex, NULL, 0); ++ do_put = 1; ++ break; ++ } ++ } else ++ do_put_plink(plink, 1); ++ ++ if (do_put) { ++ for (bindex = bstart; bindex <= bend; bindex++) ++ if (au_h_iptr(inode, bindex)) { ++ do_put = 0; ++ break; ++ } ++ if (do_put) ++ do_put_plink(plink, 1); ++ } ++ ii_write_unlock(inode); ++ iput(inode); ++ } ++} +diff -Naur a/fs/aufs/rwsem.h b/fs/aufs/rwsem.h +--- a/fs/aufs/rwsem.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/rwsem.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,61 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * simple read-write semaphore wrappers ++ */ ++ ++#ifndef __AUFS_RWSEM_H__ ++#define __AUFS_RWSEM_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++ ++#define au_rwsem_destroy(rw) AuDebugOn(rwsem_is_locked(rw)) ++#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->wait_list)) ++ ++#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \ ++static inline void prefix##_read_lock(param) \ ++{ down_read(rwsem); } \ ++static inline void prefix##_write_lock(param) \ ++{ down_write(rwsem); } \ ++static inline int prefix##_read_trylock(param) \ ++{ return down_read_trylock(rwsem); } \ ++static inline int prefix##_write_trylock(param) \ ++{ return down_write_trylock(rwsem); } ++/* why is not _nested version defined */ ++/* static inline void prefix##_read_trylock_nested(param, lsc) ++{ down_write_trylock_nested(rwsem, lsc)); } ++static inline void prefix##_write_trylock_nestd(param, lsc) ++{ down_write_trylock_nested(rwsem, lsc); } */ ++ ++#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \ ++static inline void prefix##_read_unlock(param) \ ++{ up_read(rwsem); } \ ++static inline void prefix##_write_unlock(param) \ ++{ up_write(rwsem); } \ ++static inline void prefix##_downgrade_lock(param) \ ++{ downgrade_write(rwsem); } ++ ++#define AuSimpleRwsemFuncs(prefix, param, rwsem) \ ++ AuSimpleLockRwsemFuncs(prefix, param, rwsem) \ ++ AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_RWSEM_H__ */ +diff -Naur a/fs/aufs/sbinfo.c b/fs/aufs/sbinfo.c +--- a/fs/aufs/sbinfo.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/sbinfo.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,203 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * superblock private data ++ */ ++ ++#include "aufs.h" ++ ++/* ++ * they are necessary regardless sysfs is disabled. ++ */ ++void au_si_free(struct kobject *kobj) ++{ ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ ++ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); ++ AuDebugOn(!list_empty(&sbinfo->si_plink.head)); ++ ++ sb = sbinfo->si_sb; ++ si_write_lock(sb); ++ au_xino_clr(sb); ++ au_br_free(sbinfo); ++ kfree(sbinfo->si_branch); ++ mutex_destroy(&sbinfo->si_xib_mtx); ++ si_write_unlock(sb); ++ au_rwsem_destroy(&sbinfo->si_rwsem); ++ ++ kfree(sbinfo); ++} ++ ++int au_si_alloc(struct super_block *sb) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ ++ err = -ENOMEM; ++ sbinfo = kmalloc(sizeof(*sbinfo), GFP_NOFS); ++ if (unlikely(!sbinfo)) ++ goto out; ++ ++ /* will be reallocated separately */ ++ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS); ++ if (unlikely(!sbinfo->si_branch)) ++ goto out_sbinfo; ++ ++ memset(&sbinfo->si_kobj, 0, sizeof(sbinfo->si_kobj)); ++ err = sysaufs_si_init(sbinfo); ++ if (unlikely(err)) ++ goto out_br; ++ ++ au_nwt_init(&sbinfo->si_nowait); ++ init_rwsem(&sbinfo->si_rwsem); ++ down_write(&sbinfo->si_rwsem); ++ sbinfo->si_generation = 0; ++ sbinfo->au_si_status = 0; ++ sbinfo->si_bend = -1; ++ sbinfo->si_last_br_id = 0; ++ ++ sbinfo->si_wbr_copyup = AuWbrCopyup_Def; ++ sbinfo->si_wbr_create = AuWbrCreate_Def; ++ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + AuWbrCopyup_Def; ++ sbinfo->si_wbr_create_ops = au_wbr_create_ops + AuWbrCreate_Def; ++ ++ sbinfo->si_mntflags = AuOpt_Def; ++ ++ sbinfo->si_xread = NULL; ++ sbinfo->si_xwrite = NULL; ++ sbinfo->si_xib = NULL; ++ mutex_init(&sbinfo->si_xib_mtx); ++ sbinfo->si_xib_buf = NULL; ++ sbinfo->si_xino_brid = -1; ++ /* leave si_xib_last_pindex and si_xib_next_bit */ ++ ++ sbinfo->si_rdcache = AUFS_RDCACHE_DEF * HZ; ++ sbinfo->si_rdblk = AUFS_RDBLK_DEF; ++ sbinfo->si_rdhash = AUFS_RDHASH_DEF; ++ sbinfo->si_dirwh = AUFS_DIRWH_DEF; ++ ++ au_spl_init(&sbinfo->si_plink); ++ init_waitqueue_head(&sbinfo->si_plink_wq); ++ ++ /* leave other members for sysaufs and si_mnt. */ ++ sbinfo->si_sb = sb; ++ sb->s_fs_info = sbinfo; ++ au_debug_sbinfo_init(sbinfo); ++ return 0; /* success */ ++ ++ out_br: ++ kfree(sbinfo->si_branch); ++ out_sbinfo: ++ kfree(sbinfo); ++ out: ++ return err; ++} ++ ++int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr) ++{ ++ int err, sz; ++ struct au_branch **brp; ++ ++ err = -ENOMEM; ++ sz = sizeof(*brp) * (sbinfo->si_bend + 1); ++ if (unlikely(!sz)) ++ sz = sizeof(*brp); ++ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS); ++ if (brp) { ++ sbinfo->si_branch = brp; ++ err = 0; ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++unsigned int au_sigen_inc(struct super_block *sb) ++{ ++ unsigned int gen; ++ ++ gen = ++au_sbi(sb)->si_generation; ++ au_update_digen(sb->s_root); ++ au_update_iigen(sb->s_root->d_inode); ++ sb->s_root->d_inode->i_version++; ++ return gen; ++} ++ ++aufs_bindex_t au_new_br_id(struct super_block *sb) ++{ ++ aufs_bindex_t br_id; ++ int i; ++ struct au_sbinfo *sbinfo; ++ ++ sbinfo = au_sbi(sb); ++ for (i = 0; i <= AUFS_BRANCH_MAX; i++) { ++ br_id = ++sbinfo->si_last_br_id; ++ if (br_id && au_br_index(sb, br_id) < 0) ++ return br_id; ++ } ++ ++ return -1; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* dentry and super_block lock. call at entry point */ ++void aufs_read_lock(struct dentry *dentry, int flags) ++{ ++ si_read_lock(dentry->d_sb, flags); ++ if (au_ftest_lock(flags, DW)) ++ di_write_lock_child(dentry); ++ else ++ di_read_lock_child(dentry, flags); ++} ++ ++void aufs_read_unlock(struct dentry *dentry, int flags) ++{ ++ if (au_ftest_lock(flags, DW)) ++ di_write_unlock(dentry); ++ else ++ di_read_unlock(dentry, flags); ++ si_read_unlock(dentry->d_sb); ++} ++ ++void aufs_write_lock(struct dentry *dentry) ++{ ++ si_write_lock(dentry->d_sb); ++ di_write_lock_child(dentry); ++} ++ ++void aufs_write_unlock(struct dentry *dentry) ++{ ++ di_write_unlock(dentry); ++ si_write_unlock(dentry->d_sb); ++} ++ ++void aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags) ++{ ++ si_read_lock(d1->d_sb, flags); ++ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR)); ++} ++ ++void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2) ++{ ++ di_write_unlock2(d1, d2); ++ si_read_unlock(d1->d_sb); ++} +diff -Naur a/fs/aufs/spl.h b/fs/aufs/spl.h +--- a/fs/aufs/spl.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/spl.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,57 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * simple list protected by a spinlock ++ */ ++ ++#ifndef __AUFS_SPL_H__ ++#define __AUFS_SPL_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++ ++struct au_splhead { ++ spinlock_t spin; ++ struct list_head head; ++}; ++ ++static inline void au_spl_init(struct au_splhead *spl) ++{ ++ spin_lock_init(&spl->spin); ++ INIT_LIST_HEAD(&spl->head); ++} ++ ++static inline void au_spl_add(struct list_head *list, struct au_splhead *spl) ++{ ++ spin_lock(&spl->spin); ++ list_add(list, &spl->head); ++ spin_unlock(&spl->spin); ++} ++ ++static inline void au_spl_del(struct list_head *list, struct au_splhead *spl) ++{ ++ spin_lock(&spl->spin); ++ list_del(list); ++ spin_unlock(&spl->spin); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_SPL_H__ */ +diff -Naur a/fs/aufs/super.c b/fs/aufs/super.c +--- a/fs/aufs/super.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/super.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,870 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * mount and super_block operations ++ */ ++ ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++/* ++ * super_operations ++ */ ++static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused) ++{ ++ struct au_icntnr *c; ++ ++ c = au_cache_alloc_icntnr(); ++ if (c) { ++ inode_init_once(&c->vfs_inode); ++ c->vfs_inode.i_version = 1; /* sigen(sb); */ ++ c->iinfo.ii_hinode = NULL; ++ return &c->vfs_inode; ++ } ++ return NULL; ++} ++ ++static void aufs_destroy_inode(struct inode *inode) ++{ ++ au_iinfo_fin(inode); ++ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode)); ++} ++ ++struct inode *au_iget_locked(struct super_block *sb, ino_t ino) ++{ ++ struct inode *inode; ++ int err; ++ ++ inode = iget_locked(sb, ino); ++ if (unlikely(!inode)) { ++ inode = ERR_PTR(-ENOMEM); ++ goto out; ++ } ++ if (!(inode->i_state & I_NEW)) ++ goto out; ++ ++ err = au_xigen_new(inode); ++ if (!err) ++ err = au_iinfo_init(inode); ++ if (!err) ++ inode->i_version++; ++ else { ++ iget_failed(inode); ++ inode = ERR_PTR(err); ++ } ++ ++ out: ++ /* never return NULL */ ++ AuDebugOn(!inode); ++ AuTraceErrPtr(inode); ++ return inode; ++} ++ ++/* lock free root dinfo */ ++static int au_show_brs(struct seq_file *seq, struct super_block *sb) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ struct path path; ++ struct au_hdentry *hd; ++ struct au_branch *br; ++ ++ err = 0; ++ bend = au_sbend(sb); ++ hd = au_di(sb->s_root)->di_hdentry; ++ for (bindex = 0; !err && bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ path.mnt = br->br_mnt; ++ path.dentry = hd[bindex].hd_dentry; ++ err = au_seq_path(seq, &path); ++ if (err > 0) ++ err = seq_printf(seq, "=%s", ++ au_optstr_br_perm(br->br_perm)); ++ if (!err && bindex != bend) ++ err = seq_putc(seq, ':'); ++ } ++ ++ return err; ++} ++ ++static void au_show_wbr_create(struct seq_file *m, int v, ++ struct au_sbinfo *sbinfo) ++{ ++ const char *pat; ++ ++ seq_printf(m, ",create="); ++ pat = au_optstr_wbr_create(v); ++ switch (v) { ++ case AuWbrCreate_TDP: ++ case AuWbrCreate_RR: ++ case AuWbrCreate_MFS: ++ case AuWbrCreate_PMFS: ++ seq_printf(m, pat); ++ break; ++ case AuWbrCreate_MFSV: ++ seq_printf(m, /*pat*/"mfs:%lu", ++ sbinfo->si_wbr_mfs.mfs_expire / HZ); ++ break; ++ case AuWbrCreate_PMFSV: ++ seq_printf(m, /*pat*/"pmfs:%lu", ++ sbinfo->si_wbr_mfs.mfs_expire / HZ); ++ break; ++ case AuWbrCreate_MFSRR: ++ seq_printf(m, /*pat*/"mfsrr:%llu", ++ sbinfo->si_wbr_mfs.mfsrr_watermark); ++ break; ++ case AuWbrCreate_MFSRRV: ++ seq_printf(m, /*pat*/"mfsrr:%llu:%lu", ++ sbinfo->si_wbr_mfs.mfsrr_watermark, ++ sbinfo->si_wbr_mfs.mfs_expire / HZ); ++ break; ++ } ++} ++ ++static int au_show_xino(struct seq_file *seq, struct vfsmount *mnt) ++{ ++#ifdef CONFIG_SYSFS ++ return 0; ++#else ++ int err; ++ const int len = sizeof(AUFS_XINO_FNAME) - 1; ++ aufs_bindex_t bindex, brid; ++ struct super_block *sb; ++ struct qstr *name; ++ struct file *f; ++ struct dentry *d, *h_root; ++ ++ err = 0; ++ sb = mnt->mnt_sb; ++ f = au_sbi(sb)->si_xib; ++ if (!f) ++ goto out; ++ ++ /* stop printing the default xino path on the first writable branch */ ++ h_root = NULL; ++ brid = au_xino_brid(sb); ++ if (brid >= 0) { ++ bindex = au_br_index(sb, brid); ++ h_root = au_di(sb->s_root)->di_hdentry[0 + bindex].hd_dentry; ++ } ++ d = f->f_dentry; ++ name = &d->d_name; ++ /* safe ->d_parent because the file is unlinked */ ++ if (d->d_parent == h_root ++ && name->len == len ++ && !memcmp(name->name, AUFS_XINO_FNAME, len)) ++ goto out; ++ ++ seq_puts(seq, ",xino="); ++ err = au_xino_path(seq, f); ++ ++ out: ++ return err; ++#endif ++} ++ ++/* seq_file will re-call me in case of too long string */ ++static int aufs_show_options(struct seq_file *m, struct vfsmount *mnt) ++{ ++ int err, n; ++ unsigned int mnt_flags, v; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ ++#define AuBool(name, str) do { \ ++ v = au_opt_test(mnt_flags, name); \ ++ if (v != au_opt_test(AuOpt_Def, name)) \ ++ seq_printf(m, ",%s" #str, v ? "" : "no"); \ ++} while (0) ++ ++#define AuStr(name, str) do { \ ++ v = mnt_flags & AuOptMask_##name; \ ++ if (v != (AuOpt_Def & AuOptMask_##name)) \ ++ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \ ++} while (0) ++ ++#define AuUInt(name, str, val) do { \ ++ if (val != AUFS_##name##_DEF) \ ++ seq_printf(m, "," #str "=%u", val); \ ++} while (0) ++ ++ /* lock free root dinfo */ ++ sb = mnt->mnt_sb; ++ si_noflush_read_lock(sb); ++ sbinfo = au_sbi(sb); ++ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo)); ++ ++ mnt_flags = au_mntflags(sb); ++ if (au_opt_test(mnt_flags, XINO)) { ++ err = au_show_xino(m, mnt); ++ if (unlikely(err)) ++ goto out; ++ } else ++ seq_puts(m, ",noxino"); ++ ++ AuBool(TRUNC_XINO, trunc_xino); ++ AuStr(UDBA, udba); ++ AuBool(SHWH, shwh); ++ AuBool(PLINK, plink); ++ /* AuBool(DIRPERM1, dirperm1); */ ++ /* AuBool(REFROF, refrof); */ ++ ++ v = sbinfo->si_wbr_create; ++ if (v != AuWbrCreate_Def) ++ au_show_wbr_create(m, v, sbinfo); ++ ++ v = sbinfo->si_wbr_copyup; ++ if (v != AuWbrCopyup_Def) ++ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v)); ++ ++ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ); ++ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ)) ++ seq_printf(m, ",diropq=%c", v ? 'a' : 'w'); ++ ++ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh); ++ ++ n = sbinfo->si_rdcache / HZ; ++ AuUInt(RDCACHE, rdcache, n); ++ ++ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk); ++ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash); ++ ++ AuBool(SUM, sum); ++ /* AuBool(SUM_W, wsum); */ ++ AuBool(WARN_PERM, warn_perm); ++ AuBool(VERBOSE, verbose); ++ ++ out: ++ /* be sure to print "br:" last */ ++ if (!sysaufs_brs) { ++ seq_puts(m, ",br:"); ++ au_show_brs(m, sb); ++ } ++ si_read_unlock(sb); ++ return 0; ++ ++#undef Deleted ++#undef AuBool ++#undef AuStr ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* sum mode which returns the summation for statfs(2) */ ++ ++static u64 au_add_till_max(u64 a, u64 b) ++{ ++ u64 old; ++ ++ old = a; ++ a += b; ++ if (old < a) ++ return a; ++ return ULLONG_MAX; ++} ++ ++static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf) ++{ ++ int err; ++ u64 blocks, bfree, bavail, files, ffree; ++ aufs_bindex_t bend, bindex, i; ++ unsigned char shared; ++ struct vfsmount *h_mnt; ++ struct super_block *h_sb; ++ ++ blocks = 0; ++ bfree = 0; ++ bavail = 0; ++ files = 0; ++ ffree = 0; ++ ++ err = 0; ++ bend = au_sbend(sb); ++ for (bindex = bend; bindex >= 0; bindex--) { ++ h_mnt = au_sbr_mnt(sb, bindex); ++ h_sb = h_mnt->mnt_sb; ++ shared = 0; ++ for (i = bindex + 1; !shared && i <= bend; i++) ++ shared = (au_sbr_sb(sb, i) == h_sb); ++ if (shared) ++ continue; ++ ++ /* sb->s_root for NFS is unreliable */ ++ err = vfs_statfs(h_mnt->mnt_root, buf); ++ if (unlikely(err)) ++ goto out; ++ ++ blocks = au_add_till_max(blocks, buf->f_blocks); ++ bfree = au_add_till_max(bfree, buf->f_bfree); ++ bavail = au_add_till_max(bavail, buf->f_bavail); ++ files = au_add_till_max(files, buf->f_files); ++ ffree = au_add_till_max(ffree, buf->f_ffree); ++ } ++ ++ buf->f_blocks = blocks; ++ buf->f_bfree = bfree; ++ buf->f_bavail = bavail; ++ buf->f_files = files; ++ buf->f_ffree = ffree; ++ ++ out: ++ return err; ++} ++ ++static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf) ++{ ++ int err; ++ struct super_block *sb; ++ ++ /* lock free root dinfo */ ++ sb = dentry->d_sb; ++ si_noflush_read_lock(sb); ++ if (!au_opt_test(au_mntflags(sb), SUM)) ++ /* sb->s_root for NFS is unreliable */ ++ err = vfs_statfs(au_sbr_mnt(sb, 0)->mnt_root, buf); ++ else ++ err = au_statfs_sum(sb, buf); ++ si_read_unlock(sb); ++ ++ if (!err) { ++ buf->f_type = AUFS_SUPER_MAGIC; ++ buf->f_namelen -= AUFS_WH_PFX_LEN; ++ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid)); ++ } ++ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */ ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* try flushing the lower fs at aufs remount/unmount time */ ++ ++static void au_fsync_br(struct super_block *sb) ++{ ++ aufs_bindex_t bend, bindex; ++ int brperm; ++ struct au_branch *br; ++ struct super_block *h_sb; ++ ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex < bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ brperm = br->br_perm; ++ if (brperm == AuBrPerm_RR || brperm == AuBrPerm_RRWH) ++ continue; ++ h_sb = br->br_mnt->mnt_sb; ++ if (bdev_read_only(h_sb->s_bdev)) ++ continue; ++ ++ lockdep_off(); ++ down_write(&h_sb->s_umount); ++ shrink_dcache_sb(h_sb); ++ fsync_super(h_sb); ++ up_write(&h_sb->s_umount); ++ lockdep_on(); ++ } ++} ++ ++/* ++ * this IS NOT for super_operations. ++ * I guess it will be reverted someday. ++ */ ++static void aufs_umount_begin(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ sbinfo = au_sbi(sb); ++ if (!sbinfo) ++ return; ++ ++ si_write_lock(sb); ++ au_fsync_br(sb); ++ if (au_opt_test(au_mntflags(sb), PLINK)) ++ au_plink_put(sb); ++ if (sbinfo->si_wbr_create_ops->fin) ++ sbinfo->si_wbr_create_ops->fin(sb); ++ si_write_unlock(sb); ++} ++ ++/* final actions when unmounting a file system */ ++static void aufs_put_super(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ sbinfo = au_sbi(sb); ++ if (!sbinfo) ++ return; ++ ++ aufs_umount_begin(sb); ++ dbgaufs_si_fin(sbinfo); ++ kobject_put(&sbinfo->si_kobj); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * refresh dentry and inode at remount time. ++ */ ++static int do_refresh(struct dentry *dentry, mode_t type, ++ unsigned int dir_flags) ++{ ++ int err; ++ struct dentry *parent; ++ ++ di_write_lock_child(dentry); ++ parent = dget_parent(dentry); ++ di_read_lock_parent(parent, AuLock_IR); ++ ++ /* returns the number of positive dentries */ ++ err = au_refresh_hdentry(dentry, type); ++ if (err >= 0) { ++ struct inode *inode = dentry->d_inode; ++ err = au_refresh_hinode(inode, dentry); ++ if (!err && type == S_IFDIR) ++ au_reset_hinotify(inode, dir_flags); ++ } ++ if (unlikely(err)) ++ AuErr("unrecoverable error %d, %.*s\n", err, AuDLNPair(dentry)); ++ ++ di_read_unlock(parent, AuLock_IR); ++ dput(parent); ++ di_write_unlock(dentry); ++ ++ return err; ++} ++ ++static int test_dir(struct dentry *dentry, void *arg __maybe_unused) ++{ ++ return S_ISDIR(dentry->d_inode->i_mode); ++} ++ ++/* gave up consolidating with refresh_nondir() */ ++static int refresh_dir(struct dentry *root, unsigned int sigen) ++{ ++ int err, i, j, ndentry, e; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry **dentries; ++ struct inode *inode; ++ const unsigned int flags = au_hi_flags(root->d_inode, /*isdir*/1); ++ ++ err = 0; ++ list_for_each_entry(inode, &root->d_sb->s_inodes, i_sb_list) ++ if (S_ISDIR(inode->i_mode) && au_iigen(inode) != sigen) { ++ ii_write_lock_child(inode); ++ e = au_refresh_hinode_self(inode, /*do_attr*/1); ++ ii_write_unlock(inode); ++ if (unlikely(e)) { ++ AuDbg("e %d, i%lu\n", e, inode->i_ino); ++ if (!err) ++ err = e; ++ /* go on even if err */ ++ } ++ } ++ ++ e = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(e)) { ++ if (!err) ++ err = e; ++ goto out; ++ } ++ e = au_dcsub_pages(&dpages, root, test_dir, NULL); ++ if (unlikely(e)) { ++ if (!err) ++ err = e; ++ goto out_dpages; ++ } ++ ++ for (i = 0; !e && i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ dentries = dpage->dentries; ++ ndentry = dpage->ndentry; ++ for (j = 0; !e && j < ndentry; j++) { ++ struct dentry *d; ++ ++ d = dentries[j]; ++ au_dbg_verify_dir_parent(d, sigen); ++ if (au_digen(d) != sigen) { ++ e = do_refresh(d, S_IFDIR, flags); ++ if (unlikely(e && !err)) ++ err = e; ++ /* break on err */ ++ } ++ } ++ } ++ ++ out_dpages: ++ au_dpages_free(&dpages); ++ out: ++ return err; ++} ++ ++static int test_nondir(struct dentry *dentry, void *arg __maybe_unused) ++{ ++ return !S_ISDIR(dentry->d_inode->i_mode); ++} ++ ++static int refresh_nondir(struct dentry *root, unsigned int sigen, ++ int do_dentry) ++{ ++ int err, i, j, ndentry, e; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry **dentries; ++ struct inode *inode; ++ ++ err = 0; ++ list_for_each_entry(inode, &root->d_sb->s_inodes, i_sb_list) ++ if (!S_ISDIR(inode->i_mode) && au_iigen(inode) != sigen) { ++ ii_write_lock_child(inode); ++ e = au_refresh_hinode_self(inode, /*do_attr*/1); ++ ii_write_unlock(inode); ++ if (unlikely(e)) { ++ AuDbg("e %d, i%lu\n", e, inode->i_ino); ++ if (!err) ++ err = e; ++ /* go on even if err */ ++ } ++ } ++ ++ if (!do_dentry) ++ goto out; ++ ++ e = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(e)) { ++ if (!err) ++ err = e; ++ goto out; ++ } ++ e = au_dcsub_pages(&dpages, root, test_nondir, NULL); ++ if (unlikely(e)) { ++ if (!err) ++ err = e; ++ goto out_dpages; ++ } ++ ++ for (i = 0; i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ dentries = dpage->dentries; ++ ndentry = dpage->ndentry; ++ for (j = 0; j < ndentry; j++) { ++ struct dentry *d; ++ ++ d = dentries[j]; ++ au_dbg_verify_nondir_parent(d, sigen); ++ inode = d->d_inode; ++ if (inode && au_digen(d) != sigen) { ++ e = do_refresh(d, inode->i_mode & S_IFMT, ++ /*dir_flags*/0); ++ if (unlikely(e && !err)) ++ err = e; ++ /* go on even err */ ++ } ++ } ++ } ++ ++ out_dpages: ++ au_dpages_free(&dpages); ++ out: ++ return err; ++} ++ ++static void au_remount_refresh(struct super_block *sb, unsigned int flags) ++{ ++ int err; ++ unsigned int sigen; ++ struct au_sbinfo *sbinfo; ++ struct dentry *root; ++ struct inode *inode; ++ ++ au_sigen_inc(sb); ++ sigen = au_sigen(sb); ++ sbinfo = au_sbi(sb); ++ au_fclr_si(sbinfo, FAILED_REFRESH_DIRS); ++ ++ root = sb->s_root; ++ DiMustNoWaiters(root); ++ inode = root->d_inode; ++ IiMustNoWaiters(inode); ++ au_reset_hinotify(inode, au_hi_flags(inode, /*isdir*/1)); ++ di_write_unlock(root); ++ ++ err = refresh_dir(root, sigen); ++ if (unlikely(err)) { ++ au_fset_si(sbinfo, FAILED_REFRESH_DIRS); ++ AuWarn("Refreshing directories failed, ignored (%d)\n", err); ++ } ++ ++ if (au_ftest_opts(flags, REFRESH_NONDIR)) { ++ err = refresh_nondir(root, sigen, !err); ++ if (unlikely(err)) ++ AuWarn("Refreshing non-directories failed, ignored" ++ "(%d)\n", err); ++ } ++ ++ /* aufs_write_lock() calls ..._child() */ ++ di_write_lock_child(root); ++ au_cpup_attr_all(root->d_inode, /*force*/1); ++} ++ ++/* stop extra interpretation of errno in mount(8), and strange error messages */ ++static int cvt_err(int err) ++{ ++ AuTraceErr(err); ++ ++ switch (err) { ++ case -ENOENT: ++ case -ENOTDIR: ++ case -EEXIST: ++ case -EIO: ++ err = -EINVAL; ++ } ++ return err; ++} ++ ++static int aufs_remount_fs(struct super_block *sb, int *flags, char *data) ++{ ++ int err; ++ struct au_opts opts; ++ struct dentry *root; ++ struct inode *inode; ++ struct au_sbinfo *sbinfo; ++ ++ err = 0; ++ root = sb->s_root; ++ if (!data || !*data) { ++ aufs_write_lock(root); ++ err = au_opts_verify(sb, *flags, /*pending*/0); ++ if (!err) ++ au_fsync_br(sb); ++ aufs_write_unlock(root); ++ goto out; ++ } ++ ++ err = -ENOMEM; ++ memset(&opts, 0, sizeof(opts)); ++ opts.opt = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!opts.opt)) ++ goto out; ++ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); ++ opts.flags = AuOpts_REMOUNT; ++ opts.sb_flags = *flags; ++ ++ /* parse it before aufs lock */ ++ err = au_opts_parse(sb, data, &opts); ++ if (unlikely(err)) ++ goto out_opts; ++ ++ sbinfo = au_sbi(sb); ++ inode = root->d_inode; ++ mutex_lock(&inode->i_mutex); ++ aufs_write_lock(root); ++ au_fsync_br(sb); ++ ++ /* au_opts_remount() may return an error */ ++ err = au_opts_remount(sb, &opts); ++ au_opts_free(&opts); ++ ++ if (au_ftest_opts(opts.flags, REFRESH_DIR) ++ || au_ftest_opts(opts.flags, REFRESH_NONDIR)) ++ au_remount_refresh(sb, opts.flags); ++ ++ aufs_write_unlock(root); ++ mutex_unlock(&inode->i_mutex); ++ ++ out_opts: ++ free_page((unsigned long)opts.opt); ++ out: ++ err = cvt_err(err); ++ AuTraceErr(err); ++ return err; ++} ++ ++static struct super_operations aufs_sop = { ++ .alloc_inode = aufs_alloc_inode, ++ .destroy_inode = aufs_destroy_inode, ++ .drop_inode = generic_delete_inode, ++ .show_options = aufs_show_options, ++ .statfs = aufs_statfs, ++ .put_super = aufs_put_super, ++ .remount_fs = aufs_remount_fs ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int alloc_root(struct super_block *sb) ++{ ++ int err; ++ struct inode *inode; ++ struct dentry *root; ++ ++ err = -ENOMEM; ++ inode = au_iget_locked(sb, AUFS_ROOT_INO); ++ err = PTR_ERR(inode); ++ if (IS_ERR(inode)) ++ goto out; ++ ++ inode->i_op = &aufs_dir_iop; ++ inode->i_fop = &aufs_dir_fop; ++ inode->i_mode = S_IFDIR; ++ inode->i_nlink = 2; ++ unlock_new_inode(inode); ++ ++ root = d_alloc_root(inode); ++ if (unlikely(!root)) ++ goto out_iput; ++ err = PTR_ERR(root); ++ if (IS_ERR(root)) ++ goto out_iput; ++ ++ err = au_alloc_dinfo(root); ++ if (!err) { ++ sb->s_root = root; ++ return 0; /* success */ ++ } ++ dput(root); ++ goto out; /* do not iput */ ++ ++ out_iput: ++ iget_failed(inode); ++ iput(inode); ++ out: ++ return err; ++ ++} ++ ++static int aufs_fill_super(struct super_block *sb, void *raw_data, ++ int silent __maybe_unused) ++{ ++ int err; ++ struct au_opts opts; ++ struct dentry *root; ++ struct inode *inode; ++ char *arg = raw_data; ++ ++ if (unlikely(!arg || !*arg)) { ++ err = -EINVAL; ++ AuErr("no arg\n"); ++ goto out; ++ } ++ ++ err = -ENOMEM; ++ memset(&opts, 0, sizeof(opts)); ++ opts.opt = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!opts.opt)) ++ goto out; ++ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); ++ opts.sb_flags = sb->s_flags; ++ ++ err = au_si_alloc(sb); ++ if (unlikely(err)) ++ goto out_opts; ++ ++ /* all timestamps always follow the ones on the branch */ ++ sb->s_flags |= MS_NOATIME | MS_NODIRATIME; ++ sb->s_op = &aufs_sop; ++ sb->s_magic = AUFS_SUPER_MAGIC; ++ sb->s_maxbytes = 0; ++ au_export_init(sb); ++ ++ err = alloc_root(sb); ++ if (unlikely(err)) { ++ si_write_unlock(sb); ++ goto out_info; ++ } ++ root = sb->s_root; ++ inode = root->d_inode; ++ ++ /* ++ * actually we can parse options regardless aufs lock here. ++ * but at remount time, parsing must be done before aufs lock. ++ * so we follow the same rule. ++ */ ++ ii_write_lock_parent(inode); ++ aufs_write_unlock(root); ++ err = au_opts_parse(sb, arg, &opts); ++ if (unlikely(err)) ++ goto out_root; ++ ++ /* lock vfs_inode first, then aufs. */ ++ mutex_lock(&inode->i_mutex); ++ inode->i_op = &aufs_dir_iop; ++ inode->i_fop = &aufs_dir_fop; ++ aufs_write_lock(root); ++ err = au_opts_mount(sb, &opts); ++ au_opts_free(&opts); ++ if (unlikely(err)) ++ goto out_unlock; ++ aufs_write_unlock(root); ++ mutex_unlock(&inode->i_mutex); ++ goto out_opts; /* success */ ++ ++ out_unlock: ++ aufs_write_unlock(root); ++ mutex_unlock(&inode->i_mutex); ++ out_root: ++ dput(root); ++ sb->s_root = NULL; ++ out_info: ++ kobject_put(&au_sbi(sb)->si_kobj); ++ sb->s_fs_info = NULL; ++ out_opts: ++ free_page((unsigned long)opts.opt); ++ out: ++ AuTraceErr(err); ++ err = cvt_err(err); ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int aufs_get_sb(struct file_system_type *fs_type, int flags, ++ const char *dev_name __maybe_unused, void *raw_data, ++ struct vfsmount *mnt) ++{ ++ int err; ++ struct super_block *sb; ++ ++ /* all timestamps always follow the ones on the branch */ ++ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */ ++ err = get_sb_nodev(fs_type, flags, raw_data, aufs_fill_super, mnt); ++ if (!err) { ++ sb = mnt->mnt_sb; ++ si_write_lock(sb); ++ sysaufs_brs_add(sb, 0); ++ si_write_unlock(sb); ++ } ++ return err; ++} ++ ++struct file_system_type aufs_fs_type = { ++ .name = AUFS_FSTYPE, ++ .fs_flags = ++ FS_RENAME_DOES_D_MOVE /* a race between rename and others */ ++ | FS_REVAL_DOT, /* for NFS branch and udba */ ++ .get_sb = aufs_get_sb, ++ .kill_sb = generic_shutdown_super, ++ /* no need to __module_get() and module_put(). */ ++ .owner = THIS_MODULE, ++}; +diff -Naur a/fs/aufs/super.h b/fs/aufs/super.h +--- a/fs/aufs/super.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/super.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,359 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * super_block operations ++ */ ++ ++#ifndef __AUFS_SUPER_H__ ++#define __AUFS_SUPER_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include "rwsem.h" ++#include "spl.h" ++#include "wkq.h" ++ ++typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *); ++typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t, ++ loff_t *); ++ ++/* policies to select one among multiple writable branches */ ++struct au_wbr_copyup_operations { ++ int (*copyup)(struct dentry *dentry); ++}; ++ ++struct au_wbr_create_operations { ++ int (*create)(struct dentry *dentry, int isdir); ++ int (*init)(struct super_block *sb); ++ int (*fin)(struct super_block *sb); ++}; ++ ++struct au_wbr_mfs { ++ struct mutex mfs_lock; /* protect this structure */ ++ unsigned long mfs_jiffy; ++ unsigned long mfs_expire; ++ aufs_bindex_t mfs_bindex; ++ ++ unsigned long long mfsrr_bytes; ++ unsigned long long mfsrr_watermark; ++}; ++ ++/* sbinfo status flags */ ++/* ++ * set true when refresh_dirs() failed at remount time. ++ * then try refreshing dirs at access time again. ++ * if it is false, refreshing dirs at access time is unnecesary ++ */ ++#define AuSi_FAILED_REFRESH_DIRS 1 ++#define AuSi_MAINTAIN_PLINK (1 << 1) /* ioctl */ ++#define au_ftest_si(sbinfo, name) ((sbinfo)->au_si_status & AuSi_##name) ++#define au_fset_si(sbinfo, name) \ ++ { (sbinfo)->au_si_status |= AuSi_##name; } ++#define au_fclr_si(sbinfo, name) \ ++ { (sbinfo)->au_si_status &= ~AuSi_##name; } ++ ++struct au_branch; ++struct au_sbinfo { ++ /* nowait tasks in the system-wide workqueue */ ++ struct au_nowait_tasks si_nowait; ++ ++ struct rw_semaphore si_rwsem; ++ ++ /* branch management */ ++ unsigned int si_generation; ++ ++ /* see above flags */ ++ unsigned char au_si_status; ++ ++ aufs_bindex_t si_bend; ++ aufs_bindex_t si_last_br_id; ++ struct au_branch **si_branch; ++ ++ /* policy to select a writable branch */ ++ unsigned char si_wbr_copyup; ++ unsigned char si_wbr_create; ++ struct au_wbr_copyup_operations *si_wbr_copyup_ops; ++ struct au_wbr_create_operations *si_wbr_create_ops; ++ ++ /* round robin */ ++ atomic_t si_wbr_rr_next; ++ ++ /* most free space */ ++ struct au_wbr_mfs si_wbr_mfs; ++ ++ /* mount flags */ ++ /* include/asm-ia64/siginfo.h defines a macro named si_flags */ ++ unsigned int si_mntflags; ++ ++ /* external inode number (bitmap and translation table) */ ++ au_readf_t si_xread; ++ au_writef_t si_xwrite; ++ struct file *si_xib; ++ struct mutex si_xib_mtx; /* protect xib members */ ++ unsigned long *si_xib_buf; ++ unsigned long si_xib_last_pindex; ++ int si_xib_next_bit; ++ aufs_bindex_t si_xino_brid; ++ /* reserved for future use */ ++ /* unsigned long long si_xib_limit; */ /* Max xib file size */ ++ ++#ifdef CONFIG_AUFS_EXPORT ++ /* i_generation */ ++ struct file *si_xigen; ++ atomic_t si_xigen_next; ++#endif ++ ++ /* vdir parameters */ ++ unsigned long si_rdcache; /* max cache time in HZ */ ++ unsigned int si_rdblk; /* deblk size */ ++ unsigned int si_rdhash; /* hash size */ ++ ++ /* ++ * If the number of whiteouts are larger than si_dirwh, leave all of ++ * them after au_whtmp_ren to reduce the cost of rmdir(2). ++ * future fsck.aufs or kernel thread will remove them later. ++ * Otherwise, remove all whiteouts and the dir in rmdir(2). ++ */ ++ unsigned int si_dirwh; ++ ++ /* ++ * rename(2) a directory with all children. ++ */ ++ /* reserved for future use */ ++ /* int si_rendir; */ ++ ++ /* pseudo_link list */ ++ struct au_splhead si_plink; ++ wait_queue_head_t si_plink_wq; ++ ++ /* ++ * sysfs and lifetime management. ++ * this is not a small structure and it may be a waste of memory in case ++ * of sysfs is disabled, particulary when many aufs-es are mounted. ++ * but using sysfs is majority. ++ */ ++ struct kobject si_kobj; ++#ifdef CONFIG_DEBUG_FS ++ struct dentry *si_dbgaufs, *si_dbgaufs_xib; ++#ifdef CONFIG_AUFS_EXPORT ++ struct dentry *si_dbgaufs_xigen; ++#endif ++#endif ++ ++ /* dirty, necessary for unmounting, sysfs and sysrq */ ++ struct super_block *si_sb; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* policy to select one among writable branches */ ++#define AuWbrCopyup(sbinfo, args...) \ ++ ((sbinfo)->si_wbr_copyup_ops->copyup(args)) ++#define AuWbrCreate(sbinfo, args...) \ ++ ((sbinfo)->si_wbr_create_ops->create(args)) ++ ++/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */ ++#define AuLock_DW 1 /* write-lock dentry */ ++#define AuLock_IR (1 << 1) /* read-lock inode */ ++#define AuLock_IW (1 << 2) /* write-lock inode */ ++#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */ ++#define AuLock_DIR (1 << 4) /* target is a dir */ ++#define au_ftest_lock(flags, name) ((flags) & AuLock_##name) ++#define au_fset_lock(flags, name) { (flags) |= AuLock_##name; } ++#define au_fclr_lock(flags, name) { (flags) &= ~AuLock_##name; } ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* super.c */ ++extern struct file_system_type aufs_fs_type; ++struct inode *au_iget_locked(struct super_block *sb, ino_t ino); ++ ++/* sbinfo.c */ ++void au_si_free(struct kobject *kobj); ++int au_si_alloc(struct super_block *sb); ++int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr); ++ ++unsigned int au_sigen_inc(struct super_block *sb); ++aufs_bindex_t au_new_br_id(struct super_block *sb); ++ ++void aufs_read_lock(struct dentry *dentry, int flags); ++void aufs_read_unlock(struct dentry *dentry, int flags); ++void aufs_write_lock(struct dentry *dentry); ++void aufs_write_unlock(struct dentry *dentry); ++void aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int isdir); ++void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2); ++ ++/* wbr_policy.c */ ++extern struct au_wbr_copyup_operations au_wbr_copyup_ops[]; ++extern struct au_wbr_create_operations au_wbr_create_ops[]; ++int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct au_sbinfo *au_sbi(struct super_block *sb) ++{ ++ return sb->s_fs_info; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_EXPORT ++void au_export_init(struct super_block *sb); ++ ++static inline int au_test_nfsd(struct task_struct *tsk) ++{ ++ return !tsk->mm && !strcmp(tsk->comm, "nfsd"); ++} ++ ++int au_xigen_inc(struct inode *inode); ++int au_xigen_new(struct inode *inode); ++int au_xigen_set(struct super_block *sb, struct file *base); ++void au_xigen_clr(struct super_block *sb); ++ ++static inline int au_busy_or_stale(void) ++{ ++ if (!au_test_nfsd(current)) ++ return -EBUSY; ++ return -ESTALE; ++} ++#else ++static inline void au_export_init(struct super_block *sb) ++{ ++ /* nothing */ ++} ++ ++static inline int au_test_nfsd(struct task_struct *tsk) ++{ ++ return 0; ++} ++ ++static inline int au_xigen_inc(struct inode *inode) ++{ ++ return 0; ++} ++ ++static inline int au_xigen_new(struct inode *inode) ++{ ++ return 0; ++} ++ ++static inline int au_xigen_set(struct super_block *sb, struct file *base) ++{ ++ return 0; ++} ++ ++static inline void au_xigen_clr(struct super_block *sb) ++{ ++ /* empty */ ++} ++ ++static inline int au_busy_or_stale(void) ++{ ++ return -EBUSY; ++} ++#endif /* CONFIG_AUFS_EXPORT */ ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo) ++{ ++#ifdef CONFIG_DEBUG_FS ++ sbinfo->si_dbgaufs = NULL; ++ sbinfo->si_dbgaufs_xib = NULL; ++#ifdef CONFIG_AUFS_EXPORT ++ sbinfo->si_dbgaufs_xigen = NULL; ++#endif ++#endif ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* lock superblock. mainly for entry point functions */ ++/* ++ * si_noflush_read_lock, si_noflush_write_lock, ++ * si_read_unlock, si_write_unlock, si_downgrade_lock ++ */ ++AuSimpleLockRwsemFuncs(si_noflush, struct super_block *sb, ++ &au_sbi(sb)->si_rwsem); ++AuSimpleUnlockRwsemFuncs(si, struct super_block *sb, &au_sbi(sb)->si_rwsem); ++ ++static inline void si_read_lock(struct super_block *sb, int flags) ++{ ++ if (au_ftest_lock(flags, FLUSH)) ++ au_nwt_flush(&au_sbi(sb)->si_nowait); ++ si_noflush_read_lock(sb); ++} ++ ++static inline void si_write_lock(struct super_block *sb) ++{ ++ au_nwt_flush(&au_sbi(sb)->si_nowait); ++ si_noflush_write_lock(sb); ++} ++ ++static inline int si_read_trylock(struct super_block *sb, int flags) ++{ ++ if (au_ftest_lock(flags, FLUSH)) ++ au_nwt_flush(&au_sbi(sb)->si_nowait); ++ return si_noflush_read_trylock(sb); ++} ++ ++static inline int si_write_trylock(struct super_block *sb, int flags) ++{ ++ if (au_ftest_lock(flags, FLUSH)) ++ au_nwt_flush(&au_sbi(sb)->si_nowait); ++ return si_noflush_write_trylock(sb); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline aufs_bindex_t au_sbend(struct super_block *sb) ++{ ++ return au_sbi(sb)->si_bend; ++} ++ ++static inline unsigned int au_mntflags(struct super_block *sb) ++{ ++ return au_sbi(sb)->si_mntflags; ++} ++ ++static inline unsigned int au_sigen(struct super_block *sb) ++{ ++ return au_sbi(sb)->si_generation; ++} ++ ++static inline struct au_branch *au_sbr(struct super_block *sb, ++ aufs_bindex_t bindex) ++{ ++ return au_sbi(sb)->si_branch[0 + bindex]; ++} ++ ++static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid) ++{ ++ au_sbi(sb)->si_xino_brid = brid; ++} ++ ++static inline aufs_bindex_t au_xino_brid(struct super_block *sb) ++{ ++ return au_sbi(sb)->si_xino_brid; ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_SUPER_H__ */ +diff -Naur a/fs/aufs/sysaufs.c b/fs/aufs/sysaufs.c +--- a/fs/aufs/sysaufs.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/sysaufs.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * sysfs interface and lifetime management ++ * they are necessary regardless sysfs is disabled. ++ */ ++ ++#include ++#include ++#include ++#include "aufs.h" ++ ++unsigned long sysaufs_si_mask; ++struct kset *sysaufs_ket; ++ ++#define AuSiAttr(_name) { \ ++ .attr = { .name = __stringify(_name), .mode = 0444 }, \ ++ .show = sysaufs_si_##_name, \ ++} ++ ++static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path); ++struct attribute *sysaufs_si_attrs[] = { ++ &sysaufs_si_attr_xi_path.attr, ++ NULL, ++}; ++ ++static struct sysfs_ops au_sbi_ops = { ++ .show = sysaufs_si_show ++}; ++ ++static struct kobj_type au_sbi_ktype = { ++ .release = au_si_free, ++ .sysfs_ops = &au_sbi_ops, ++ .default_attrs = sysaufs_si_attrs ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++int sysaufs_si_init(struct au_sbinfo *sbinfo) ++{ ++ int err; ++ ++ sbinfo->si_kobj.kset = sysaufs_ket; ++ /* cf. sysaufs_name() */ ++ err = kobject_init_and_add ++ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_ket->kobj*/NULL, ++ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo)); ++ ++ dbgaufs_si_null(sbinfo); ++ if (!err) { ++ err = dbgaufs_si_init(sbinfo); ++ if (unlikely(err)) ++ kobject_put(&sbinfo->si_kobj); ++ } ++ return err; ++} ++ ++void sysaufs_fin(void) ++{ ++ dbgaufs_fin(); ++ sysfs_remove_group(&sysaufs_ket->kobj, sysaufs_attr_group); ++ kset_unregister(sysaufs_ket); ++} ++ ++int __init sysaufs_init(void) ++{ ++ int err; ++ ++ do { ++ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask)); ++ } while (!sysaufs_si_mask); ++ ++ sysaufs_ket = kset_create_and_add(AUFS_NAME, NULL, fs_kobj); ++ err = PTR_ERR(sysaufs_ket); ++ if (IS_ERR(sysaufs_ket)) ++ goto out; ++ err = sysfs_create_group(&sysaufs_ket->kobj, sysaufs_attr_group); ++ if (unlikely(err)) { ++ kset_unregister(sysaufs_ket); ++ goto out; ++ } ++ ++ err = dbgaufs_init(); ++ if (unlikely(err)) ++ sysaufs_fin(); ++ out: ++ return err; ++} +diff -Naur a/fs/aufs/sysaufs.h b/fs/aufs/sysaufs.h +--- a/fs/aufs/sysaufs.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/sysaufs.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,120 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * sysfs interface and mount lifetime management ++ */ ++ ++#ifndef __SYSAUFS_H__ ++#define __SYSAUFS_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include "module.h" ++ ++struct super_block; ++struct au_sbinfo; ++ ++struct sysaufs_si_attr { ++ struct attribute attr; ++ int (*show)(struct seq_file *seq, struct super_block *sb); ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* sysaufs.c */ ++extern unsigned long sysaufs_si_mask; ++extern struct kset *sysaufs_ket; ++extern struct attribute *sysaufs_si_attrs[]; ++int sysaufs_si_init(struct au_sbinfo *sbinfo); ++int __init sysaufs_init(void); ++void sysaufs_fin(void); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* some people doesn't like to show a pointer in kernel */ ++static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo) ++{ ++ return sysaufs_si_mask ^ (unsigned long)sbinfo; ++} ++ ++#define SysaufsSiNamePrefix "si_" ++#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16) ++static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name) ++{ ++ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx", ++ sysaufs_si_id(sbinfo)); ++} ++ ++struct au_branch; ++#ifdef CONFIG_SYSFS ++/* sysfs.c */ ++extern struct attribute_group *sysaufs_attr_group; ++ ++int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb); ++ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr, ++ char *buf); ++ ++void sysaufs_br_init(struct au_branch *br); ++void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex); ++void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex); ++ ++#define sysaufs_brs_init() do {} while (0) ++ ++#else ++#define sysaufs_attr_group NULL ++ ++static inline ++int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb) ++{ ++ return 0; ++} ++ ++static inline ++ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr, ++ char *buf) ++{ ++ return 0; ++} ++ ++static inline void sysaufs_br_init(struct au_branch *br) ++{ ++ /* empty */ ++} ++ ++static inline void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ /* nothing */ ++} ++ ++static inline void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ /* nothing */ ++} ++ ++static inline void sysaufs_brs_init(void) ++{ ++ sysaufs_brs = 0; ++} ++ ++#endif /* CONFIG_SYSFS */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __SYSAUFS_H__ */ +diff -Naur a/fs/aufs/sysfs.c b/fs/aufs/sysfs.c +--- a/fs/aufs/sysfs.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/sysfs.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,208 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * sysfs interface ++ */ ++ ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++static struct attribute *au_attr[] = { ++ NULL, /* need to NULL terminate the list of attributes */ ++}; ++ ++static struct attribute_group sysaufs_attr_group_body = { ++ .attrs = au_attr ++}; ++ ++struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body; ++ ++/* ---------------------------------------------------------------------- */ ++ ++int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb) ++{ ++ int err; ++ ++ err = 0; ++ if (au_opt_test(au_mntflags(sb), XINO)) { ++ err = au_xino_path(seq, au_sbi(sb)->si_xib); ++ seq_putc(seq, '\n'); ++ } ++ return err; ++} ++ ++/* ++ * the lifetime of branch is independent from the entry under sysfs. ++ * sysfs handles the lifetime of the entry, and never call ->show() after it is ++ * unlinked. ++ */ ++static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb, ++ aufs_bindex_t bindex) ++{ ++ struct path path; ++ struct dentry *root; ++ struct au_branch *br; ++ ++ AuDbg("b%d\n", bindex); ++ ++ root = sb->s_root; ++ di_read_lock_parent(root, !AuLock_IR); ++ br = au_sbr(sb, bindex); ++ path.mnt = br->br_mnt; ++ path.dentry = au_h_dptr(root, bindex); ++ au_seq_path(seq, &path); ++ di_read_unlock(root, !AuLock_IR); ++ seq_printf(seq, "=%s\n", au_optstr_br_perm(br->br_perm)); ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct seq_file *au_seq(char *p, ssize_t len) ++{ ++ struct seq_file *seq; ++ ++ seq = kzalloc(sizeof(*seq), GFP_NOFS); ++ if (seq) { ++ /* mutex_init(&seq.lock); */ ++ seq->buf = p; ++ seq->size = len; ++ return seq; /* success */ ++ } ++ ++ seq = ERR_PTR(-ENOMEM); ++ return seq; ++} ++ ++#define SysaufsBr_PREFIX "br" ++ ++/* todo: file size may exceed PAGE_SIZE */ ++ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr, ++ char *buf) ++{ ++ ssize_t err; ++ long l; ++ aufs_bindex_t bend; ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ struct seq_file *seq; ++ char *name; ++ struct attribute **cattr; ++ ++ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); ++ sb = sbinfo->si_sb; ++ si_noflush_read_lock(sb); ++ ++ seq = au_seq(buf, PAGE_SIZE); ++ err = PTR_ERR(seq); ++ if (IS_ERR(seq)) ++ goto out; ++ ++ name = (void *)attr->name; ++ cattr = sysaufs_si_attrs; ++ while (*cattr) { ++ if (!strcmp(name, (*cattr)->name)) { ++ err = container_of(*cattr, struct sysaufs_si_attr, attr) ++ ->show(seq, sb); ++ goto out_seq; ++ } ++ cattr++; ++ } ++ ++ bend = au_sbend(sb); ++ if (!strncmp(name, SysaufsBr_PREFIX, sizeof(SysaufsBr_PREFIX) - 1)) { ++ name += sizeof(SysaufsBr_PREFIX) - 1; ++ err = strict_strtol(name, 10, &l); ++ if (!err) { ++ if (l <= bend) ++ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l); ++ else ++ err = -ENOENT; ++ } ++ goto out_seq; ++ } ++ BUG(); ++ ++ out_seq: ++ if (!err) { ++ err = seq->count; ++ /* sysfs limit */ ++ if (unlikely(err == PAGE_SIZE)) ++ err = -EFBIG; ++ } ++ kfree(seq); ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void sysaufs_br_init(struct au_branch *br) ++{ ++ br->br_attr.name = br->br_name; ++ br->br_attr.mode = S_IRUGO; ++ br->br_attr.owner = THIS_MODULE; ++} ++ ++void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ struct au_branch *br; ++ struct kobject *kobj; ++ aufs_bindex_t bend; ++ ++ dbgaufs_brs_del(sb, bindex); ++ ++ if (!sysaufs_brs) ++ return; ++ ++ kobj = &au_sbi(sb)->si_kobj; ++ bend = au_sbend(sb); ++ for (; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ sysfs_remove_file(kobj, &br->br_attr); ++ } ++} ++ ++void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ int err; ++ aufs_bindex_t bend; ++ struct kobject *kobj; ++ struct au_branch *br; ++ ++ dbgaufs_brs_add(sb, bindex); ++ ++ if (!sysaufs_brs) ++ return; ++ ++ kobj = &au_sbi(sb)->si_kobj; ++ bend = au_sbend(sb); ++ for (; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ snprintf(br->br_name, sizeof(br->br_name), SysaufsBr_PREFIX ++ "%d", bindex); ++ err = sysfs_create_file(kobj, &br->br_attr); ++ if (unlikely(err)) ++ AuWarn("failed %s under sysfs(%d)\n", br->br_name, err); ++ } ++} +diff -Naur a/fs/aufs/sysrq.c b/fs/aufs/sysrq.c +--- a/fs/aufs/sysrq.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/sysrq.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,115 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * magic sysrq hanlder ++ */ ++ ++#include ++#include ++#include ++/* #include */ ++#include "aufs.h" ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void sysrq_sb(struct super_block *sb) ++{ ++ char *plevel; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ ++ plevel = au_plevel; ++ au_plevel = KERN_WARNING; ++ au_debug(1); ++ ++ sbinfo = au_sbi(sb); ++ pr_warning("si=%lx\n", sysaufs_si_id(sbinfo)); ++ pr_warning(AUFS_NAME ": superblock\n"); ++ au_dpri_sb(sb); ++ pr_warning(AUFS_NAME ": root dentry\n"); ++ au_dpri_dentry(sb->s_root); ++ pr_warning(AUFS_NAME ": root inode\n"); ++ au_dpri_inode(sb->s_root->d_inode); ++#if 0 ++ struct inode *i; ++ pr_warning(AUFS_NAME ": isolated inode\n"); ++ list_for_each_entry(i, &sb->s_inodes, i_sb_list) ++ if (list_empty(&i->i_dentry)) ++ au_dpri_inode(i); ++#endif ++ pr_warning(AUFS_NAME ": files\n"); ++ list_for_each_entry(file, &sb->s_files, f_u.fu_list) ++ if (!special_file(file->f_dentry->d_inode->i_mode)) ++ au_dpri_file(file); ++ ++ au_plevel = plevel; ++ au_debug(0); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* module parameter */ ++static char *aufs_sysrq_key = "a"; ++module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO); ++MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME); ++ ++static void au_sysrq(int key __maybe_unused, ++ struct tty_struct *tty __maybe_unused) ++{ ++ struct kobject *kobj; ++ struct au_sbinfo *sbinfo; ++ ++ /* spin_lock(&sysaufs_ket->list_lock); */ ++ list_for_each_entry(kobj, &sysaufs_ket->list, entry) { ++ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); ++ sysrq_sb(sbinfo->si_sb); ++ } ++ /* spin_unlock(&sysaufs_ket->list_lock); */ ++} ++ ++static struct sysrq_key_op au_sysrq_op = { ++ .handler = au_sysrq, ++ .help_msg = "Aufs", ++ .action_msg = "Aufs", ++ .enable_mask = SYSRQ_ENABLE_DUMP ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++int __init au_sysrq_init(void) ++{ ++ int err; ++ char key; ++ ++ err = -1; ++ key = *aufs_sysrq_key; ++ if ('a' <= key && key <= 'z') ++ err = register_sysrq_key(key, &au_sysrq_op); ++ if (unlikely(err)) ++ AuErr("err %d, sysrq=%c\n", err, key); ++ return err; ++} ++ ++void au_sysrq_fin(void) ++{ ++ int err; ++ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op); ++ if (unlikely(err)) ++ AuErr("err %d (ignored)\n", err); ++} +diff -Naur a/fs/aufs/vdir.c b/fs/aufs/vdir.c +--- a/fs/aufs/vdir.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/vdir.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,876 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * virtual or vertical directory ++ */ ++ ++#include ++#include "aufs.h" ++ ++static unsigned int calc_size(int nlen) ++{ ++ BUILD_BUG_ON(sizeof(ino_t) != sizeof(long)); ++ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t)); ++} ++ ++static int set_deblk_end(union au_vdir_deblk_p *p, ++ union au_vdir_deblk_p *deblk_end) ++{ ++ if (calc_size(0) <= deblk_end->deblk - p->deblk) { ++ p->de->de_str.len = 0; ++ /* smp_mb(); */ ++ return 0; ++ } ++ return -1; /* error */ ++} ++ ++/* returns true or false */ ++static int is_deblk_end(union au_vdir_deblk_p *p, ++ union au_vdir_deblk_p *deblk_end) ++{ ++ if (calc_size(0) <= deblk_end->deblk - p->deblk) ++ return !p->de->de_str.len; ++ return 1; ++} ++ ++static unsigned char *last_deblk(struct au_vdir *vdir) ++{ ++ return vdir->vd_deblk[vdir->vd_nblk - 1]; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * the allocated memory has to be freed by ++ * au_nhash_wh_free() or au_nhash_de_free(). ++ */ ++int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp) ++{ ++ struct hlist_head *head; ++ unsigned int u; ++ ++ head = kmalloc(sizeof(*nhash->nh_head) * num_hash, gfp); ++ if (head) { ++ nhash->nh_num = num_hash; ++ nhash->nh_head = head; ++ for (u = 0; u < num_hash; u++) ++ INIT_HLIST_HEAD(head++); ++ return 0; /* success */ ++ } ++ ++ return -ENOMEM; ++} ++ ++static void nhash_count(struct hlist_head *head) ++{ ++#if 0 ++ unsigned long n; ++ struct hlist_node *pos; ++ ++ n = 0; ++ hlist_for_each(pos, head) ++ n++; ++ AuInfo("%lu\n", n); ++#endif ++} ++ ++static void au_nhash_wh_do_free(struct hlist_head *head) ++{ ++ struct au_vdir_wh *tpos; ++ struct hlist_node *pos, *node; ++ ++ hlist_for_each_entry_safe(tpos, pos, node, head, wh_hash) { ++ /* hlist_del(pos); */ ++ kfree(tpos); ++ } ++} ++ ++static void au_nhash_de_do_free(struct hlist_head *head) ++{ ++ struct au_vdir_dehstr *tpos; ++ struct hlist_node *pos, *node; ++ ++ hlist_for_each_entry_safe(tpos, pos, node, head, hash) { ++ /* hlist_del(pos); */ ++ au_cache_free_dehstr(tpos); ++ } ++} ++ ++static void au_nhash_do_free(struct au_nhash *nhash, ++ void (*free)(struct hlist_head *head)) ++{ ++ unsigned int u, n; ++ struct hlist_head *head; ++ ++ n = nhash->nh_num; ++ head = nhash->nh_head; ++ for (u = 0; u < n; u++) { ++ nhash_count(head); ++ free(head++); ++ } ++ kfree(nhash->nh_head); ++} ++ ++void au_nhash_wh_free(struct au_nhash *whlist) ++{ ++ au_nhash_do_free(whlist, au_nhash_wh_do_free); ++} ++ ++static void au_nhash_de_free(struct au_nhash *delist) ++{ ++ au_nhash_do_free(delist, au_nhash_de_do_free); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt, ++ int limit) ++{ ++ int num; ++ unsigned int u, n; ++ struct hlist_head *head; ++ struct au_vdir_wh *tpos; ++ struct hlist_node *pos; ++ ++ num = 0; ++ n = whlist->nh_num; ++ head = whlist->nh_head; ++ for (u = 0; u < n; u++) { ++ hlist_for_each_entry(tpos, pos, head, wh_hash) ++ if (tpos->wh_bindex == btgt && ++num > limit) ++ return 1; ++ head++; ++ } ++ return 0; ++} ++ ++static struct hlist_head *au_name_hash(struct au_nhash *nhash, ++ unsigned char *name, ++ unsigned int len) ++{ ++ unsigned int v; ++ /* const unsigned int magic_bit = 12; */ ++ ++ v = 0; ++ while (len--) ++ v += *name++; ++ /* v = hash_long(v, magic_bit); */ ++ v %= nhash->nh_num; ++ return nhash->nh_head + v; ++} ++ ++static int au_nhash_test_name(struct au_vdir_destr *str, const char *name, ++ int nlen) ++{ ++ return str->len == nlen && !memcmp(str->name, name, nlen); ++} ++ ++/* returns found or not */ ++int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen) ++{ ++ struct hlist_head *head; ++ struct au_vdir_wh *tpos; ++ struct hlist_node *pos; ++ struct au_vdir_destr *str; ++ ++ head = au_name_hash(whlist, name, nlen); ++ hlist_for_each_entry(tpos, pos, head, wh_hash) { ++ str = &tpos->wh_str; ++ AuDbg("%.*s\n", str->len, str->name); ++ if (au_nhash_test_name(str, name, nlen)) ++ return 1; ++ } ++ return 0; ++} ++ ++/* returns found(true) or not */ ++static int test_known(struct au_nhash *delist, char *name, int nlen) ++{ ++ struct hlist_head *head; ++ struct au_vdir_dehstr *tpos; ++ struct hlist_node *pos; ++ struct au_vdir_destr *str; ++ ++ head = au_name_hash(delist, name, nlen); ++ hlist_for_each_entry(tpos, pos, head, hash) { ++ str = tpos->str; ++ AuDbg("%.*s\n", str->len, str->name); ++ if (au_nhash_test_name(str, name, nlen)) ++ return 1; ++ } ++ return 0; ++} ++ ++static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino, ++ unsigned char d_type) ++{ ++#ifdef CONFIG_AUFS_SHWH ++ wh->wh_ino = ino; ++ wh->wh_type = d_type; ++#endif ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino, ++ unsigned int d_type, aufs_bindex_t bindex, ++ unsigned char shwh) ++{ ++ int err; ++ struct au_vdir_destr *str; ++ struct au_vdir_wh *wh; ++ ++ AuDbg("%.*s\n", nlen, name); ++ err = -ENOMEM; ++ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS); ++ if (unlikely(!wh)) ++ goto out; ++ ++ err = 0; ++ wh->wh_bindex = bindex; ++ if (shwh) ++ au_shwh_init_wh(wh, ino, d_type); ++ str = &wh->wh_str; ++ str->len = nlen; ++ memcpy(str->name, name, nlen); ++ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen)); ++ /* smp_mb(); */ ++ ++ out: ++ return err; ++} ++ ++static int append_deblk(struct au_vdir *vdir) ++{ ++ int err; ++ unsigned long ul; ++ const unsigned int deblk_sz = vdir->vd_deblk_sz; ++ union au_vdir_deblk_p p, deblk_end; ++ unsigned char **o; ++ ++ err = -ENOMEM; ++ o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1), ++ GFP_NOFS); ++ if (unlikely(!o)) ++ goto out; ++ ++ vdir->vd_deblk = o; ++ p.deblk = kmalloc(deblk_sz, GFP_NOFS); ++ if (p.deblk) { ++ ul = vdir->vd_nblk++; ++ vdir->vd_deblk[ul] = p.deblk; ++ vdir->vd_last.ul = ul; ++ vdir->vd_last.p.deblk = p.deblk; ++ deblk_end.deblk = p.deblk + deblk_sz; ++ err = set_deblk_end(&p, &deblk_end); ++ } ++ ++ out: ++ return err; ++} ++ ++static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino, ++ unsigned int d_type, struct au_nhash *delist) ++{ ++ int err; ++ unsigned int sz; ++ const unsigned int deblk_sz = vdir->vd_deblk_sz; ++ union au_vdir_deblk_p p, *room, deblk_end; ++ struct au_vdir_dehstr *dehstr; ++ ++ p.deblk = last_deblk(vdir); ++ deblk_end.deblk = p.deblk + deblk_sz; ++ room = &vdir->vd_last.p; ++ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk ++ || !is_deblk_end(room, &deblk_end)); ++ ++ sz = calc_size(nlen); ++ if (unlikely(sz > deblk_end.deblk - room->deblk)) { ++ err = append_deblk(vdir); ++ if (unlikely(err)) ++ goto out; ++ ++ p.deblk = last_deblk(vdir); ++ deblk_end.deblk = p.deblk + deblk_sz; ++ /* smp_mb(); */ ++ AuDebugOn(room->deblk != p.deblk); ++ } ++ ++ err = -ENOMEM; ++ dehstr = au_cache_alloc_dehstr(); ++ if (unlikely(!dehstr)) ++ goto out; ++ ++ dehstr->str = &room->de->de_str; ++ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen)); ++ room->de->de_ino = ino; ++ room->de->de_type = d_type; ++ room->de->de_str.len = nlen; ++ memcpy(room->de->de_str.name, name, nlen); ++ ++ err = 0; ++ room->deblk += sz; ++ if (unlikely(set_deblk_end(room, &deblk_end))) ++ err = append_deblk(vdir); ++ /* smp_mb(); */ ++ ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_vdir_free(struct au_vdir *vdir) ++{ ++ unsigned char **deblk; ++ ++ deblk = vdir->vd_deblk; ++ while (vdir->vd_nblk--) ++ kfree(*deblk++); ++ kfree(vdir->vd_deblk); ++ au_cache_free_vdir(vdir); ++} ++ ++static struct au_vdir *alloc_vdir(struct super_block *sb) ++{ ++ struct au_vdir *vdir; ++ int err; ++ ++ err = -ENOMEM; ++ vdir = au_cache_alloc_vdir(); ++ if (unlikely(!vdir)) ++ goto out; ++ ++ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS); ++ if (unlikely(!vdir->vd_deblk)) ++ goto out_free; ++ ++ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk; ++ vdir->vd_nblk = 0; ++ vdir->vd_version = 0; ++ vdir->vd_jiffy = 0; ++ err = append_deblk(vdir); ++ if (!err) ++ return vdir; /* success */ ++ ++ kfree(vdir->vd_deblk); ++ ++ out_free: ++ au_cache_free_vdir(vdir); ++ out: ++ vdir = ERR_PTR(err); ++ return vdir; ++} ++ ++static int reinit_vdir(struct au_vdir *vdir) ++{ ++ int err; ++ union au_vdir_deblk_p p, deblk_end; ++ ++ while (vdir->vd_nblk > 1) { ++ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]); ++ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */ ++ vdir->vd_nblk--; ++ } ++ p.deblk = vdir->vd_deblk[0]; ++ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz; ++ err = set_deblk_end(&p, &deblk_end); ++ /* keep vd_dblk_sz */ ++ vdir->vd_last.ul = 0; ++ vdir->vd_last.p.deblk = vdir->vd_deblk[0]; ++ vdir->vd_version = 0; ++ vdir->vd_jiffy = 0; ++ /* smp_mb(); */ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ unsigned int d_type, ino_t *ino) ++{ ++ int err; ++ struct mutex *mtx; ++ const int isdir = (d_type == DT_DIR); ++ ++ /* prevent hardlinks from race condition */ ++ mtx = NULL; ++ if (!isdir) { ++ mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx; ++ mutex_lock(mtx); ++ } ++ err = au_xino_read(sb, bindex, h_ino, ino); ++ if (unlikely(err)) ++ goto out; ++ ++ if (!*ino) { ++ err = -EIO; ++ *ino = au_xino_new_ino(sb); ++ if (unlikely(!*ino)) ++ goto out; ++ err = au_xino_write(sb, bindex, h_ino, *ino); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ out: ++ if (!isdir) ++ mutex_unlock(mtx); ++ return err; ++} ++ ++static int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ unsigned int d_type, ino_t *ino) ++{ ++#ifdef CONFIG_AUFS_SHWH ++ return au_ino(sb, bindex, h_ino, d_type, ino); ++#else ++ return 0; ++#endif ++} ++ ++#define AuFillVdir_CALLED 1 ++#define AuFillVdir_WHABLE (1 << 1) ++#define AuFillVdir_SHWH (1 << 2) ++#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name) ++#define au_fset_fillvdir(flags, name) { (flags) |= AuFillVdir_##name; } ++#define au_fclr_fillvdir(flags, name) { (flags) &= ~AuFillVdir_##name; } ++ ++#ifndef CONFIG_AUFS_SHWH ++#undef AuFillVdir_SHWH ++#define AuFillVdir_SHWH 0 ++#endif ++ ++struct fillvdir_arg { ++ struct file *file; ++ struct au_vdir *vdir; ++ struct au_nhash delist; ++ struct au_nhash whlist; ++ aufs_bindex_t bindex; ++ unsigned int flags; ++ int err; ++}; ++ ++static int fillvdir(void *__arg, const char *__name, int nlen, ++ loff_t offset __maybe_unused, u64 h_ino, ++ unsigned int d_type) ++{ ++ struct fillvdir_arg *arg = __arg; ++ char *name = (void *)__name; ++ struct super_block *sb; ++ ino_t ino; ++ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH); ++ ++ arg->err = 0; ++ sb = arg->file->f_dentry->d_sb; ++ au_fset_fillvdir(arg->flags, CALLED); ++ /* smp_mb(); */ ++ if (nlen <= AUFS_WH_PFX_LEN ++ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { ++ if (test_known(&arg->delist, name, nlen) ++ || au_nhash_test_known_wh(&arg->whlist, name, nlen)) ++ goto out; /* already exists or whiteouted */ ++ ++ sb = arg->file->f_dentry->d_sb; ++ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino); ++ if (!arg->err) ++ arg->err = append_de(arg->vdir, name, nlen, ino, ++ d_type, &arg->delist); ++ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) { ++ name += AUFS_WH_PFX_LEN; ++ nlen -= AUFS_WH_PFX_LEN; ++ if (au_nhash_test_known_wh(&arg->whlist, name, nlen)) ++ goto out; /* already whiteouted */ ++ ++ if (shwh) ++ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type, ++ &ino); ++ if (!arg->err) ++ arg->err = au_nhash_append_wh ++ (&arg->whlist, name, nlen, ino, d_type, ++ arg->bindex, shwh); ++ } ++ ++ out: ++ if (!arg->err) ++ arg->vdir->vd_jiffy = jiffies; ++ /* smp_mb(); */ ++ AuTraceErr(arg->err); ++ return arg->err; ++} ++ ++static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir, ++ struct au_nhash *whlist, struct au_nhash *delist) ++{ ++#ifdef CONFIG_AUFS_SHWH ++ int err; ++ unsigned int nh, u; ++ struct hlist_head *head; ++ struct au_vdir_wh *tpos; ++ struct hlist_node *pos, *n; ++ char *p, *o; ++ struct au_vdir_destr *destr; ++ ++ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH)); ++ ++ err = -ENOMEM; ++ o = p = __getname(); ++ if (unlikely(!p)) ++ goto out; ++ ++ err = 0; ++ nh = whlist->nh_num; ++ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); ++ p += AUFS_WH_PFX_LEN; ++ for (u = 0; u < nh; u++) { ++ head = whlist->nh_head + u; ++ hlist_for_each_entry_safe(tpos, pos, n, head, wh_hash) { ++ destr = &tpos->wh_str; ++ memcpy(p, destr->name, destr->len); ++ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN, ++ tpos->wh_ino, tpos->wh_type, delist); ++ if (unlikely(err)) ++ break; ++ } ++ } ++ ++ __putname(o); ++ ++ out: ++ AuTraceErr(err); ++ return err; ++#else ++ return 0; ++#endif ++} ++ ++static int au_do_read_vdir(struct fillvdir_arg *arg) ++{ ++ int err; ++ unsigned int rdhash; ++ loff_t offset; ++ aufs_bindex_t bend, bindex, bstart; ++ unsigned char shwh; ++ struct file *hf, *file; ++ struct super_block *sb; ++ ++ file = arg->file; ++ sb = file->f_dentry->d_sb; ++ rdhash = au_sbi(sb)->si_rdhash; ++ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS); ++ if (unlikely(err)) ++ goto out_delist; ++ ++ err = 0; ++ arg->flags = 0; ++ shwh = 0; ++ if (au_opt_test(au_mntflags(sb), SHWH)) { ++ shwh = 1; ++ au_fset_fillvdir(arg->flags, SHWH); ++ } ++ bstart = au_fbstart(file); ++ bend = au_fbend(file); ++ for (bindex = bstart; !err && bindex <= bend; bindex++) { ++ hf = au_h_fptr(file, bindex); ++ if (!hf) ++ continue; ++ ++ offset = vfsub_llseek(hf, 0, SEEK_SET); ++ err = offset; ++ if (unlikely(offset)) ++ break; ++ ++ arg->bindex = bindex; ++ au_fclr_fillvdir(arg->flags, WHABLE); ++ if (shwh ++ || (bindex != bend ++ && au_br_whable(au_sbr_perm(sb, bindex)))) ++ au_fset_fillvdir(arg->flags, WHABLE); ++ do { ++ arg->err = 0; ++ au_fclr_fillvdir(arg->flags, CALLED); ++ /* smp_mb(); */ ++ err = vfsub_readdir(hf, fillvdir, arg); ++ if (err >= 0) ++ err = arg->err; ++ } while (!err && au_ftest_fillvdir(arg->flags, CALLED)); ++ } ++ ++ if (!err && shwh) ++ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist); ++ ++ au_nhash_wh_free(&arg->whlist); ++ ++ out_delist: ++ au_nhash_de_free(&arg->delist); ++ out: ++ return err; ++} ++ ++static int read_vdir(struct file *file, int may_read) ++{ ++ int err; ++ unsigned long expire; ++ unsigned char do_read; ++ struct fillvdir_arg arg; ++ struct inode *inode; ++ struct au_vdir *vdir, *allocated; ++ ++ err = 0; ++ inode = file->f_dentry->d_inode; ++ IMustLock(inode); ++ allocated = NULL; ++ do_read = 0; ++ expire = au_sbi(inode->i_sb)->si_rdcache; ++ vdir = au_ivdir(inode); ++ if (!vdir) { ++ do_read = 1; ++ vdir = alloc_vdir(inode->i_sb); ++ err = PTR_ERR(vdir); ++ if (IS_ERR(vdir)) ++ goto out; ++ err = 0; ++ allocated = vdir; ++ } else if (may_read ++ && (inode->i_version != vdir->vd_version ++ || time_after(jiffies, vdir->vd_jiffy + expire))) { ++ do_read = 1; ++ err = reinit_vdir(vdir); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ if (!do_read) ++ return 0; /* success */ ++ ++ arg.file = file; ++ arg.vdir = vdir; ++ err = au_do_read_vdir(&arg); ++ if (!err) { ++ /* file->f_pos = 0; */ ++ vdir->vd_version = inode->i_version; ++ vdir->vd_last.ul = 0; ++ vdir->vd_last.p.deblk = vdir->vd_deblk[0]; ++ if (allocated) ++ au_set_ivdir(inode, allocated); ++ } else if (allocated) ++ au_vdir_free(allocated); ++ ++ out: ++ return err; ++} ++ ++static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src) ++{ ++ int err, rerr; ++ unsigned long ul, n; ++ const unsigned int deblk_sz = src->vd_deblk_sz; ++ ++ AuDebugOn(tgt->vd_nblk != 1); ++ ++ err = -ENOMEM; ++ if (tgt->vd_nblk < src->vd_nblk) { ++ unsigned char **p; ++ ++ p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk, ++ GFP_NOFS); ++ if (unlikely(!p)) ++ goto out; ++ tgt->vd_deblk = p; ++ } ++ ++ tgt->vd_nblk = src->vd_nblk; ++ tgt->vd_deblk_sz = deblk_sz; ++ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz); ++ /* tgt->vd_last.i = 0; */ ++ /* tgt->vd_last.p.deblk = tgt->vd_deblk[0]; */ ++ tgt->vd_version = src->vd_version; ++ tgt->vd_jiffy = src->vd_jiffy; ++ ++ n = src->vd_nblk; ++ for (ul = 1; ul < n; ul++) { ++ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz, ++ GFP_NOFS); ++ if (unlikely(!tgt->vd_deblk[ul])) ++ goto out; ++ } ++ /* smp_mb(); */ ++ return 0; /* success */ ++ ++ out: ++ rerr = reinit_vdir(tgt); ++ BUG_ON(rerr); ++ return err; ++} ++ ++int au_vdir_init(struct file *file) ++{ ++ int err; ++ struct inode *inode; ++ struct au_vdir *vdir_cache, *allocated; ++ ++ err = read_vdir(file, !file->f_pos); ++ if (unlikely(err)) ++ goto out; ++ ++ allocated = NULL; ++ vdir_cache = au_fvdir_cache(file); ++ if (!vdir_cache) { ++ vdir_cache = alloc_vdir(file->f_dentry->d_sb); ++ err = PTR_ERR(vdir_cache); ++ if (IS_ERR(vdir_cache)) ++ goto out; ++ allocated = vdir_cache; ++ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) { ++ err = reinit_vdir(vdir_cache); ++ if (unlikely(err)) ++ goto out; ++ } else ++ return 0; /* success */ ++ ++ inode = file->f_dentry->d_inode; ++ err = copy_vdir(vdir_cache, au_ivdir(inode)); ++ if (!err) { ++ file->f_version = inode->i_version; ++ if (allocated) ++ au_set_fvdir_cache(file, allocated); ++ } else if (allocated) ++ au_vdir_free(allocated); ++ ++ out: ++ return err; ++} ++ ++static loff_t calc_offset(struct au_vdir *vdir) ++{ ++ loff_t offset; ++ union au_vdir_deblk_p p; ++ ++ p.deblk = vdir->vd_deblk[vdir->vd_last.ul]; ++ offset = vdir->vd_last.p.deblk - p.deblk; ++ offset += vdir->vd_deblk_sz * vdir->vd_last.ul; ++ return offset; ++} ++ ++/* returns true or false */ ++static int seek_vdir(struct file *file) ++{ ++ int valid; ++ unsigned int deblk_sz; ++ unsigned long ul, n; ++ loff_t offset; ++ union au_vdir_deblk_p p, deblk_end; ++ struct au_vdir *vdir_cache; ++ ++ valid = 1; ++ vdir_cache = au_fvdir_cache(file); ++ offset = calc_offset(vdir_cache); ++ AuDbg("offset %lld\n", offset); ++ if (file->f_pos == offset) ++ goto out; ++ ++ vdir_cache->vd_last.ul = 0; ++ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0]; ++ if (!file->f_pos) ++ goto out; ++ ++ valid = 0; ++ deblk_sz = vdir_cache->vd_deblk_sz; ++ ul = div64_u64(file->f_pos, deblk_sz); ++ AuDbg("ul %lu\n", ul); ++ if (ul >= vdir_cache->vd_nblk) ++ goto out; ++ ++ n = vdir_cache->vd_nblk; ++ for (; ul < n; ul++) { ++ p.deblk = vdir_cache->vd_deblk[ul]; ++ deblk_end.deblk = p.deblk + deblk_sz; ++ offset = ul; ++ offset *= deblk_sz; ++ while (!is_deblk_end(&p, &deblk_end) && offset < file->f_pos) { ++ unsigned int l; ++ ++ l = calc_size(p.de->de_str.len); ++ offset += l; ++ p.deblk += l; ++ } ++ if (!is_deblk_end(&p, &deblk_end)) { ++ valid = 1; ++ vdir_cache->vd_last.ul = ul; ++ vdir_cache->vd_last.p = p; ++ break; ++ } ++ } ++ ++ out: ++ /* smp_mb(); */ ++ AuTraceErr(!valid); ++ return valid; ++} ++ ++int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir) ++{ ++ int err; ++ unsigned int l, deblk_sz; ++ union au_vdir_deblk_p deblk_end; ++ struct au_vdir *vdir_cache; ++ struct au_vdir_de *de; ++ ++ vdir_cache = au_fvdir_cache(file); ++ if (!seek_vdir(file)) ++ return 0; ++ ++ deblk_sz = vdir_cache->vd_deblk_sz; ++ while (1) { ++ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul]; ++ deblk_end.deblk += deblk_sz; ++ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) { ++ de = vdir_cache->vd_last.p.de; ++ AuDbg("%.*s, off%lld, i%lu, dt%d\n", ++ de->de_str.len, de->de_str.name, file->f_pos, ++ (unsigned long)de->de_ino, de->de_type); ++ err = filldir(dirent, de->de_str.name, de->de_str.len, ++ file->f_pos, de->de_ino, de->de_type); ++ if (unlikely(err)) { ++ AuTraceErr(err); ++ /* todo: ignore the error caused by udba? */ ++ /* return err; */ ++ return 0; ++ } ++ ++ l = calc_size(de->de_str.len); ++ vdir_cache->vd_last.p.deblk += l; ++ file->f_pos += l; ++ } ++ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) { ++ vdir_cache->vd_last.ul++; ++ vdir_cache->vd_last.p.deblk ++ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul]; ++ file->f_pos = deblk_sz * vdir_cache->vd_last.ul; ++ continue; ++ } ++ break; ++ } ++ ++ /* smp_mb(); */ ++ return 0; ++} +diff -Naur a/fs/aufs/vfsub.c b/fs/aufs/vfsub.c +--- a/fs/aufs/vfsub.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/vfsub.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,736 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * sub-routines for VFS ++ */ ++ ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++int vfsub_update_h_iattr(struct path *h_path, int *did) ++{ ++ int err; ++ struct kstat st; ++ struct super_block *h_sb; ++ ++ /* for remote fs, leave work for its getattr or d_revalidate */ ++ /* for bad i_attr fs, handle them in aufs_getattr() */ ++ /* still some fs may acquire i_mutex. we need to skip them */ ++ err = 0; ++ if (!did) ++ did = &err; ++ h_sb = h_path->dentry->d_sb; ++ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb)); ++ if (*did) ++ err = vfs_getattr(h_path->mnt, h_path->dentry, &st); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct file *vfsub_filp_open(const char *path, int oflags, int mode) ++{ ++ struct file *file; ++ ++ lockdep_off(); ++ file = filp_open(path, oflags, mode); ++ lockdep_on(); ++ if (IS_ERR(file)) ++ goto out; ++ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ ++ ++ out: ++ return file; ++} ++ ++int vfsub_kern_path(const char *name, unsigned int flags, struct path *path) ++{ ++ int err; ++ ++ /* lockdep_off(); */ ++ err = kern_path(name, flags, path); ++ /* lockdep_on(); */ ++ if (!err && path->dentry->d_inode) ++ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, ++ int len) ++{ ++ struct path path = { ++ .mnt = NULL ++ }; ++ ++ IMustLock(parent->d_inode); ++ ++ path.dentry = lookup_one_len(name, parent, len); ++ if (IS_ERR(path.dentry)) ++ goto out; ++ if (path.dentry->d_inode) ++ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/ ++ ++ out: ++ return path.dentry; ++} ++ ++struct dentry *vfsub_lookup_hash(struct nameidata *nd) ++{ ++ struct path path = { ++ .mnt = nd->path.mnt ++ }; ++ ++ IMustLock(nd->path.dentry->d_inode); ++ ++ path.dentry = lookup_hash(nd); ++ if (!IS_ERR(path.dentry) && path.dentry->d_inode) ++ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/ ++ ++ return path.dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1, ++ struct dentry *d2, struct au_hinode *hdir2) ++{ ++ struct dentry *d; ++ ++ lockdep_off(); ++ d = lock_rename(d1, d2); ++ lockdep_on(); ++ au_hin_suspend(hdir1); ++ if (hdir1 != hdir2) ++ au_hin_suspend(hdir2); ++ ++ return d; ++} ++ ++void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1, ++ struct dentry *d2, struct au_hinode *hdir2) ++{ ++ au_hin_resume(hdir1); ++ if (hdir1 != hdir2) ++ au_hin_resume(hdir2); ++ lockdep_off(); ++ unlock_rename(d1, d2); ++ lockdep_on(); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int vfsub_create(struct inode *dir, struct path *path, int mode) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_mknod(path, path->dentry, mode, 0); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ if (au_test_fs_null_nd(dir->i_sb)) ++ err = vfs_create(dir, path->dentry, mode, NULL); ++ else { ++ struct nameidata h_nd; ++ ++ memset(&h_nd, 0, sizeof(h_nd)); ++ h_nd.flags = LOOKUP_CREATE; ++ h_nd.intent.open.flags = O_CREAT ++ | vfsub_fmode_to_uint(FMODE_READ); ++ h_nd.intent.open.create_mode = mode; ++ h_nd.path.dentry = path->dentry->d_parent; ++ h_nd.path.mnt = path->mnt; ++ path_get(&h_nd.path); ++ err = vfs_create(dir, path->dentry, mode, &h_nd); ++ path_put(&h_nd.path); ++ } ++ ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++int vfsub_symlink(struct inode *dir, struct path *path, const char *symname) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_symlink(path, path->dentry, symname); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ err = vfs_symlink(dir, path->dentry, symname); ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_mknod(path, path->dentry, mode, dev); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ err = vfs_mknod(dir, path->dentry, mode, dev); ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++static int au_test_nlink(struct inode *inode) ++{ ++ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */ ++ ++ if (!au_test_fs_no_limit_nlink(inode->i_sb) ++ || inode->i_nlink < link_max) ++ return 0; ++ return -EMLINK; ++} ++ ++int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ err = au_test_nlink(src_dentry->d_inode); ++ if (unlikely(err)) ++ return err; ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_link(src_dentry, path, path->dentry); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ lockdep_off(); ++ err = vfs_link(src_dentry, dir, path->dentry); ++ lockdep_on(); ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ /* fuse has different memory inode for the same inumber */ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ tmp.dentry = src_dentry; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, ++ struct inode *dir, struct path *path) ++{ ++ int err; ++ struct path tmp = { ++ .mnt = path->mnt ++ }; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ IMustLock(src_dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ tmp.dentry = src_dentry->d_parent; ++ err = security_path_rename(&tmp, src_dentry, path, path->dentry); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ lockdep_off(); ++ err = vfs_rename(src_dir, src_dentry, dir, path->dentry); ++ lockdep_on(); ++ if (!err) { ++ int did; ++ ++ tmp.dentry = d->d_parent; ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = src_dentry; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ tmp.dentry = src_dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++int vfsub_mkdir(struct inode *dir, struct path *path, int mode) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_mkdir(path, path->dentry, mode); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ err = vfs_mkdir(dir, path->dentry, mode); ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++int vfsub_rmdir(struct inode *dir, struct path *path) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_rmdir(path, path->dentry); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ lockdep_off(); ++ err = vfs_rmdir(dir, path->dentry); ++ lockdep_on(); ++ if (!err) { ++ struct path tmp = { ++ .dentry = path->dentry->d_parent, ++ .mnt = path->mnt ++ }; ++ ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, ++ loff_t *ppos) ++{ ++ ssize_t err; ++ ++ err = vfs_read(file, ubuf, count, ppos); ++ if (err >= 0) ++ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++/* todo: kernel_read()? */ ++ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, ++ loff_t *ppos) ++{ ++ ssize_t err; ++ mm_segment_t oldfs; ++ ++ oldfs = get_fs(); ++ set_fs(KERNEL_DS); ++ err = vfsub_read_u(file, (char __user *)kbuf, count, ppos); ++ set_fs(oldfs); ++ return err; ++} ++ ++ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, ++ loff_t *ppos) ++{ ++ ssize_t err; ++ ++ lockdep_off(); ++ err = vfs_write(file, ubuf, count, ppos); ++ lockdep_on(); ++ if (err >= 0) ++ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos) ++{ ++ ssize_t err; ++ mm_segment_t oldfs; ++ ++ oldfs = get_fs(); ++ set_fs(KERNEL_DS); ++ err = vfsub_write_u(file, (const char __user *)kbuf, count, ppos); ++ set_fs(oldfs); ++ return err; ++} ++ ++int vfsub_readdir(struct file *file, filldir_t filldir, void *arg) ++{ ++ int err; ++ ++ lockdep_off(); ++ err = vfs_readdir(file, filldir, arg); ++ lockdep_on(); ++ if (err >= 0) ++ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++long vfsub_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags) ++{ ++ long err; ++ ++ lockdep_off(); ++ err = do_splice_to(in, ppos, pipe, len, flags); ++ lockdep_on(); ++ if (err >= 0) ++ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags) ++{ ++ long err; ++ ++ lockdep_off(); ++ err = do_splice_from(pipe, out, ppos, len, flags); ++ lockdep_on(); ++ if (err >= 0) ++ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */ ++int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr, ++ struct file *h_file) ++{ ++ int err; ++ struct inode *h_inode; ++ ++ h_inode = h_path->dentry->d_inode; ++ if (!h_file) { ++ err = mnt_want_write(h_path->mnt); ++ if (err) ++ goto out; ++ err = inode_permission(h_inode, MAY_WRITE); ++ if (err) ++ goto out_mnt; ++ err = get_write_access(h_inode); ++ if (err) ++ goto out_mnt; ++ err = break_lease(h_inode, vfsub_fmode_to_uint(FMODE_WRITE)); ++ if (err) ++ goto out_inode; ++ } ++ ++ err = locks_verify_truncate(h_inode, h_file, length); ++ if (!err) ++ err = security_path_truncate(h_path, length, attr); ++ if (!err) { ++ lockdep_off(); ++ err = do_truncate(h_path->dentry, length, attr, h_file); ++ lockdep_on(); ++ } ++ ++ out_inode: ++ if (!h_file) ++ put_write_access(h_inode); ++ out_mnt: ++ if (!h_file) ++ mnt_drop_write(h_path->mnt); ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_vfsub_mkdir_args { ++ int *errp; ++ struct inode *dir; ++ struct path *path; ++ int mode; ++}; ++ ++static void au_call_vfsub_mkdir(void *args) ++{ ++ struct au_vfsub_mkdir_args *a = args; ++ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode); ++} ++ ++int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode) ++{ ++ int err, do_sio, wkq_err; ++ ++ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE); ++ if (!do_sio) ++ err = vfsub_mkdir(dir, path, mode); ++ else { ++ struct au_vfsub_mkdir_args args = { ++ .errp = &err, ++ .dir = dir, ++ .path = path, ++ .mode = mode ++ }; ++ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ return err; ++} ++ ++struct au_vfsub_rmdir_args { ++ int *errp; ++ struct inode *dir; ++ struct path *path; ++}; ++ ++static void au_call_vfsub_rmdir(void *args) ++{ ++ struct au_vfsub_rmdir_args *a = args; ++ *a->errp = vfsub_rmdir(a->dir, a->path); ++} ++ ++int vfsub_sio_rmdir(struct inode *dir, struct path *path) ++{ ++ int err, do_sio, wkq_err; ++ ++ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE); ++ if (!do_sio) ++ err = vfsub_rmdir(dir, path); ++ else { ++ struct au_vfsub_rmdir_args args = { ++ .errp = &err, ++ .dir = dir, ++ .path = path ++ }; ++ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct notify_change_args { ++ int *errp; ++ struct path *path; ++ struct iattr *ia; ++}; ++ ++static void call_notify_change(void *args) ++{ ++ struct notify_change_args *a = args; ++ struct inode *h_inode; ++ ++ h_inode = a->path->dentry->d_inode; ++ IMustLock(h_inode); ++ ++ *a->errp = -EPERM; ++ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) { ++ lockdep_off(); ++ *a->errp = notify_change(a->path->dentry, a->ia); ++ lockdep_on(); ++ if (!*a->errp) ++ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/ ++ } ++ AuTraceErr(*a->errp); ++} ++ ++int vfsub_notify_change(struct path *path, struct iattr *ia) ++{ ++ int err; ++ struct notify_change_args args = { ++ .errp = &err, ++ .path = path, ++ .ia = ia ++ }; ++ ++ call_notify_change(&args); ++ ++ return err; ++} ++ ++int vfsub_sio_notify_change(struct path *path, struct iattr *ia) ++{ ++ int err, wkq_err; ++ struct notify_change_args args = { ++ .errp = &err, ++ .path = path, ++ .ia = ia ++ }; ++ ++ wkq_err = au_wkq_wait(call_notify_change, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct unlink_args { ++ int *errp; ++ struct inode *dir; ++ struct path *path; ++}; ++ ++static void call_unlink(void *args) ++{ ++ struct unlink_args *a = args; ++ struct dentry *d = a->path->dentry; ++ struct inode *h_inode; ++ const int stop_sillyrename = (au_test_nfs(d->d_sb) ++ && atomic_read(&d->d_count) == 1); ++ ++ IMustLock(a->dir); ++ ++ a->path->dentry = d->d_parent; ++ *a->errp = security_path_unlink(a->path, d); ++ a->path->dentry = d; ++ if (unlikely(*a->errp)) ++ return; ++ ++ if (!stop_sillyrename) ++ dget(d); ++ h_inode = d->d_inode; ++ if (h_inode) ++ atomic_inc(&h_inode->i_count); ++ ++ lockdep_off(); ++ *a->errp = vfs_unlink(a->dir, d); ++ lockdep_on(); ++ if (!*a->errp) { ++ struct path tmp = { ++ .dentry = d->d_parent, ++ .mnt = a->path->mnt ++ }; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/ ++ } ++ ++ if (!stop_sillyrename) ++ dput(d); ++ if (h_inode) ++ iput(h_inode); ++ ++ AuTraceErr(*a->errp); ++} ++ ++/* ++ * @dir: must be locked. ++ * @dentry: target dentry. ++ */ ++int vfsub_unlink(struct inode *dir, struct path *path, int force) ++{ ++ int err; ++ struct unlink_args args = { ++ .errp = &err, ++ .dir = dir, ++ .path = path ++ }; ++ ++ if (!force) ++ call_unlink(&args); ++ else { ++ int wkq_err; ++ ++ wkq_err = au_wkq_wait(call_unlink, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ return err; ++} +diff -Naur a/fs/aufs/vfsub.h b/fs/aufs/vfsub.h +--- a/fs/aufs/vfsub.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/vfsub.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,171 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * sub-routines for VFS ++ */ ++ ++#ifndef __AUFS_VFSUB_H__ ++#define __AUFS_VFSUB_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* lock subclass for lower inode */ ++/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */ ++/* reduce? gave up. */ ++enum { ++ AuLsc_I_Begin = I_MUTEX_QUOTA, /* 4 */ ++ AuLsc_I_PARENT, /* lower inode, parent first */ ++ AuLsc_I_PARENT2, /* copyup dirs */ ++ AuLsc_I_CHILD, ++ AuLsc_I_CHILD2, ++ AuLsc_I_End ++}; ++ ++/* to debug easier, do not make them inlined functions */ ++#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx)) ++#define IMustLock(i) MtxMustLock(&(i)->i_mutex) ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline void vfsub_copy_inode_size(struct inode *inode, ++ struct inode *h_inode) ++{ ++ spin_lock(&inode->i_lock); ++ fsstack_copy_inode_size(inode, h_inode); ++ spin_unlock(&inode->i_lock); ++} ++ ++int vfsub_update_h_iattr(struct path *h_path, int *did); ++struct file *vfsub_filp_open(const char *path, int oflags, int mode); ++int vfsub_kern_path(const char *name, unsigned int flags, struct path *path); ++struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, ++ int len); ++struct dentry *vfsub_lookup_hash(struct nameidata *nd); ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_hinode; ++struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1, ++ struct dentry *d2, struct au_hinode *hdir2); ++void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1, ++ struct dentry *d2, struct au_hinode *hdir2); ++ ++int vfsub_create(struct inode *dir, struct path *path, int mode); ++int vfsub_symlink(struct inode *dir, struct path *path, ++ const char *symname); ++int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev); ++int vfsub_link(struct dentry *src_dentry, struct inode *dir, ++ struct path *path); ++int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry, ++ struct inode *hdir, struct path *path); ++int vfsub_mkdir(struct inode *dir, struct path *path, int mode); ++int vfsub_rmdir(struct inode *dir, struct path *path); ++ ++/* ---------------------------------------------------------------------- */ ++ ++ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, ++ loff_t *ppos); ++ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, ++ loff_t *ppos); ++ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, ++ loff_t *ppos); ++ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, ++ loff_t *ppos); ++int vfsub_readdir(struct file *file, filldir_t filldir, void *arg); ++ ++static inline void vfsub_file_accessed(struct file *h_file) ++{ ++ file_accessed(h_file); ++ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/ ++} ++ ++static inline void vfsub_touch_atime(struct vfsmount *h_mnt, ++ struct dentry *h_dentry) ++{ ++ struct path h_path = { ++ .dentry = h_dentry, ++ .mnt = h_mnt ++ }; ++ touch_atime(h_mnt, h_dentry); ++ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/ ++} ++ ++long vfsub_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags); ++long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags); ++int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr, ++ struct file *h_file); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin) ++{ ++ loff_t err; ++ ++ lockdep_off(); ++ err = vfs_llseek(file, offset, origin); ++ lockdep_on(); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* dirty workaround for strict type of fmode_t */ ++union vfsub_fmu { ++ fmode_t fm; ++ unsigned int ui; ++}; ++ ++static inline unsigned int vfsub_fmode_to_uint(fmode_t fm) ++{ ++ union vfsub_fmu u = { ++ .fm = fm ++ }; ++ ++ BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui)); ++ ++ return u.ui; ++} ++ ++static inline fmode_t vfsub_uint_to_fmode(unsigned int ui) ++{ ++ union vfsub_fmu u = { ++ .ui = ui ++ }; ++ ++ return u.fm; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode); ++int vfsub_sio_rmdir(struct inode *dir, struct path *path); ++int vfsub_sio_notify_change(struct path *path, struct iattr *ia); ++int vfsub_notify_change(struct path *path, struct iattr *ia); ++int vfsub_unlink(struct inode *dir, struct path *path, int force); ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_VFSUB_H__ */ +diff -Naur a/fs/aufs/wbr_policy.c b/fs/aufs/wbr_policy.c +--- a/fs/aufs/wbr_policy.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/wbr_policy.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,637 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * policies for selecting one among multiple writable branches ++ */ ++ ++#include ++#include "aufs.h" ++ ++/* subset of cpup_attr() */ ++static noinline_for_stack ++int au_cpdown_attr(struct path *h_path, struct dentry *h_src) ++{ ++ int err, sbits; ++ struct iattr ia; ++ struct inode *h_isrc; ++ ++ h_isrc = h_src->d_inode; ++ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID; ++ ia.ia_mode = h_isrc->i_mode; ++ ia.ia_uid = h_isrc->i_uid; ++ ia.ia_gid = h_isrc->i_gid; ++ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID)); ++ au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc); ++ err = vfsub_sio_notify_change(h_path, &ia); ++ ++ /* is this nfs only? */ ++ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) { ++ ia.ia_valid = ATTR_FORCE | ATTR_MODE; ++ ia.ia_mode = h_isrc->i_mode; ++ err = vfsub_sio_notify_change(h_path, &ia); ++ } ++ ++ return err; ++} ++ ++#define AuCpdown_PARENT_OPQ 1 ++#define AuCpdown_WHED (1 << 1) ++#define AuCpdown_MADE_DIR (1 << 2) ++#define AuCpdown_DIROPQ (1 << 3) ++#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name) ++#define au_fset_cpdown(flags, name) { (flags) |= AuCpdown_##name; } ++#define au_fclr_cpdown(flags, name) { (flags) &= ~AuCpdown_##name; } ++ ++struct au_cpdown_dir_args { ++ struct dentry *parent; ++ unsigned int flags; ++}; ++ ++static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst, ++ struct au_cpdown_dir_args *a) ++{ ++ int err; ++ struct dentry *opq_dentry; ++ ++ opq_dentry = au_diropq_create(dentry, bdst); ++ err = PTR_ERR(opq_dentry); ++ if (IS_ERR(opq_dentry)) ++ goto out; ++ dput(opq_dentry); ++ au_fset_cpdown(a->flags, DIROPQ); ++ ++ out: ++ return err; ++} ++ ++static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent, ++ struct inode *dir, aufs_bindex_t bdst) ++{ ++ int err; ++ struct path h_path; ++ struct au_branch *br; ++ ++ br = au_sbr(dentry->d_sb, bdst); ++ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br); ++ err = PTR_ERR(h_path.dentry); ++ if (IS_ERR(h_path.dentry)) ++ goto out; ++ ++ err = 0; ++ if (h_path.dentry->d_inode) { ++ h_path.mnt = br->br_mnt; ++ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path, ++ dentry); ++ } ++ dput(h_path.dentry); ++ ++ out: ++ return err; ++} ++ ++static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst, ++ struct dentry *h_parent, void *arg) ++{ ++ int err, rerr; ++ aufs_bindex_t bend, bopq, bstart; ++ unsigned char parent_opq; ++ struct path h_path; ++ struct dentry *parent; ++ struct inode *h_dir, *h_inode, *inode, *dir; ++ struct au_cpdown_dir_args *args = arg; ++ ++ bstart = au_dbstart(dentry); ++ /* dentry is di-locked */ ++ parent = dget_parent(dentry); ++ dir = parent->d_inode; ++ h_dir = h_parent->d_inode; ++ AuDebugOn(h_dir != au_h_iptr(dir, bdst)); ++ IMustLock(h_dir); ++ ++ err = au_lkup_neg(dentry, bdst); ++ if (unlikely(err < 0)) ++ goto out; ++ h_path.dentry = au_h_dptr(dentry, bdst); ++ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst); ++ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path, ++ S_IRWXU | S_IRUGO | S_IXUGO); ++ if (unlikely(err)) ++ goto out_put; ++ au_fset_cpdown(args->flags, MADE_DIR); ++ ++ bend = au_dbend(dentry); ++ bopq = au_dbdiropq(dentry); ++ au_fclr_cpdown(args->flags, WHED); ++ au_fclr_cpdown(args->flags, DIROPQ); ++ if (au_dbwh(dentry) == bdst) ++ au_fset_cpdown(args->flags, WHED); ++ if (!au_ftest_cpdown(args->flags, PARENT_OPQ) && bopq <= bdst) ++ au_fset_cpdown(args->flags, PARENT_OPQ); ++ parent_opq = (au_ftest_cpdown(args->flags, PARENT_OPQ) ++ && args->parent == dentry); ++ h_inode = h_path.dentry->d_inode; ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ if (au_ftest_cpdown(args->flags, WHED)) { ++ err = au_cpdown_dir_opq(dentry, bdst, args); ++ if (unlikely(err)) { ++ mutex_unlock(&h_inode->i_mutex); ++ goto out_dir; ++ } ++ } ++ ++ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart)); ++ mutex_unlock(&h_inode->i_mutex); ++ if (unlikely(err)) ++ goto out_opq; ++ ++ if (au_ftest_cpdown(args->flags, WHED)) { ++ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst); ++ if (unlikely(err)) ++ goto out_opq; ++ } ++ ++ inode = dentry->d_inode; ++ if (au_ibend(inode) < bdst) ++ au_set_ibend(inode, bdst); ++ au_set_h_iptr(inode, bdst, au_igrab(h_inode), ++ au_hi_flags(inode, /*isdir*/1)); ++ goto out; /* success */ ++ ++ /* revert */ ++ out_opq: ++ if (au_ftest_cpdown(args->flags, DIROPQ)) { ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ rerr = au_diropq_remove(dentry, bdst); ++ mutex_unlock(&h_inode->i_mutex); ++ if (unlikely(rerr)) { ++ AuIOErr("failed removing diropq for %.*s b%d (%d)\n", ++ AuDLNPair(dentry), bdst, rerr); ++ err = -EIO; ++ goto out; ++ } ++ } ++ out_dir: ++ if (au_ftest_cpdown(args->flags, MADE_DIR)) { ++ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path); ++ if (unlikely(rerr)) { ++ AuIOErr("failed removing %.*s b%d (%d)\n", ++ AuDLNPair(dentry), bdst, rerr); ++ err = -EIO; ++ } ++ } ++ out_put: ++ au_set_h_dptr(dentry, bdst, NULL); ++ if (au_dbend(dentry) == bdst) ++ au_update_dbend(dentry); ++ out: ++ dput(parent); ++ return err; ++} ++ ++int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst) ++{ ++ int err; ++ struct au_cpdown_dir_args args = { ++ .parent = dget_parent(dentry), ++ .flags = 0 ++ }; ++ ++ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &args); ++ dput(args.parent); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* policies for create */ ++ ++static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ for (; bindex >= 0; bindex--) ++ if (!au_br_rdonly(au_sbr(sb, bindex))) ++ return bindex; ++ return -EROFS; ++} ++ ++/* top down parent */ ++static int au_wbr_create_tdp(struct dentry *dentry, int isdir __maybe_unused) ++{ ++ int err; ++ aufs_bindex_t bstart, bindex; ++ struct super_block *sb; ++ struct dentry *parent, *h_parent; ++ ++ sb = dentry->d_sb; ++ bstart = au_dbstart(dentry); ++ err = bstart; ++ if (!au_br_rdonly(au_sbr(sb, bstart))) ++ goto out; ++ ++ err = -EROFS; ++ parent = dget_parent(dentry); ++ for (bindex = au_dbstart(parent); bindex < bstart; bindex++) { ++ h_parent = au_h_dptr(parent, bindex); ++ if (!h_parent || !h_parent->d_inode) ++ continue; ++ ++ if (!au_br_rdonly(au_sbr(sb, bindex))) { ++ err = bindex; ++ break; ++ } ++ } ++ dput(parent); ++ ++ /* bottom up here */ ++ if (unlikely(err < 0)) ++ err = au_wbr_bu(sb, bstart - 1); ++ ++ out: ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* an exception for the policy other than tdp */ ++static int au_wbr_create_exp(struct dentry *dentry) ++{ ++ int err; ++ aufs_bindex_t bwh, bdiropq; ++ struct dentry *parent; ++ ++ err = -1; ++ bwh = au_dbwh(dentry); ++ parent = dget_parent(dentry); ++ bdiropq = au_dbdiropq(parent); ++ if (bwh >= 0) { ++ if (bdiropq >= 0) ++ err = min(bdiropq, bwh); ++ else ++ err = bwh; ++ AuDbg("%d\n", err); ++ } else if (bdiropq >= 0) { ++ err = bdiropq; ++ AuDbg("%d\n", err); ++ } ++ dput(parent); ++ ++ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err))) ++ err = -1; ++ ++ AuDbg("%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* round robin */ ++static int au_wbr_create_init_rr(struct super_block *sb) ++{ ++ int err; ++ ++ err = au_wbr_bu(sb, au_sbend(sb)); ++ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */ ++ ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++static int au_wbr_create_rr(struct dentry *dentry, int isdir) ++{ ++ int err, nbr; ++ unsigned int u; ++ aufs_bindex_t bindex, bend; ++ struct super_block *sb; ++ atomic_t *next; ++ ++ err = au_wbr_create_exp(dentry); ++ if (err >= 0) ++ goto out; ++ ++ sb = dentry->d_sb; ++ next = &au_sbi(sb)->si_wbr_rr_next; ++ bend = au_sbend(sb); ++ nbr = bend + 1; ++ for (bindex = 0; bindex <= bend; bindex++) { ++ if (!isdir) { ++ err = atomic_dec_return(next) + 1; ++ /* modulo for 0 is meaningless */ ++ if (unlikely(!err)) ++ err = atomic_dec_return(next) + 1; ++ } else ++ err = atomic_read(next); ++ AuDbg("%d\n", err); ++ u = err; ++ err = u % nbr; ++ AuDbg("%d\n", err); ++ if (!au_br_rdonly(au_sbr(sb, err))) ++ break; ++ err = -EROFS; ++ } ++ ++ out: ++ AuDbg("%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* most free space */ ++static void au_mfs(struct dentry *dentry) ++{ ++ struct super_block *sb; ++ struct au_branch *br; ++ struct au_wbr_mfs *mfs; ++ aufs_bindex_t bindex, bend; ++ int err; ++ unsigned long long b, bavail; ++ /* reduce the stack usage */ ++ struct kstatfs *st; ++ ++ st = kmalloc(sizeof(*st), GFP_NOFS); ++ if (unlikely(!st)) { ++ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM); ++ return; ++ } ++ ++ bavail = 0; ++ sb = dentry->d_sb; ++ mfs = &au_sbi(sb)->si_wbr_mfs; ++ mfs->mfs_bindex = -EROFS; ++ mfs->mfsrr_bytes = 0; ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (au_br_rdonly(br)) ++ continue; ++ ++ /* sb->s_root for NFS is unreliable */ ++ err = vfs_statfs(br->br_mnt->mnt_root, st); ++ if (unlikely(err)) { ++ AuWarn1("failed statfs, b%d, %d\n", bindex, err); ++ continue; ++ } ++ ++ /* when the available size is equal, select the lower one */ ++ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail) ++ || sizeof(b) < sizeof(st->f_bsize)); ++ b = st->f_bavail * st->f_bsize; ++ br->br_wbr->wbr_bytes = b; ++ if (b >= bavail) { ++ bavail = b; ++ mfs->mfs_bindex = bindex; ++ mfs->mfs_jiffy = jiffies; ++ } ++ } ++ ++ mfs->mfsrr_bytes = bavail; ++ AuDbg("b%d\n", mfs->mfs_bindex); ++ kfree(st); ++} ++ ++static int au_wbr_create_mfs(struct dentry *dentry, int isdir __maybe_unused) ++{ ++ int err; ++ struct super_block *sb; ++ struct au_wbr_mfs *mfs; ++ ++ err = au_wbr_create_exp(dentry); ++ if (err >= 0) ++ goto out; ++ ++ sb = dentry->d_sb; ++ mfs = &au_sbi(sb)->si_wbr_mfs; ++ mutex_lock(&mfs->mfs_lock); ++ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire) ++ || mfs->mfs_bindex < 0 ++ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex))) ++ au_mfs(dentry); ++ mutex_unlock(&mfs->mfs_lock); ++ err = mfs->mfs_bindex; ++ ++ out: ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++static int au_wbr_create_init_mfs(struct super_block *sb) ++{ ++ struct au_wbr_mfs *mfs; ++ ++ mfs = &au_sbi(sb)->si_wbr_mfs; ++ mutex_init(&mfs->mfs_lock); ++ mfs->mfs_jiffy = 0; ++ mfs->mfs_bindex = -EROFS; ++ ++ return 0; ++} ++ ++static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused) ++{ ++ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock); ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* most free space and then round robin */ ++static int au_wbr_create_mfsrr(struct dentry *dentry, int isdir) ++{ ++ int err; ++ struct au_wbr_mfs *mfs; ++ ++ err = au_wbr_create_mfs(dentry, isdir); ++ if (err >= 0) { ++ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs; ++ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark) ++ err = au_wbr_create_rr(dentry, isdir); ++ } ++ ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++static int au_wbr_create_init_mfsrr(struct super_block *sb) ++{ ++ int err; ++ ++ au_wbr_create_init_mfs(sb); /* ignore */ ++ err = au_wbr_create_init_rr(sb); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* top down parent and most free space */ ++static int au_wbr_create_pmfs(struct dentry *dentry, int isdir) ++{ ++ int err, e2; ++ unsigned long long b; ++ aufs_bindex_t bindex, bstart, bend; ++ struct super_block *sb; ++ struct dentry *parent, *h_parent; ++ struct au_branch *br; ++ ++ err = au_wbr_create_tdp(dentry, isdir); ++ if (unlikely(err < 0)) ++ goto out; ++ parent = dget_parent(dentry); ++ bstart = au_dbstart(parent); ++ bend = au_dbtaildir(parent); ++ if (bstart == bend) ++ goto out_parent; /* success */ ++ ++ e2 = au_wbr_create_mfs(dentry, isdir); ++ if (e2 < 0) ++ goto out_parent; /* success */ ++ ++ /* when the available size is equal, select upper one */ ++ sb = dentry->d_sb; ++ br = au_sbr(sb, err); ++ b = br->br_wbr->wbr_bytes; ++ AuDbg("b%d, %llu\n", err, b); ++ ++ for (bindex = bstart; bindex <= bend; bindex++) { ++ h_parent = au_h_dptr(parent, bindex); ++ if (!h_parent || !h_parent->d_inode) ++ continue; ++ ++ br = au_sbr(sb, bindex); ++ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) { ++ b = br->br_wbr->wbr_bytes; ++ err = bindex; ++ AuDbg("b%d, %llu\n", err, b); ++ } ++ } ++ ++ out_parent: ++ dput(parent); ++ out: ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* policies for copyup */ ++ ++/* top down parent */ ++static int au_wbr_copyup_tdp(struct dentry *dentry) ++{ ++ return au_wbr_create_tdp(dentry, /*isdir, anything is ok*/0); ++} ++ ++/* bottom up parent */ ++static int au_wbr_copyup_bup(struct dentry *dentry) ++{ ++ int err; ++ aufs_bindex_t bindex, bstart; ++ struct dentry *parent, *h_parent; ++ struct super_block *sb; ++ ++ err = -EROFS; ++ sb = dentry->d_sb; ++ parent = dget_parent(dentry); ++ bstart = au_dbstart(parent); ++ for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) { ++ h_parent = au_h_dptr(parent, bindex); ++ if (!h_parent || !h_parent->d_inode) ++ continue; ++ ++ if (!au_br_rdonly(au_sbr(sb, bindex))) { ++ err = bindex; ++ break; ++ } ++ } ++ dput(parent); ++ ++ /* bottom up here */ ++ if (unlikely(err < 0)) ++ err = au_wbr_bu(sb, bstart - 1); ++ ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++/* bottom up */ ++static int au_wbr_copyup_bu(struct dentry *dentry) ++{ ++ int err; ++ ++ err = au_wbr_bu(dentry->d_sb, au_dbstart(dentry)); ++ ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_wbr_copyup_operations au_wbr_copyup_ops[] = { ++ [AuWbrCopyup_TDP] = { ++ .copyup = au_wbr_copyup_tdp ++ }, ++ [AuWbrCopyup_BUP] = { ++ .copyup = au_wbr_copyup_bup ++ }, ++ [AuWbrCopyup_BU] = { ++ .copyup = au_wbr_copyup_bu ++ } ++}; ++ ++struct au_wbr_create_operations au_wbr_create_ops[] = { ++ [AuWbrCreate_TDP] = { ++ .create = au_wbr_create_tdp ++ }, ++ [AuWbrCreate_RR] = { ++ .create = au_wbr_create_rr, ++ .init = au_wbr_create_init_rr ++ }, ++ [AuWbrCreate_MFS] = { ++ .create = au_wbr_create_mfs, ++ .init = au_wbr_create_init_mfs, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_MFSV] = { ++ .create = au_wbr_create_mfs, ++ .init = au_wbr_create_init_mfs, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_MFSRR] = { ++ .create = au_wbr_create_mfsrr, ++ .init = au_wbr_create_init_mfsrr, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_MFSRRV] = { ++ .create = au_wbr_create_mfsrr, ++ .init = au_wbr_create_init_mfsrr, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_PMFS] = { ++ .create = au_wbr_create_pmfs, ++ .init = au_wbr_create_init_mfs, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_PMFSV] = { ++ .create = au_wbr_create_pmfs, ++ .init = au_wbr_create_init_mfs, ++ .fin = au_wbr_create_fin_mfs ++ } ++}; +diff -Naur a/fs/aufs/whout.c b/fs/aufs/whout.c +--- a/fs/aufs/whout.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/whout.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,1042 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * whiteout for logical deletion and opaque directory ++ */ ++ ++#include ++#include "aufs.h" ++ ++#define WH_MASK S_IRUGO ++ ++/* ++ * If a directory contains this file, then it is opaque. We start with the ++ * .wh. flag so that it is blocked by lookup. ++ */ ++static struct qstr diropq_name = { ++ .name = AUFS_WH_DIROPQ, ++ .len = sizeof(AUFS_WH_DIROPQ) - 1 ++}; ++ ++/* ++ * generate whiteout name, which is NOT terminated by NULL. ++ * @name: original d_name.name ++ * @len: original d_name.len ++ * @wh: whiteout qstr ++ * returns zero when succeeds, otherwise error. ++ * succeeded value as wh->name should be freed by kfree(). ++ */ ++int au_wh_name_alloc(struct qstr *wh, const struct qstr *name) ++{ ++ char *p; ++ ++ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN)) ++ return -ENAMETOOLONG; ++ ++ wh->len = name->len + AUFS_WH_PFX_LEN; ++ p = kmalloc(wh->len, GFP_NOFS); ++ wh->name = p; ++ if (p) { ++ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); ++ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len); ++ /* smp_mb(); */ ++ return 0; ++ } ++ return -ENOMEM; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * test if the @wh_name exists under @h_parent. ++ * @try_sio specifies the necessary of super-io. ++ */ ++int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, ++ struct au_branch *br, int try_sio) ++{ ++ int err; ++ struct dentry *wh_dentry; ++ struct inode *h_dir; ++ ++ h_dir = h_parent->d_inode; ++ if (!try_sio) ++ wh_dentry = au_lkup_one(wh_name, h_parent, br, /*nd*/NULL); ++ else ++ wh_dentry = au_sio_lkup_one(wh_name, h_parent, br); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out; ++ ++ err = 0; ++ if (!wh_dentry->d_inode) ++ goto out_wh; /* success */ ++ ++ err = 1; ++ if (S_ISREG(wh_dentry->d_inode->i_mode)) ++ goto out_wh; /* success */ ++ ++ err = -EIO; ++ AuIOErr("%.*s Invalid whiteout entry type 0%o.\n", ++ AuDLNPair(wh_dentry), wh_dentry->d_inode->i_mode); ++ ++ out_wh: ++ dput(wh_dentry); ++ out: ++ return err; ++} ++ ++/* ++ * test if the @h_dentry sets opaque or not. ++ */ ++int au_diropq_test(struct dentry *h_dentry, struct au_branch *br) ++{ ++ int err; ++ struct inode *h_dir; ++ ++ h_dir = h_dentry->d_inode; ++ err = au_wh_test(h_dentry, &diropq_name, br, ++ au_test_h_perm_sio(h_dir, MAY_EXEC)); ++ return err; ++} ++ ++/* ++ * returns a negative dentry whose name is unique and temporary. ++ */ ++struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br, ++ struct qstr *prefix) ++{ ++#define HEX_LEN 4 ++ struct dentry *dentry; ++ int i; ++ char defname[AUFS_WH_PFX_LEN * 2 + DNAME_INLINE_LEN_MIN + 1 ++ + HEX_LEN + 1], *name, *p; ++ static unsigned short cnt; ++ struct qstr qs; ++ ++ name = defname; ++ qs.len = sizeof(defname) - DNAME_INLINE_LEN_MIN + prefix->len - 1; ++ if (unlikely(prefix->len > DNAME_INLINE_LEN_MIN)) { ++ dentry = ERR_PTR(-ENAMETOOLONG); ++ if (unlikely(qs.len >= PATH_MAX)) ++ goto out; ++ dentry = ERR_PTR(-ENOMEM); ++ name = kmalloc(qs.len + 1, GFP_NOFS); ++ if (unlikely(!name)) ++ goto out; ++ } ++ ++ /* doubly whiteout-ed */ ++ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2); ++ p = name + AUFS_WH_PFX_LEN * 2; ++ memcpy(p, prefix->name, prefix->len); ++ p += prefix->len; ++ *p++ = '.'; ++ AuDebugOn(name + qs.len + 1 - p <= HEX_LEN); ++ ++ qs.name = name; ++ for (i = 0; i < 3; i++) { ++ sprintf(p, "%.*d", HEX_LEN, cnt++); ++ dentry = au_sio_lkup_one(&qs, h_parent, br); ++ if (IS_ERR(dentry) || !dentry->d_inode) ++ goto out_name; ++ dput(dentry); ++ } ++ /* AuWarn("could not get random name\n"); */ ++ dentry = ERR_PTR(-EEXIST); ++ AuDbg("%.*s\n", AuLNPair(&qs)); ++ BUG(); ++ ++ out_name: ++ if (name != defname) ++ kfree(name); ++ out: ++ return dentry; ++#undef HEX_LEN ++} ++ ++/* ++ * rename the @h_dentry on @br to the whiteouted temporary name. ++ */ ++int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br) ++{ ++ int err; ++ struct path h_path = { ++ .mnt = br->br_mnt ++ }; ++ struct inode *h_dir; ++ struct dentry *h_parent; ++ ++ h_parent = h_dentry->d_parent; /* dir inode is locked */ ++ h_dir = h_parent->d_inode; ++ IMustLock(h_dir); ++ ++ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name); ++ err = PTR_ERR(h_path.dentry); ++ if (IS_ERR(h_path.dentry)) ++ goto out; ++ ++ /* under the same dir, no need to lock_rename() */ ++ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path); ++ AuTraceErr(err); ++ dput(h_path.dentry); ++ ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* ++ * functions for removing a whiteout ++ */ ++ ++static int do_unlink_wh(struct inode *h_dir, struct path *h_path) ++{ ++ int force; ++ ++ /* ++ * forces superio when the dir has a sticky bit. ++ * this may be a violation of unix fs semantics. ++ */ ++ force = (h_dir->i_mode & S_ISVTX) ++ && h_path->dentry->d_inode->i_uid != current_fsuid(); ++ return vfsub_unlink(h_dir, h_path, force); ++} ++ ++int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path, ++ struct dentry *dentry) ++{ ++ int err; ++ ++ err = do_unlink_wh(h_dir, h_path); ++ if (!err && dentry) ++ au_set_dbwh(dentry, -1); ++ ++ return err; ++} ++ ++static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh, ++ struct au_branch *br) ++{ ++ int err; ++ struct path h_path = { ++ .mnt = br->br_mnt ++ }; ++ ++ err = 0; ++ h_path.dentry = au_lkup_one(wh, h_parent, br, /*nd*/NULL); ++ if (IS_ERR(h_path.dentry)) ++ err = PTR_ERR(h_path.dentry); ++ else { ++ if (h_path.dentry->d_inode ++ && S_ISREG(h_path.dentry->d_inode->i_mode)) ++ err = do_unlink_wh(h_parent->d_inode, &h_path); ++ dput(h_path.dentry); ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* ++ * initialize/clean whiteout for a branch ++ */ ++ ++static void au_wh_clean(struct inode *h_dir, struct path *whpath, ++ const int isdir) ++{ ++ int err; ++ ++ if (!whpath->dentry->d_inode) ++ return; ++ ++ err = mnt_want_write(whpath->mnt); ++ if (!err) { ++ if (isdir) ++ err = vfsub_rmdir(h_dir, whpath); ++ else ++ err = vfsub_unlink(h_dir, whpath, /*force*/0); ++ mnt_drop_write(whpath->mnt); ++ } ++ if (unlikely(err)) ++ AuWarn("failed removing %.*s (%d), ignored.\n", ++ AuDLNPair(whpath->dentry), err); ++} ++ ++static int test_linkable(struct dentry *h_root) ++{ ++ struct inode *h_dir = h_root->d_inode; ++ ++ if (h_dir->i_op->link) ++ return 0; ++ ++ AuErr("%.*s (%s) doesn't support link(2), use noplink and rw+nolwh\n", ++ AuDLNPair(h_root), au_sbtype(h_root->d_sb)); ++ return -ENOSYS; ++} ++ ++/* todo: should this mkdir be done in /sbin/mount.aufs helper? */ ++static int au_whdir(struct inode *h_dir, struct path *path) ++{ ++ int err; ++ ++ err = -EEXIST; ++ if (!path->dentry->d_inode) { ++ int mode = S_IRWXU; ++ ++ if (au_test_nfs(path->dentry->d_sb)) ++ mode |= S_IXUGO; ++ err = mnt_want_write(path->mnt); ++ if (!err) { ++ err = vfsub_mkdir(h_dir, path, mode); ++ mnt_drop_write(path->mnt); ++ } ++ } else if (S_ISDIR(path->dentry->d_inode->i_mode)) ++ err = 0; ++ else ++ AuErr("unknown %.*s exists\n", AuDLNPair(path->dentry)); ++ ++ return err; ++} ++ ++struct au_wh_base { ++ const struct qstr *name; ++ struct dentry *dentry; ++}; ++ ++static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[], ++ struct path *h_path) ++{ ++ h_path->dentry = base[AuBrWh_BASE].dentry; ++ au_wh_clean(h_dir, h_path, /*isdir*/0); ++ h_path->dentry = base[AuBrWh_PLINK].dentry; ++ au_wh_clean(h_dir, h_path, /*isdir*/1); ++ h_path->dentry = base[AuBrWh_ORPH].dentry; ++ au_wh_clean(h_dir, h_path, /*isdir*/1); ++} ++ ++/* ++ * returns tri-state, ++ * minus: error, caller should print the mesage ++ * zero: succuess ++ * plus: error, caller should NOT print the mesage ++ */ ++static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr, ++ int do_plink, struct au_wh_base base[], ++ struct path *h_path) ++{ ++ int err; ++ struct inode *h_dir; ++ ++ h_dir = h_root->d_inode; ++ h_path->dentry = base[AuBrWh_BASE].dentry; ++ au_wh_clean(h_dir, h_path, /*isdir*/0); ++ h_path->dentry = base[AuBrWh_PLINK].dentry; ++ if (do_plink) { ++ err = test_linkable(h_root); ++ if (unlikely(err)) { ++ err = 1; ++ goto out; ++ } ++ ++ err = au_whdir(h_dir, h_path); ++ if (unlikely(err)) ++ goto out; ++ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry); ++ } else ++ au_wh_clean(h_dir, h_path, /*isdir*/1); ++ h_path->dentry = base[AuBrWh_ORPH].dentry; ++ err = au_whdir(h_dir, h_path); ++ if (unlikely(err)) ++ goto out; ++ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry); ++ ++ out: ++ return err; ++} ++ ++/* ++ * for the moment, aufs supports the branch filesystem which does not support ++ * link(2). testing on FAT which does not support i_op->setattr() fully either, ++ * copyup failed. finally, such filesystem will not be used as the writable ++ * branch. ++ * ++ * returns tri-state, see above. ++ */ ++static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr, ++ int do_plink, struct au_wh_base base[], ++ struct path *h_path) ++{ ++ int err; ++ struct inode *h_dir; ++ ++ err = test_linkable(h_root); ++ if (unlikely(err)) { ++ err = 1; ++ goto out; ++ } ++ ++ /* ++ * todo: should this create be done in /sbin/mount.aufs helper? ++ */ ++ err = -EEXIST; ++ h_dir = h_root->d_inode; ++ if (!base[AuBrWh_BASE].dentry->d_inode) { ++ err = mnt_want_write(h_path->mnt); ++ if (!err) { ++ h_path->dentry = base[AuBrWh_BASE].dentry; ++ err = vfsub_create(h_dir, h_path, WH_MASK); ++ mnt_drop_write(h_path->mnt); ++ } ++ } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode)) ++ err = 0; ++ else ++ AuErr("unknown %.*s/%.*s exists\n", ++ AuDLNPair(h_root), AuDLNPair(base[AuBrWh_BASE].dentry)); ++ if (unlikely(err)) ++ goto out; ++ ++ h_path->dentry = base[AuBrWh_PLINK].dentry; ++ if (do_plink) { ++ err = au_whdir(h_dir, h_path); ++ if (unlikely(err)) ++ goto out; ++ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry); ++ } else ++ au_wh_clean(h_dir, h_path, /*isdir*/1); ++ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry); ++ ++ h_path->dentry = base[AuBrWh_ORPH].dentry; ++ err = au_whdir(h_dir, h_path); ++ if (unlikely(err)) ++ goto out; ++ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry); ++ ++ out: ++ return err; ++} ++ ++/* ++ * initialize the whiteout base file/dir for @br. ++ */ ++int au_wh_init(struct dentry *h_root, struct au_branch *br, ++ struct super_block *sb) ++{ ++ int err, i; ++ const unsigned char do_plink ++ = !!au_opt_test(au_mntflags(sb), PLINK); ++ struct path path = { ++ .mnt = br->br_mnt ++ }; ++ struct inode *h_dir; ++ struct au_wbr *wbr = br->br_wbr; ++ static const struct qstr base_name[] = { ++ [AuBrWh_BASE] = { ++ .name = AUFS_BASE_NAME, ++ .len = sizeof(AUFS_BASE_NAME) - 1 ++ }, ++ [AuBrWh_PLINK] = { ++ .name = AUFS_PLINKDIR_NAME, ++ .len = sizeof(AUFS_PLINKDIR_NAME) - 1 ++ }, ++ [AuBrWh_ORPH] = { ++ .name = AUFS_ORPHDIR_NAME, ++ .len = sizeof(AUFS_ORPHDIR_NAME) - 1 ++ } ++ }; ++ struct au_wh_base base[] = { ++ [AuBrWh_BASE] = { ++ .name = base_name + AuBrWh_BASE, ++ .dentry = NULL ++ }, ++ [AuBrWh_PLINK] = { ++ .name = base_name + AuBrWh_PLINK, ++ .dentry = NULL ++ }, ++ [AuBrWh_ORPH] = { ++ .name = base_name + AuBrWh_ORPH, ++ .dentry = NULL ++ } ++ }; ++ ++ ++ h_dir = h_root->d_inode; ++ for (i = 0; i < AuBrWh_Last; i++) { ++ /* doubly whiteouted */ ++ struct dentry *d; ++ ++ d = au_wh_lkup(h_root, (void *)base[i].name, br); ++ err = PTR_ERR(d); ++ if (IS_ERR(d)) ++ goto out; ++ ++ base[i].dentry = d; ++ AuDebugOn(wbr ++ && wbr->wbr_wh[i] ++ && wbr->wbr_wh[i] != base[i].dentry); ++ } ++ ++ if (wbr) ++ for (i = 0; i < AuBrWh_Last; i++) { ++ dput(wbr->wbr_wh[i]); ++ wbr->wbr_wh[i] = NULL; ++ } ++ ++ err = 0; ++ ++ switch (br->br_perm) { ++ case AuBrPerm_RO: ++ case AuBrPerm_ROWH: ++ case AuBrPerm_RR: ++ case AuBrPerm_RRWH: ++ au_wh_init_ro(h_dir, base, &path); ++ break; ++ ++ case AuBrPerm_RWNoLinkWH: ++ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path); ++ if (err > 0) ++ goto out; ++ else if (err) ++ goto out_err; ++ break; ++ ++ case AuBrPerm_RW: ++ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path); ++ if (err > 0) ++ goto out; ++ else if (err) ++ goto out_err; ++ break; ++ ++ default: ++ BUG(); ++ } ++ goto out; /* success */ ++ ++ out_err: ++ AuErr("an error(%d) on the writable branch %.*s(%s)\n", ++ err, AuDLNPair(h_root), au_sbtype(h_root->d_sb)); ++ out: ++ for (i = 0; i < AuBrWh_Last; i++) ++ dput(base[i].dentry); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* ++ * whiteouts are all hard-linked usually. ++ * when its link count reaches a ceiling, we create a new whiteout base ++ * asynchronously. ++ */ ++ ++struct reinit_br_wh { ++ struct super_block *sb; ++ struct au_branch *br; ++}; ++ ++static void reinit_br_wh(void *arg) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ struct path h_path; ++ struct reinit_br_wh *a = arg; ++ struct au_wbr *wbr; ++ struct inode *dir; ++ struct dentry *h_root; ++ struct au_hinode *hdir; ++ ++ err = 0; ++ wbr = a->br->br_wbr; ++ /* big aufs lock */ ++ si_noflush_write_lock(a->sb); ++ if (!au_br_writable(a->br->br_perm)) ++ goto out; ++ bindex = au_br_index(a->sb, a->br->br_id); ++ if (unlikely(bindex < 0)) ++ goto out; ++ ++ dir = a->sb->s_root->d_inode; ++ /* ii_read_lock_parent(dir); */ ++ hdir = au_hi(dir, bindex); ++ h_root = au_h_dptr(a->sb->s_root, bindex); ++ ++ au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT); ++ wbr_wh_write_lock(wbr); ++ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode, ++ h_root, a->br); ++ if (!err) { ++ err = mnt_want_write(a->br->br_mnt); ++ if (!err) { ++ h_path.dentry = wbr->wbr_whbase; ++ h_path.mnt = a->br->br_mnt; ++ err = vfsub_unlink(hdir->hi_inode, &h_path, /*force*/0); ++ mnt_drop_write(a->br->br_mnt); ++ } ++ } else { ++ AuWarn("%.*s is moved, ignored\n", AuDLNPair(wbr->wbr_whbase)); ++ err = 0; ++ } ++ dput(wbr->wbr_whbase); ++ wbr->wbr_whbase = NULL; ++ if (!err) ++ err = au_wh_init(h_root, a->br, a->sb); ++ wbr_wh_write_unlock(wbr); ++ au_hin_imtx_unlock(hdir); ++ /* ii_read_unlock(dir); */ ++ ++ out: ++ if (wbr) ++ atomic_dec(&wbr->wbr_wh_running); ++ atomic_dec(&a->br->br_count); ++ au_nwt_done(&au_sbi(a->sb)->si_nowait); ++ si_write_unlock(a->sb); ++ kfree(arg); ++ if (unlikely(err)) ++ AuIOErr("err %d\n", err); ++} ++ ++static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br) ++{ ++ int do_dec, wkq_err; ++ struct reinit_br_wh *arg; ++ ++ do_dec = 1; ++ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1) ++ goto out; ++ ++ /* ignore ENOMEM */ ++ arg = kmalloc(sizeof(*arg), GFP_NOFS); ++ if (arg) { ++ /* ++ * dec(wh_running), kfree(arg) and dec(br_count) ++ * in reinit function ++ */ ++ arg->sb = sb; ++ arg->br = br; ++ atomic_inc(&br->br_count); ++ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb); ++ if (unlikely(wkq_err)) { ++ atomic_dec(&br->br_wbr->wbr_wh_running); ++ atomic_dec(&br->br_count); ++ kfree(arg); ++ } ++ do_dec = 0; ++ } ++ ++ out: ++ if (do_dec) ++ atomic_dec(&br->br_wbr->wbr_wh_running); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * create the whiteout @wh. ++ */ ++static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex, ++ struct dentry *wh) ++{ ++ int err; ++ struct path h_path = { ++ .dentry = wh ++ }; ++ struct au_branch *br; ++ struct au_wbr *wbr; ++ struct dentry *h_parent; ++ struct inode *h_dir; ++ ++ h_parent = wh->d_parent; /* dir inode is locked */ ++ h_dir = h_parent->d_inode; ++ IMustLock(h_dir); ++ ++ br = au_sbr(sb, bindex); ++ h_path.mnt = br->br_mnt; ++ wbr = br->br_wbr; ++ wbr_wh_read_lock(wbr); ++ if (wbr->wbr_whbase) { ++ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path); ++ if (!err || err != -EMLINK) ++ goto out; ++ ++ /* link count full. re-initialize br_whbase. */ ++ kick_reinit_br_wh(sb, br); ++ } ++ ++ /* return this error in this context */ ++ err = vfsub_create(h_dir, &h_path, WH_MASK); ++ ++ out: ++ wbr_wh_read_unlock(wbr); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * create or remove the diropq. ++ */ ++static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int flags) ++{ ++ struct dentry *opq_dentry, *h_dentry; ++ struct super_block *sb; ++ struct au_branch *br; ++ int err; ++ ++ sb = dentry->d_sb; ++ br = au_sbr(sb, bindex); ++ h_dentry = au_h_dptr(dentry, bindex); ++ opq_dentry = au_lkup_one(&diropq_name, h_dentry, br, /*nd*/NULL); ++ if (IS_ERR(opq_dentry)) ++ goto out; ++ ++ if (au_ftest_diropq(flags, CREATE)) { ++ err = link_or_create_wh(sb, bindex, opq_dentry); ++ if (!err) { ++ au_set_dbdiropq(dentry, bindex); ++ goto out; /* success */ ++ } ++ } else { ++ struct path tmp = { ++ .dentry = opq_dentry, ++ .mnt = br->br_mnt ++ }; ++ err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp); ++ if (!err) ++ au_set_dbdiropq(dentry, -1); ++ } ++ dput(opq_dentry); ++ opq_dentry = ERR_PTR(err); ++ ++ out: ++ return opq_dentry; ++} ++ ++struct do_diropq_args { ++ struct dentry **errp; ++ struct dentry *dentry; ++ aufs_bindex_t bindex; ++ unsigned int flags; ++}; ++ ++static void call_do_diropq(void *args) ++{ ++ struct do_diropq_args *a = args; ++ *a->errp = do_diropq(a->dentry, a->bindex, a->flags); ++} ++ ++struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int flags) ++{ ++ struct dentry *diropq, *h_dentry; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE)) ++ diropq = do_diropq(dentry, bindex, flags); ++ else { ++ int wkq_err; ++ struct do_diropq_args args = { ++ .errp = &diropq, ++ .dentry = dentry, ++ .bindex = bindex, ++ .flags = flags ++ }; ++ ++ wkq_err = au_wkq_wait(call_do_diropq, &args); ++ if (unlikely(wkq_err)) ++ diropq = ERR_PTR(wkq_err); ++ } ++ ++ return diropq; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * lookup whiteout dentry. ++ * @h_parent: lower parent dentry which must exist and be locked ++ * @base_name: name of dentry which will be whiteouted ++ * returns dentry for whiteout. ++ */ ++struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name, ++ struct au_branch *br) ++{ ++ int err; ++ struct qstr wh_name; ++ struct dentry *wh_dentry; ++ ++ err = au_wh_name_alloc(&wh_name, base_name); ++ wh_dentry = ERR_PTR(err); ++ if (!err) { ++ wh_dentry = au_lkup_one(&wh_name, h_parent, br, /*nd*/NULL); ++ kfree(wh_name.name); ++ } ++ return wh_dentry; ++} ++ ++/* ++ * link/create a whiteout for @dentry on @bindex. ++ */ ++struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent) ++{ ++ struct dentry *wh_dentry; ++ struct super_block *sb; ++ int err; ++ ++ sb = dentry->d_sb; ++ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex)); ++ if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) { ++ err = link_or_create_wh(sb, bindex, wh_dentry); ++ if (!err) ++ au_set_dbwh(dentry, bindex); ++ else { ++ dput(wh_dentry); ++ wh_dentry = ERR_PTR(err); ++ } ++ } ++ ++ return wh_dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* Delete all whiteouts in this directory on branch bindex. */ ++static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist, ++ aufs_bindex_t bindex, struct au_branch *br) ++{ ++ int err; ++ unsigned long ul, n; ++ struct qstr wh_name; ++ char *p; ++ struct hlist_head *head; ++ struct au_vdir_wh *tpos; ++ struct hlist_node *pos; ++ struct au_vdir_destr *str; ++ ++ err = -ENOMEM; ++ p = __getname(); ++ wh_name.name = p; ++ if (unlikely(!wh_name.name)) ++ goto out; ++ ++ err = 0; ++ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); ++ p += AUFS_WH_PFX_LEN; ++ n = whlist->nh_num; ++ head = whlist->nh_head; ++ for (ul = 0; !err && ul < n; ul++, head++) { ++ hlist_for_each_entry(tpos, pos, head, wh_hash) { ++ if (tpos->wh_bindex != bindex) ++ continue; ++ ++ str = &tpos->wh_str; ++ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) { ++ memcpy(p, str->name, str->len); ++ wh_name.len = AUFS_WH_PFX_LEN + str->len; ++ err = unlink_wh_name(h_dentry, &wh_name, br); ++ if (!err) ++ continue; ++ break; ++ } ++ AuIOErr("whiteout name too long %.*s\n", ++ str->len, str->name); ++ err = -EIO; ++ break; ++ } ++ } ++ __putname(wh_name.name); ++ ++ out: ++ return err; ++} ++ ++struct del_wh_children_args { ++ int *errp; ++ struct dentry *h_dentry; ++ struct au_nhash whlist; ++ aufs_bindex_t bindex; ++ struct au_branch *br; ++}; ++ ++static void call_del_wh_children(void *args) ++{ ++ struct del_wh_children_args *a = args; ++ *a->errp = del_wh_children(a->h_dentry, &a->whlist, a->bindex, a->br); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp) ++{ ++ struct au_whtmp_rmdir *whtmp; ++ int err; ++ ++ whtmp = kmalloc(sizeof(*whtmp), gfp); ++ if (unlikely(!whtmp)) { ++ whtmp = ERR_PTR(-ENOMEM); ++ goto out; ++ } ++ ++ whtmp->dir = NULL; ++ whtmp->wh_dentry = NULL; ++ err = au_nhash_alloc(&whtmp->whlist, au_sbi(sb)->si_rdhash, gfp); ++ if (!err) ++ return whtmp; /* success */ ++ ++ kfree(whtmp); ++ whtmp = ERR_PTR(err); ++ ++ out: ++ return whtmp; ++} ++ ++void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp) ++{ ++ dput(whtmp->wh_dentry); ++ iput(whtmp->dir); ++ au_nhash_wh_free(&whtmp->whlist); ++ kfree(whtmp); ++} ++ ++/* ++ * rmdir the whiteouted temporary named dir @h_dentry. ++ * @whlist: whiteouted children. ++ */ ++int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct au_nhash *whlist) ++{ ++ int err; ++ struct path h_tmp; ++ struct inode *wh_inode, *h_dir; ++ struct au_branch *br; ++ ++ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */ ++ IMustLock(h_dir); ++ ++ br = au_sbr(dir->i_sb, bindex); ++ wh_inode = wh_dentry->d_inode; ++ mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD); ++ ++ /* ++ * someone else might change some whiteouts while we were sleeping. ++ * it means this whlist may have an obsoleted entry. ++ */ ++ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE)) ++ err = del_wh_children(wh_dentry, whlist, bindex, br); ++ else { ++ int wkq_err; ++ struct del_wh_children_args args = { ++ .errp = &err, ++ .h_dentry = wh_dentry, ++ .whlist = *whlist, ++ .bindex = bindex, ++ .br = br ++ }; ++ ++ wkq_err = au_wkq_wait(call_del_wh_children, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ mutex_unlock(&wh_inode->i_mutex); ++ ++ if (!err) { ++ h_tmp.dentry = wh_dentry; ++ h_tmp.mnt = br->br_mnt; ++ err = vfsub_rmdir(h_dir, &h_tmp); ++ /* d_drop(h_dentry); */ ++ } ++ ++ if (!err) { ++ if (au_ibstart(dir) == bindex) { ++ au_cpup_attr_timesizes(dir); ++ drop_nlink(dir); ++ } ++ return 0; /* success */ ++ } ++ ++ AuWarn("failed removing %.*s(%d), ignored\n", ++ AuDLNPair(wh_dentry), err); ++ return err; ++} ++ ++static void call_rmdir_whtmp(void *args) ++{ ++ int err; ++ struct au_whtmp_rmdir *a = args; ++ struct super_block *sb; ++ struct dentry *h_parent; ++ struct inode *h_dir; ++ struct au_branch *br; ++ struct au_hinode *hdir; ++ ++ /* rmdir by nfsd may cause deadlock with this i_mutex */ ++ /* mutex_lock(&a->dir->i_mutex); */ ++ sb = a->dir->i_sb; ++ si_noflush_read_lock(sb); ++ err = au_test_ro(sb, a->bindex, NULL); ++ if (unlikely(err)) ++ goto out; ++ ++ err = -EIO; ++ br = au_sbr(sb, a->bindex); ++ ii_write_lock_parent(a->dir); ++ h_parent = dget_parent(a->wh_dentry); ++ h_dir = h_parent->d_inode; ++ hdir = au_hi(a->dir, a->bindex); ++ au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT); ++ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent, br); ++ if (!err) { ++ err = mnt_want_write(br->br_mnt); ++ if (!err) { ++ err = au_whtmp_rmdir(a->dir, a->bindex, a->wh_dentry, ++ &a->whlist); ++ mnt_drop_write(br->br_mnt); ++ } ++ } ++ au_hin_imtx_unlock(hdir); ++ dput(h_parent); ++ ii_write_unlock(a->dir); ++ ++ out: ++ /* mutex_unlock(&a->dir->i_mutex); */ ++ au_nwt_done(&au_sbi(sb)->si_nowait); ++ si_read_unlock(sb); ++ au_whtmp_rmdir_free(a); ++ if (unlikely(err)) ++ AuIOErr("err %d\n", err); ++} ++ ++void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct au_whtmp_rmdir *args) ++{ ++ int wkq_err; ++ ++ IMustLock(dir); ++ ++ /* all post-process will be done in do_rmdir_whtmp(). */ ++ args->dir = au_igrab(dir); ++ args->bindex = bindex; ++ args->wh_dentry = dget(wh_dentry); ++ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, dir->i_sb); ++ if (unlikely(wkq_err)) { ++ AuWarn("rmdir error %.*s (%d), ignored\n", ++ AuDLNPair(wh_dentry), wkq_err); ++ au_whtmp_rmdir_free(args); ++ } ++} +diff -Naur a/fs/aufs/whout.h b/fs/aufs/whout.h +--- a/fs/aufs/whout.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/whout.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,87 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * whiteout for logical deletion and opaque directory ++ */ ++ ++#ifndef __AUFS_WHOUT_H__ ++#define __AUFS_WHOUT_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include "dir.h" ++ ++/* whout.c */ ++int au_wh_name_alloc(struct qstr *wh, const struct qstr *name); ++struct au_branch; ++int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, ++ struct au_branch *br, int try_sio); ++int au_diropq_test(struct dentry *h_dentry, struct au_branch *br); ++struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br, ++ struct qstr *prefix); ++int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br); ++int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path, ++ struct dentry *dentry); ++int au_wh_init(struct dentry *h_parent, struct au_branch *br, ++ struct super_block *sb); ++ ++/* diropq flags */ ++#define AuDiropq_CREATE 1 ++#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name) ++#define au_fset_diropq(flags, name) { (flags) |= AuDiropq_##name; } ++#define au_fclr_diropq(flags, name) { (flags) &= ~AuDiropq_##name; } ++ ++struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int flags); ++struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name, ++ struct au_branch *br); ++struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent); ++ ++/* real rmdir for the whiteout-ed dir */ ++struct au_whtmp_rmdir { ++ struct inode *dir; ++ aufs_bindex_t bindex; ++ struct dentry *wh_dentry; ++ struct au_nhash whlist; ++}; ++ ++struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp); ++void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp); ++int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct au_nhash *whlist); ++void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct au_whtmp_rmdir *args); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct dentry *au_diropq_create(struct dentry *dentry, ++ aufs_bindex_t bindex) ++{ ++ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE); ++} ++ ++static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE)); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_WHOUT_H__ */ +diff -Naur a/fs/aufs/wkq.c b/fs/aufs/wkq.c +--- a/fs/aufs/wkq.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/wkq.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,259 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * workqueue for asynchronous/super-io operations ++ * todo: try new dredential scheme ++ */ ++ ++#include ++#include "aufs.h" ++ ++/* internal workqueue named AUFS_WKQ_NAME */ ++static struct au_wkq { ++ struct workqueue_struct *q; ++ ++ /* balancing */ ++ atomic_t busy; ++} *au_wkq; ++ ++struct au_wkinfo { ++ struct work_struct wk; ++ struct super_block *sb; ++ ++ unsigned int flags; /* see wkq.h */ ++ ++ au_wkq_func_t func; ++ void *args; ++ ++ atomic_t *busyp; ++ struct completion *comp; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int enqueue(struct au_wkq *wkq, struct au_wkinfo *wkinfo) ++{ ++ wkinfo->busyp = &wkq->busy; ++ if (au_ftest_wkq(wkinfo->flags, WAIT)) ++ return !queue_work(wkq->q, &wkinfo->wk); ++ else ++ return !schedule_work(&wkinfo->wk); ++} ++ ++static void do_wkq(struct au_wkinfo *wkinfo) ++{ ++ unsigned int idle, n; ++ int i, idle_idx; ++ ++ while (1) { ++ if (au_ftest_wkq(wkinfo->flags, WAIT)) { ++ idle_idx = 0; ++ idle = UINT_MAX; ++ for (i = 0; i < aufs_nwkq; i++) { ++ n = atomic_inc_return(&au_wkq[i].busy); ++ if (n == 1 && !enqueue(au_wkq + i, wkinfo)) ++ return; /* success */ ++ ++ if (n < idle) { ++ idle_idx = i; ++ idle = n; ++ } ++ atomic_dec(&au_wkq[i].busy); ++ } ++ } else ++ idle_idx = aufs_nwkq; ++ ++ atomic_inc(&au_wkq[idle_idx].busy); ++ if (!enqueue(au_wkq + idle_idx, wkinfo)) ++ return; /* success */ ++ ++ /* impossible? */ ++ AuWarn1("failed to queue_work()\n"); ++ yield(); ++ } ++} ++ ++static void wkq_func(struct work_struct *wk) ++{ ++ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk); ++ ++ wkinfo->func(wkinfo->args); ++ atomic_dec(wkinfo->busyp); ++ if (au_ftest_wkq(wkinfo->flags, WAIT)) ++ complete(wkinfo->comp); ++ else { ++ kobject_put(&au_sbi(wkinfo->sb)->si_kobj); ++ module_put(THIS_MODULE); ++ kfree(wkinfo); ++ } ++} ++ ++/* ++ * Since struct completion is large, try allocating it dynamically. ++ */ ++#if defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) ++#define AuWkqCompDeclare(name) struct completion *comp = NULL ++ ++static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp) ++{ ++ *comp = kmalloc(sizeof(**comp), GFP_NOFS); ++ if (*comp) { ++ init_completion(*comp); ++ wkinfo->comp = *comp; ++ return 0; ++ } ++ return -ENOMEM; ++} ++ ++static void au_wkq_comp_free(struct completion *comp) ++{ ++ kfree(comp); ++} ++ ++#else ++ ++/* no braces */ ++#define AuWkqCompDeclare(name) \ ++ DECLARE_COMPLETION_ONSTACK(_ ## name); \ ++ struct completion *comp = &_ ## name ++ ++static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp) ++{ ++ wkinfo->comp = *comp; ++ return 0; ++} ++ ++static void au_wkq_comp_free(struct completion *comp __maybe_unused) ++{ ++ /* empty */ ++} ++#endif /* 4KSTACKS */ ++ ++static void au_wkq_run(struct au_wkinfo *wkinfo) ++{ ++ au_dbg_verify_kthread(); ++ INIT_WORK(&wkinfo->wk, wkq_func); ++ do_wkq(wkinfo); ++} ++ ++int au_wkq_wait(au_wkq_func_t func, void *args) ++{ ++ int err; ++ AuWkqCompDeclare(comp); ++ struct au_wkinfo wkinfo = { ++ .flags = AuWkq_WAIT, ++ .func = func, ++ .args = args ++ }; ++ ++ err = au_wkq_comp_alloc(&wkinfo, &comp); ++ if (!err) { ++ au_wkq_run(&wkinfo); ++ /* no timeout, no interrupt */ ++ wait_for_completion(wkinfo.comp); ++ au_wkq_comp_free(comp); ++ } ++ ++ return err; ++ ++} ++ ++int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb) ++{ ++ int err; ++ struct au_wkinfo *wkinfo; ++ ++ atomic_inc(&au_sbi(sb)->si_nowait.nw_len); ++ ++ /* ++ * wkq_func() must free this wkinfo. ++ * it highly depends upon the implementation of workqueue. ++ */ ++ err = 0; ++ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS); ++ if (wkinfo) { ++ wkinfo->sb = sb; ++ wkinfo->flags = !AuWkq_WAIT; ++ wkinfo->func = func; ++ wkinfo->args = args; ++ wkinfo->comp = NULL; ++ kobject_get(&au_sbi(sb)->si_kobj); ++ __module_get(THIS_MODULE); ++ ++ au_wkq_run(wkinfo); ++ } else { ++ err = -ENOMEM; ++ atomic_dec(&au_sbi(sb)->si_nowait.nw_len); ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_nwt_init(struct au_nowait_tasks *nwt) ++{ ++ atomic_set(&nwt->nw_len, 0); ++ /* smp_mb();*/ /* atomic_set */ ++ init_waitqueue_head(&nwt->nw_wq); ++} ++ ++void au_wkq_fin(void) ++{ ++ int i; ++ ++ for (i = 0; i < aufs_nwkq; i++) ++ if (au_wkq[i].q && !IS_ERR(au_wkq[i].q)) ++ destroy_workqueue(au_wkq[i].q); ++ kfree(au_wkq); ++} ++ ++int __init au_wkq_init(void) ++{ ++ int err, i; ++ struct au_wkq *nowaitq; ++ ++ /* '+1' is for accounting of nowait queue */ ++ err = -ENOMEM; ++ au_wkq = kcalloc(aufs_nwkq + 1, sizeof(*au_wkq), GFP_NOFS); ++ if (unlikely(!au_wkq)) ++ goto out; ++ ++ err = 0; ++ for (i = 0; i < aufs_nwkq; i++) { ++ au_wkq[i].q = create_singlethread_workqueue(AUFS_WKQ_NAME); ++ if (au_wkq[i].q && !IS_ERR(au_wkq[i].q)) { ++ atomic_set(&au_wkq[i].busy, 0); ++ continue; ++ } ++ ++ err = PTR_ERR(au_wkq[i].q); ++ au_wkq_fin(); ++ goto out; ++ } ++ ++ /* nowait accounting */ ++ nowaitq = au_wkq + aufs_nwkq; ++ atomic_set(&nowaitq->busy, 0); ++ nowaitq->q = NULL; ++ /* smp_mb(); */ /* atomic_set */ ++ ++ out: ++ return err; ++} +diff -Naur a/fs/aufs/wkq.h b/fs/aufs/wkq.h +--- a/fs/aufs/wkq.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/wkq.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,82 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * workqueue for asynchronous/super-io operations ++ * todo: try new credentials management scheme ++ */ ++ ++#ifndef __AUFS_WKQ_H__ ++#define __AUFS_WKQ_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++ ++struct super_block; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue ++ */ ++struct au_nowait_tasks { ++ atomic_t nw_len; ++ wait_queue_head_t nw_wq; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++typedef void (*au_wkq_func_t)(void *args); ++ ++/* wkq flags */ ++#define AuWkq_WAIT 1 ++#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name) ++#define au_fset_wkq(flags, name) { (flags) |= AuWkq_##name; } ++#define au_fclr_wkq(flags, name) { (flags) &= ~AuWkq_##name; } ++ ++/* wkq.c */ ++int au_wkq_wait(au_wkq_func_t func, void *args); ++int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb); ++void au_nwt_init(struct au_nowait_tasks *nwt); ++int __init au_wkq_init(void); ++void au_wkq_fin(void); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline int au_test_wkq(struct task_struct *tsk) ++{ ++ return !tsk->mm && !strcmp(tsk->comm, AUFS_WKQ_NAME); ++} ++ ++static inline void au_nwt_done(struct au_nowait_tasks *nwt) ++{ ++ if (!atomic_dec_return(&nwt->nw_len)) ++ wake_up_all(&nwt->nw_wq); ++} ++ ++static inline int au_nwt_flush(struct au_nowait_tasks *nwt) ++{ ++ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len)); ++ return 0; ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_WKQ_H__ */ +diff -Naur a/fs/aufs/xino.c b/fs/aufs/xino.c +--- a/fs/aufs/xino.c 1969-12-31 16:00:00.000000000 -0800 ++++ b/fs/aufs/xino.c 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,1191 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * external inode number translation table and bitmap ++ */ ++ ++#include ++#include ++#include ++#include "aufs.h" ++ ++ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size, ++ loff_t *pos) ++{ ++ ssize_t err; ++ mm_segment_t oldfs; ++ ++ oldfs = get_fs(); ++ set_fs(KERNEL_DS); ++ do { ++ /* todo: signal_pending? */ ++ err = func(file, (char __user *)buf, size, pos); ++ } while (err == -EAGAIN || err == -EINTR); ++ set_fs(oldfs); ++ ++#if 0 /* reserved for future use */ ++ if (err > 0) ++ fsnotify_access(file->f_dentry); ++#endif ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *buf, ++ size_t size, loff_t *pos) ++{ ++ ssize_t err; ++ mm_segment_t oldfs; ++ ++ oldfs = get_fs(); ++ set_fs(KERNEL_DS); ++ lockdep_off(); ++ do { ++ /* todo: signal_pending? */ ++ err = func(file, (const char __user *)buf, size, pos); ++ } while (err == -EAGAIN || err == -EINTR); ++ lockdep_on(); ++ set_fs(oldfs); ++ ++#if 0 /* reserved for future use */ ++ if (err > 0) ++ fsnotify_modify(file->f_dentry); ++#endif ++ ++ return err; ++} ++ ++struct do_xino_fwrite_args { ++ ssize_t *errp; ++ au_writef_t func; ++ struct file *file; ++ void *buf; ++ size_t size; ++ loff_t *pos; ++}; ++ ++static void call_do_xino_fwrite(void *args) ++{ ++ struct do_xino_fwrite_args *a = args; ++ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos); ++} ++ ++ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size, ++ loff_t *pos) ++{ ++ ssize_t err; ++ ++ /* todo: signal block and no wkq? */ ++ /* todo: new credential scheme */ ++ /* ++ * it breaks RLIMIT_FSIZE and normal user's limit, ++ * users should care about quota and real 'filesystem full.' ++ */ ++ if (!au_test_wkq(current)) { ++ int wkq_err; ++ struct do_xino_fwrite_args args = { ++ .errp = &err, ++ .func = func, ++ .file = file, ++ .buf = buf, ++ .size = size, ++ .pos = pos ++ }; ++ ++ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } else ++ err = do_xino_fwrite(func, file, buf, size, pos); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * create a new xinofile at the same place/path as @base_file. ++ */ ++struct file *au_xino_create2(struct file *base_file, struct file *copy_src) ++{ ++ struct file *file; ++ struct dentry *base, *dentry, *parent; ++ struct inode *dir; ++ struct qstr *name; ++ int err; ++ ++ base = base_file->f_dentry; ++ parent = base->d_parent; /* dir inode is locked */ ++ dir = parent->d_inode; ++ IMustLock(dir); ++ ++ file = ERR_PTR(-EINVAL); ++ name = &base->d_name; ++ dentry = vfsub_lookup_one_len(name->name, parent, name->len); ++ if (IS_ERR(dentry)) { ++ file = (void *)dentry; ++ AuErr("%.*s lookup err %ld\n", AuLNPair(name), PTR_ERR(dentry)); ++ goto out; ++ } ++ ++ /* no need to mnt_want_write() since we call dentry_open() later */ ++ err = vfs_create(dir, dentry, S_IRUGO | S_IWUGO, NULL); ++ if (unlikely(err)) { ++ file = ERR_PTR(err); ++ AuErr("%.*s create err %d\n", AuLNPair(name), err); ++ goto out_dput; ++ } ++ ++ file = dentry_open(dget(dentry), mntget(base_file->f_vfsmnt), ++ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE, ++ current_cred()); ++ if (IS_ERR(file)) { ++ AuErr("%.*s open err %ld\n", AuLNPair(name), PTR_ERR(file)); ++ goto out_dput; ++ } ++ ++ err = vfsub_unlink(dir, &file->f_path, /*force*/0); ++ if (unlikely(err)) { ++ AuErr("%.*s unlink err %d\n", AuLNPair(name), err); ++ goto out_fput; ++ } ++ ++ if (copy_src) { ++ /* no one can touch copy_src xino */ ++ err = au_copy_file(file, copy_src, ++ i_size_read(copy_src->f_dentry->d_inode)); ++ if (unlikely(err)) { ++ AuErr("%.*s copy err %d\n", AuLNPair(name), err); ++ goto out_fput; ++ } ++ } ++ goto out_dput; /* success */ ++ ++ out_fput: ++ fput(file); ++ file = ERR_PTR(err); ++ out_dput: ++ dput(dentry); ++ out: ++ return file; ++} ++ ++struct au_xino_lock_dir { ++ struct au_hinode *hdir; ++ struct dentry *parent; ++ struct mutex *mtx; ++}; ++ ++static void au_xino_lock_dir(struct super_block *sb, struct file *xino, ++ struct au_xino_lock_dir *ldir) ++{ ++ aufs_bindex_t brid, bindex; ++ ++ ldir->hdir = NULL; ++ bindex = -1; ++ brid = au_xino_brid(sb); ++ if (brid >= 0) ++ bindex = au_br_index(sb, brid); ++ if (bindex >= 0) { ++ ldir->hdir = au_hi(sb->s_root->d_inode, bindex); ++ au_hin_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT); ++ } else { ++ ldir->parent = dget_parent(xino->f_dentry); ++ ldir->mtx = &ldir->parent->d_inode->i_mutex; ++ mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT); ++ } ++} ++ ++static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir) ++{ ++ if (ldir->hdir) ++ au_hin_imtx_unlock(ldir->hdir); ++ else { ++ mutex_unlock(ldir->mtx); ++ dput(ldir->parent); ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* trucate xino files asynchronously */ ++ ++int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ int err; ++ aufs_bindex_t bi, bend; ++ struct au_branch *br; ++ struct file *new_xino, *file; ++ struct super_block *h_sb; ++ struct au_xino_lock_dir ldir; ++ ++ err = -EINVAL; ++ bend = au_sbend(sb); ++ if (unlikely(bindex < 0 || bend < bindex)) ++ goto out; ++ br = au_sbr(sb, bindex); ++ file = br->br_xino.xi_file; ++ if (!file) ++ goto out; ++ ++ au_xino_lock_dir(sb, file, &ldir); ++ /* mnt_want_write() is unnecessary here */ ++ new_xino = au_xino_create2(file, file); ++ au_xino_unlock_dir(&ldir); ++ err = PTR_ERR(new_xino); ++ if (IS_ERR(new_xino)) ++ goto out; ++ err = 0; ++ fput(file); ++ br->br_xino.xi_file = new_xino; ++ ++ h_sb = br->br_mnt->mnt_sb; ++ for (bi = 0; bi <= bend; bi++) { ++ if (unlikely(bi == bindex)) ++ continue; ++ br = au_sbr(sb, bi); ++ if (br->br_mnt->mnt_sb != h_sb) ++ continue; ++ ++ fput(br->br_xino.xi_file); ++ br->br_xino.xi_file = new_xino; ++ get_file(new_xino); ++ } ++ ++ out: ++ return err; ++} ++ ++struct xino_do_trunc_args { ++ struct super_block *sb; ++ struct au_branch *br; ++}; ++ ++static void xino_do_trunc(void *_args) ++{ ++ struct xino_do_trunc_args *args = _args; ++ struct super_block *sb; ++ struct au_branch *br; ++ struct inode *dir; ++ int err; ++ aufs_bindex_t bindex; ++ ++ err = 0; ++ sb = args->sb; ++ dir = sb->s_root->d_inode; ++ br = args->br; ++ ++ si_noflush_write_lock(sb); ++ ii_read_lock_parent(dir); ++ bindex = au_br_index(sb, br->br_id); ++ err = au_xino_trunc(sb, bindex); ++ if (unlikely(err)) ++ goto out; ++ ++ if (br->br_xino.xi_file->f_dentry->d_inode->i_blocks ++ >= br->br_xino_upper) ++ br->br_xino_upper += AUFS_XINO_TRUNC_STEP; ++ ++ out: ++ ii_read_unlock(dir); ++ if (unlikely(err)) ++ AuWarn("err b%d, (%d)\n", bindex, err); ++ atomic_dec(&br->br_xino_running); ++ atomic_dec(&br->br_count); ++ au_nwt_done(&au_sbi(sb)->si_nowait); ++ si_write_unlock(sb); ++ kfree(args); ++} ++ ++static void xino_try_trunc(struct super_block *sb, struct au_branch *br) ++{ ++ struct xino_do_trunc_args *args; ++ int wkq_err; ++ ++ if (br->br_xino.xi_file->f_dentry->d_inode->i_blocks ++ < br->br_xino_upper) ++ return; ++ ++ if (atomic_inc_return(&br->br_xino_running) > 1) ++ goto out; ++ ++ /* lock and kfree() will be called in trunc_xino() */ ++ args = kmalloc(sizeof(*args), GFP_NOFS); ++ if (unlikely(!args)) { ++ AuErr1("no memory\n"); ++ goto out_args; ++ } ++ ++ atomic_inc(&br->br_count); ++ args->sb = sb; ++ args->br = br; ++ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb); ++ if (!wkq_err) ++ return; /* success */ ++ ++ AuErr("wkq %d\n", wkq_err); ++ atomic_dec(&br->br_count); ++ ++ out_args: ++ kfree(args); ++ out: ++ atomic_dec(&br->br_xino_running); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_xino_do_write(au_writef_t write, struct file *file, ++ ino_t h_ino, ino_t ino) ++{ ++ loff_t pos; ++ ssize_t sz; ++ ++ pos = h_ino; ++ if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) { ++ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino); ++ return -EFBIG; ++ } ++ pos *= sizeof(ino); ++ sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos); ++ if (sz == sizeof(ino)) ++ return 0; /* success */ ++ ++ AuIOErr("write failed (%zd)\n", sz); ++ return -EIO; ++} ++ ++/* ++ * write @ino to the xinofile for the specified branch{@sb, @bindex} ++ * at the position of @h_ino. ++ * even if @ino is zero, it is written to the xinofile and means no entry. ++ * if the size of the xino file on a specific filesystem exceeds the watermark, ++ * try truncating it. ++ */ ++int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t ino) ++{ ++ int err; ++ unsigned int mnt_flags; ++ struct au_branch *br; ++ ++ BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max) ++ || ((loff_t)-1) > 0); ++ ++ mnt_flags = au_mntflags(sb); ++ if (!au_opt_test(mnt_flags, XINO)) ++ return 0; ++ ++ br = au_sbr(sb, bindex); ++ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file, ++ h_ino, ino); ++ if (!err) { ++ if (au_opt_test(mnt_flags, TRUNC_XINO) ++ && au_test_fs_trunc_xino(br->br_mnt->mnt_sb)) ++ xino_try_trunc(sb, br); ++ return 0; /* success */ ++ } ++ ++ AuIOErr("write failed (%d)\n", err); ++ return -EIO; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* aufs inode number bitmap */ ++ ++static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE; ++static ino_t xib_calc_ino(unsigned long pindex, int bit) ++{ ++ ino_t ino; ++ ++ AuDebugOn(bit < 0 || page_bits <= bit); ++ ino = AUFS_FIRST_INO + pindex * page_bits + bit; ++ return ino; ++} ++ ++static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit) ++{ ++ AuDebugOn(ino < AUFS_FIRST_INO); ++ ino -= AUFS_FIRST_INO; ++ *pindex = ino / page_bits; ++ *bit = ino % page_bits; ++} ++ ++static int xib_pindex(struct super_block *sb, unsigned long pindex) ++{ ++ int err; ++ loff_t pos; ++ ssize_t sz; ++ struct au_sbinfo *sbinfo; ++ struct file *xib; ++ unsigned long *p; ++ ++ sbinfo = au_sbi(sb); ++ MtxMustLock(&sbinfo->si_xib_mtx); ++ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE ++ || !au_opt_test(sbinfo->si_mntflags, XINO)); ++ ++ if (pindex == sbinfo->si_xib_last_pindex) ++ return 0; ++ ++ xib = sbinfo->si_xib; ++ p = sbinfo->si_xib_buf; ++ pos = sbinfo->si_xib_last_pindex; ++ pos *= PAGE_SIZE; ++ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos); ++ if (unlikely(sz != PAGE_SIZE)) ++ goto out; ++ ++ pos = pindex; ++ pos *= PAGE_SIZE; ++ if (i_size_read(xib->f_dentry->d_inode) >= pos + PAGE_SIZE) ++ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos); ++ else { ++ memset(p, 0, PAGE_SIZE); ++ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos); ++ } ++ if (sz == PAGE_SIZE) { ++ sbinfo->si_xib_last_pindex = pindex; ++ return 0; /* success */ ++ } ++ ++ out: ++ AuIOErr1("write failed (%zd)\n", sz); ++ err = sz; ++ if (sz >= 0) ++ err = -EIO; ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_xino_write0(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t ino) ++{ ++ int err, bit; ++ unsigned long pindex; ++ struct au_sbinfo *sbinfo; ++ ++ if (!au_opt_test(au_mntflags(sb), XINO)) ++ return 0; ++ ++ err = 0; ++ if (ino) { ++ sbinfo = au_sbi(sb); ++ xib_calc_bit(ino, &pindex, &bit); ++ AuDebugOn(page_bits <= bit); ++ mutex_lock(&sbinfo->si_xib_mtx); ++ err = xib_pindex(sb, pindex); ++ if (!err) { ++ clear_bit(bit, sbinfo->si_xib_buf); ++ sbinfo->si_xib_next_bit = bit; ++ } ++ mutex_unlock(&sbinfo->si_xib_mtx); ++ } ++ ++ if (!err) ++ err = au_xino_write(sb, bindex, h_ino, 0); ++ return err; ++} ++ ++/* get an unused inode number from bitmap */ ++ino_t au_xino_new_ino(struct super_block *sb) ++{ ++ ino_t ino; ++ unsigned long *p, pindex, ul, pend; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ int free_bit, err; ++ ++ if (!au_opt_test(au_mntflags(sb), XINO)) ++ return iunique(sb, AUFS_FIRST_INO); ++ ++ sbinfo = au_sbi(sb); ++ mutex_lock(&sbinfo->si_xib_mtx); ++ p = sbinfo->si_xib_buf; ++ free_bit = sbinfo->si_xib_next_bit; ++ if (free_bit < page_bits && !test_bit(free_bit, p)) ++ goto out; /* success */ ++ free_bit = find_first_zero_bit(p, page_bits); ++ if (free_bit < page_bits) ++ goto out; /* success */ ++ ++ pindex = sbinfo->si_xib_last_pindex; ++ for (ul = pindex - 1; ul < ULONG_MAX; ul--) { ++ err = xib_pindex(sb, ul); ++ if (unlikely(err)) ++ goto out_err; ++ free_bit = find_first_zero_bit(p, page_bits); ++ if (free_bit < page_bits) ++ goto out; /* success */ ++ } ++ ++ file = sbinfo->si_xib; ++ pend = i_size_read(file->f_dentry->d_inode) / PAGE_SIZE; ++ for (ul = pindex + 1; ul <= pend; ul++) { ++ err = xib_pindex(sb, ul); ++ if (unlikely(err)) ++ goto out_err; ++ free_bit = find_first_zero_bit(p, page_bits); ++ if (free_bit < page_bits) ++ goto out; /* success */ ++ } ++ BUG(); ++ ++ out: ++ set_bit(free_bit, p); ++ sbinfo->si_xib_next_bit++; ++ pindex = sbinfo->si_xib_last_pindex; ++ mutex_unlock(&sbinfo->si_xib_mtx); ++ ino = xib_calc_ino(pindex, free_bit); ++ AuDbg("i%lu\n", (unsigned long)ino); ++ return ino; ++ out_err: ++ mutex_unlock(&sbinfo->si_xib_mtx); ++ AuDbg("i0\n"); ++ return 0; ++} ++ ++/* ++ * read @ino from xinofile for the specified branch{@sb, @bindex} ++ * at the position of @h_ino. ++ * if @ino does not exist and @do_new is true, get new one. ++ */ ++int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t *ino) ++{ ++ int err; ++ ssize_t sz; ++ loff_t pos; ++ struct file *file; ++ struct au_sbinfo *sbinfo; ++ ++ *ino = 0; ++ if (!au_opt_test(au_mntflags(sb), XINO)) ++ return 0; /* no xino */ ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ pos = h_ino; ++ if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) { ++ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino); ++ return -EFBIG; ++ } ++ pos *= sizeof(*ino); ++ ++ file = au_sbr(sb, bindex)->br_xino.xi_file; ++ if (i_size_read(file->f_dentry->d_inode) < pos + sizeof(*ino)) ++ return 0; /* no ino */ ++ ++ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos); ++ if (sz == sizeof(*ino)) ++ return 0; /* success */ ++ ++ err = sz; ++ if (unlikely(sz >= 0)) { ++ err = -EIO; ++ AuIOErr("xino read error (%zd)\n", sz); ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* create and set a new xino file */ ++ ++struct file *au_xino_create(struct super_block *sb, char *fname, int silent) ++{ ++ struct file *file; ++ struct dentry *h_parent, *d; ++ struct inode *h_dir; ++ int err; ++ ++ /* ++ * at mount-time, and the xino file is the default path, ++ * hinotify is disabled so we have no inotify events to ignore. ++ * when a user specified the xino, we cannot get au_hdir to be ignored. ++ */ ++ file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE, ++ S_IRUGO | S_IWUGO); ++ if (IS_ERR(file)) { ++ if (!silent) ++ AuErr("open %s(%ld)\n", fname, PTR_ERR(file)); ++ return file; ++ } ++ ++ /* keep file count */ ++ h_parent = dget_parent(file->f_dentry); ++ h_dir = h_parent->d_inode; ++ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); ++ /* mnt_want_write() is unnecessary here */ ++ err = vfsub_unlink(h_dir, &file->f_path, /*force*/0); ++ mutex_unlock(&h_dir->i_mutex); ++ dput(h_parent); ++ if (unlikely(err)) { ++ if (!silent) ++ AuErr("unlink %s(%d)\n", fname, err); ++ goto out; ++ } ++ ++ err = -EINVAL; ++ d = file->f_dentry; ++ if (unlikely(sb == d->d_sb)) { ++ if (!silent) ++ AuErr("%s must be outside\n", fname); ++ goto out; ++ } ++ if (unlikely(au_test_fs_bad_xino(d->d_sb))) { ++ if (!silent) ++ AuErr("xino doesn't support %s(%s)\n", ++ fname, au_sbtype(d->d_sb)); ++ goto out; ++ } ++ return file; /* success */ ++ ++ out: ++ fput(file); ++ file = ERR_PTR(err); ++ return file; ++} ++ ++/* ++ * find another branch who is on the same filesystem of the specified ++ * branch{@btgt}. search until @bend. ++ */ ++static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt, ++ aufs_bindex_t bend) ++{ ++ aufs_bindex_t bindex; ++ struct super_block *tgt_sb = au_sbr_sb(sb, btgt); ++ ++ for (bindex = 0; bindex < btgt; bindex++) ++ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex))) ++ return bindex; ++ for (bindex++; bindex <= bend; bindex++) ++ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex))) ++ return bindex; ++ return -1; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * initialize the xinofile for the specified branch @br ++ * at the place/path where @base_file indicates. ++ * test whether another branch is on the same filesystem or not, ++ * if @do_test is true. ++ */ ++int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino, ++ struct file *base_file, int do_test) ++{ ++ int err; ++ ino_t ino; ++ aufs_bindex_t bend, bindex; ++ struct au_branch *shared_br, *b; ++ struct file *file; ++ struct super_block *tgt_sb; ++ ++ shared_br = NULL; ++ bend = au_sbend(sb); ++ if (do_test) { ++ tgt_sb = br->br_mnt->mnt_sb; ++ for (bindex = 0; bindex <= bend; bindex++) { ++ b = au_sbr(sb, bindex); ++ if (tgt_sb == b->br_mnt->mnt_sb) { ++ shared_br = b; ++ break; ++ } ++ } ++ } ++ ++ if (!shared_br || !shared_br->br_xino.xi_file) { ++ struct au_xino_lock_dir ldir; ++ ++ au_xino_lock_dir(sb, base_file, &ldir); ++ /* mnt_want_write() is unnecessary here */ ++ file = au_xino_create2(base_file, NULL); ++ au_xino_unlock_dir(&ldir); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ br->br_xino.xi_file = file; ++ } else { ++ br->br_xino.xi_file = shared_br->br_xino.xi_file; ++ get_file(br->br_xino.xi_file); ++ } ++ ++ ino = AUFS_ROOT_INO; ++ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file, ++ h_ino, ino); ++ if (!err) ++ return 0; /* success */ ++ ++ ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* trucate a xino bitmap file */ ++ ++/* todo: slow */ ++static int do_xib_restore(struct super_block *sb, struct file *file, void *page) ++{ ++ int err, bit; ++ ssize_t sz; ++ unsigned long pindex; ++ loff_t pos, pend; ++ struct au_sbinfo *sbinfo; ++ au_readf_t func; ++ ino_t *ino; ++ unsigned long *p; ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ p = sbinfo->si_xib_buf; ++ func = sbinfo->si_xread; ++ pend = i_size_read(file->f_dentry->d_inode); ++ pos = 0; ++ while (pos < pend) { ++ sz = xino_fread(func, file, page, PAGE_SIZE, &pos); ++ err = sz; ++ if (unlikely(sz <= 0)) ++ goto out; ++ ++ err = 0; ++ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) { ++ if (unlikely(*ino < AUFS_FIRST_INO)) ++ continue; ++ ++ xib_calc_bit(*ino, &pindex, &bit); ++ AuDebugOn(page_bits <= bit); ++ err = xib_pindex(sb, pindex); ++ if (!err) ++ set_bit(bit, p); ++ else ++ goto out; ++ } ++ } ++ ++ out: ++ return err; ++} ++ ++static int xib_restore(struct super_block *sb) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ void *page; ++ ++ err = -ENOMEM; ++ page = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!page)) ++ goto out; ++ ++ err = 0; ++ bend = au_sbend(sb); ++ for (bindex = 0; !err && bindex <= bend; bindex++) ++ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0) ++ err = do_xib_restore ++ (sb, au_sbr(sb, bindex)->br_xino.xi_file, page); ++ else ++ AuDbg("b%d\n", bindex); ++ free_page((unsigned long)page); ++ ++ out: ++ return err; ++} ++ ++int au_xib_trunc(struct super_block *sb) ++{ ++ int err; ++ ssize_t sz; ++ loff_t pos; ++ struct au_xino_lock_dir ldir; ++ struct au_sbinfo *sbinfo; ++ unsigned long *p; ++ struct file *file; ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ if (!au_opt_test(sbinfo->si_mntflags, XINO)) ++ goto out; ++ ++ file = sbinfo->si_xib; ++ if (i_size_read(file->f_dentry->d_inode) <= PAGE_SIZE) ++ goto out; ++ ++ au_xino_lock_dir(sb, file, &ldir); ++ /* mnt_want_write() is unnecessary here */ ++ file = au_xino_create2(sbinfo->si_xib, NULL); ++ au_xino_unlock_dir(&ldir); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ fput(sbinfo->si_xib); ++ sbinfo->si_xib = file; ++ ++ p = sbinfo->si_xib_buf; ++ memset(p, 0, PAGE_SIZE); ++ pos = 0; ++ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos); ++ if (unlikely(sz != PAGE_SIZE)) { ++ err = sz; ++ AuIOErr("err %d\n", err); ++ if (sz >= 0) ++ err = -EIO; ++ goto out; ++ } ++ ++ mutex_lock(&sbinfo->si_xib_mtx); ++ /* mnt_want_write() is unnecessary here */ ++ err = xib_restore(sb); ++ mutex_unlock(&sbinfo->si_xib_mtx); ++ ++out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * xino mount option handlers ++ */ ++static au_readf_t find_readf(struct file *h_file) ++{ ++ const struct file_operations *fop = h_file->f_op; ++ ++ if (fop) { ++ if (fop->read) ++ return fop->read; ++ if (fop->aio_read) ++ return do_sync_read; ++ } ++ return ERR_PTR(-ENOSYS); ++} ++ ++static au_writef_t find_writef(struct file *h_file) ++{ ++ const struct file_operations *fop = h_file->f_op; ++ ++ if (fop) { ++ if (fop->write) ++ return fop->write; ++ if (fop->aio_write) ++ return do_sync_write; ++ } ++ return ERR_PTR(-ENOSYS); ++} ++ ++/* xino bitmap */ ++static void xino_clear_xib(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ sbinfo = au_sbi(sb); ++ sbinfo->si_xread = NULL; ++ sbinfo->si_xwrite = NULL; ++ if (sbinfo->si_xib) ++ fput(sbinfo->si_xib); ++ sbinfo->si_xib = NULL; ++ free_page((unsigned long)sbinfo->si_xib_buf); ++ sbinfo->si_xib_buf = NULL; ++} ++ ++static int au_xino_set_xib(struct super_block *sb, struct file *base) ++{ ++ int err; ++ loff_t pos; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ ++ sbinfo = au_sbi(sb); ++ file = au_xino_create2(base, sbinfo->si_xib); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ if (sbinfo->si_xib) ++ fput(sbinfo->si_xib); ++ sbinfo->si_xib = file; ++ sbinfo->si_xread = find_readf(file); ++ sbinfo->si_xwrite = find_writef(file); ++ ++ err = -ENOMEM; ++ if (!sbinfo->si_xib_buf) ++ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS); ++ if (unlikely(!sbinfo->si_xib_buf)) ++ goto out_unset; ++ ++ sbinfo->si_xib_last_pindex = 0; ++ sbinfo->si_xib_next_bit = 0; ++ if (i_size_read(file->f_dentry->d_inode) < PAGE_SIZE) { ++ pos = 0; ++ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf, ++ PAGE_SIZE, &pos); ++ if (unlikely(err != PAGE_SIZE)) ++ goto out_free; ++ } ++ err = 0; ++ goto out; /* success */ ++ ++ out_free: ++ free_page((unsigned long)sbinfo->si_xib_buf); ++ sbinfo->si_xib_buf = NULL; ++ if (err >= 0) ++ err = -EIO; ++ out_unset: ++ fput(sbinfo->si_xib); ++ sbinfo->si_xib = NULL; ++ sbinfo->si_xread = NULL; ++ sbinfo->si_xwrite = NULL; ++ out: ++ return err; ++} ++ ++/* xino for each branch */ ++static void xino_clear_br(struct super_block *sb) ++{ ++ aufs_bindex_t bindex, bend; ++ struct au_branch *br; ++ ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (!br || !br->br_xino.xi_file) ++ continue; ++ ++ fput(br->br_xino.xi_file); ++ br->br_xino.xi_file = NULL; ++ } ++} ++ ++static int au_xino_set_br(struct super_block *sb, struct file *base) ++{ ++ int err; ++ ino_t ino; ++ aufs_bindex_t bindex, bend, bshared; ++ struct { ++ struct file *old, *new; ++ } *fpair, *p; ++ struct au_branch *br; ++ struct inode *inode; ++ au_writef_t writef; ++ ++ err = -ENOMEM; ++ bend = au_sbend(sb); ++ fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS); ++ if (unlikely(!fpair)) ++ goto out; ++ ++ inode = sb->s_root->d_inode; ++ ino = AUFS_ROOT_INO; ++ writef = au_sbi(sb)->si_xwrite; ++ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) { ++ br = au_sbr(sb, bindex); ++ bshared = is_sb_shared(sb, bindex, bindex - 1); ++ if (bshared >= 0) { ++ /* shared xino */ ++ *p = fpair[bshared]; ++ get_file(p->new); ++ } ++ ++ if (!p->new) { ++ /* new xino */ ++ p->old = br->br_xino.xi_file; ++ p->new = au_xino_create2(base, br->br_xino.xi_file); ++ err = PTR_ERR(p->new); ++ if (IS_ERR(p->new)) { ++ p->new = NULL; ++ goto out_pair; ++ } ++ } ++ ++ err = au_xino_do_write(writef, p->new, ++ au_h_iptr(inode, bindex)->i_ino, ino); ++ if (unlikely(err)) ++ goto out_pair; ++ } ++ ++ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) { ++ br = au_sbr(sb, bindex); ++ if (br->br_xino.xi_file) ++ fput(br->br_xino.xi_file); ++ get_file(p->new); ++ br->br_xino.xi_file = p->new; ++ } ++ ++ out_pair: ++ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) ++ if (p->new) ++ fput(p->new); ++ else ++ break; ++ kfree(fpair); ++ out: ++ return err; ++} ++ ++void au_xino_clr(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ au_xigen_clr(sb); ++ xino_clear_xib(sb); ++ xino_clear_br(sb); ++ sbinfo = au_sbi(sb); ++ /* lvalue, do not call au_mntflags() */ ++ au_opt_clr(sbinfo->si_mntflags, XINO); ++} ++ ++int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount) ++{ ++ int err, skip; ++ struct dentry *parent, *cur_parent; ++ struct qstr *dname, *cur_name; ++ struct file *cur_xino; ++ struct inode *dir; ++ struct au_sbinfo *sbinfo; ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ parent = dget_parent(xino->file->f_dentry); ++ if (remount) { ++ skip = 0; ++ dname = &xino->file->f_dentry->d_name; ++ cur_xino = sbinfo->si_xib; ++ if (cur_xino) { ++ cur_parent = dget_parent(cur_xino->f_dentry); ++ cur_name = &cur_xino->f_dentry->d_name; ++ skip = (cur_parent == parent ++ && dname->len == cur_name->len ++ && !memcmp(dname->name, cur_name->name, ++ dname->len)); ++ dput(cur_parent); ++ } ++ if (skip) ++ goto out; ++ } ++ ++ au_opt_set(sbinfo->si_mntflags, XINO); ++ dir = parent->d_inode; ++ mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT); ++ /* mnt_want_write() is unnecessary here */ ++ err = au_xino_set_xib(sb, xino->file); ++ if (!err) ++ err = au_xigen_set(sb, xino->file); ++ if (!err) ++ err = au_xino_set_br(sb, xino->file); ++ mutex_unlock(&dir->i_mutex); ++ if (!err) ++ goto out; /* success */ ++ ++ /* reset all */ ++ AuIOErr("failed creating xino(%d).\n", err); ++ ++ out: ++ dput(parent); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * create a xinofile at the default place/path. ++ */ ++struct file *au_xino_def(struct super_block *sb) ++{ ++ struct file *file; ++ char *page, *p; ++ struct au_branch *br; ++ struct super_block *h_sb; ++ struct path path; ++ aufs_bindex_t bend, bindex, bwr; ++ ++ br = NULL; ++ bend = au_sbend(sb); ++ bwr = -1; ++ for (bindex = 0; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (au_br_writable(br->br_perm) ++ && !au_test_fs_bad_xino(br->br_mnt->mnt_sb)) { ++ bwr = bindex; ++ break; ++ } ++ } ++ ++ if (bwr >= 0) { ++ file = ERR_PTR(-ENOMEM); ++ page = __getname(); ++ if (unlikely(!page)) ++ goto out; ++ path.mnt = br->br_mnt; ++ path.dentry = au_h_dptr(sb->s_root, bwr); ++ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME)); ++ file = (void *)p; ++ if (!IS_ERR(p)) { ++ strcat(p, "/" AUFS_XINO_FNAME); ++ AuDbg("%s\n", p); ++ file = au_xino_create(sb, p, /*silent*/0); ++ if (!IS_ERR(file)) ++ au_xino_brid_set(sb, br->br_id); ++ } ++ __putname(page); ++ } else { ++ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0); ++ if (IS_ERR(file)) ++ goto out; ++ h_sb = file->f_dentry->d_sb; ++ if (unlikely(au_test_fs_bad_xino(h_sb))) { ++ AuErr("xino doesn't support %s(%s)\n", ++ AUFS_XINO_DEFPATH, au_sbtype(h_sb)); ++ fput(file); ++ file = ERR_PTR(-EINVAL); ++ } ++ if (!IS_ERR(file)) ++ au_xino_brid_set(sb, -1); ++ } ++ ++ out: ++ return file; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_xino_path(struct seq_file *seq, struct file *file) ++{ ++ int err; ++ ++ err = au_seq_path(seq, &file->f_path); ++ if (unlikely(err < 0)) ++ goto out; ++ ++ err = 0; ++#define Deleted "\\040(deleted)" ++ seq->count -= sizeof(Deleted) - 1; ++ AuDebugOn(memcmp(seq->buf + seq->count, Deleted, ++ sizeof(Deleted) - 1)); ++#undef Deleted ++ ++ out: ++ return err; ++} +diff -Naur a/include/linux/aufs_type.h b/include/linux/aufs_type.h +--- a/include/linux/aufs_type.h 1969-12-31 16:00:00.000000000 -0800 ++++ b/include/linux/aufs_type.h 2009-06-22 23:36:25.000000000 -0700 +@@ -0,0 +1,109 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++#ifndef __AUFS_TYPE_H__ ++#define __AUFS_TYPE_H__ ++ ++#include ++ ++#define AUFS_VERSION "2-standalone.tree-29-20090622" ++ ++/* todo? move this to linux-2.6.19/include/magic.h */ ++#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_BRANCH_MAX_127 ++/* some environments treat 'char' as 'unsigned char' by default */ ++typedef signed char aufs_bindex_t; ++#define AUFS_BRANCH_MAX 127 ++#else ++typedef short aufs_bindex_t; ++#ifdef CONFIG_AUFS_BRANCH_MAX_511 ++#define AUFS_BRANCH_MAX 511 ++#elif defined(CONFIG_AUFS_BRANCH_MAX_1023) ++#define AUFS_BRANCH_MAX 1023 ++#elif defined(CONFIG_AUFS_BRANCH_MAX_32767) ++#define AUFS_BRANCH_MAX 32767 ++#endif ++#endif ++ ++#ifdef __KERNEL__ ++#ifndef AUFS_BRANCH_MAX ++#error unknown CONFIG_AUFS_BRANCH_MAX value ++#endif ++#endif /* __KERNEL__ */ ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define AUFS_NAME "aufs" ++#define AUFS_FSTYPE AUFS_NAME ++ ++#define AUFS_ROOT_INO 2 ++#define AUFS_FIRST_INO 11 ++ ++#define AUFS_WH_PFX ".wh." ++#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1) ++#define AUFS_XINO_FNAME "." AUFS_NAME ".xino" ++#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME ++#define AUFS_XINO_TRUNC_INIT 64 /* blocks */ ++#define AUFS_XINO_TRUNC_STEP 4 /* blocks */ ++#define AUFS_DIRWH_DEF 3 ++#define AUFS_RDCACHE_DEF 10 /* seconds */ ++#define AUFS_RDBLK_DEF 512 /* bytes */ ++#define AUFS_RDHASH_DEF 32 ++#define AUFS_WKQ_NAME AUFS_NAME "d" ++#define AUFS_NWKQ_DEF 4 ++#define AUFS_MFS_SECOND_DEF 30 /* seconds */ ++#define AUFS_PLINK_WARN 100 /* number of plinks */ ++ ++#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */ ++#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME ++ ++#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME ++#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk" ++#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph" ++ ++/* doubly whiteouted */ ++#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME ++#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME ++#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME ++ ++/* branch permission */ ++#define AUFS_BRPERM_RW "rw" ++#define AUFS_BRPERM_RO "ro" ++#define AUFS_BRPERM_RR "rr" ++#define AUFS_BRPERM_WH "wh" ++#define AUFS_BRPERM_NLWH "nolwh" ++#define AUFS_BRPERM_ROWH AUFS_BRPERM_RO "+" AUFS_BRPERM_WH ++#define AUFS_BRPERM_RRWH AUFS_BRPERM_RR "+" AUFS_BRPERM_WH ++#define AUFS_BRPERM_RWNLWH AUFS_BRPERM_RW "+" AUFS_BRPERM_NLWH ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ioctl */ ++enum { ++ AuCtl_PLINK_MAINT, ++ AuCtl_PLINK_CLEAN ++}; ++ ++#define AuCtlType 'A' ++#define AUFS_CTL_PLINK_MAINT _IO(AuCtlType, AuCtl_PLINK_MAINT) ++#define AUFS_CTL_PLINK_CLEAN _IO(AuCtlType, AuCtl_PLINK_CLEAN) ++ ++#endif /* __AUFS_TYPE_H__ */ diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-squashfs-mount-to-avoid-initramfs.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-squashfs-mount-to-avoid-initramfs.patch new file mode 100644 index 0000000000..1d409e2532 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-squashfs-mount-to-avoid-initramfs.patch @@ -0,0 +1,40 @@ +--- linux-omap-2.6/init/do_mounts.c 2008-11-23 01:22:52.000000000 -0800 ++++ linux-omap-2.6/init/do_mounts.c 2008-11-23 02:17:58.000000000 -0800 +@@ -325,6 +325,37 @@ + + void __init mount_root(void) + { ++ int do_special = 0; ++ if (strcmp(root_device_name, "special") == 0) ++ do_special = 1; ++ do_special = 1; ++ ++ if (do_special) { ++ dev_t ROOT_DEV_RO; ++ dev_t ROOT_DEV_RW; ++ ++ sys_mkdir("/root-ro", 0700); ++ ROOT_DEV_RO = name_to_dev_t("/dev/mtd4"); ++ create_dev("/dev/root-ro", ROOT_DEV_RO); ++ if (sys_mount("/dev/root-ro", "/root-ro", "squashfs", MS_RDONLY | MS_SILENT, NULL) != 0) { ++ ROOT_DEV_RO = name_to_dev_t("/dev/mmcblk0p2"); ++ create_dev("/dev/root-ro2", ROOT_DEV_RO); ++ if (sys_mount("/dev/root-ro2", "/root-ro", "squashfs", MS_RDONLY | MS_SILENT, NULL) != 0) ++ goto no_special; ++ } ++ ++ sys_mkdir("/root-rw", 0700); ++ ROOT_DEV_RW = name_to_dev_t("/dev/mmcblk0p3"); ++ create_dev("/dev/root-rw", ROOT_DEV_RW); ++ if (sys_mount("/dev/root-rw", "/root-rw", "ext3", MS_SILENT, NULL) != 0) ++ goto no_special; ++ sys_mount("none", "/root", "aufs", 0, "br:/root-rw:/root-ro=ro"); ++ sys_chdir("/root"); ++ return; ++ } ++ ++no_special: ++ + #ifdef CONFIG_ROOT_NFS + if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) { + if (mount_nfs_root()) diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery1-tps65950-charging-management-1.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery1-tps65950-charging-management-1.patch new file mode 100644 index 0000000000..035627ac79 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery1-tps65950-charging-management-1.patch @@ -0,0 +1,221 @@ +From 1b3e7e2e095648f244a08b1459ff035bbdc99942 Mon Sep 17 00:00:00 2001 +From: Tim Yamin +Date: Tue, 5 May 2009 23:33:00 -0700 +Subject: [PATCH] TWL BCI: Make charge current controllable and backup battery optional. + +This patch makes the charging current controllable via sysfs and also +makes the backup battery optional. Also, if you don't care about the +temperature readings, you can opt-out from having to supply a +temperature lookup table. + +Signed-off-by: Tim Yamin +--- + drivers/power/twl4030_bci_battery.c | 91 +++++++++++++++++++++++++++++------ + include/linux/i2c/twl4030.h | 2 + + 2 files changed, 78 insertions(+), 15 deletions(-) + +diff --git a/drivers/power/twl4030_bci_battery.c b/drivers/power/twl4030_bci_battery.c +index ddba62b..eab0933 100644 +--- a/drivers/power/twl4030_bci_battery.c ++++ b/drivers/power/twl4030_bci_battery.c +@@ -125,6 +125,14 @@ + /* BCIEDR3 */ + #define VBATLVL_EDRRISIN 0x02 + ++/* BCIIREF1 */ ++#define REG_BCIIREF1 0x027 ++#define REG_BCIIREF2 0x028 ++ ++/* Key */ ++#define KEY_IIREF 0xE7 ++#define REG_BCIMFKEY 0x011 ++ + /* Step size and prescaler ratio */ + #define TEMP_STEP_SIZE 147 + #define TEMP_PSR_R 100 +@@ -142,9 +150,6 @@ + #define ENABLE 1 + #define DISABLE 1 + +-/* Ptr to thermistor table */ +-int *therm_tbl; +- + struct twl4030_bci_device_info { + struct device *dev; + +@@ -160,6 +165,8 @@ struct twl4030_bci_device_info { + struct power_supply bk_bat; + struct delayed_work twl4030_bci_monitor_work; + struct delayed_work twl4030_bk_bci_monitor_work; ++ ++ struct twl4030_bci_platform_data *pdata; + }; + + static int usb_charger_flag; +@@ -518,11 +525,15 @@ int twl4030charger_usb_en(int enable) + * Return battery temperature + * Or < 0 on failure. + */ +-static int twl4030battery_temperature(void) ++static int twl4030battery_temperature(struct twl4030_bci_device_info *di) + { + u8 val; + int temp, curr, volt, res, ret; + ++ /* Is a temperature table specified? */ ++ if (!di->pdata->tblsize) ++ return 0; ++ + /* Getting and calculating the thermistor voltage */ + ret = read_bci_val(T2_BATTERY_TEMP); + if (ret < 0) +@@ -543,7 +554,7 @@ static int twl4030battery_temperature(void) + + /*calculating temperature*/ + for (temp = 58; temp >= 0; temp--) { +- int actual = therm_tbl[temp]; ++ int actual = di->pdata->battery_tmp_tbl[temp]; + if ((actual - res) >= 0) + break; + } +@@ -772,13 +783,14 @@ static void twl4030_bk_bci_battery_work(struct work_struct *work) + struct twl4030_bci_device_info, + twl4030_bk_bci_monitor_work.work); + +- twl4030_bk_bci_battery_read_status(di); ++ if(!di->pdata->no_backup_battery) ++ twl4030_bk_bci_battery_read_status(di); + schedule_delayed_work(&di->twl4030_bk_bci_monitor_work, 500); + } + + static void twl4030_bci_battery_read_status(struct twl4030_bci_device_info *di) + { +- di->temp_C = twl4030battery_temperature(); ++ di->temp_C = twl4030battery_temperature(di); + di->voltage_uV = twl4030battery_voltage(); + di->current_uA = twl4030battery_current(); + } +@@ -819,6 +831,43 @@ static void twl4030_bci_battery_external_power_changed(struct power_supply *psy) + #define to_twl4030_bk_bci_device_info(x) container_of((x), \ + struct twl4030_bci_device_info, bk_bat); + ++static ssize_t ++show_charge_current(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ return sprintf(buf, "%d\n", read_bci_val(REG_BCIIREF1)); ++} ++ ++static ssize_t ++set_charge_current(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) ++{ ++ unsigned long newCurrent; ++ int ret; ++ ++ ret = strict_strtoul(buf, 10, &newCurrent); ++ if (ret) ++ return -EINVAL; ++ ++ ret = twl4030_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE, KEY_IIREF, REG_BCIMFKEY); ++ if (ret) ++ return ret; ++ ++ ret = twl4030_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE, newCurrent & 0xff, REG_BCIIREF1); ++ if (ret) ++ return ret; ++ ++ ret = twl4030_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE, KEY_IIREF, REG_BCIMFKEY); ++ if (ret) ++ return ret; ++ ++ ret = twl4030_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE, (newCurrent >> 8) & 0x03, REG_BCIIREF2); ++ if (ret) ++ return ret; ++ ++ return count; ++} ++ ++static DEVICE_ATTR(charge_current, S_IRUGO | S_IWUGO, show_charge_current, set_charge_current); ++ + static int twl4030_bk_bci_battery_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +@@ -912,8 +961,6 @@ static int __init twl4030_bci_battery_probe(struct platform_device *pdev) + int irq; + int ret; + +- therm_tbl = pdata->battery_tmp_tbl; +- + di = kzalloc(sizeof(*di), GFP_KERNEL); + if (!di) + return -ENOMEM; +@@ -937,6 +984,7 @@ static int __init twl4030_bci_battery_probe(struct platform_device *pdev) + di->bk_bat.num_properties = ARRAY_SIZE(twl4030_bk_bci_battery_props); + di->bk_bat.get_property = twl4030_bk_bci_battery_get_property; + di->bk_bat.external_power_changed = NULL; ++ di->pdata = pdata; + + twl4030charger_ac_en(ENABLE); + twl4030charger_usb_en(ENABLE); +@@ -951,9 +999,12 @@ static int __init twl4030_bci_battery_probe(struct platform_device *pdev) + goto temp_setup_fail; + + /* enabling GPCH09 for read back battery voltage */ +- ret = twl4030backupbatt_voltage_setup(); +- if (ret) +- goto voltage_setup_fail; ++ if(!di->pdata->no_backup_battery) ++ { ++ ret = twl4030backupbatt_voltage_setup(); ++ if (ret) ++ goto voltage_setup_fail; ++ } + + /* REVISIT do we need to request both IRQs ?? */ + +@@ -988,9 +1039,18 @@ static int __init twl4030_bci_battery_probe(struct platform_device *pdev) + twl4030_bci_battery_work); + schedule_delayed_work(&di->twl4030_bci_monitor_work, 0); + +- ret = power_supply_register(&pdev->dev, &di->bk_bat); ++ if(!pdata->no_backup_battery) ++ { ++ ret = power_supply_register(&pdev->dev, &di->bk_bat); ++ if (ret) { ++ dev_dbg(&pdev->dev, "failed to register backup battery\n"); ++ goto bk_batt_failed; ++ } ++ } ++ ++ ret = device_create_file(di->bat.dev, &dev_attr_charge_current); + if (ret) { +- dev_dbg(&pdev->dev, "failed to register backup battery\n"); ++ dev_err(&pdev->dev, "failed to create sysfs entries\n"); + goto bk_batt_failed; + } + +@@ -1001,7 +1061,8 @@ static int __init twl4030_bci_battery_probe(struct platform_device *pdev) + return 0; + + bk_batt_failed: +- power_supply_unregister(&di->bat); ++ if(!pdata->no_backup_battery) ++ power_supply_unregister(&di->bat); + batt_failed: + free_irq(irq, di); + chg_irq_fail: +diff --git a/include/linux/i2c/twl4030.h b/include/linux/i2c/twl4030.h +index 87accda..a188b6c 100644 +--- a/include/linux/i2c/twl4030.h ++++ b/include/linux/i2c/twl4030.h +@@ -299,6 +299,8 @@ int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); + struct twl4030_bci_platform_data { + int *battery_tmp_tbl; + unsigned int tblsize; ++ ++ bool no_backup_battery; + }; + + /* TWL4030_GPIO_MAX (18) GPIOs, with interrupts */ +-- +1.5.6.3 + diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery1-tps65950-charging-management-2.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery1-tps65950-charging-management-2.patch new file mode 100644 index 0000000000..ce5a98f69d --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery1-tps65950-charging-management-2.patch @@ -0,0 +1,246 @@ +diff --git a/drivers/power/twl4030_bci_battery.c b/drivers/power/twl4030_bci_battery.c +index eab0933..d1220d7 100644 +--- a/drivers/power/twl4030_bci_battery.c ++++ b/drivers/power/twl4030_bci_battery.c +@@ -15,6 +15,9 @@ + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + ++/* Boot with automatic charge */ ++#define CHARGE_MODE 1 ++ + #include + #include + #include +@@ -50,6 +53,7 @@ + /* Boot BCI flag bits */ + #define BCIAUTOWEN 0x020 + #define CONFIG_DONE 0x010 ++#define CVENAC 0x004 + #define BCIAUTOUSB 0x002 + #define BCIAUTOAC 0x001 + #define BCIMSTAT_MASK 0x03F +@@ -81,6 +85,11 @@ + #define REG_BB_CFG 0x012 + #define BBCHEN 0x010 + ++/* GPBR */ ++#define REG_GPBR1 0x0c ++#define MADC_HFCLK_EN 0x80 ++#define DEFAULT_MADC_CLK_EN 0x10 ++ + /* Power supply charge interrupt */ + #define REG_PWR_ISR1 0x00 + #define REG_PWR_IMR1 0x01 +@@ -129,8 +138,12 @@ + #define REG_BCIIREF1 0x027 + #define REG_BCIIREF2 0x028 + ++/* BCIMFTH1 */ ++#define REG_BCIMFTH1 0x016 ++ + /* Key */ + #define KEY_IIREF 0xE7 ++#define KEY_FTH1 0xD2 + #define REG_BCIMFKEY 0x011 + + /* Step size and prescaler ratio */ +@@ -432,15 +445,21 @@ static int twl4030battery_hw_presence_en(int enable) + /* + * Enable/Disable AC Charge funtionality. + */ +-static int twl4030charger_ac_en(int enable) ++static int twl4030charger_ac_en(int enable, int automatic) + { + int ret; + + if (enable) { + /* forcing the field BCIAUTOAC (BOOT_BCI[0) to 1 */ +- ret = clear_n_set(TWL4030_MODULE_PM_MASTER, 0, +- (CONFIG_DONE | BCIAUTOWEN | BCIAUTOAC), +- REG_BOOT_BCI); ++ if(!automatic) { ++ ret = clear_n_set(TWL4030_MODULE_PM_MASTER, BCIAUTOAC | CVENAC, ++ (CONFIG_DONE | BCIAUTOWEN), ++ REG_BOOT_BCI); ++ } else { ++ ret = clear_n_set(TWL4030_MODULE_PM_MASTER, 0, ++ (CONFIG_DONE | BCIAUTOWEN | BCIAUTOAC | CVENAC), ++ REG_BOOT_BCI); ++ } + if (ret) + return ret; + } else { +@@ -672,6 +691,9 @@ static int twl4030bci_status(void) + return ret; + } + ++#ifdef DEBUG ++ printk("BCI DEBUG: BCIMSTATEC Charge state is 0x%x\n", status); ++#endif + return (int) (status & BCIMSTAT_MASK); + } + +@@ -720,14 +742,43 @@ static int twl4030backupbatt_voltage_setup(void) + */ + static int twl4030battery_temp_setup(void) + { +- int ret; ++#ifdef DEBUG ++ u8 i; ++#endif ++ u8 ret; + + /* Enabling thermistor current */ +- ret = clear_n_set(TWL4030_MODULE_MAIN_CHARGE, 0, ITHEN, ++ ret = clear_n_set(TWL4030_MODULE_MAIN_CHARGE, 0, 0x1B, + REG_BCICTL1); + if (ret) + return ret; + ++#ifdef DEBUG ++ twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &ret, REG_BOOT_BCI); ++ printk("BCI DEBUG: BOOT_BCI Value is 0x%x\n", ret); ++ ++ twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &ret, REG_STS_HW_CONDITIONS); ++ printk("BCI DEBUG: STS_HW_CONDITIONS Value is 0x%x\n", ret); ++ ++ twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &ret, REG_BCICTL1); ++ printk("BCI DEBUG: BCICTL1 Value is 0x%x\n", ret); ++ ++ twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &ret, REG_BCICTL2); ++ printk("BCI DEBUG: BCICTL2 Value is 0x%x\n", ret); ++ ++ twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &ret, 0x0); ++ printk("BCI DEBUG: BCIMDEN Value is 0x%x\n", ret); ++ ++ twl4030_i2c_read_u8(TWL4030_MODULE_INTBR, &ret, REG_GPBR1); ++ printk("BCI DEBUG: GPBR1 Value is 0x%x\n", ret); ++ ++ for(i = 0x0; i <= 0x32; i++) ++ { ++ twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &ret, i); ++ printk("BCI DEBUG: BCI 0x%x Value is 0x%x\n", i, ret); ++ } ++#endif ++ + return 0; + } + +@@ -743,7 +794,6 @@ static inline int clear_n_set(u8 mod_no, u8 clear, u8 set, u8 reg) + ret = twl4030_i2c_read_u8(mod_no, &val, reg); + if (ret) + return ret; +- + /* Clearing all those bits to clear */ + val &= ~(clear); + +@@ -834,7 +884,19 @@ static void twl4030_bci_battery_external_power_changed(struct power_supply *psy) + static ssize_t + show_charge_current(struct device *dev, struct device_attribute *attr, char *buf) + { +- return sprintf(buf, "%d\n", read_bci_val(REG_BCIIREF1)); ++ u8 ctl; ++ int ret = read_bci_val(REG_BCIIREF1) & 0x1FF; ++ twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &ctl, REG_BCICTL1); ++ ++ if (ctl & CGAIN) ++ ret |= 0x200; ++ ++#ifdef DEBUG ++ /* Dump debug */ ++ twl4030battery_temp_setup(); ++#endif ++ ++ return sprintf(buf, "%d\n", ret); + } + + static ssize_t +@@ -859,13 +921,45 @@ set_charge_current(struct device *dev, struct device_attribute *attr, const char + if (ret) + return ret; + +- ret = twl4030_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE, (newCurrent >> 8) & 0x03, REG_BCIIREF2); ++ ret = twl4030_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE, (newCurrent >> 8) & 0x1, REG_BCIIREF2); + if (ret) + return ret; + ++ /* Set software-controlled charge */ ++ twl4030charger_ac_en(ENABLE, 0); ++ ++ /* Set CGAIN = 0 or 1 */ ++ if(newCurrent > 511) { ++ u8 tmp; ++ ++ /* Set CGAIN = 1 -- need to wait until automatic charge turns off */ ++ while(!ret) { ++ clear_n_set(TWL4030_MODULE_MAIN_CHARGE, 0, CGAIN | 0x1B, REG_BCICTL1); ++ twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &tmp, REG_BCICTL1); ++ ++ ret = tmp & CGAIN; ++ if(!ret) ++ mdelay(50); ++ } ++ } else { ++ u8 tmp; ++ ++ /* Set CGAIN = 0 -- need to wait until automatic charge turns off */ ++ while(!ret) { ++ clear_n_set(TWL4030_MODULE_MAIN_CHARGE, CGAIN, 0x1B, REG_BCICTL1); ++ twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &tmp, REG_BCICTL1); ++ ++ ret = !(tmp & CGAIN); ++ if(!ret) ++ mdelay(50); ++ } ++ } ++ ++ /* Set automatic charge (CGAIN = 0/1 persists) */ ++ twl4030charger_ac_en(ENABLE, 1); ++ + return count; + } +- + static DEVICE_ATTR(charge_current, S_IRUGO | S_IWUGO, show_charge_current, set_charge_current); + + static int twl4030_bk_bci_battery_get_property(struct power_supply *psy, +@@ -986,7 +1080,10 @@ static int __init twl4030_bci_battery_probe(struct platform_device *pdev) + di->bk_bat.external_power_changed = NULL; + di->pdata = pdata; + +- twl4030charger_ac_en(ENABLE); ++ /* Set up clocks */ ++ twl4030_i2c_write_u8(TWL4030_MODULE_INTBR, MADC_HFCLK_EN | DEFAULT_MADC_CLK_EN, REG_GPBR1); ++ ++ twl4030charger_ac_en(ENABLE, CHARGE_MODE); + twl4030charger_usb_en(ENABLE); + twl4030battery_hw_level_en(ENABLE); + twl4030battery_hw_presence_en(ENABLE); +@@ -1058,6 +1155,7 @@ static int __init twl4030_bci_battery_probe(struct platform_device *pdev) + twl4030_bk_bci_battery_work); + schedule_delayed_work(&di->twl4030_bk_bci_monitor_work, 500); + ++ set_charge_current (NULL, NULL, "1023", 4); + return 0; + + bk_batt_failed: +@@ -1071,7 +1169,7 @@ chg_irq_fail: + batt_irq_fail: + voltage_setup_fail: + temp_setup_fail: +- twl4030charger_ac_en(DISABLE); ++ twl4030charger_ac_en(DISABLE, CHARGE_MODE); + twl4030charger_usb_en(DISABLE); + twl4030battery_hw_level_en(DISABLE); + twl4030battery_hw_presence_en(DISABLE); +@@ -1085,7 +1183,7 @@ static int __exit twl4030_bci_battery_remove(struct platform_device *pdev) + struct twl4030_bci_device_info *di = platform_get_drvdata(pdev); + int irq; + +- twl4030charger_ac_en(DISABLE); ++ twl4030charger_ac_en(DISABLE, CHARGE_MODE); + twl4030charger_usb_en(DISABLE); + twl4030battery_hw_level_en(DISABLE); + twl4030battery_hw_presence_en(DISABLE); + + diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery2-bq27200-gpio-charged.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery2-bq27200-gpio-charged.patch new file mode 100644 index 0000000000..fd629078ca --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery2-bq27200-gpio-charged.patch @@ -0,0 +1,53 @@ +diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c +index bc6ef06..df7aa70 100644 +--- a/drivers/power/bq27x00_battery.c ++++ b/drivers/power/bq27x00_battery.c +@@ -28,6 +28,7 @@ + + #define DRIVER_VERSION "1.0.0" + ++#define BQ27x00_REG_MODE 0x00 + #define BQ27x00_REG_TEMP 0x06 + #define BQ27x00_REG_VOLT 0x08 + #define BQ27x00_REG_RSOC 0x0B /* Relative State-of-Charge */ +@@ -65,6 +66,7 @@ static enum power_supply_property bq27x00_battery_props[] = { + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_TEMP, ++ POWER_SUPPLY_PROP_ONLINE, + }; + + /* +@@ -83,6 +85,22 @@ static int bq27x00_read(u8 reg, int *rt_value, int b_single, + } + + /* ++ * Return the GPIO status (0 or 1) ++ * Or < 0 if something fails. ++ */ ++static int bq27x00_gpio(struct bq27x00_device_info *di) ++{ ++ int ret; ++ int gpio = 0; ++ ++ ret = bq27x00_read(BQ27x00_REG_MODE, &gpio, 0, di); ++ if (ret) ++ return ret; ++ ++ return (gpio & 0x40) >> 6; ++} ++ ++/* + * Return the battery temperature in Celcius degrees + * Or < 0 if something fails. + */ +@@ -184,6 +202,9 @@ static int bq27x00_battery_get_property(struct power_supply *psy, + case POWER_SUPPLY_PROP_TEMP: + val->intval = bq27x00_battery_temperature(di); + break; ++ case POWER_SUPPLY_PROP_ONLINE: ++ val->intval = bq27x00_gpio(di); ++ break; + default: + return -EINVAL; + } diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery2-bq27200-no-error-message.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery2-bq27200-no-error-message.patch new file mode 100644 index 0000000000..eb7c8c9699 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery2-bq27200-no-error-message.patch @@ -0,0 +1,39 @@ +--- a/drivers/power/bq27x00_battery.c ++++ b/drivers/power/bq27x00_battery.c +@@ -93,7 +93,6 @@ static int bq27x00_battery_temperature(struct bq27x00_device_info *di) + + ret = bq27x00_read(BQ27x00_REG_TEMP, &temp, 0, di); + if (ret) { +- dev_err(di->dev, "error reading temperature\n"); + return ret; + } + +@@ -111,7 +110,6 @@ static int bq27x00_battery_voltage(struct bq27x00_device_info *di) + + ret = bq27x00_read(BQ27x00_REG_VOLT, &volt, 0, di); + if (ret) { +- dev_err(di->dev, "error reading voltage\n"); + return ret; + } + +@@ -131,12 +129,10 @@ static int bq27x00_battery_current(struct bq27x00_device_info *di) + + ret = bq27x00_read(BQ27x00_REG_AI, &curr, 0, di); + if (ret) { +- dev_err(di->dev, "error reading current\n"); + return 0; + } + ret = bq27x00_read(BQ27x00_REG_FLAGS, &flags, 0, di); + if (ret < 0) { +- dev_err(di->dev, "error reading flags\n"); + return 0; + } + if ((flags & (1 << 7)) != 0) { +@@ -157,7 +153,6 @@ static int bq27x00_battery_rsoc(struct bq27x00_device_info *di) + + ret = bq27x00_read(BQ27x00_REG_RSOC, &rsoc, 1, di); + if (ret) { +- dev_err(di->dev, "error reading relative State-of-Charge\n"); + return ret; + } + diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/beagle-asoc.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/beagle-asoc.patch new file mode 100644 index 0000000000..b2b920037e --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/beagle-asoc.patch @@ -0,0 +1,35 @@ +diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig +index 4f7f040..ccd8973 100644 +--- a/sound/soc/omap/Kconfig ++++ b/sound/soc/omap/Kconfig +@@ -55,3 +55,13 @@ config SND_OMAP_SOC_OMAP3_PANDORA + select SND_SOC_TWL4030 + help + Say Y if you want to add support for SoC audio on the OMAP3 Pandora. ++ ++config SND_OMAP_SOC_OMAP3_BEAGLE ++ tristate "SoC Audio support for OMAP3 Beagle" ++ depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_BEAGLE ++ select SND_OMAP_SOC_MCBSP ++ select SND_SOC_TWL4030 ++ help ++ Say Y if you want to add support for SoC audio on the Beagleboard. ++ ++ +diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile +index 76fedd9..0c9e4ac 100644 +--- a/sound/soc/omap/Makefile ++++ b/sound/soc/omap/Makefile +@@ -12,6 +12,7 @@ snd-soc-overo-objs := overo.o + snd-soc-omap2evm-objs := omap2evm.o + snd-soc-sdp3430-objs := sdp3430.o + snd-soc-omap3pandora-objs := omap3pandora.o ++snd-soc-omap3beagle-objs := omap3beagle.o + + obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o + obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o +@@ -19,3 +20,4 @@ obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o + obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o + obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o + obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o ++obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/board-omap3beagle.c b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/board-omap3beagle.c new file mode 100644 index 0000000000..26efafff21 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/board-omap3beagle.c @@ -0,0 +1,739 @@ +/* + * linux/arch/arm/mach-omap2/board-omap3beagle.c + * + * Copyright (C) 2008 Texas Instruments + * + * Modified from mach-omap2/board-3430sdp.c + * + * Initial code: Syed Mohammed Khasim + * + * 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 +#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 +#include +#include + +#include "twl4030-generic-scripts.h" +#include "mmc-twl4030.h" + + +#define GPMC_CS0_BASE 0x60 +#define GPMC_CS_SIZE 0x30 + +#define NAND_BLOCK_SIZE SZ_128K + +#define OMAP3_AC_GPIO 136 //Int1 DRDY +#define OMAP3_TS_GPIO 162 +#define TB_BL_PWM_TIMER 9 +#define TB_KILL_POWER_GPIO 168 + +static struct mtd_partition omap3beagle_nand_partitions[] = { + /* All the partition sizes are listed in terms of NAND block size */ + { + .name = "X-Loader", + .offset = 0, + .size = 4 * NAND_BLOCK_SIZE, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "U-Boot", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */ + .size = 15 * NAND_BLOCK_SIZE, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "U-Boot Env", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */ + .size = 1 * NAND_BLOCK_SIZE, + }, + { + .name = "Kernel", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */ + .size = 32 * NAND_BLOCK_SIZE, + }, + { + .name = "File System", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */ + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct omap_nand_platform_data omap3beagle_nand_data = { + .options = NAND_BUSWIDTH_16, + .parts = omap3beagle_nand_partitions, + .nr_parts = ARRAY_SIZE(omap3beagle_nand_partitions), + .dma_channel = -1, /* disable DMA in OMAP NAND driver */ + .nand_setup = NULL, + .dev_ready = NULL, +}; + +static struct resource omap3beagle_nand_resource = { + .flags = IORESOURCE_MEM, +}; + +static struct platform_device omap3beagle_nand_device = { + .name = "omap2-nand", + .id = -1, + .dev = { + .platform_data = &omap3beagle_nand_data, + }, + .num_resources = 1, + .resource = &omap3beagle_nand_resource, +}; + +#include "sdram-micron-mt46h32m32lf-6.h" + +static struct omap_uart_config omap3_beagle_uart_config __initdata = { + .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), +}; + +static struct twl4030_usb_data beagle_usb_data = { + .usb_mode = T2_USB_MODE_ULPI, +}; + +static struct twl4030_hsmmc_info mmc[] = { + { + .mmc = 1, + .wires = 8, + .gpio_wp = 29, + }, + {} /* Terminator */ +}; + +static struct regulator_consumer_supply beagle_vmmc1_supply = { + .supply = "vmmc", +}; + +static struct regulator_consumer_supply beagle_vsim_supply = { + .supply = "vmmc_aux", +}; + +static struct gpio_led gpio_leds[]; + +static int beagle_twl_gpio_setup(struct device *dev, + unsigned gpio, unsigned ngpio) +{ + /* gpio + 0 is "mmc0_cd" (input/IRQ) */ + omap_cfg_reg(AH8_34XX_GPIO29); + mmc[0].gpio_cd = gpio + 0; + twl4030_mmc_init(mmc); + + /* link regulators to MMC adapters */ + beagle_vmmc1_supply.dev = mmc[0].dev; + beagle_vsim_supply.dev = mmc[0].dev; + + /* REVISIT: need ehci-omap hooks for external VBUS + * power switch and overcurrent detect + */ + +#if 0 /* TODO: This needs to be modified to not rely on u-boot */ + gpio_request(gpio + 1, "EHCI_nOC"); + gpio_direction_input(gpio + 1); + + /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */ + gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR"); + gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1); + + /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ + gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; +#endif + return 0; +} + +static struct twl4030_gpio_platform_data beagle_gpio_data = { + .gpio_base = OMAP_MAX_GPIO_LINES, + .irq_base = TWL4030_GPIO_IRQ_BASE, + .irq_end = TWL4030_GPIO_IRQ_END, + .use_leds = true, + .pullups = BIT(1), + .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13) + | BIT(15) | BIT(16) | BIT(17), + .setup = beagle_twl_gpio_setup, +}; + +static struct platform_device omap3_beagle_lcd_device = { + .name = "omap3beagle_lcd", + .id = -1, +}; + +static struct regulator_consumer_supply beagle_vdac_supply = { + .supply = "vdac", + .dev = &omap3_beagle_lcd_device.dev, +}; + +static struct regulator_consumer_supply beagle_vdvi_supply = { + .supply = "vdvi", + .dev = &omap3_beagle_lcd_device.dev, +}; + +/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ +static struct regulator_init_data beagle_vmmc1 = { + .constraints = { + .min_uV = 1850000, + .max_uV = 3150000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &beagle_vmmc1_supply, +}; + +/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */ +static struct regulator_init_data beagle_vsim = { + .constraints = { + .min_uV = 1800000, + .max_uV = 3000000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &beagle_vsim_supply, +}; + +/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */ +static struct regulator_init_data beagle_vdac = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &beagle_vdac_supply, +}; + +/* VPLL2 for digital video outputs */ +static struct regulator_init_data beagle_vpll2 = { + .constraints = { + .name = "VDVI", + .min_uV = 1800000, + .max_uV = 1800000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &beagle_vdvi_supply, +}; + +static const struct twl4030_resconfig beagle_resconfig[] = { + /* disable regulators that u-boot left enabled; the + * devices' drivers should be managing these. + */ + { .resource = RES_VAUX3, }, /* not even connected! */ + { .resource = RES_VMMC1, }, + { .resource = RES_VSIM, }, + { .resource = RES_VPLL2, }, + { .resource = RES_VDAC, }, + { .resource = RES_VUSB_1V5, }, + { .resource = RES_VUSB_1V8, }, + { .resource = RES_VUSB_3V1, }, + { 0, }, +}; + +static struct twl4030_power_data beagle_power_data = { + .resource_config = beagle_resconfig, + /* REVISIT can't use GENERIC3430_T2SCRIPTS_DATA; + * among other things, it makes reboot fail. + */ +}; + +static struct twl4030_bci_platform_data touchbook_bci_data = { + .tblsize = 0, + .no_backup_battery = 1, +}; + +static struct twl4030_platform_data beagle_twldata = { + .irq_base = TWL4030_IRQ_BASE, + .irq_end = TWL4030_IRQ_END, + + /* platform_data for children goes here */ + .usb = &beagle_usb_data, + .gpio = &beagle_gpio_data, + .power = &beagle_power_data, + .vmmc1 = &beagle_vmmc1, + .vsim = &beagle_vsim, + .vdac = &beagle_vdac, + .vpll2 = &beagle_vpll2, + + /* TouchBook BCI */ + .bci = &touchbook_bci_data, +}; + +static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl4030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &beagle_twldata, + }, +}; + +static struct i2c_board_info __initdata touchBook_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("bq27200", 0x55), + }, +}; + +static int __init omap3_beagle_i2c_init(void) +{ + /* Standard BeagleBoard bus */ + omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo, + ARRAY_SIZE(beagle_i2c_boardinfo)); + + /* TouchBook keyboard bus */ + omap_register_i2c_bus(3, 100, touchBook_i2c_boardinfo, + ARRAY_SIZE(touchBook_i2c_boardinfo)); + + return 0; +} + +static void __init omap3_ads7846_init(void) +{ + if (gpio_request(OMAP3_TS_GPIO, "ads7846_pen_down")) { + printk(KERN_ERR "Failed to request GPIO %d for " + "ads7846 pen down IRQ\n", OMAP3_TS_GPIO); + return; + } + + gpio_direction_input(OMAP3_TS_GPIO); + omap_set_gpio_debounce(OMAP3_TS_GPIO, 1); + omap_set_gpio_debounce_time(OMAP3_TS_GPIO, 0xa); +} + +static struct ads7846_platform_data ads7846_config = { + .x_min = 100, + .y_min = 265, + .x_max = 3950, + .y_max = 3750, + .x_plate_ohms = 40, + .pressure_max = 255, + .debounce_max = 10, + .debounce_tol = 5, + .debounce_rep = 1, + .gpio_pendown = OMAP3_TS_GPIO, + .keep_vref_on = 1, +}; + +static struct omap2_mcspi_device_config ads7846_mcspi_config = { + .turbo_mode = 0, + .single_channel = 1, /* 0: slave, 1: master */ +}; + +static struct spi_board_info omap3_ads7846_spi_board_info[] __initdata = { + { + .modalias = "ads7846", + .bus_num = 4, + .chip_select = 0, + .max_speed_hz = 1500000, + .controller_data = &ads7846_mcspi_config, //(void *) 161, + .irq = OMAP_GPIO_IRQ(OMAP3_TS_GPIO), + .platform_data = &ads7846_config, + } +}; + +static void __init omap3_beagle_init_irq(void) +{ + omap2_init_common_hw(mt46h32m32lf6_sdrc_params); + omap_init_irq(); + omap_gpio_init(); +} + +static struct gpio_led gpio_leds[] = { + { + .name = "beagleboard::usr0", + .default_trigger = "heartbeat", + .gpio = 150, + }, + { + .name = "beagleboard::usr1", + .default_trigger = "mmc0", + .gpio = 149, + }, + { + .name = "beagleboard::pmu_stat", + .gpio = -EINVAL, /* gets replaced */ + .active_low = true, + }, +}; + +static struct gpio_led_platform_data gpio_led_info = { + .leds = gpio_leds, + .num_leds = ARRAY_SIZE(gpio_leds), +}; + +static struct platform_device leds_gpio = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &gpio_led_info, + }, +}; + +static struct gpio_keys_button gpio_buttons[] = { + { + .code = BTN_EXTRA, + .gpio = 7, + .desc = "user", + .wakeup = 1, + }, + { + .code = KEY_POWER, + .gpio = 183, + .desc = "power", + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data gpio_key_info = { + .buttons = gpio_buttons, + .nbuttons = ARRAY_SIZE(gpio_buttons), +}; + +static struct platform_device keys_gpio = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &gpio_key_info, + }, +}; + +/* DSS */ + +static int beagle_enable_dvi(struct omap_display *display) +{ + if (display->hw_config.panel_reset_gpio != -1) + gpio_set_value(display->hw_config.panel_reset_gpio, 1); + + return 0; +} + +static void beagle_disable_dvi(struct omap_display *display) +{ + if (display->hw_config.panel_reset_gpio != -1) + gpio_set_value(display->hw_config.panel_reset_gpio, 0); +} + +static struct omap_dss_display_config beagle_display_data_dvi = { + .type = OMAP_DISPLAY_TYPE_DPI, + .name = "dvi", + .panel_name = "panel-generic", + .u.dpi.data_lines = 24, + .panel_reset_gpio = 176, + .panel_enable = beagle_enable_dvi, + .panel_disable = beagle_disable_dvi, +}; + + +static int beagle_panel_enable_tv(struct omap_display *display) +{ +#define ENABLE_VDAC_DEDICATED 0x03 +#define ENABLE_VDAC_DEV_GRP 0x20 + + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, + ENABLE_VDAC_DEDICATED, + TWL4030_VDAC_DEDICATED); + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, + ENABLE_VDAC_DEV_GRP, TWL4030_VDAC_DEV_GRP); + + return 0; +} + +static void beagle_panel_disable_tv(struct omap_display *display) +{ + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x00, + TWL4030_VDAC_DEDICATED); + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x00, + TWL4030_VDAC_DEV_GRP); +} + +static struct omap_dss_display_config beagle_display_data_tv = { + .type = OMAP_DISPLAY_TYPE_VENC, + .name = "tv", + .u.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO, + .panel_enable = beagle_panel_enable_tv, + .panel_disable = beagle_panel_disable_tv, +}; + +static struct omap_dss_board_info beagle_dss_data = { + .num_displays = 2, + .displays = { + &beagle_display_data_dvi, + &beagle_display_data_tv, + } +}; + +static struct platform_device beagle_dss_device = { + .name = "omapdss", + .id = -1, + .dev = { + .platform_data = &beagle_dss_data, + }, +}; + +static void __init beagle_display_init(void) +{ + int r; + + r = gpio_request(beagle_display_data_dvi.panel_reset_gpio, "DVI reset"); + if (r < 0) { + printk(KERN_ERR "Unable to get DVI reset GPIO\n"); + return; + } + + gpio_direction_output(beagle_display_data_dvi.panel_reset_gpio, 0); +} + +static struct omap_board_config_kernel omap3_beagle_config[] __initdata = { + { OMAP_TAG_UART, &omap3_beagle_uart_config }, +}; + +static struct platform_device *omap3_beagle_devices[] __initdata = { + &beagle_dss_device, + &leds_gpio, + &keys_gpio, +}; + +static void __init omap3beagle_flash_init(void) +{ + u8 cs = 0; + u8 nandcs = GPMC_CS_NUM + 1; + + u32 gpmc_base_add = OMAP34XX_GPMC_VIRT; + + /* find out the chip-select on which NAND exists */ + while (cs < GPMC_CS_NUM) { + u32 ret = 0; + ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); + + if ((ret & 0xC00) == 0x800) { + printk(KERN_INFO "Found NAND on CS%d\n", cs); + if (nandcs > GPMC_CS_NUM) + nandcs = cs; + } + cs++; + } + + if (nandcs > GPMC_CS_NUM) { + printk(KERN_INFO "NAND: Unable to find configuration " + "in GPMC\n "); + return; + } + + if (nandcs < GPMC_CS_NUM) { + omap3beagle_nand_data.cs = nandcs; + omap3beagle_nand_data.gpmc_cs_baseaddr = (void *) + (gpmc_base_add + GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE); + omap3beagle_nand_data.gpmc_baseaddr = (void *) (gpmc_base_add); + + printk(KERN_INFO "Registering NAND on CS%d\n", nandcs); + if (platform_device_register(&omap3beagle_nand_device) < 0) + printk(KERN_ERR "Unable to register NAND device\n"); + } +} + +static void __init omap3_mma7455l_init(void) +{ + int ret; + + ret = gpio_request(OMAP3_AC_GPIO, "mma7455l"); + if (ret < 0) { + printk(KERN_ERR "Failed to request GPIO %d for mma7455l IRQ\n", OMAP3_AC_GPIO); + return; + } + + gpio_direction_input(OMAP3_AC_GPIO); +} + +static struct mma7455l_platform_data mma7455l_config = { + .calibration_x = -4, //26 for Beagleboard + .calibration_y = 28, //44 for Beagleboard + .calibration_z = -28, //26 for Beagleboard +}; + +static struct omap2_mcspi_device_config mma7455l_mcspi_config = { + .turbo_mode = 0, + .single_channel = 1, /* 0: slave, 1: master */ +}; + +static struct spi_board_info omap3_mma7455l_spi_board_info[] __initdata = { + { + .modalias = "mma7455l", + .bus_num = 3, + .chip_select = 0, + .max_speed_hz = 200000, + .irq = OMAP_GPIO_IRQ(OMAP3_AC_GPIO), + .controller_data = &mma7455l_mcspi_config, //(void *) 135, + .platform_data = &mma7455l_config, + } +}; + +static int touchbook_backlight_brightness = 50; +static struct omap_dm_timer *touchbook_backlight_pwm; + +static int touchbook_backlight_read(struct backlight_device *bd) +{ + return touchbook_backlight_brightness; +} + +static int touchbook_backlight_update(struct backlight_device *bd) +{ + int value = bd->props.brightness; + touchbook_backlight_brightness = value; + + /* Frequency calculation: + - For 200Hz PWM, you want to load -164 (=> -32768Hz / 200Hz). + - Minimum duty cycle for the backlight is 15%. + - You have (164*0.85) => ~140 levels of brightness. + */ + + /* Convert from 0-100 range to 0-140 range */ + value = (value * 14) / 10 / 2; + + /* For maximum brightness, just stop the timer... */ + if(value != bd->props.max_brightness) + { + omap_dm_timer_set_load(touchbook_backlight_pwm, 1, -164); + omap_dm_timer_set_match(touchbook_backlight_pwm, 1, -24 - value); + omap_dm_timer_write_counter(touchbook_backlight_pwm, -1); + //omap_dm_timer_stop(touchbook_backlight_pwm); + omap_dm_timer_start(touchbook_backlight_pwm); + } + else + omap_dm_timer_stop(touchbook_backlight_pwm); + + + return 0; +} + +static struct backlight_ops touchbook_backlight_properties = { + .get_brightness = touchbook_backlight_read, + .update_status = touchbook_backlight_update, +}; + +static void __init omap3_touchbook_backlight_init(void) +{ + static struct backlight_device *bd; + bd = backlight_device_register("touchbook", NULL, NULL, &touchbook_backlight_properties); + + if(bd) + { + touchbook_backlight_pwm = omap_dm_timer_request_specific(TB_BL_PWM_TIMER); + omap_dm_timer_enable(touchbook_backlight_pwm); + omap_dm_timer_set_source(touchbook_backlight_pwm, OMAP_TIMER_SRC_32_KHZ); + omap_dm_timer_set_pwm(touchbook_backlight_pwm, 1, 1, OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE); + + bd->props.max_brightness = 100; + bd->props.brightness = touchbook_backlight_brightness; + } + + touchbook_backlight_update(bd); +} + +static void omap3_touchbook_poweroff(void) +{ + int r; + + r = gpio_request(TB_KILL_POWER_GPIO, "DVI reset"); + if (r < 0) { + printk(KERN_ERR "Unable to get kill power GPIO\n"); + return; + } + + gpio_direction_output(TB_KILL_POWER_GPIO, 0); +} + +static void __init omap3_beagle_init(void) +{ + pm_power_off = omap3_touchbook_poweroff; + + omap3_beagle_i2c_init(); + platform_add_devices(omap3_beagle_devices, + ARRAY_SIZE(omap3_beagle_devices)); + omap_board_config = omap3_beagle_config; + omap_board_config_size = ARRAY_SIZE(omap3_beagle_config); + omap_serial_init(); + + omap_cfg_reg(J25_34XX_GPIO170); + + omap3beagle_flash_init(); + beagle_display_init(); + omap3_touchbook_backlight_init(); + + /* Touch Book */ + spi_register_board_info(omap3_ads7846_spi_board_info, ARRAY_SIZE(omap3_ads7846_spi_board_info)); + spi_register_board_info(omap3_mma7455l_spi_board_info, ARRAY_SIZE(omap3_mma7455l_spi_board_info)); + + omap3_ads7846_init(); + omap3_mma7455l_init(); + + usb_musb_init(); + usb_ehci_init(); +} + +static void __init omap3_beagle_map_io(void) +{ + omap2_set_globals_343x(); + omap2_map_common_io(); +} + +MACHINE_START(OMAP3_BEAGLE, "OMAP3 Touch Book") + /* Maintainer: Gregoire Gentil - http://www.alwaysinnovating.com */ + .phys_io = 0x48000000, + .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, + .boot_params = 0x80000100, + .map_io = omap3_beagle_map_io, + .init_irq = omap3_beagle_init_irq, + .init_machine = omap3_beagle_init, + .timer = &omap_timer, +MACHINE_END diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/boot-no-power-message.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/boot-no-power-message.patch new file mode 100644 index 0000000000..4be59a4212 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/boot-no-power-message.patch @@ -0,0 +1,11 @@ +--- a/arch/arm/mach-omap2/pm34xx.c 2009-07-18 10:13:43.000000000 -0700 ++++ b/arch/arm/mach-omap2/pm34xx.c 2009-07-18 10:13:54.000000000 -0700 +@@ -625,7 +625,7 @@ + struct power_state *pwrst, *tmp; + int ret; + +- printk(KERN_ERR "Power Management for TI OMAP3.\n"); ++// printk(KERN_ERR "Power Management for TI OMAP3.\n"); + + /* XXX prcm_setup_regs needs to be before enabling hw + * supervised mode for powerdomains */ diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/defconfig b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/defconfig new file mode 100644 index 0000000000..2ff46a4832 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/defconfig @@ -0,0 +1,2720 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.29-omap1 +# Fri May 29 14:47:52 2009 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_OPROFILE_ARMV7=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_ELF_CORE is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_COMPAT_BRK is not set +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +# CONFIG_MARKERS is not set +CONFIG_OPROFILE=y +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_BLOCK=y +CONFIG_LBD=y +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_FREEZER=y + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +CONFIG_ARCH_OMAP=y +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_W90X900 is not set + +# +# TI OMAP Implementations +# +CONFIG_ARCH_OMAP_OTG=y +# CONFIG_ARCH_OMAP1 is not set +# CONFIG_ARCH_OMAP2 is not set +CONFIG_ARCH_OMAP3=y + +# +# OMAP Feature Selections +# +# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set +# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set +CONFIG_OMAP_SMARTREFLEX=y +# CONFIG_OMAP_SMARTREFLEX_TESTING is not set +CONFIG_OMAP_RESET_CLOCKS=y +CONFIG_OMAP_BOOT_TAG=y +CONFIG_OMAP_BOOT_REASON=y +# CONFIG_OMAP_COMPONENT_VERSION is not set +# CONFIG_OMAP_GPIO_SWITCH is not set +# CONFIG_OMAP_MUX is not set +CONFIG_OMAP_MCBSP=y +# CONFIG_OMAP_MBOX_FWK is not set +# CONFIG_OMAP_IOMMU is not set +# CONFIG_OMAP_MPU_TIMER is not set +CONFIG_OMAP_32K_TIMER=y +CONFIG_OMAP_32K_TIMER_HZ=128 +CONFIG_OMAP_TICK_GPTIMER=12 +CONFIG_OMAP_DM_TIMER=y +# CONFIG_OMAP_LL_DEBUG_UART1 is not set +# CONFIG_OMAP_LL_DEBUG_UART2 is not set +CONFIG_OMAP_LL_DEBUG_UART3=y +CONFIG_ARCH_OMAP34XX=y +CONFIG_ARCH_OMAP3430=y + +# +# OMAP Board Type +# +# CONFIG_MACH_NOKIA_RX51 is not set +# CONFIG_MACH_OMAP_LDP is not set +# CONFIG_MACH_OMAP_3430SDP is not set +# CONFIG_MACH_OMAP3EVM is not set +CONFIG_MACH_OMAP3_BEAGLE=y +# CONFIG_MACH_OVERO is not set +# CONFIG_MACH_OMAP3_PANDORA is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_V7=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_IFAR=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +CONFIG_ARM_THUMBEE=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_HAS_TLS_REG=y +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_VMSPLIT_3G is not set +CONFIG_VMSPLIT_2G=y +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0x80000000 +# CONFIG_PREEMPT is not set +CONFIG_HZ=128 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +CONFIG_ARCH_FLATMEM_HAS_HOLES=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_LEDS=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE=" debug " +# CONFIG_XIP_KERNEL is not set +CONFIG_KEXEC=y +CONFIG_ATAGS_PROC=y + +# +# CPU Power Management +# +# CONFIG_CPU_FREQ is not set +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=y +# CONFIG_ARM_ERRATUM_451034 is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_HAVE_AOUT=y +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_MISC=y + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_DEBUG=y +# CONFIG_PM_VERBOSE is not set +CONFIG_CAN_PM_TRACE=y +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_SUSPEND_FREEZER=y +# CONFIG_APM_EMULATION is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_COMPAT_NET_DEV_OPS=y +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=m +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +# CONFIG_IPV6_PIMSM_V2 is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +# CONFIG_NETFILTER_TPROXY is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +# CONFIG_NETFILTER_XT_TARGET_TRACE is not set +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +CONFIG_IP_VS_DEBUG=y +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_IDLETIMER=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_DCCP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_RAW=m +# CONFIG_BRIDGE_NF_EBTABLES is not set +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m + +# +# DCCP CCIDs Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=y +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +CONFIG_IP_DCCP_TFRC_LIB=y + +# +# DCCP Kernel Hacking +# +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_STP=m +CONFIG_GARP=m +CONFIG_BRIDGE=m +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +CONFIG_WAN_ROUTER=m +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_CLS_IND=y +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +CONFIG_CAN=m +CONFIG_CAN_RAW=m +CONFIG_CAN_BCM=m + +# +# CAN Device Drivers +# +CONFIG_CAN_VCAN=m +# CONFIG_CAN_DEBUG_DEVICES is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +CONFIG_IRDA_ULTRA=y + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_DEBUG=y + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TOIM3232_DONGLE=m +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +# CONFIG_ACT200L_DONGLE is not set +CONFIG_KINGSUN_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KS959_DONGLE=m + +# +# FIR device drivers +# +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_MCS_FIR=m +# CONFIG_OMAP_IR is not set +CONFIG_BT=y +CONFIG_BT_L2CAP=y +CONFIG_BT_SCO=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIBTUSB=y +CONFIG_BT_HCIBTSDIO=y +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIBCM203X=y +CONFIG_BT_HCIBPA10X=y +CONFIG_BT_HCIBFUSB=y +# CONFIG_BT_HCIBRF6150 is not set +# CONFIG_BT_HCIH4P is not set +# CONFIG_BT_HCIVHCI is not set +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +# CONFIG_RXKAD is not set +# CONFIG_PHONET is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_CFG80211=y +# CONFIG_CFG80211_REG_DEBUG is not set +CONFIG_NL80211=y +CONFIG_WIRELESS_OLD_REGULATORY=y +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_LIB80211=y +CONFIG_LIB80211_CRYPT_WEP=y +CONFIG_LIB80211_CRYPT_CCMP=y +CONFIG_LIB80211_CRYPT_TKIP=y +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=y + +# +# Rate control algorithm selection +# +CONFIG_MAC80211_RC_PID=y +# CONFIG_MAC80211_RC_MINSTREL is not set +CONFIG_MAC80211_RC_DEFAULT_PID=y +# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set +CONFIG_MAC80211_RC_DEFAULT="pid" +# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_WIMAX=m +CONFIG_WIMAX_DEBUG_LEVEL=8 +# CONFIG_RFKILL is not set +CONFIG_NET_9P=m +# CONFIG_NET_9P_DEBUG is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_OMAP2=y +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +CONFIG_MTD_NAND_PLATFORM=y +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_GLUEBI is not set + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_BLK_DEV_XIP is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ICS932S401 is not set +# CONFIG_OMAP_STI is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +CONFIG_EEPROM_93CX6=y +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_RAID_ATTRS=m +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=m +# CONFIG_LIBFC is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_ATA is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_DELAY=m +# CONFIG_DM_UEVENT is not set +CONFIG_NETDEVICES=y +CONFIG_DUMMY=m +CONFIG_BONDING=m +CONFIG_MACVLAN=m +CONFIG_EQUALIZER=m +CONFIG_TUN=m +CONFIG_VETH=m +# CONFIG_NET_ETHERNET is not set +CONFIG_MII=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +CONFIG_WLAN_80211=y +CONFIG_LIBERTAS=y +CONFIG_LIBERTAS_USB=y +# CONFIG_LIBERTAS_SDIO is not set +# CONFIG_LIBERTAS_DEBUG is not set +# CONFIG_LIBERTAS_THINFIRM is not set +CONFIG_USB_ZD1201=y +CONFIG_USB_NET_RNDIS_WLAN=y +CONFIG_RTL8187=y +# CONFIG_MAC80211_HWSIM is not set +CONFIG_P54_COMMON=y +CONFIG_P54_USB=y +# CONFIG_IWLWIFI_LEDS is not set +CONFIG_HOSTAP=y +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_B43=y +CONFIG_B43_LEDS=y +# CONFIG_B43_DEBUG is not set +# CONFIG_B43LEGACY is not set +CONFIG_ZD1211RW=y +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_RT2X00=y +CONFIG_RT2500USB=y +CONFIG_RT73USB=y +CONFIG_RT2X00_LIB_USB=y +CONFIG_RT2X00_LIB=y +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set + +# +# WiMAX Wireless Broadband devices +# +# CONFIG_WIMAX_I2400M_USB is not set +# CONFIG_WIMAX_I2400M_SDIO is not set + +# +# USB Network Adapters +# +CONFIG_USB_CATC=y +CONFIG_USB_KAWETH=y +CONFIG_USB_PEGASUS=y +CONFIG_USB_RTL8150=y +CONFIG_USB_USBNET=y +CONFIG_USB_NET_AX8817X=y +CONFIG_USB_NET_CDCETHER=y +CONFIG_USB_NET_DM9601=y +CONFIG_USB_NET_SMSC95XX=y +CONFIG_USB_NET_GL620A=y +CONFIG_USB_NET_NET1080=y +CONFIG_USB_NET_PLUSB=y +CONFIG_USB_NET_MCS7830=y +CONFIG_USB_NET_RNDIS_HOST=y +CONFIG_USB_NET_CDC_SUBSET=y +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +CONFIG_USB_NET_ZAURUS=y +# CONFIG_WAN is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +# CONFIG_ATM_TCP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +# CONFIG_PPPOATM is not set +CONFIG_PPPOL2TP=m +# CONFIG_SLIP is not set +CONFIG_SLHC=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETPOLL=y +CONFIG_NETPOLL_TRAP=y +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=y +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_TWL4030 is not set +# CONFIG_KEYBOARD_LM8323 is not set +CONFIG_KEYBOARD_GPIO=y +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_GPIO is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=y +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_TSC2005 is not set +# CONFIG_TOUCHSCREEN_TSC210X is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +CONFIG_INPUT_TWL4030_PWRBUTTON=y +CONFIG_INPUT_UINPUT=y +CONFIG_INPUT_MMA7455L=y + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=32 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +CONFIG_I2C_OMAP=y +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_PCF8575 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +CONFIG_TWL4030_MADC=y +CONFIG_TWL4030_POWEROFF=y +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_TSL2563 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +CONFIG_SPI_OMAP24XX=y + +# +# SPI Protocol Masters +# +# CONFIG_SPI_TSC210X is not set +# CONFIG_SPI_TSC2301 is not set +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +CONFIG_GPIO_TWL4030=y + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_W1 is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_BATTERY_DS2760 is not set +CONFIG_TWL4030_BCI_BATTERY=y +CONFIG_BATTERY_BQ27x00=y +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7473 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_TSC210X is not set +CONFIG_SENSORS_OMAP34XX=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_OMAP_WATCHDOG=y + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +CONFIG_SSB=y +# CONFIG_SSB_SILENT is not set +# CONFIG_SSB_DEBUG is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_TPS65010 is not set +CONFIG_TWL4030_CORE=y +# CONFIG_TWL4030_POWER is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L2_COMMON=m +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_DVB_CORE=m +CONFIG_VIDEO_MEDIA=m + +# +# Multimedia drivers +# +CONFIG_MEDIA_ATTACH=y +CONFIG_MEDIA_TUNER=m +# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L1=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_VIVI=m +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_VIDEO_AU0828 is not set +# CONFIG_VIDEO_OMAP3 is not set +# CONFIG_SOC_CAMERA is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_PVRUSB2_DVB=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_USB_VICAM=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_ET61X251=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_USB_W9968CF=m +CONFIG_USB_OV511=m +CONFIG_USB_SE401=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STV680=m +CONFIG_USB_ZC0301=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_ZR364XX=m +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_S2255=m +CONFIG_RADIO_ADAPTERS=y +# CONFIG_USB_DSBR is not set +# CONFIG_USB_SI470X is not set +# CONFIG_USB_MR800 is not set +# CONFIG_RADIO_TEA5764 is not set +CONFIG_DVB_DYNAMIC_MINORS=y +CONFIG_DVB_CAPTURE_DRIVERS=y +# CONFIG_TTPCI_EEPROM is not set + +# +# Supported USB Adapters +# +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_SIANO_SMS1XXX=m +CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS=y + +# +# Supported FlexCopII (B2C2) Adapters +# +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set + +# +# Supported DVB Frontends +# + +# +# Customise DVB Frontends +# +# CONFIG_DVB_FE_CUSTOMISE is not set + +# +# Multistandard (satellite) frontends +# +CONFIG_DVB_STB0899=m +CONFIG_DVB_STB6100=m + +# +# DVB-S (satellite) frontends +# +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_MT312=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8261=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_SI21XX=m + +# +# DVB-T (terrestrial) frontends +# +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_DRX397XD=m +CONFIG_DVB_L64781=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_TDA10048=m + +# +# DVB-C (cable) frontends +# +CONFIG_DVB_VES1820=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +CONFIG_DVB_NXT200X=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGDT3304=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_S5H1411=m + +# +# ISDB-T (terrestrial) frontends +# +CONFIG_DVB_S921=m + +# +# Digital terrestrial only tuners/PLL +# +CONFIG_DVB_PLL=m +CONFIG_DVB_TUNER_DIB0070=m + +# +# SEC control devices for DVB-S +# +CONFIG_DVB_LNBP21=m +# CONFIG_DVB_ISL6405 is not set +CONFIG_DVB_ISL6421=m +CONFIG_DVB_LGS8GL5=m + +# +# Tools to develop new frontends +# +# CONFIG_DVB_DUMMY_FE is not set +CONFIG_DVB_AF9013=m +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set +CONFIG_OMAP2_DSS=y +CONFIG_OMAP2_DSS_VRAM_SIZE=14 +CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y +# CONFIG_OMAP2_DSS_RFBI is not set +CONFIG_OMAP2_DSS_VENC=y +# CONFIG_OMAP2_DSS_SDI is not set +CONFIG_OMAP2_DSS_DSI=y +CONFIG_OMAP2_DSS_USE_DSI_PLL=y +# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set +CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=1 + +# +# OMAP2/3 Display Device Drivers +# +CONFIG_PANEL_GENERIC=y +CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C=m +# CONFIG_PANEL_SHARP_LS037V7DW01 is not set +# CONFIG_PANEL_N800 is not set +# CONFIG_CTRL_BLIZZARD is not set +CONFIG_FB_OMAP2=y +CONFIG_FB_OMAP2_DEBUG_SUPPORT=y +# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set +CONFIG_FB_OMAP2_NUM_FBS=3 +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=y + +# +# Display device support +# +CONFIG_DISPLAY_SUPPORT=y + +# +# Display hardware drivers +# + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_HWDEP=y +CONFIG_SND_RAWMIDI=y +CONFIG_SND_SEQUENCER=m +# CONFIG_SND_SEQ_DUMMY is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_HRTIMER=m +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +# CONFIG_SND_ARM is not set +CONFIG_SND_SPI=y +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_SOC=y +CONFIG_SND_OMAP_SOC=y +CONFIG_SND_OMAP_SOC_MCBSP=y +CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE=y +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SOC_TWL4030=y +# CONFIG_SOUND_PRIME is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +CONFIG_HID_DEBUG=y +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# Special HID drivers +# +CONFIG_HID_COMPAT=y +CONFIG_HID_A4TECH=y +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_CYPRESS=y +CONFIG_HID_EZKEY=y +CONFIG_HID_GYRATION=y +CONFIG_HID_LOGITECH=y +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +CONFIG_HID_NTRIG=y +CONFIG_HID_PANTHERLORD=y +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=y +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_HID_SUNPLUS=y +CONFIG_GREENASIA_FF=y +CONFIG_HID_TOPSEED=y +# CONFIG_THRUSTMASTER_FF is not set +# CONFIG_ZEROPLUS_FF is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y +CONFIG_USB_OTG=y +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_OMAP_EHCI_PHY_MODE=y +# CONFIG_OMAP_EHCI_TLL_MODE is not set +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_OXU210HP_HCD=y +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_U132_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_SOC=y + +# +# OMAP 343x high speed USB support +# +# CONFIG_USB_MUSB_HOST is not set +# CONFIG_USB_MUSB_PERIPHERAL is not set +CONFIG_USB_MUSB_OTG=y +CONFIG_USB_GADGET_MUSB_HDRC=y +CONFIG_USB_MUSB_HDRC_HCD=y +# CONFIG_MUSB_PIO_ONLY is not set +CONFIG_USB_INVENTRA_DMA=y +# CONFIG_USB_TI_CPPI_DMA is not set +# CONFIG_USB_MUSB_DEBUG is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_WDM=m +CONFIG_USB_TMC=m + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; +# + +# +# see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=m +CONFIG_USB_EZUSB=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MOTOROLA=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIEMENS_MPI=m +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTICON=m +CONFIG_USB_SERIAL_DEBUG=m + +# +# USB Miscellaneous drivers +# +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_LED=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_FTDI_ELAN=m +# CONFIG_USB_APPLEDISPLAY is not set +CONFIG_USB_SISUSBVGA=m +CONFIG_USB_SISUSBVGA_CON=y +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +# CONFIG_USB_IOWARRIOR is not set +CONFIG_USB_TEST=m +# CONFIG_USB_ISIGHTFW is not set +CONFIG_USB_VST=m +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_DEBUG_FS=y +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_ZERO=m +CONFIG_USB_ZERO_HNPTEST=y +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m +CONFIG_USB_MIDI_GADGET=m +CONFIG_USB_G_PRINTER=m +CONFIG_USB_CDC_COMPOSITE=m + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +CONFIG_USB_GPIO_VBUS=y +# CONFIG_ISP1301_OMAP is not set +CONFIG_TWL4030_USB=y +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_UNSAFE_RESUME=y + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +CONFIG_SDIO_UART=y +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +CONFIG_MMC_OMAP_HS=y +CONFIG_MMC_SPI=m +# CONFIG_MEMSTICK is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_OMAP_DEBUG is not set +CONFIG_LEDS_OMAP=y +# CONFIG_LEDS_OMAP_PWM is not set +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_PCA955X is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +CONFIG_RTC_DRV_TWL4030=y +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_DMADEVICES is not set +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_BQ24022 is not set +CONFIG_REGULATOR_TWL4030=y +CONFIG_UIO=m +CONFIG_UIO_PDRV=m +CONFIG_UIO_PDRV_GENIRQ=m +# CONFIG_UIO_SMX is not set +# CONFIG_UIO_SERCOS3 is not set +CONFIG_STAGING=y +# CONFIG_STAGING_EXCLUDE_BUILD is not set +# CONFIG_MEILHAUS is not set +# CONFIG_USB_IP_COMMON is not set +CONFIG_W35UND=m +CONFIG_PRISM2_USB=m +# CONFIG_ECHO is not set +CONFIG_USB_ATMEL=m +# CONFIG_AGNX is not set +CONFIG_OTUS=m +# CONFIG_COMEDI is not set +# CONFIG_ASUS_OLED is not set +# CONFIG_INPUT_MIMIO is not set +# CONFIG_TRANZPORT is not set + +# +# Android +# +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ANDROID_LOGGER=m +CONFIG_ANDROID_RAM_CONSOLE=y +CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE=y +# CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION is not set +# CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT is not set +CONFIG_ANDROID_TIMED_GPIO=m +CONFIG_ANDROID_LOW_MEMORY_KILLER=y + +# +# CBUS support +# +# CONFIG_CBUS is not set +CONFIG_MPU_BRIDGE=m +CONFIG_BRIDGE_MEMPOOL_SIZE=0x600000 +# CONFIG_BRIDGE_DEBUG is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4_FS=m +# CONFIG_EXT4DEV_COMPAT is not set +CONFIG_EXT4_FS_XATTR=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +# CONFIG_EXT4_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_JBD2=m +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=m +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_PROC_INFO=y +CONFIG_REISERFS_FS_XATTR=y +# CONFIG_REISERFS_FS_POSIX_ACL is not set +# CONFIG_REISERFS_FS_SECURITY is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_FILE_LOCKING=y +CONFIG_XFS_FS=m +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_DEBUG is not set +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +CONFIG_OCFS2_FS_STATS=y +CONFIG_OCFS2_DEBUG_MASKLOG=y +# CONFIG_OCFS2_DEBUG_FS is not set +# CONFIG_OCFS2_FS_POSIX_ACL is not set +CONFIG_BTRFS_FS=m +# CONFIG_BTRFS_FS_POSIX_ACL is not set +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_QUOTA_TREE=y +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=y +CONFIG_QUOTACTL=y +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=y + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=m +CONFIG_MISC_FILESYSTEMS=y +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_AFFS_FS=m +# CONFIG_ECRYPT_FS is not set +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BFS_FS=m +CONFIG_EFS_FS=m +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_FS_POSIX_ACL=y +CONFIG_JFFS2_FS_SECURITY=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RTIME=y +CONFIG_JFFS2_RUBIN=y +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +CONFIG_UBIFS_FS=y +CONFIG_UBIFS_FS_XATTR=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +# CONFIG_UBIFS_FS_DEBUG is not set +CONFIG_CRAMFS=m +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +CONFIG_VXFS_FS=m +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m +CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_ROMFS_FS=m +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +CONFIG_AUFS_FS=y +CONFIG_AUFS_BRANCH_MAX_127=y +# CONFIG_AUFS_BRANCH_MAX_511 is not set +# CONFIG_AUFS_BRANCH_MAX_1023 is not set +# CONFIG_AUFS_BRANCH_MAX_32767 is not set +# CONFIG_AUFS_HINOTIFY is not set +# CONFIG_AUFS_SHWH is not set +# CONFIG_AUFS_BR_RAMFS is not set +CONFIG_AUFS_DEBUG=y +CONFIG_AUFS_MAGIC_SYSRQ=y +CONFIG_AUFS_BDEV_LOOP=y +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_REGISTER_V4 is not set +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +CONFIG_CIFS_STATS=y +CONFIG_CIFS_STATS2=y +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +CONFIG_CIFS_EXPERIMENTAL=y +# CONFIG_CIFS_DFS_UPCALL is not set +CONFIG_NCP_FS=m +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +CONFIG_CODA_FS=m +CONFIG_AFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_9P_FS=m + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +CONFIG_LDM_DEBUG=y +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=y +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_RING_BUFFER=y +CONFIG_TRACING=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_XOR_BLOCKS=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_FIPS=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=m +CONFIG_CRYPTO_XCBC=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=y +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_LZO=y + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +CONFIG_CRC_T10DIF=y +CONFIG_CRC_ITU_T=y +CONFIG_CRC32=y +CONFIG_CRC7=y +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/defconfig.orig b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/defconfig.orig new file mode 100644 index 0000000000..1aa7cf57ac --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/defconfig.orig @@ -0,0 +1,2701 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.29-omap1 +# Fri May 29 14:47:52 2009 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_OPROFILE_ARMV7=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_ELF_CORE is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_COMPAT_BRK is not set +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +# CONFIG_MARKERS is not set +CONFIG_OPROFILE=y +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_BLOCK=y +CONFIG_LBD=y +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_FREEZER=y + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +CONFIG_ARCH_OMAP=y +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_W90X900 is not set + +# +# TI OMAP Implementations +# +CONFIG_ARCH_OMAP_OTG=y +# CONFIG_ARCH_OMAP1 is not set +# CONFIG_ARCH_OMAP2 is not set +CONFIG_ARCH_OMAP3=y + +# +# OMAP Feature Selections +# +# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set +# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set +CONFIG_OMAP_SMARTREFLEX=y +# CONFIG_OMAP_SMARTREFLEX_TESTING is not set +CONFIG_OMAP_RESET_CLOCKS=y +CONFIG_OMAP_BOOT_TAG=y +CONFIG_OMAP_BOOT_REASON=y +# CONFIG_OMAP_COMPONENT_VERSION is not set +# CONFIG_OMAP_GPIO_SWITCH is not set +# CONFIG_OMAP_MUX is not set +CONFIG_OMAP_MCBSP=y +# CONFIG_OMAP_MBOX_FWK is not set +# CONFIG_OMAP_IOMMU is not set +# CONFIG_OMAP_MPU_TIMER is not set +CONFIG_OMAP_32K_TIMER=y +CONFIG_OMAP_32K_TIMER_HZ=128 +CONFIG_OMAP_TICK_GPTIMER=12 +CONFIG_OMAP_DM_TIMER=y +# CONFIG_OMAP_LL_DEBUG_UART1 is not set +# CONFIG_OMAP_LL_DEBUG_UART2 is not set +CONFIG_OMAP_LL_DEBUG_UART3=y +CONFIG_ARCH_OMAP34XX=y +CONFIG_ARCH_OMAP3430=y + +# +# OMAP Board Type +# +# CONFIG_MACH_NOKIA_RX51 is not set +# CONFIG_MACH_OMAP_LDP is not set +# CONFIG_MACH_OMAP_3430SDP is not set +# CONFIG_MACH_OMAP3EVM is not set +CONFIG_MACH_OMAP3_BEAGLE=y +# CONFIG_MACH_OVERO is not set +# CONFIG_MACH_OMAP3_PANDORA is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_V7=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_IFAR=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +CONFIG_ARM_THUMBEE=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_HAS_TLS_REG=y +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PREEMPT is not set +CONFIG_HZ=128 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +CONFIG_ARCH_FLATMEM_HAS_HOLES=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_LEDS=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE=" debug " +# CONFIG_XIP_KERNEL is not set +CONFIG_KEXEC=y +CONFIG_ATAGS_PROC=y + +# +# CPU Power Management +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_FREQ_DEBUG=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_STAT_DETAILS=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=y +# CONFIG_ARM_ERRATUM_451034 is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_HAVE_AOUT=y +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_MISC=y + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_DEBUG=y +# CONFIG_PM_VERBOSE is not set +CONFIG_CAN_PM_TRACE=y +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_SUSPEND_FREEZER=y +# CONFIG_APM_EMULATION is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_COMPAT_NET_DEV_OPS=y +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=m +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +# CONFIG_IPV6_PIMSM_V2 is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +# CONFIG_NETFILTER_TPROXY is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +# CONFIG_NETFILTER_XT_TARGET_TRACE is not set +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +CONFIG_IP_VS_DEBUG=y +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_IDLETIMER=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_DCCP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_RAW=m +# CONFIG_BRIDGE_NF_EBTABLES is not set +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m + +# +# DCCP CCIDs Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=y +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +CONFIG_IP_DCCP_TFRC_LIB=y + +# +# DCCP Kernel Hacking +# +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_STP=m +CONFIG_GARP=m +CONFIG_BRIDGE=m +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +CONFIG_WAN_ROUTER=m +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_CLS_IND=y +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +CONFIG_CAN=m +CONFIG_CAN_RAW=m +CONFIG_CAN_BCM=m + +# +# CAN Device Drivers +# +CONFIG_CAN_VCAN=m +# CONFIG_CAN_DEBUG_DEVICES is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +CONFIG_IRDA_ULTRA=y + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_DEBUG=y + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TOIM3232_DONGLE=m +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +# CONFIG_ACT200L_DONGLE is not set +CONFIG_KINGSUN_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KS959_DONGLE=m + +# +# FIR device drivers +# +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_MCS_FIR=m +# CONFIG_OMAP_IR is not set +CONFIG_BT=y +CONFIG_BT_L2CAP=y +CONFIG_BT_SCO=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIBTUSB=y +CONFIG_BT_HCIBTSDIO=y +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIBCM203X=y +CONFIG_BT_HCIBPA10X=y +CONFIG_BT_HCIBFUSB=y +# CONFIG_BT_HCIBRF6150 is not set +# CONFIG_BT_HCIH4P is not set +# CONFIG_BT_HCIVHCI is not set +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +# CONFIG_RXKAD is not set +# CONFIG_PHONET is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_CFG80211=y +# CONFIG_CFG80211_REG_DEBUG is not set +CONFIG_NL80211=y +CONFIG_WIRELESS_OLD_REGULATORY=y +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_LIB80211=y +CONFIG_LIB80211_CRYPT_WEP=y +CONFIG_LIB80211_CRYPT_CCMP=y +CONFIG_LIB80211_CRYPT_TKIP=y +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=y + +# +# Rate control algorithm selection +# +CONFIG_MAC80211_RC_PID=y +# CONFIG_MAC80211_RC_MINSTREL is not set +CONFIG_MAC80211_RC_DEFAULT_PID=y +# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set +CONFIG_MAC80211_RC_DEFAULT="pid" +# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_WIMAX=m +CONFIG_WIMAX_DEBUG_LEVEL=8 +# CONFIG_RFKILL is not set +CONFIG_NET_9P=m +# CONFIG_NET_9P_DEBUG is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_OMAP2=y +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +CONFIG_MTD_NAND_PLATFORM=y +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_GLUEBI is not set + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_BLK_DEV_XIP is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ICS932S401 is not set +# CONFIG_OMAP_STI is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +CONFIG_EEPROM_93CX6=y +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_RAID_ATTRS=m +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=m +# CONFIG_LIBFC is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_ATA is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_DELAY=m +# CONFIG_DM_UEVENT is not set +CONFIG_NETDEVICES=y +CONFIG_DUMMY=m +CONFIG_BONDING=m +CONFIG_MACVLAN=m +CONFIG_EQUALIZER=m +CONFIG_TUN=m +CONFIG_VETH=m +# CONFIG_NET_ETHERNET is not set +CONFIG_MII=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +CONFIG_WLAN_80211=y +CONFIG_LIBERTAS=y +CONFIG_LIBERTAS_USB=y +# CONFIG_LIBERTAS_SDIO is not set +# CONFIG_LIBERTAS_DEBUG is not set +# CONFIG_LIBERTAS_THINFIRM is not set +CONFIG_USB_ZD1201=y +CONFIG_USB_NET_RNDIS_WLAN=y +CONFIG_RTL8187=y +# CONFIG_MAC80211_HWSIM is not set +CONFIG_P54_COMMON=y +CONFIG_P54_USB=y +# CONFIG_IWLWIFI_LEDS is not set +CONFIG_HOSTAP=y +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_B43=y +CONFIG_B43_LEDS=y +# CONFIG_B43_DEBUG is not set +# CONFIG_B43LEGACY is not set +CONFIG_ZD1211RW=y +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_RT2X00=y +CONFIG_RT2500USB=y +CONFIG_RT73USB=y +CONFIG_RT2X00_LIB_USB=y +CONFIG_RT2X00_LIB=y +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set + +# +# WiMAX Wireless Broadband devices +# +# CONFIG_WIMAX_I2400M_USB is not set +# CONFIG_WIMAX_I2400M_SDIO is not set + +# +# USB Network Adapters +# +CONFIG_USB_CATC=y +CONFIG_USB_KAWETH=y +CONFIG_USB_PEGASUS=y +CONFIG_USB_RTL8150=y +CONFIG_USB_USBNET=y +CONFIG_USB_NET_AX8817X=y +CONFIG_USB_NET_CDCETHER=y +CONFIG_USB_NET_DM9601=y +CONFIG_USB_NET_SMSC95XX=y +CONFIG_USB_NET_GL620A=y +CONFIG_USB_NET_NET1080=y +CONFIG_USB_NET_PLUSB=y +CONFIG_USB_NET_MCS7830=y +CONFIG_USB_NET_RNDIS_HOST=y +CONFIG_USB_NET_CDC_SUBSET=y +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +CONFIG_USB_NET_ZAURUS=y +# CONFIG_WAN is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +# CONFIG_ATM_TCP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +# CONFIG_PPPOATM is not set +CONFIG_PPPOL2TP=m +# CONFIG_SLIP is not set +CONFIG_SLHC=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETPOLL=y +CONFIG_NETPOLL_TRAP=y +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=y +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_TWL4030 is not set +# CONFIG_KEYBOARD_LM8323 is not set +CONFIG_KEYBOARD_GPIO=y +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_GPIO is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +CONFIG_INPUT_TWL4030_PWRBUTTON=y +CONFIG_INPUT_UINPUT=y + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=32 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +CONFIG_I2C_OMAP=y +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_PCF8575 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +CONFIG_TWL4030_MADC=m +CONFIG_TWL4030_POWEROFF=y +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_TSL2563 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_OMAP24XX is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_TSC210X is not set +# CONFIG_SPI_TSC2301 is not set +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +CONFIG_GPIO_TWL4030=y + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_W1 is not set +CONFIG_POWER_SUPPLY=m +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_TWL4030_BCI_BATTERY is not set +# CONFIG_BATTERY_BQ27x00 is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7473 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_TSC210X is not set +CONFIG_SENSORS_OMAP34XX=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_OMAP_WATCHDOG=y + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +CONFIG_SSB=y +# CONFIG_SSB_SILENT is not set +# CONFIG_SSB_DEBUG is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_TPS65010 is not set +CONFIG_TWL4030_CORE=y +# CONFIG_TWL4030_POWER is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L2_COMMON=m +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_DVB_CORE=m +CONFIG_VIDEO_MEDIA=m + +# +# Multimedia drivers +# +CONFIG_MEDIA_ATTACH=y +CONFIG_MEDIA_TUNER=m +# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L1=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_VIVI=m +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_VIDEO_AU0828 is not set +# CONFIG_VIDEO_OMAP3 is not set +# CONFIG_SOC_CAMERA is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_PVRUSB2_DVB=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_USB_VICAM=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_ET61X251=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_USB_W9968CF=m +CONFIG_USB_OV511=m +CONFIG_USB_SE401=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STV680=m +CONFIG_USB_ZC0301=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_ZR364XX=m +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_S2255=m +CONFIG_RADIO_ADAPTERS=y +# CONFIG_USB_DSBR is not set +# CONFIG_USB_SI470X is not set +# CONFIG_USB_MR800 is not set +# CONFIG_RADIO_TEA5764 is not set +CONFIG_DVB_DYNAMIC_MINORS=y +CONFIG_DVB_CAPTURE_DRIVERS=y +# CONFIG_TTPCI_EEPROM is not set + +# +# Supported USB Adapters +# +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_SIANO_SMS1XXX=m +CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS=y + +# +# Supported FlexCopII (B2C2) Adapters +# +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set + +# +# Supported DVB Frontends +# + +# +# Customise DVB Frontends +# +# CONFIG_DVB_FE_CUSTOMISE is not set + +# +# Multistandard (satellite) frontends +# +CONFIG_DVB_STB0899=m +CONFIG_DVB_STB6100=m + +# +# DVB-S (satellite) frontends +# +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_MT312=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8261=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_SI21XX=m + +# +# DVB-T (terrestrial) frontends +# +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_DRX397XD=m +CONFIG_DVB_L64781=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_TDA10048=m + +# +# DVB-C (cable) frontends +# +CONFIG_DVB_VES1820=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +CONFIG_DVB_NXT200X=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGDT3304=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_S5H1411=m + +# +# ISDB-T (terrestrial) frontends +# +CONFIG_DVB_S921=m + +# +# Digital terrestrial only tuners/PLL +# +CONFIG_DVB_PLL=m +CONFIG_DVB_TUNER_DIB0070=m + +# +# SEC control devices for DVB-S +# +CONFIG_DVB_LNBP21=m +# CONFIG_DVB_ISL6405 is not set +CONFIG_DVB_ISL6421=m +CONFIG_DVB_LGS8GL5=m + +# +# Tools to develop new frontends +# +# CONFIG_DVB_DUMMY_FE is not set +CONFIG_DVB_AF9013=m +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set +CONFIG_OMAP2_DSS=y +CONFIG_OMAP2_DSS_VRAM_SIZE=14 +CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y +# CONFIG_OMAP2_DSS_RFBI is not set +CONFIG_OMAP2_DSS_VENC=y +# CONFIG_OMAP2_DSS_SDI is not set +CONFIG_OMAP2_DSS_DSI=y +CONFIG_OMAP2_DSS_USE_DSI_PLL=y +# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set +CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=1 + +# +# OMAP2/3 Display Device Drivers +# +CONFIG_PANEL_GENERIC=y +CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C=m +# CONFIG_PANEL_SHARP_LS037V7DW01 is not set +# CONFIG_PANEL_N800 is not set +# CONFIG_CTRL_BLIZZARD is not set +CONFIG_FB_OMAP2=y +CONFIG_FB_OMAP2_DEBUG_SUPPORT=y +# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set +CONFIG_FB_OMAP2_NUM_FBS=3 +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +CONFIG_DISPLAY_SUPPORT=y + +# +# Display hardware drivers +# + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_HWDEP=y +CONFIG_SND_RAWMIDI=y +CONFIG_SND_SEQUENCER=m +# CONFIG_SND_SEQ_DUMMY is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_HRTIMER=m +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +# CONFIG_SND_ARM is not set +CONFIG_SND_SPI=y +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_SOC=y +CONFIG_SND_OMAP_SOC=y +CONFIG_SND_OMAP_SOC_MCBSP=y +CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE=y +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SOC_TWL4030=y +# CONFIG_SOUND_PRIME is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +CONFIG_HID_DEBUG=y +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# Special HID drivers +# +CONFIG_HID_COMPAT=y +CONFIG_HID_A4TECH=y +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_CYPRESS=y +CONFIG_HID_EZKEY=y +CONFIG_HID_GYRATION=y +CONFIG_HID_LOGITECH=y +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +CONFIG_HID_NTRIG=y +CONFIG_HID_PANTHERLORD=y +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=y +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_HID_SUNPLUS=y +CONFIG_GREENASIA_FF=y +CONFIG_HID_TOPSEED=y +# CONFIG_THRUSTMASTER_FF is not set +# CONFIG_ZEROPLUS_FF is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y +CONFIG_USB_OTG=y +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_OMAP_EHCI_PHY_MODE=y +# CONFIG_OMAP_EHCI_TLL_MODE is not set +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_OXU210HP_HCD=y +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_U132_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_SOC=y + +# +# OMAP 343x high speed USB support +# +# CONFIG_USB_MUSB_HOST is not set +# CONFIG_USB_MUSB_PERIPHERAL is not set +CONFIG_USB_MUSB_OTG=y +CONFIG_USB_GADGET_MUSB_HDRC=y +CONFIG_USB_MUSB_HDRC_HCD=y +# CONFIG_MUSB_PIO_ONLY is not set +CONFIG_USB_INVENTRA_DMA=y +# CONFIG_USB_TI_CPPI_DMA is not set +# CONFIG_USB_MUSB_DEBUG is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_WDM=m +CONFIG_USB_TMC=m + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; +# + +# +# see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=m +CONFIG_USB_EZUSB=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MOTOROLA=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIEMENS_MPI=m +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTICON=m +CONFIG_USB_SERIAL_DEBUG=m + +# +# USB Miscellaneous drivers +# +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_LED=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_FTDI_ELAN=m +# CONFIG_USB_APPLEDISPLAY is not set +CONFIG_USB_SISUSBVGA=m +CONFIG_USB_SISUSBVGA_CON=y +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +# CONFIG_USB_IOWARRIOR is not set +CONFIG_USB_TEST=m +# CONFIG_USB_ISIGHTFW is not set +CONFIG_USB_VST=m +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_DEBUG_FS=y +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_ZERO=m +CONFIG_USB_ZERO_HNPTEST=y +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m +CONFIG_USB_MIDI_GADGET=m +CONFIG_USB_G_PRINTER=m +CONFIG_USB_CDC_COMPOSITE=m + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +CONFIG_USB_GPIO_VBUS=y +# CONFIG_ISP1301_OMAP is not set +CONFIG_TWL4030_USB=y +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_UNSAFE_RESUME=y + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +CONFIG_SDIO_UART=y +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +CONFIG_MMC_OMAP_HS=y +CONFIG_MMC_SPI=m +# CONFIG_MEMSTICK is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_OMAP_DEBUG is not set +CONFIG_LEDS_OMAP=y +# CONFIG_LEDS_OMAP_PWM is not set +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_PCA955X is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +CONFIG_RTC_DRV_TWL4030=y +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_DMADEVICES is not set +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_BQ24022 is not set +CONFIG_REGULATOR_TWL4030=y +CONFIG_UIO=m +CONFIG_UIO_PDRV=m +CONFIG_UIO_PDRV_GENIRQ=m +# CONFIG_UIO_SMX is not set +# CONFIG_UIO_SERCOS3 is not set +CONFIG_STAGING=y +# CONFIG_STAGING_EXCLUDE_BUILD is not set +# CONFIG_MEILHAUS is not set +# CONFIG_USB_IP_COMMON is not set +CONFIG_W35UND=m +CONFIG_PRISM2_USB=m +# CONFIG_ECHO is not set +CONFIG_USB_ATMEL=m +# CONFIG_AGNX is not set +CONFIG_OTUS=m +# CONFIG_COMEDI is not set +# CONFIG_ASUS_OLED is not set +# CONFIG_INPUT_MIMIO is not set +# CONFIG_TRANZPORT is not set + +# +# Android +# +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ANDROID_LOGGER=m +CONFIG_ANDROID_RAM_CONSOLE=y +CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE=y +# CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION is not set +# CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT is not set +CONFIG_ANDROID_TIMED_GPIO=m +CONFIG_ANDROID_LOW_MEMORY_KILLER=y + +# +# CBUS support +# +# CONFIG_CBUS is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4_FS=m +# CONFIG_EXT4DEV_COMPAT is not set +CONFIG_EXT4_FS_XATTR=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +# CONFIG_EXT4_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_JBD2=m +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=m +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_PROC_INFO=y +CONFIG_REISERFS_FS_XATTR=y +# CONFIG_REISERFS_FS_POSIX_ACL is not set +# CONFIG_REISERFS_FS_SECURITY is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_FILE_LOCKING=y +CONFIG_XFS_FS=m +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_DEBUG is not set +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +CONFIG_OCFS2_FS_STATS=y +CONFIG_OCFS2_DEBUG_MASKLOG=y +# CONFIG_OCFS2_DEBUG_FS is not set +# CONFIG_OCFS2_FS_POSIX_ACL is not set +CONFIG_BTRFS_FS=m +# CONFIG_BTRFS_FS_POSIX_ACL is not set +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_QUOTA_TREE=y +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=y +CONFIG_QUOTACTL=y +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=m +CONFIG_MISC_FILESYSTEMS=y +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_AFFS_FS=m +# CONFIG_ECRYPT_FS is not set +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BFS_FS=m +CONFIG_EFS_FS=m +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_FS_POSIX_ACL=y +CONFIG_JFFS2_FS_SECURITY=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RTIME=y +CONFIG_JFFS2_RUBIN=y +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +CONFIG_UBIFS_FS=y +CONFIG_UBIFS_FS_XATTR=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +# CONFIG_UBIFS_FS_DEBUG is not set +CONFIG_CRAMFS=m +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +CONFIG_VXFS_FS=m +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m +CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_ROMFS_FS=m +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_REGISTER_V4 is not set +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +CONFIG_CIFS_STATS=y +CONFIG_CIFS_STATS2=y +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +CONFIG_CIFS_EXPERIMENTAL=y +# CONFIG_CIFS_DFS_UPCALL is not set +CONFIG_NCP_FS=m +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +CONFIG_CODA_FS=m +CONFIG_AFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_9P_FS=m + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +CONFIG_LDM_DEBUG=y +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=y +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_RING_BUFFER=y +CONFIG_TRACING=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_XOR_BLOCKS=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_FIPS=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=m +CONFIG_CRYPTO_XCBC=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=y +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_LZO=y + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +CONFIG_CRC_T10DIF=y +CONFIG_CRC_ITU_T=y +CONFIG_CRC32=y +CONFIG_CRC7=y +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/dspbridge.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/dspbridge.patch new file mode 100644 index 0000000000..621ae93d3b --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/dspbridge.patch @@ -0,0 +1,66715 @@ +From ea83ad971e877ef8e9b1304f2678469c2fc74c67 Mon Sep 17 00:00:00 2001 +From: Tim Yamin +Date: Sun, 26 Apr 2009 18:58:30 -0700 +Subject: [PATCH] Merge in tidspbridge from git://gitorious.org/tidspbridge/mainline.git + revisions fe30e75..20f5ca. + +Made a few changes so this compiles clean against a 2.6.29 non-PM +tree. + +Signed-off-by: Tim Yamin +--- + Documentation/tidspbridge/README | 70 + + arch/arm/Kconfig | 2 + + arch/arm/mach-omap2/Makefile | 2 + + arch/arm/mach-omap2/dspbridge.c | 74 + + arch/arm/mach-omap2/io.c | 3 + + arch/arm/plat-omap/devices.c | 28 + + arch/arm/plat-omap/include/dspbridge/_chnl_sm.h | 212 ++ + arch/arm/plat-omap/include/dspbridge/_dcd.h | 187 + + arch/arm/plat-omap/include/dspbridge/brddefs.h | 54 + + arch/arm/plat-omap/include/dspbridge/cfg.h | 339 ++ + arch/arm/plat-omap/include/dspbridge/cfgdefs.h | 126 + + arch/arm/plat-omap/include/dspbridge/chnl.h | 170 + + arch/arm/plat-omap/include/dspbridge/chnl_sm.h | 168 + + arch/arm/plat-omap/include/dspbridge/chnldefs.h | 92 + + arch/arm/plat-omap/include/dspbridge/chnlpriv.h | 136 + + arch/arm/plat-omap/include/dspbridge/clk.h | 155 + + arch/arm/plat-omap/include/dspbridge/cmm.h | 420 +++ + arch/arm/plat-omap/include/dspbridge/cmmdefs.h | 135 + + arch/arm/plat-omap/include/dspbridge/cod.h | 433 +++ + arch/arm/plat-omap/include/dspbridge/csl.h | 135 + + arch/arm/plat-omap/include/dspbridge/dbc.h | 66 + + arch/arm/plat-omap/include/dspbridge/dbdcd.h | 388 +++ + arch/arm/plat-omap/include/dspbridge/dbdcddef.h | 94 + + arch/arm/plat-omap/include/dspbridge/dbdefs.h | 580 ++++ + arch/arm/plat-omap/include/dspbridge/dbg.h | 110 + + arch/arm/plat-omap/include/dspbridge/dbl.h | 354 ++ + arch/arm/plat-omap/include/dspbridge/dbldefs.h | 155 + + arch/arm/plat-omap/include/dspbridge/dbll.h | 70 + + arch/arm/plat-omap/include/dspbridge/dblldefs.h | 509 +++ + arch/arm/plat-omap/include/dspbridge/dbof.h | 117 + + arch/arm/plat-omap/include/dspbridge/dbreg.h | 113 + + arch/arm/plat-omap/include/dspbridge/dbtype.h | 103 + + arch/arm/plat-omap/include/dspbridge/dehdefs.h | 42 + + arch/arm/plat-omap/include/dspbridge/dev.h | 785 +++++ + arch/arm/plat-omap/include/dspbridge/devdefs.h | 35 + + arch/arm/plat-omap/include/dspbridge/disp.h | 236 ++ + arch/arm/plat-omap/include/dspbridge/dispdefs.h | 45 + + arch/arm/plat-omap/include/dspbridge/dmm.h | 85 + + arch/arm/plat-omap/include/dspbridge/dpc.h | 167 + + arch/arm/plat-omap/include/dspbridge/drv.h | 449 +++ + arch/arm/plat-omap/include/dspbridge/drvdefs.h | 34 + + arch/arm/plat-omap/include/dspbridge/dspdrv.h | 106 + + .../plat-omap/include/dspbridge/dynamic_loader.h | 505 +++ + arch/arm/plat-omap/include/dspbridge/errbase.h | 509 +++ + arch/arm/plat-omap/include/dspbridge/gb.h | 85 + + arch/arm/plat-omap/include/dspbridge/getsection.h | 118 + + arch/arm/plat-omap/include/dspbridge/gh.h | 37 + + arch/arm/plat-omap/include/dspbridge/gs.h | 64 + + arch/arm/plat-omap/include/dspbridge/gt.h | 315 ++ + arch/arm/plat-omap/include/dspbridge/host_os.h | 96 + + arch/arm/plat-omap/include/dspbridge/io.h | 132 + + arch/arm/plat-omap/include/dspbridge/io_sm.h | 335 ++ + arch/arm/plat-omap/include/dspbridge/iodefs.h | 45 + + arch/arm/plat-omap/include/dspbridge/kfile.h | 216 ++ + arch/arm/plat-omap/include/dspbridge/ldr.h | 51 + + arch/arm/plat-omap/include/dspbridge/list.h | 296 ++ + arch/arm/plat-omap/include/dspbridge/mbx_sh.h | 213 ++ + arch/arm/plat-omap/include/dspbridge/mem.h | 340 ++ + arch/arm/plat-omap/include/dspbridge/memdefs.h | 52 + + arch/arm/plat-omap/include/dspbridge/mgr.h | 234 ++ + arch/arm/plat-omap/include/dspbridge/mgrpriv.h | 55 + + arch/arm/plat-omap/include/dspbridge/msg.h | 106 + + arch/arm/plat-omap/include/dspbridge/msgdefs.h | 43 + + arch/arm/plat-omap/include/dspbridge/nldr.h | 81 + + arch/arm/plat-omap/include/dspbridge/nldrdefs.h | 307 ++ + arch/arm/plat-omap/include/dspbridge/node.h | 619 ++++ + arch/arm/plat-omap/include/dspbridge/nodedefs.h | 40 + + arch/arm/plat-omap/include/dspbridge/nodepriv.h | 202 ++ + arch/arm/plat-omap/include/dspbridge/ntfy.h | 146 + + arch/arm/plat-omap/include/dspbridge/proc.h | 648 ++++ + arch/arm/plat-omap/include/dspbridge/procpriv.h | 35 + + arch/arm/plat-omap/include/dspbridge/pwr.h | 129 + + arch/arm/plat-omap/include/dspbridge/pwr_sh.h | 41 + + arch/arm/plat-omap/include/dspbridge/reg.h | 257 ++ + .../plat-omap/include/dspbridge/resourcecleanup.h | 88 + + arch/arm/plat-omap/include/dspbridge/rmm.h | 199 ++ + arch/arm/plat-omap/include/dspbridge/rms_sh.h | 125 + + arch/arm/plat-omap/include/dspbridge/rmstypes.h | 40 + + arch/arm/plat-omap/include/dspbridge/services.h | 63 + + arch/arm/plat-omap/include/dspbridge/std.h | 143 + + arch/arm/plat-omap/include/dspbridge/strm.h | 441 +++ + arch/arm/plat-omap/include/dspbridge/strmdefs.h | 57 + + arch/arm/plat-omap/include/dspbridge/sync.h | 340 ++ + arch/arm/plat-omap/include/dspbridge/util.h | 122 + + arch/arm/plat-omap/include/dspbridge/utildefs.h | 51 + + arch/arm/plat-omap/include/dspbridge/uuidutil.h | 74 + + arch/arm/plat-omap/include/dspbridge/wcd.h | 61 + + arch/arm/plat-omap/include/dspbridge/wcdioctl.h | 519 +++ + arch/arm/plat-omap/include/dspbridge/wmd.h | 1193 +++++++ + arch/arm/plat-omap/include/dspbridge/wmdchnl.h | 90 + + arch/arm/plat-omap/include/dspbridge/wmddeh.h | 64 + + arch/arm/plat-omap/include/dspbridge/wmdio.h | 53 + + arch/arm/plat-omap/include/dspbridge/wmdioctl.h | 91 + + arch/arm/plat-omap/include/dspbridge/wmdmsg.h | 70 + + drivers/Makefile | 1 + + drivers/dsp/bridge/Kbuild | 39 + + drivers/dsp/bridge/Kconfig | 36 + + drivers/dsp/bridge/dynload/cload.c | 1854 ++++++++++ + drivers/dsp/bridge/dynload/dlclasses_hdr.h | 41 + + drivers/dsp/bridge/dynload/dload_internal.h | 237 ++ + drivers/dsp/bridge/dynload/doff.h | 347 ++ + drivers/dsp/bridge/dynload/getsection.c | 412 +++ + drivers/dsp/bridge/dynload/header.h | 59 + + drivers/dsp/bridge/dynload/module_list.h | 161 + + drivers/dsp/bridge/dynload/params.h | 231 ++ + drivers/dsp/bridge/dynload/reloc.c | 425 +++ + drivers/dsp/bridge/dynload/reloc_table.h | 102 + + drivers/dsp/bridge/dynload/reloc_table_c6000.c | 258 ++ + drivers/dsp/bridge/gen/_gt_para.c | 107 + + drivers/dsp/bridge/gen/gb.c | 182 + + drivers/dsp/bridge/gen/gh.c | 191 ++ + drivers/dsp/bridge/gen/gs.c | 108 + + drivers/dsp/bridge/gen/gt.c | 348 ++ + drivers/dsp/bridge/gen/uuidutil.c | 238 ++ + drivers/dsp/bridge/hw/EasiGlobal.h | 42 + + drivers/dsp/bridge/hw/GlobalTypes.h | 325 ++ + drivers/dsp/bridge/hw/IPIAccInt.h | 41 + + drivers/dsp/bridge/hw/IVA2RegAcM.h | 28 + + drivers/dsp/bridge/hw/MLBAccInt.h | 132 + + drivers/dsp/bridge/hw/MLBRegAcM.h | 200 ++ + drivers/dsp/bridge/hw/MMUAccInt.h | 76 + + drivers/dsp/bridge/hw/MMURegAcM.h | 253 ++ + drivers/dsp/bridge/hw/PRCMAccInt.h | 300 ++ + drivers/dsp/bridge/hw/PRCMRegAcM.h | 669 ++++ + drivers/dsp/bridge/hw/hw_defs.h | 73 + + drivers/dsp/bridge/hw/hw_dspssC64P.c | 55 + + drivers/dsp/bridge/hw/hw_dspssC64P.h | 48 + + drivers/dsp/bridge/hw/hw_mbox.c | 244 ++ + drivers/dsp/bridge/hw/hw_mbox.h | 323 ++ + drivers/dsp/bridge/hw/hw_mmu.c | 598 ++++ + drivers/dsp/bridge/hw/hw_mmu.h | 177 + + drivers/dsp/bridge/hw/hw_prcm.c | 167 + + drivers/dsp/bridge/hw/hw_prcm.h | 168 + + drivers/dsp/bridge/pmgr/chnl.c | 260 ++ + drivers/dsp/bridge/pmgr/chnlobj.h | 71 + + drivers/dsp/bridge/pmgr/cmm.c | 1291 +++++++ + drivers/dsp/bridge/pmgr/cod.c | 683 ++++ + drivers/dsp/bridge/pmgr/dbl.c | 1385 ++++++++ + drivers/dsp/bridge/pmgr/dbll.c | 1564 +++++++++ + drivers/dsp/bridge/pmgr/dev.c | 1476 ++++++++ + drivers/dsp/bridge/pmgr/dmm.c | 692 ++++ + drivers/dsp/bridge/pmgr/io.c | 205 ++ + drivers/dsp/bridge/pmgr/ioobj.h | 52 + + drivers/dsp/bridge/pmgr/msg.c | 173 + + drivers/dsp/bridge/pmgr/msgobj.h | 52 + + drivers/dsp/bridge/pmgr/wcd.c | 1647 +++++++++ + drivers/dsp/bridge/rmgr/dbdcd.c | 1573 +++++++++ + drivers/dsp/bridge/rmgr/disp.c | 916 +++++ + drivers/dsp/bridge/rmgr/drv.c | 1893 +++++++++++ + drivers/dsp/bridge/rmgr/drv_interface.c | 777 +++++ + drivers/dsp/bridge/rmgr/drv_interface.h | 40 + + drivers/dsp/bridge/rmgr/dspdrv.c | 276 ++ + drivers/dsp/bridge/rmgr/mgr.c | 491 +++ + drivers/dsp/bridge/rmgr/nldr.c | 1967 +++++++++++ + drivers/dsp/bridge/rmgr/node.c | 3544 ++++++++++++++++++++ + drivers/dsp/bridge/rmgr/proc.c | 1985 +++++++++++ + drivers/dsp/bridge/rmgr/pwr.c | 184 + + drivers/dsp/bridge/rmgr/rmm.c | 604 ++++ + drivers/dsp/bridge/rmgr/strm.c | 1066 ++++++ + drivers/dsp/bridge/services/cfg.c | 483 +++ + drivers/dsp/bridge/services/clk.c | 375 +++ + drivers/dsp/bridge/services/csl.c | 173 + + drivers/dsp/bridge/services/dbg.c | 119 + + drivers/dsp/bridge/services/dpc.c | 274 ++ + drivers/dsp/bridge/services/kfile.c | 338 ++ + drivers/dsp/bridge/services/list.c | 285 ++ + drivers/dsp/bridge/services/mem.c | 599 ++++ + drivers/dsp/bridge/services/ntfy.c | 329 ++ + drivers/dsp/bridge/services/reg.c | 196 ++ + drivers/dsp/bridge/services/regsup.c | 368 ++ + drivers/dsp/bridge/services/regsup.h | 58 + + drivers/dsp/bridge/services/services.c | 193 ++ + drivers/dsp/bridge/services/sync.c | 602 ++++ + drivers/dsp/bridge/wmd/_cmm.h | 59 + + drivers/dsp/bridge/wmd/_deh.h | 46 + + drivers/dsp/bridge/wmd/_msg_sm.h | 158 + + drivers/dsp/bridge/wmd/_tiomap.h | 384 +++ + drivers/dsp/bridge/wmd/_tiomap_mmu.h | 53 + + drivers/dsp/bridge/wmd/_tiomap_pwr.h | 102 + + drivers/dsp/bridge/wmd/_tiomap_util.h | 46 + + drivers/dsp/bridge/wmd/chnl_sm.c | 1100 ++++++ + drivers/dsp/bridge/wmd/io_sm.c | 2011 +++++++++++ + drivers/dsp/bridge/wmd/mmu_fault.c | 172 + + drivers/dsp/bridge/wmd/mmu_fault.h | 45 + + drivers/dsp/bridge/wmd/msg_sm.c | 643 ++++ + drivers/dsp/bridge/wmd/tiomap3430.c | 2149 ++++++++++++ + drivers/dsp/bridge/wmd/tiomap3430_pwr.c | 731 ++++ + drivers/dsp/bridge/wmd/tiomap_io.c | 427 +++ + drivers/dsp/bridge/wmd/tiomap_io.h | 112 + + drivers/dsp/bridge/wmd/tiomap_sm.c | 195 ++ + drivers/dsp/bridge/wmd/ue_deh.c | 329 ++ + 191 files changed, 65137 insertions(+), 0 deletions(-) + create mode 100644 Documentation/tidspbridge/README + create mode 100644 arch/arm/mach-omap2/dspbridge.c + create mode 100644 arch/arm/plat-omap/include/dspbridge/_chnl_sm.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/_dcd.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/brddefs.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/cfg.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/cfgdefs.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/chnl.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/chnl_sm.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/chnldefs.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/chnlpriv.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/clk.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/cmm.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/cmmdefs.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/cod.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/csl.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/dbc.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/dbdcd.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/dbdcddef.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/dbdefs.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/dbg.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/dbl.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/dbldefs.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/dbll.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/dblldefs.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/dbof.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/dbreg.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/dbtype.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/dehdefs.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/dev.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/devdefs.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/disp.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/dispdefs.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/dmm.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/dpc.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/drv.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/drvdefs.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/dspdrv.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/dynamic_loader.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/errbase.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/gb.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/getsection.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/gh.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/gs.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/gt.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/host_os.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/io.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/io_sm.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/iodefs.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/kfile.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/ldr.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/list.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/mbx_sh.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/mem.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/memdefs.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/mgr.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/mgrpriv.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/msg.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/msgdefs.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/nldr.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/nldrdefs.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/node.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/nodedefs.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/nodepriv.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/ntfy.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/proc.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/procpriv.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/pwr.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/pwr_sh.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/reg.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/resourcecleanup.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/rmm.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/rms_sh.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/rmstypes.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/services.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/std.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/strm.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/strmdefs.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/sync.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/util.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/utildefs.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/uuidutil.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/wcd.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/wcdioctl.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/wmd.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/wmdchnl.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/wmddeh.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/wmdio.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/wmdioctl.h + create mode 100644 arch/arm/plat-omap/include/dspbridge/wmdmsg.h + create mode 100644 drivers/dsp/bridge/Kbuild + create mode 100644 drivers/dsp/bridge/Kconfig + create mode 100644 drivers/dsp/bridge/dynload/cload.c + create mode 100644 drivers/dsp/bridge/dynload/dlclasses_hdr.h + create mode 100644 drivers/dsp/bridge/dynload/dload_internal.h + create mode 100644 drivers/dsp/bridge/dynload/doff.h + create mode 100644 drivers/dsp/bridge/dynload/getsection.c + create mode 100644 drivers/dsp/bridge/dynload/header.h + create mode 100644 drivers/dsp/bridge/dynload/module_list.h + create mode 100644 drivers/dsp/bridge/dynload/params.h + create mode 100644 drivers/dsp/bridge/dynload/reloc.c + create mode 100644 drivers/dsp/bridge/dynload/reloc_table.h + create mode 100644 drivers/dsp/bridge/dynload/reloc_table_c6000.c + create mode 100644 drivers/dsp/bridge/gen/_gt_para.c + create mode 100644 drivers/dsp/bridge/gen/gb.c + create mode 100644 drivers/dsp/bridge/gen/gh.c + create mode 100644 drivers/dsp/bridge/gen/gs.c + create mode 100644 drivers/dsp/bridge/gen/gt.c + create mode 100644 drivers/dsp/bridge/gen/uuidutil.c + create mode 100644 drivers/dsp/bridge/hw/EasiGlobal.h + create mode 100644 drivers/dsp/bridge/hw/GlobalTypes.h + create mode 100644 drivers/dsp/bridge/hw/IPIAccInt.h + create mode 100644 drivers/dsp/bridge/hw/IVA2RegAcM.h + create mode 100644 drivers/dsp/bridge/hw/MLBAccInt.h + create mode 100644 drivers/dsp/bridge/hw/MLBRegAcM.h + create mode 100644 drivers/dsp/bridge/hw/MMUAccInt.h + create mode 100644 drivers/dsp/bridge/hw/MMURegAcM.h + create mode 100644 drivers/dsp/bridge/hw/PRCMAccInt.h + create mode 100644 drivers/dsp/bridge/hw/PRCMRegAcM.h + create mode 100644 drivers/dsp/bridge/hw/hw_defs.h + create mode 100644 drivers/dsp/bridge/hw/hw_dspssC64P.c + create mode 100644 drivers/dsp/bridge/hw/hw_dspssC64P.h + create mode 100644 drivers/dsp/bridge/hw/hw_mbox.c + create mode 100644 drivers/dsp/bridge/hw/hw_mbox.h + create mode 100644 drivers/dsp/bridge/hw/hw_mmu.c + create mode 100644 drivers/dsp/bridge/hw/hw_mmu.h + create mode 100644 drivers/dsp/bridge/hw/hw_prcm.c + create mode 100644 drivers/dsp/bridge/hw/hw_prcm.h + create mode 100644 drivers/dsp/bridge/pmgr/chnl.c + create mode 100644 drivers/dsp/bridge/pmgr/chnlobj.h + create mode 100644 drivers/dsp/bridge/pmgr/cmm.c + create mode 100644 drivers/dsp/bridge/pmgr/cod.c + create mode 100644 drivers/dsp/bridge/pmgr/dbl.c + create mode 100644 drivers/dsp/bridge/pmgr/dbll.c + create mode 100644 drivers/dsp/bridge/pmgr/dev.c + create mode 100644 drivers/dsp/bridge/pmgr/dmm.c + create mode 100644 drivers/dsp/bridge/pmgr/io.c + create mode 100644 drivers/dsp/bridge/pmgr/ioobj.h + create mode 100644 drivers/dsp/bridge/pmgr/msg.c + create mode 100644 drivers/dsp/bridge/pmgr/msgobj.h + create mode 100644 drivers/dsp/bridge/pmgr/wcd.c + create mode 100644 drivers/dsp/bridge/rmgr/dbdcd.c + create mode 100644 drivers/dsp/bridge/rmgr/disp.c + create mode 100644 drivers/dsp/bridge/rmgr/drv.c + create mode 100644 drivers/dsp/bridge/rmgr/drv_interface.c + create mode 100644 drivers/dsp/bridge/rmgr/drv_interface.h + create mode 100644 drivers/dsp/bridge/rmgr/dspdrv.c + create mode 100644 drivers/dsp/bridge/rmgr/mgr.c + create mode 100644 drivers/dsp/bridge/rmgr/nldr.c + create mode 100644 drivers/dsp/bridge/rmgr/node.c + create mode 100644 drivers/dsp/bridge/rmgr/proc.c + create mode 100644 drivers/dsp/bridge/rmgr/pwr.c + create mode 100644 drivers/dsp/bridge/rmgr/rmm.c + create mode 100644 drivers/dsp/bridge/rmgr/strm.c + create mode 100644 drivers/dsp/bridge/services/cfg.c + create mode 100644 drivers/dsp/bridge/services/clk.c + create mode 100644 drivers/dsp/bridge/services/csl.c + create mode 100644 drivers/dsp/bridge/services/dbg.c + create mode 100644 drivers/dsp/bridge/services/dpc.c + create mode 100644 drivers/dsp/bridge/services/kfile.c + create mode 100644 drivers/dsp/bridge/services/list.c + create mode 100644 drivers/dsp/bridge/services/mem.c + create mode 100644 drivers/dsp/bridge/services/ntfy.c + create mode 100644 drivers/dsp/bridge/services/reg.c + create mode 100644 drivers/dsp/bridge/services/regsup.c + create mode 100644 drivers/dsp/bridge/services/regsup.h + create mode 100644 drivers/dsp/bridge/services/services.c + create mode 100644 drivers/dsp/bridge/services/sync.c + create mode 100644 drivers/dsp/bridge/wmd/_cmm.h + create mode 100644 drivers/dsp/bridge/wmd/_deh.h + create mode 100644 drivers/dsp/bridge/wmd/_msg_sm.h + create mode 100644 drivers/dsp/bridge/wmd/_tiomap.h + create mode 100644 drivers/dsp/bridge/wmd/_tiomap_mmu.h + create mode 100644 drivers/dsp/bridge/wmd/_tiomap_pwr.h + create mode 100644 drivers/dsp/bridge/wmd/_tiomap_util.h + create mode 100644 drivers/dsp/bridge/wmd/chnl_sm.c + create mode 100644 drivers/dsp/bridge/wmd/io_sm.c + create mode 100644 drivers/dsp/bridge/wmd/mmu_fault.c + create mode 100644 drivers/dsp/bridge/wmd/mmu_fault.h + create mode 100644 drivers/dsp/bridge/wmd/msg_sm.c + create mode 100644 drivers/dsp/bridge/wmd/tiomap3430.c + create mode 100644 drivers/dsp/bridge/wmd/tiomap3430_pwr.c + create mode 100644 drivers/dsp/bridge/wmd/tiomap_io.c + create mode 100644 drivers/dsp/bridge/wmd/tiomap_io.h + create mode 100644 drivers/dsp/bridge/wmd/tiomap_sm.c + create mode 100644 drivers/dsp/bridge/wmd/ue_deh.c + +diff --git a/Documentation/tidspbridge/README b/Documentation/tidspbridge/README +new file mode 100644 +index 0000000..df6d371 +--- /dev/null ++++ b/Documentation/tidspbridge/README +@@ -0,0 +1,70 @@ ++ Linux DSP/BIOS Bridge release ++ ++DSP/BIOS Bridge overview ++======================== ++ ++DSP/BIOS Bridge is designed for platforms that contain a GPP and one or more ++attached DSPs. The GPP is considered the master or "host" processor, and the ++attached DSPs are processing resources that can be utilized by applications ++and drivers running on the GPP. ++ ++The abstraction that DSP/BIOS Bridge supplies, is a direct link between a GPP ++program and a DSP task. This communication link is partitioned into two ++types of sub-links: messaging (short, fixed-length packets) and data ++streaming (multiple, large buffers). Each sub-link operates independently, ++and features in-order delivery of data, meaning that messages are delivered ++in the order they were submitted to the message link, and stream buffers are ++delivered in the order they were submitted to the stream link. ++ ++In addition, a GPP client can specify what inputs and outputs a DSP task ++uses. DSP tasks typically use message objects for passing control and status ++information and stream objects for efficient streaming of real-time data. ++ ++GPP Software Architecture ++========================= ++ ++A GPP application communicates with its associated DSP task running on the ++DSP subsystem using the DSP/BIOS Bridge API. For example, a GPP audio ++application can use the API to pass messages to a DSP task that is managing ++data flowing from analog-to-digital converters (ADCs) to digital-to-analog ++converters (DACs). ++ ++From the perspective of the GPP OS, the DSP is treated as just another ++peripheral device. Most high level GPP OS typically support a device driver ++model, whereby applications can safely access and share a hardware peripheral ++through standard driver interfaces. Therefore, to allow multiple GPP ++applications to share access to the DSP, the GPP side of DSP/BIOS Bridge ++implements a device driver for the DSP. ++ ++Since driver interfaces are not always standard across GPP OS, and to provide ++some level of interoperability of application code using DSP/BIOS Bridge ++between GPP OS, DSP/BIOS Bridge provides a standard library of APIs which ++wrap calls into the device driver. So, rather than calling GPP OS specific ++driver interfaces, applications (and even other device drivers) can use the ++standard API library directly. ++ ++DSP Software Architecture ++========================= ++ ++For DSP/BIOS, DSP/BIOS Bridge adds a device-independent streaming I/O (STRM) ++interface, a messaging interface (NODE), and a Resource Manager (RM) Server. ++The RM Server runs as a task of DSP/BIOS and is subservient to commands ++and queries from the GPP. It executes commands to start and stop DSP signal ++processing nodes in response to GPP programs making requests through the ++(GPP-side) API. ++ ++DSP tasks started by the RM Server are similar to any other DSP task with two ++important differences: they must follow a specific task model consisting of ++three C-callable functions (node create, execute, and delete), with specific ++sets of arguments, and they have a pre-defined task environment established ++by the RM Server. ++ ++Tasks started by the RM Server communicate using the STRM and NODE interfaces ++and act as servers for their corresponding GPP clients, performing signal ++processing functions as requested by messages sent by their GPP client. ++Typically, a DSP task moves data from source devices to sink devices using ++device independent I/O streams, performing application-specific processing ++and transformations on the data while it is moved. For example, an audio ++task might perform audio decompression (ADPCM, MPEG, CELP) on data received ++from a GPP audio driver and then send the decompressed linear samples to a ++digital-to-analog converter. +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index e7fb201..2060772 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -1331,6 +1331,8 @@ if ARCH_OMAP + source "drivers/cbus/Kconfig" + endif + ++source "drivers/dsp/bridge/Kconfig" ++ + endmenu + + source "fs/Kconfig" +diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile +index 9b270d8..e52e01e 100644 +--- a/arch/arm/mach-omap2/Makefile ++++ b/arch/arm/mach-omap2/Makefile +@@ -34,6 +34,8 @@ obj-$(CONFIG_OMAP_SMARTREFLEX) += smartreflex.o + obj-$(CONFIG_ARCH_OMAP2) += clock24xx.o + obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o + ++obj-$(CONFIG_MPU_BRIDGE) += dspbridge.o ++ + # DSP + obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o + mailbox_mach-objs := mailbox.o +diff --git a/arch/arm/mach-omap2/dspbridge.c b/arch/arm/mach-omap2/dspbridge.c +new file mode 100644 +index 0000000..221e8ff +--- /dev/null ++++ b/arch/arm/mach-omap2/dspbridge.c +@@ -0,0 +1,74 @@ ++/* ++ * TI's dspbridge platform device registration ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * Copyright (C) 2009 Nokia Corporation ++ * ++ * Written by Hiroshi DOYU ++ * ++ * 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 ++ ++static struct platform_device *dspbridge_pdev; ++ ++#ifdef CONFIG_BRIDGE_DVFS ++#include ++static struct dspbridge_platform_data dspbridge_pdata __initdata = { ++ .dsp_set_min_opp = omap_pm_dsp_set_min_opp, ++ .dsp_get_opp = omap_pm_dsp_get_opp, ++ .cpu_set_freq = omap_pm_cpu_set_freq, ++ .cpu_get_freq = omap_pm_cpu_get_freq, ++}; ++#else ++static struct dspbridge_platform_data dspbridge_pdata; ++#endif ++ ++static int __init dspbridge_init(void) ++{ ++ struct platform_device *pdev; ++ int err = -ENOMEM; ++ struct dspbridge_platform_data *pdata = &dspbridge_pdata; ++ ++ pdata->phys_mempool_base = dspbridge_get_mempool_base(); ++ ++ if (pdata->phys_mempool_base) { ++ pdata->phys_mempool_size = CONFIG_BRIDGE_MEMPOOL_SIZE; ++ pr_info("%s: %x bytes @ %x\n", __func__, ++ pdata->phys_mempool_size, pdata->phys_mempool_base); ++ } ++ ++ pdev = platform_device_alloc("C6410", -1); ++ if (!pdev) ++ goto err_out; ++ ++ err = platform_device_add_data(pdev, pdata, sizeof(*pdata)); ++ if (err) ++ goto err_out; ++ ++ err = platform_device_add(pdev); ++ if (err) ++ goto err_out; ++ ++ dspbridge_pdev = pdev; ++ return 0; ++ ++err_out: ++ platform_device_put(pdev); ++ return err; ++} ++module_init(dspbridge_init); ++ ++static void __exit dspbridge_exit(void) ++{ ++ platform_device_unregister(dspbridge_pdev); ++} ++module_exit(dspbridge_exit); ++ ++MODULE_AUTHOR("Hiroshi DOYU"); ++MODULE_DESCRIPTION("TI's dspbridge platform device registration"); ++MODULE_LICENSE("GPL v2"); +diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c +index a04e3ee..40488ae 100644 +--- a/arch/arm/mach-omap2/io.c ++++ b/arch/arm/mach-omap2/io.c +@@ -38,6 +38,8 @@ + #include + #include "clockdomains.h" + ++#include ++ + /* + * The machine specific code may provide the extra mapping besides the + * default mapping provided here. +@@ -192,6 +194,7 @@ void __init omap2_map_common_io(void) + omap2_check_revision(); + omap_sram_init(); + omapfb_reserve_sdram(); ++ dspbridge_reserve_sdram(); + } + + void __init omap2_init_common_hw(struct omap_sdrc_params *sp) +diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c +index 6b742a8..e66dd8a 100644 +--- a/arch/arm/plat-omap/devices.c ++++ b/arch/arm/plat-omap/devices.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -89,6 +90,33 @@ EXPORT_SYMBOL(dsp_kfunc_device_register); + static inline void omap_init_dsp(void) { } + #endif /* CONFIG_OMAP_DSP */ + ++#if defined(CONFIG_MPU_BRIDGE) || defined(CONFIG_MPU_BRIDGE_MODULE) ++ ++static unsigned long dspbridge_phys_mempool_base; ++ ++void dspbridge_reserve_sdram(void) ++{ ++ void *va; ++ unsigned long size = CONFIG_BRIDGE_MEMPOOL_SIZE; ++ ++ if (!size) ++ return; ++ ++ va = __alloc_bootmem_nopanic(size, SZ_1M, 0); ++ if (!va) { ++ pr_err("%s: Failed to bootmem allocation(%lu bytes)\n", ++ __func__, size); ++ return; ++ } ++ dspbridge_phys_mempool_base = virt_to_phys(va); ++} ++ ++unsigned long dspbridge_get_mempool_base(void) ++{ ++ return dspbridge_phys_mempool_base; ++} ++EXPORT_SYMBOL(dspbridge_get_mempool_base); ++#endif + /*-------------------------------------------------------------------------*/ + #if defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE) + +diff --git a/arch/arm/plat-omap/include/dspbridge/_chnl_sm.h b/arch/arm/plat-omap/include/dspbridge/_chnl_sm.h +new file mode 100644 +index 0000000..28af799 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/_chnl_sm.h +@@ -0,0 +1,212 @@ ++/* ++ * _chnl_sm.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== _chnl_sm.h ======== ++ * Description: ++ * Private header file defining channel manager and channel objects for ++ * a shared memory channel driver. ++ * ++ * Public Functions: ++ * None. ++ * ++ * Notes: ++ * Shared between the modules implementing the shared memory channel class ++ * library. ++ * ++ *! Revision History: ++ *! ================ ++ *! 15-Oct-2002 kc Removed legacy PERF code. ++ *! 12-Jan-2002 ag Removed unused gppReqIO & ddmaChnlId DDMA fields. ++ *! Added zero-copy chnl descriptor array: zchnldesc. ++ *! 21-Dec-2001 ag Moved descPaGpp to private chnl obj from chnl descriptor. ++ *! 20-May-2001 ag/jeh Removed fShmSyms field from CHNL_MGR. ++ *! 04-Feb-2001 ag DSP-DMA support added. ++ *! 26-Oct-2000 jeh Added arg and resvd to SHM control structure. Added dwArg ++ *! to CHNL_IRP. ++ *! 16-Oct-2000 jeh Removed #ifdef DEBUG from around channel object's cIOCs ++ *! field, added cIOReqs. ++ *! 20-Jan-2000 ag: Incorporated code review comments. ++ *! 05-Jan-2000 ag: Text format cleanup. ++ *! 03-Nov-1999 ag: Added szEventName[] to CHNL object for name event support. ++ *! 02-Nov-1999 ag: _SHM_BEG & _END Syms from COFF now used for IO and SM CLASS. ++ *! 27-Oct-1999 jeh Define SHM structure to work for 16-bit targets. ++ *! 25-May-1999 jg: Added target side symbol names for share memory buffer ++ *! 03-Jan-1997 gp: Added fSharedIRQ field. ++ *! 22-Oct-1996 gp: Made dwProcessID a handle. ++ *! 09-Sep-1996 gp: Added dwProcessID field to CHNL_OBJECT. ++ *! 13-Aug-1996 gp: Created. ++ */ ++ ++#ifndef _CHNL_SM_ ++#define _CHNL_SM_ ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++/* ++ * These target side symbols define the beginning and ending addresses ++ * of shared memory buffer. They are defined in the *cfg.cmd file by ++ * cdb code. ++ */ ++#define CHNL_SHARED_BUFFER_BASE_SYM "_SHM_BEG" ++#define CHNL_SHARED_BUFFER_LIMIT_SYM "_SHM_END" ++#define BRIDGEINIT_BIOSGPTIMER "_BRIDGEINIT_BIOSGPTIMER" ++#define BRIDGEINIT_LOADMON_GPTIMER "_BRIDGEINIT_LOADMON_GPTIMER" ++ ++#ifndef _CHNL_WORDSIZE ++#define _CHNL_WORDSIZE 4 /* default _CHNL_WORDSIZE is 2 bytes/word */ ++#endif ++ ++#define MAXOPPS 16 ++ ++struct oppTableEntry { ++ u32 voltage; ++ u32 frequency; ++ u32 minFreq; ++ u32 maxFreq; ++} ; ++ ++struct oppStruct { ++ u32 currOppPt; ++ u32 numOppPts; ++ struct oppTableEntry oppPoint[MAXOPPS]; ++} ; ++ ++/* Request to MPU */ ++struct oppRqstStruct { ++ u32 rqstDspFreq; ++ u32 rqstOppPt; ++}; ++ ++/* Info to MPU */ ++struct loadMonStruct { ++ u32 currDspLoad; ++ u32 currDspFreq; ++ u32 predDspLoad; ++ u32 predDspFreq; ++}; ++ ++ enum SHM_DESCTYPE { ++ SHM_CURROPP = 0, ++ SHM_OPPINFO = 1, ++ SHM_GETOPP = 2, /* Get DSP requested OPP info */ ++ } ; ++ ++/* Structure in shared between DSP and PC for communication.*/ ++ struct SHM { ++ u32 dspFreeMask; /* Written by DSP, read by PC. */ ++ u32 hostFreeMask; /* Written by PC, read by DSP */ ++ ++ u32 inputFull; /* Input channel has unread data. */ ++ u32 inputId; /* Channel for which input is available. */ ++ u32 inputSize; /* Size of data block (in DSP words). */ ++ ++ u32 outputFull; /* Output channel has unread data. */ ++ u32 outputId; /* Channel for which output is available. */ ++ u32 outputSize; /* Size of data block (in DSP words). */ ++ ++ u32 arg; /* Arg for Issue/Reclaim (23 bits for 55x). */ ++ u32 resvd; /* Keep structure size even for 32-bit DSPs */ ++ ++ /* Operating Point structure */ ++ struct oppStruct oppTableStruct; ++ /* Operating Point Request structure */ ++ struct oppRqstStruct oppRequest; ++ /* load monitor information structure*/ ++ struct loadMonStruct loadMonInfo; ++ char dummy[184]; /* padding to 256 byte boundary */ ++ u32 shm_dbg_var[64]; /* shared memory debug variables */ ++ } ; ++ ++ /* Channel Manager: only one created per board: */ ++ struct CHNL_MGR { ++ u32 dwSignature; /* Used for object validation */ ++ /* Function interface to WMD */ ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ struct IO_MGR *hIOMgr; /* IO manager */ ++ /* Device this board represents */ ++ struct DEV_OBJECT *hDevObject; ++ ++ /* These fields initialized in WMD_CHNL_Create(): */ ++ u32 dwOutputMask; /* Host output channels w/ full buffers */ ++ u32 dwLastOutput; /* Last output channel fired from DPC */ ++ /* Critical section object handle */ ++ struct SYNC_CSOBJECT *hCSObj; ++ u32 uWordSize; /* Size in bytes of DSP word */ ++ u32 cChannels; /* Total number of channels */ ++ u32 cOpenChannels; /* Total number of open channels */ ++ struct CHNL_OBJECT **apChannel; /* Array of channels */ ++ u32 dwType; /* Type of channel class library */ ++ /* If no SHM syms, return for CHNL_Open */ ++ DSP_STATUS chnlOpenStatus; ++ } ; ++ ++/* ++ * Channel: up to CHNL_MAXCHANNELS per board or if DSP-DMA supported then ++ * up to CHNL_MAXCHANNELS + CHNL_MAXDDMACHNLS per board. ++ */ ++ struct CHNL_OBJECT { ++ u32 dwSignature; /* Used for object validation */ ++ /* Pointer back to channel manager */ ++ struct CHNL_MGR *pChnlMgr; ++ u32 uId; /* Channel id */ ++ u32 dwState; /* Current channel state */ ++ u32 uMode; /* Chnl mode and attributes */ ++ /* Chnl I/O completion event (user mode) */ ++ HANDLE hUserEvent; ++ /* Abstract syncronization object */ ++ struct SYNC_OBJECT *hSyncEvent; ++ /* Name of Sync event */ ++ char szEventName[SYNC_MAXNAMELENGTH + 1]; ++ u32 hProcess; /* Process which created this channel */ ++ u32 pCBArg; /* Argument to use with callback */ ++ struct LST_LIST *pIORequests; /* List of IOR's to driver */ ++ s32 cIOCs; /* Number of IOC's in queue */ ++ s32 cIOReqs; /* Number of IORequests in queue */ ++ s32 cChirps; /* Initial number of free Irps */ ++ /* List of IOC's from driver */ ++ struct LST_LIST *pIOCompletions; ++ struct LST_LIST *pFreeList; /* List of free Irps */ ++ struct NTFY_OBJECT *hNtfy; ++ u32 cBytesMoved; /* Total number of bytes transfered */ ++ ++ /* For DSP-DMA */ ++ ++ /* Type of chnl transport:CHNL_[PCPY][DDMA] */ ++ u32 uChnlType; ++ } ; ++ ++/* I/O Request/completion packet: */ ++ struct CHNL_IRP { ++ struct LST_ELEM link; /* Link to next CHIRP in queue. */ ++ /* Buffer to be filled/emptied. (User) */ ++ u8 *pHostUserBuf; ++ /* Buffer to be filled/emptied. (System) */ ++ u8 *pHostSysBuf; ++ u32 dwArg; /* Issue/Reclaim argument. */ ++ u32 uDspAddr; /* Transfer address on DSP side. */ ++ u32 cBytes; /* Bytes transferred. */ ++ u32 cBufSize; /* Actual buffer size when allocated. */ ++ u32 status; /* Status of IO completion. */ ++ } ; ++ ++#endif /* _CHNL_SM_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/_dcd.h b/arch/arm/plat-omap/include/dspbridge/_dcd.h +new file mode 100644 +index 0000000..b6a8d9e +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/_dcd.h +@@ -0,0 +1,187 @@ ++/* ++ * _dcd.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== _dcd.h ======== ++ * Description: ++ * Includes the wrapper functions called directly by the ++ * DeviceIOControl interface. ++ * ++ * Public Functions: ++ * WCD_CallDevIOCtl ++ * WCD_Init ++ * WCD_InitComplete2 ++ * WCD_Exit ++ * WRAP_* ++ * ++ * Notes: ++ * Compiled with CDECL calling convention. ++ * ++ *! Revision History: ++ *! ================ ++ *! 19-Apr-2004 sb Aligned DMM definitions with Symbian ++ *! 08-Mar-2004 sb Added the Dynamic Memory Mapping feature ++ *! 30-Jan-2002 ag Renamed CMMWRAP_AllocBuf to CMMWRAP_CallocBuf. ++ *! 22-Nov-2000 kc: Added MGRWRAP_GetPerf_Data to acquire PERF stats. ++ *! 27-Oct-2000 jeh Added NODEWRAP_AllocMsgBuf, NODEWRAP_FreeMsgBuf. Removed ++ *! NODEWRAP_GetMessageStream. ++ *! 10-Oct-2000 ag: Added user CMM wrappers. ++ *! 04-Aug-2000 rr: MEMWRAP and UTIL_Wrap added. ++ *! 27-Jul-2000 rr: NODEWRAP, STRMWRAP added. ++ *! 27-Jun-2000 rr: MGRWRAP fxns added.IFDEF to build for PM or DSP/BIOS Bridge ++ *! 03-Dec-1999 rr: WCD_InitComplete2 enabled for BRD_AutoStart. ++ *! 09-Nov-1999 kc: Added MEMRY. ++ *! 02-Nov-1999 ag: Added CHNL. ++ *! 08-Oct-1999 rr: Utilwrap_Testdll fxn added ++ *! 24-Sep-1999 rr: header changed from _wcd.h to _dcd.h ++ *! 09-Sep-1997 gp: Created. ++ */ ++ ++#ifndef _WCD_ ++#define _WCD_ ++ ++#include ++ ++/* ++ * ======== WCD_CallDevIOCtl ======== ++ * Purpose: ++ * Call the (wrapper) function for the corresponding WCD IOCTL. ++ * Parameters: ++ * cmd: IOCTL id, base 0. ++ * args: Argument structure. ++ * pResult: ++ * Returns: ++ * DSP_SOK if command called; DSP_EINVALIDARG if command not in IOCTL ++ * table. ++ * Requires: ++ * Ensures: ++ */ ++ extern DSP_STATUS WCD_CallDevIOCtl(unsigned int cmd, ++ union Trapped_Args *args, ++ u32 *pResult); ++ ++/* ++ * ======== WCD_Init ======== ++ * Purpose: ++ * Initialize WCD modules, and export WCD services to WMD's. ++ * This procedure is called when the class driver is loaded. ++ * Parameters: ++ * Returns: ++ * TRUE if success; FALSE otherwise. ++ * Requires: ++ * Ensures: ++ */ ++ extern bool WCD_Init(void); ++ ++/* ++ * ======== WCD_InitComplete2 ======== ++ * Purpose: ++ * Perform any required WCD, and WMD initialization which ++ * cannot not be performed in WCD_Init(void) or DEV_StartDevice() due ++ * to the fact that some services are not yet ++ * completely initialized. ++ * Parameters: ++ * Returns: ++ * DSP_SOK: Allow this device to load ++ * DSP_EFAIL: Failure. ++ * Requires: ++ * WCD initialized. ++ * Ensures: ++ */ ++ extern DSP_STATUS WCD_InitComplete2(void); ++ ++/* ++ * ======== WCD_Exit ======== ++ * Purpose: ++ * Exit all modules initialized in WCD_Init(void). ++ * This procedure is called when the class driver is unloaded. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * WCD_Init(void) was previously called. ++ * Ensures: ++ * Resources acquired in WCD_Init(void) are freed. ++ */ ++ extern void WCD_Exit(void); ++ ++/* MGR wrapper functions */ ++ extern u32 MGRWRAP_EnumNode_Info(union Trapped_Args *args); ++ extern u32 MGRWRAP_EnumProc_Info(union Trapped_Args *args); ++ extern u32 MGRWRAP_RegisterObject(union Trapped_Args *args); ++ extern u32 MGRWRAP_UnregisterObject(union Trapped_Args *args); ++ extern u32 MGRWRAP_WaitForBridgeEvents(union Trapped_Args *args); ++ ++#ifndef RES_CLEANUP_DISABLE ++ extern u32 MGRWRAP_GetProcessResourcesInfo(union Trapped_Args *args); ++#endif ++ ++ ++/* CPRC (Processor) wrapper Functions */ ++ extern u32 PROCWRAP_Attach(union Trapped_Args *args); ++ extern u32 PROCWRAP_Ctrl(union Trapped_Args *args); ++ extern u32 PROCWRAP_Detach(union Trapped_Args *args); ++ extern u32 PROCWRAP_EnumNode_Info(union Trapped_Args *args); ++ extern u32 PROCWRAP_EnumResources(union Trapped_Args *args); ++ extern u32 PROCWRAP_GetState(union Trapped_Args *args); ++ extern u32 PROCWRAP_GetTrace(union Trapped_Args *args); ++ extern u32 PROCWRAP_Load(union Trapped_Args *args); ++ extern u32 PROCWRAP_RegisterNotify(union Trapped_Args *args); ++ extern u32 PROCWRAP_Start(union Trapped_Args *args); ++ extern u32 PROCWRAP_ReserveMemory(union Trapped_Args *args); ++ extern u32 PROCWRAP_UnReserveMemory(union Trapped_Args *args); ++ extern u32 PROCWRAP_Map(union Trapped_Args *args); ++ extern u32 PROCWRAP_UnMap(union Trapped_Args *args); ++ extern u32 PROCWRAP_FlushMemory(union Trapped_Args *args); ++ extern u32 PROCWRAP_Stop(union Trapped_Args *args); ++ extern u32 PROCWRAP_InvalidateMemory(union Trapped_Args *args); ++ ++/* NODE wrapper functions */ ++ extern u32 NODEWRAP_Allocate(union Trapped_Args *args); ++ extern u32 NODEWRAP_AllocMsgBuf(union Trapped_Args *args); ++ extern u32 NODEWRAP_ChangePriority(union Trapped_Args *args); ++ extern u32 NODEWRAP_Connect(union Trapped_Args *args); ++ extern u32 NODEWRAP_Create(union Trapped_Args *args); ++ extern u32 NODEWRAP_Delete(union Trapped_Args *args); ++ extern u32 NODEWRAP_FreeMsgBuf(union Trapped_Args *args); ++ extern u32 NODEWRAP_GetAttr(union Trapped_Args *args); ++ extern u32 NODEWRAP_GetMessage(union Trapped_Args *args); ++ extern u32 NODEWRAP_Pause(union Trapped_Args *args); ++ extern u32 NODEWRAP_PutMessage(union Trapped_Args *args); ++ extern u32 NODEWRAP_RegisterNotify(union Trapped_Args *args); ++ extern u32 NODEWRAP_Run(union Trapped_Args *args); ++ extern u32 NODEWRAP_Terminate(union Trapped_Args *args); ++ extern u32 NODEWRAP_GetUUIDProps(union Trapped_Args *args); ++ ++/* STRM wrapper functions */ ++ extern u32 STRMWRAP_AllocateBuffer(union Trapped_Args *args); ++ extern u32 STRMWRAP_Close(union Trapped_Args *args); ++ extern u32 STRMWRAP_FreeBuffer(union Trapped_Args *args); ++ extern u32 STRMWRAP_GetEventHandle(union Trapped_Args *args); ++ extern u32 STRMWRAP_GetInfo(union Trapped_Args *args); ++ extern u32 STRMWRAP_Idle(union Trapped_Args *args); ++ extern u32 STRMWRAP_Issue(union Trapped_Args *args); ++ extern u32 STRMWRAP_Open(union Trapped_Args *args); ++ extern u32 STRMWRAP_Reclaim(union Trapped_Args *args); ++ extern u32 STRMWRAP_RegisterNotify(union Trapped_Args *args); ++ extern u32 STRMWRAP_Select(union Trapped_Args *args); ++ ++ extern u32 CMMWRAP_CallocBuf(union Trapped_Args *args); ++ extern u32 CMMWRAP_FreeBuf(union Trapped_Args *args); ++ extern u32 CMMWRAP_GetHandle(union Trapped_Args *args); ++ extern u32 CMMWRAP_GetInfo(union Trapped_Args *args); ++ ++#endif /* _WCD_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/brddefs.h b/arch/arm/plat-omap/include/dspbridge/brddefs.h +new file mode 100644 +index 0000000..c62388c +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/brddefs.h +@@ -0,0 +1,54 @@ ++/* ++ * brddefs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== brddefs.h ======== ++ * Description: ++ * Global BRD constants and types, shared between WSX, WCD, and WMD. ++ * ++ *! Revision History: ++ *! ================ ++ *! 31-Jan-2000 rr: Comment Exec changed to Monitor ++ *! 22-Jul-1999 jeh Added BRD_LOADED state. ++ *! 26-Mar-1997 gp: Added BRD_SYNCINIT state. ++ *! 11-Dec-1996 cr: Added BRD_LASTSTATE definition. ++ *! 11-Jul-1996 gp: Added missing u32 callback argument to BRD_CALLBACK. ++ *! 10-Jun-1996 gp: Created from board.h and brd.h. ++ */ ++ ++#ifndef BRDDEFS_ ++#define BRDDEFS_ ++ ++/* platform status values */ ++#define BRD_STOPPED 0x0 /* No Monitor Loaded, Not running. */ ++#define BRD_IDLE 0x1 /* Monitor Loaded, but suspended. */ ++#define BRD_RUNNING 0x2 /* Monitor loaded, and executing. */ ++#define BRD_UNKNOWN 0x3 /* Board state is indeterminate. */ ++#define BRD_SYNCINIT 0x4 ++#define BRD_LOADED 0x5 ++#define BRD_LASTSTATE BRD_LOADED /* Set to highest legal board state. */ ++#define BRD_SLEEP_TRANSITION 0x6 /* Sleep transition in progress */ ++#define BRD_HIBERNATION 0x7 /* MPU initiated hibernation */ ++#define BRD_RETENTION 0x8 /* Retention mode */ ++#define BRD_DSP_HIBERNATION 0x9 /* DSP initiated hibernation */ ++#define BRD_ERROR 0xA /* Board state is Error */ ++ typedef u32 BRD_STATUS; ++ ++/* BRD Object */ ++ struct BRD_OBJECT; ++ ++#endif /* BRDDEFS_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/cfg.h b/arch/arm/plat-omap/include/dspbridge/cfg.h +new file mode 100644 +index 0000000..68db842 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/cfg.h +@@ -0,0 +1,339 @@ ++/* ++ * cfg.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== cfg.h ======== ++ * Purpose: ++ * PM Configuration module. ++ * ++ * Private Functions: ++ * CFG_Exit ++ * CFG_GetAutoStart ++ * CFG_GetCDVersion ++ * CFG_GetDevObject ++ * CFG_GetDSPResources ++ * CFG_GetExecFile ++ * CFG_GetHostResources ++ * CFG_GetObject ++ * CFG_GetPerfValue ++ * CFG_GetWMDFileName ++ * CFG_GetZLFile ++ * CFG_Init ++ * CFG_SetDevObject ++ * CFG_SetObject ++ * ++ *! Revision History: ++ *! ================= ++ *! 26-Feb-2003 kc Removed unused CFG fxns. ++ *! 28-Aug-2001 jeh Added CFG_GetLoaderName. ++ *! 26-Jul-2000 rr: Added CFG_GetDCDName to retrieve the DCD Dll name. ++ *! 13-Jul-2000 rr: Added CFG_GetObject & CFG_SetObject. ++ *! 13-Jan-2000 rr: CFG_Get/SetPrivateDword renamed to CFG_Get/SetDevObject. ++ *! CFG_GetWinBRIDGEDir/Directory,CFG_GetSearchPath removed. ++ *! 15-Jan-1998 cr: Code review cleanup. ++ *! 16-Aug-1997 cr: Added explicit cdecl identifiers. ++ *! 12-Dec-1996 gp: Moved CFG_FindInSearchPath to CSP module. ++ *! 13-Sep-1996 gp: Added CFG_GetBoardName(). ++ *! 22-Jul-1996 gp: Added CFG_GetTraceStr, to retrieve an initial GT trace. ++ *! 26-Jun-1996 cr: Added CFG_FindInSearchPath. ++ *! 25-Jun-1996 cr: Added CFG_GetWinSPOXDir. ++ *! 17-Jun-1996 cr: Added CFG_GetDevNode. ++ *! 11-Jun-1996 cr: Cleaned up for code review. ++ *! 07-Jun-1996 cr: Added CFG_GetExecFile and CFG_GetZLFileName functions. ++ *! 04-Jun-1996 gp: Added AutoStart regkey and accessor function. Placed ++ *! OUT parameters in accessor function param. lists at end. ++ *! 29-May-1996 gp: Moved DEV_HDEVNODE to here and renamed CFG_HDEVNODE. ++ *! 22-May-1996 cr: Added GetHostResources, GetDSPResources, and ++ *! GetWMDFileName services. ++ *! 18-May-1996 gp: Created. ++ */ ++ ++#ifndef CFG_ ++#define CFG_ ++#include ++#include ++ ++/* ++ * ======== CFG_Exit ======== ++ * Purpose: ++ * Discontinue usage of the CFG module. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * CFG_Init(void) was previously called. ++ * Ensures: ++ * Resources acquired in CFG_Init(void) are freed. ++ */ ++ extern void CFG_Exit(void); ++ ++/* ++ * ======== CFG_GetAutoStart ======== ++ * Purpose: ++ * Retreive the autostart mask, if any, for this board. ++ * Parameters: ++ * hDevNode: Handle to the DevNode who's WMD we are querying. ++ * pdwAutoStart: Ptr to location for 32 bit autostart mask. ++ * Returns: ++ * DSP_SOK: Success. ++ * CFG_E_INVALIDHDEVNODE: hDevNode is invalid. ++ * CFG_E_RESOURCENOTAVAIL: Unable to retreive resource. ++ * Requires: ++ * CFG initialized. ++ * Ensures: ++ * DSP_SOK: *pdwAutoStart contains autostart mask for this devnode. ++ */ ++ extern DSP_STATUS CFG_GetAutoStart(IN struct CFG_DEVNODE *hDevNode, ++ OUT u32 *pdwAutoStart); ++ ++/* ++ * ======== CFG_GetCDVersion ======== ++ * Purpose: ++ * Retrieves the version of the PM Class Driver. ++ * Parameters: ++ * pdwVersion: Ptr to u32 to contain version number upon return. ++ * Returns: ++ * DSP_SOK: Success. pdwVersion contains Class Driver version in ++ * the form: 0xAABBCCDD where AABB is Major version and ++ * CCDD is Minor. ++ * DSP_EFAIL: Failure. ++ * Requires: ++ * CFG initialized. ++ * Ensures: ++ * DSP_SOK: Success. ++ * else: *pdwVersion is NULL. ++ */ ++ extern DSP_STATUS CFG_GetCDVersion(OUT u32 *pdwVersion); ++ ++/* ++ * ======== CFG_GetDevObject ======== ++ * Purpose: ++ * Retrieve the Device Object handle for a given devnode. ++ * Parameters: ++ * hDevNode: Platform's DevNode handle from which to retrieve value. ++ * pdwValue: Ptr to location to store the value. ++ * Returns: ++ * DSP_SOK: Success. ++ * CFG_E_INVALIDHDEVNODE: hDevNode is invalid. ++ * CFG_E_INVALIDPOINTER: phDevObject is invalid. ++ * CFG_E_RESOURCENOTAVAIL: The resource is not available. ++ * Requires: ++ * CFG initialized. ++ * Ensures: ++ * DSP_SOK: *pdwValue is set to the retrieved u32. ++ * else: *pdwValue is set to 0L. ++ */ ++ extern DSP_STATUS CFG_GetDevObject(IN struct CFG_DEVNODE *hDevNode, ++ OUT u32 *pdwValue); ++ ++/* ++ * ======== CFG_GetDSPResources ======== ++ * Purpose: ++ * Get the DSP resources available to a given device. ++ * Parameters: ++ * hDevNode: Handle to the DEVNODE who's resources we are querying. ++ * pDSPResTable: Ptr to a location to store the DSP resource table. ++ * Returns: ++ * DSP_SOK: On success. ++ * CFG_E_INVALIDHDEVNODE: hDevNode is invalid. ++ * CFG_E_RESOURCENOTAVAIL: The DSP Resource information is not ++ * available ++ * Requires: ++ * CFG initialized. ++ * Ensures: ++ * DSP_SOK: pDSPResTable points to a filled table of resources allocated ++ * for the specified WMD. ++ */ ++ extern DSP_STATUS CFG_GetDSPResources(IN struct CFG_DEVNODE *hDevNode, ++ OUT struct CFG_DSPRES *pDSPResTable); ++ ++ ++/* ++ * ======== CFG_GetExecFile ======== ++ * Purpose: ++ * Retreive the default executable, if any, for this board. ++ * Parameters: ++ * hDevNode: Handle to the DevNode who's WMD we are querying. ++ * cBufSize: Size of buffer. ++ * pstrExecFile: Ptr to character buf to hold ExecFile. ++ * Returns: ++ * DSP_SOK: Success. ++ * CFG_E_INVALIDHDEVNODE: hDevNode is invalid. ++ * CFG_E_INVALIDPOINTER: pstrExecFile is invalid. ++ * CFG_E_RESOURCENOTAVAIL: The resource is not available. ++ * Requires: ++ * CFG initialized. ++ * Ensures: ++ * DSP_SOK: Not more than cBufSize bytes were copied into pstrExecFile, ++ * and *pstrExecFile contains default executable for this ++ * devnode. ++ */ ++ extern DSP_STATUS CFG_GetExecFile(IN struct CFG_DEVNODE *hDevNode, ++ IN u32 cBufSize, ++ OUT char *pstrExecFile); ++ ++/* ++ * ======== CFG_GetHostResources ======== ++ * Purpose: ++ * Get the Host PC allocated resources assigned to a given device. ++ * Parameters: ++ * hDevNode: Handle to the DEVNODE who's resources we are querying. ++ * pHostResTable: Ptr to a location to store the host resource table. ++ * Returns: ++ * DSP_SOK: On success. ++ * CFG_E_INVALIDPOINTER: pHostResTable is invalid. ++ * CFG_E_INVALIDHDEVNODE: hDevNode is invalid. ++ * CFG_E_RESOURCENOTAVAIL: The resource is not available. ++ * Requires: ++ * CFG initialized. ++ * Ensures: ++ * DSP_SOK: pHostResTable points to a filled table of resources ++ * allocated for the specified WMD. ++ * ++ */ ++ extern DSP_STATUS CFG_GetHostResources(IN struct CFG_DEVNODE *hDevNode, ++ OUT struct CFG_HOSTRES *pHostResTable); ++ ++/* ++ * ======== CFG_GetObject ======== ++ * Purpose: ++ * Retrieve the Driver Object handle From the Registry ++ * Parameters: ++ * pdwValue: Ptr to location to store the value. ++ * dwType Type of Object to Get ++ * Returns: ++ * DSP_SOK: Success. ++ * Requires: ++ * CFG initialized. ++ * Ensures: ++ * DSP_SOK: *pdwValue is set to the retrieved u32(non-Zero). ++ * else: *pdwValue is set to 0L. ++ */ ++ extern DSP_STATUS CFG_GetObject(OUT u32 *pdwValue, u32 dwType); ++ ++/* ++ * ======== CFG_GetPerfValue ======== ++ * Purpose: ++ * Retrieve a flag indicating whether PERF should log statistics for the ++ * PM class driver. ++ * Parameters: ++ * pfEnablePerf: Location to store flag. 0 indicates the key was ++ * not found, or had a zero value. A nonzero value ++ * means the key was found and had a nonzero value. ++ * Returns: ++ * Requires: ++ * pfEnablePerf != NULL; ++ * Ensures: ++ */ ++ extern void CFG_GetPerfValue(OUT bool *pfEnablePerf); ++ ++/* ++ * ======== CFG_GetWMDFileName ======== ++ * Purpose: ++ * Get the mini-driver file name for a given device. ++ * Parameters: ++ * hDevNode: Handle to the DevNode who's WMD we are querying. ++ * cBufSize: Size of buffer. ++ * pWMDFileName: Ptr to a character buffer to hold the WMD filename. ++ * Returns: ++ * DSP_SOK: On success. ++ * CFG_E_INVALIDHDEVNODE: hDevNode is invalid. ++ * CFG_E_RESOURCENOTAVAIL: The filename is not available. ++ * Requires: ++ * CFG initialized. ++ * Ensures: ++ * DSP_SOK: Not more than cBufSize bytes were copied ++ * into pWMDFileName. ++ * ++ */ ++ extern DSP_STATUS CFG_GetWMDFileName(IN struct CFG_DEVNODE *hDevNode, ++ IN u32 cBufSize, ++ OUT char *pWMDFileName); ++ ++/* ++ * ======== CFG_GetZLFile ======== ++ * Purpose: ++ * Retreive the ZLFile, if any, for this board. ++ * Parameters: ++ * hDevNode: Handle to the DevNode who's WMD we are querying. ++ * cBufSize: Size of buffer. ++ * pstrZLFileName: Ptr to character buf to hold ZLFileName. ++ * Returns: ++ * DSP_SOK: Success. ++ * CFG_E_INVALIDPOINTER: pstrZLFileName is invalid. ++ * CFG_E_INVALIDHDEVNODE: hDevNode is invalid. ++ * CFG_E_RESOURCENOTAVAIL: couldn't find the ZLFileName. ++ * Requires: ++ * CFG initialized. ++ * Ensures: ++ * DSP_SOK: Not more than cBufSize bytes were copied into ++ * pstrZLFileName, and *pstrZLFileName contains ZLFileName ++ * for this devnode. ++ */ ++ extern DSP_STATUS CFG_GetZLFile(IN struct CFG_DEVNODE *hDevNode, ++ IN u32 cBufSize, ++ OUT char *pstrZLFileName); ++ ++/* ++ * ======== CFG_Init ======== ++ * Purpose: ++ * Initialize the CFG module's private state. ++ * Parameters: ++ * Returns: ++ * TRUE if initialized; FALSE if error occured. ++ * Requires: ++ * Ensures: ++ * A requirement for each of the other public CFG functions. ++ */ ++ extern bool CFG_Init(void); ++ ++/* ++ * ======== CFG_SetDevObject ======== ++ * Purpose: ++ * Store the Device Object handle for a given devnode. ++ * Parameters: ++ * hDevNode: Platform's DevNode handle we are storing value with. ++ * dwValue: Arbitrary value to store. ++ * Returns: ++ * DSP_SOK: Success. ++ * CFG_E_INVALIDHDEVNODE: hDevNode is invalid. ++ * DSP_EFAIL: Internal Error. ++ * Requires: ++ * CFG initialized. ++ * Ensures: ++ * DSP_SOK: The Private u32 was successfully set. ++ */ ++ extern DSP_STATUS CFG_SetDevObject(IN struct CFG_DEVNODE *hDevNode, ++ IN u32 dwValue); ++ ++/* ++ * ======== CFG_SetDrvObject ======== ++ * Purpose: ++ * Store the Driver Object handle. ++ * Parameters: ++ * dwValue: Arbitrary value to store. ++ * dwType Type of Object to Store ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Internal Error. ++ * Requires: ++ * CFG initialized. ++ * Ensures: ++ * DSP_SOK: The Private u32 was successfully set. ++ */ ++ extern DSP_STATUS CFG_SetObject(IN u32 dwValue, IN u32 dwType); ++ ++#endif /* CFG_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/cfgdefs.h b/arch/arm/plat-omap/include/dspbridge/cfgdefs.h +new file mode 100644 +index 0000000..4f78d82 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/cfgdefs.h +@@ -0,0 +1,126 @@ ++/* ++ * cfgdefs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== cfgdefs.h ======== ++ * Purpose: ++ * Global CFG constants and types, shared between class and mini driver. ++ * ++ *! Revision History: ++ *! ================ ++ *! 24-Feb-2003 kc Removed wIOPort* in CFG_HOSTRES. ++ *! 06-Sep-2000 jeh Added channel info to CFG_HOSTRES. ++ *! 09-May-2000 rr: CFG_HOSTRES now support multiple windows for PCI support. ++ *! 31-Jan-2000 rr: Comments changed after code review. ++ *! 06-Jan-2000 rr: Bus Type included in CFG_HOSTRES. ++ *! 12-Nov-1999 rr: CFG_HOSTRES member names changed. ++ *! 25-Oct-1999 rr: Modified the CFG_HOSTRES Structure ++ *! PCMCIA ISR Register/Unregister fxn removed.. ++ *! New flag PCCARD introduced during compile time. ++ *! 10-Sep-1999 ww: Added PCMCIA ISR Register/Unregister fxn. ++ *! 01-Sep-1999 ag: Removed NT/95 specific fields in CFG_HOSTRES ++ *! 27-Oct-1997 cr: Updated CFG_HOSTRES struct to support 1+ IRQs per board. ++ *! 17-Sep-1997 gp: Tacked some NT config info to end of CFG_HOSTRES structure. ++ *! 12-Dec-1996 cr: Cleaned up after code review. ++ *! 14-Nov-1996 gp: Renamed from wsxcfg.h ++ *! 19-Jun-1996 cr: Created. ++ */ ++ ++#ifndef CFGDEFS_ ++#define CFGDEFS_ ++ ++/* Maximum length of module search path. */ ++#define CFG_MAXSEARCHPATHLEN 255 ++ ++/* Maximum length of general paths. */ ++#define CFG_MAXPATH 255 ++ ++/* Host Resources: */ ++#define CFG_MAXMEMREGISTERS 9 ++#define CFG_MAXIOPORTS 20 ++#define CFG_MAXIRQS 7 ++#define CFG_MAXDMACHANNELS 7 ++ ++/* IRQ flag */ ++#define CFG_IRQSHARED 0x01 /* IRQ can be shared */ ++ ++/* DSP Resources: */ ++#define CFG_DSPMAXMEMTYPES 10 ++#define CFG_DEFAULT_NUM_WINDOWS 1 /* We support only one window. */ ++ ++/* A platform-related device handle: */ ++ struct CFG_DEVNODE; ++ ++/* ++ * Host resource structure. ++ */ ++ struct CFG_HOSTRES { ++ u32 wNumMemWindows; /* Set to default */ ++ /* This is the base.memory */ ++ u32 dwMemBase[CFG_MAXMEMREGISTERS]; /* SHM virtual address */ ++ u32 dwMemLength[CFG_MAXMEMREGISTERS]; /* Length of the Base */ ++ u32 dwMemPhys[CFG_MAXMEMREGISTERS]; /* SHM Physical address */ ++ u8 bIRQRegisters; /* IRQ Number */ ++ u8 bIRQAttrib; /* IRQ Attribute */ ++ u32 dwOffsetForMonitor; /* The Shared memory starts from ++ * dwMemBase + this offset */ ++ u32 dwBusType; /* Bus type for this device */ ++ u32 dwProgBase; /* DSP ProgBase */ ++ u32 dwProgLength; /* DSP ProgBase Length */ ++ u32 dwRegBase; /* DSP memory mapped register base */ ++ u32 dwRegLength; /* DSP Register Base Length */ ++ u32 ClientHandle; /* Client Handle */ ++ u32 SocketHandle; /* Socket and Function Pair */ ++ u32 CardInfo; /* This will be used as a context data in ++ * in the CardRequestIRQ */ ++ /* ++ * Info needed by NODE for allocating channels to communicate with RMS: ++ * dwChnlOffset: Offset of RMS channels. Lower channels are ++ * reserved. ++ * dwChnlBufSize: Size of channel buffer to send to RMS ++ * dwNumChnls: Total number of channels (including reserved). ++ */ ++ u32 dwChnlOffset; ++ u32 dwChnlBufSize; ++ u32 dwNumChnls; ++ u32 dwPrmBase; ++ u32 dwCmBase; ++ u32 dwPerBase; ++ u32 dwPerPmBase; ++ u32 dwCorePmBase; ++ u32 dwWdTimerDspBase; ++ u32 dwMboxBase; ++ u32 dwDmmuBase; ++ u32 dwDipiBase; ++ u32 dwSysCtrlBase; ++ } ; ++ ++ struct CFG_DSPMEMDESC { ++ u32 uMemType; /* Type of memory. */ ++ u32 ulMin; /* Minimum amount of memory of this type. */ ++ u32 ulMax; /* Maximum amount of memory of this type. */ ++ } ; ++ ++ struct CFG_DSPRES { ++ u32 uChipType; /* DSP chip type. */ ++ u32 uWordSize; /* Number of bytes in a word */ ++ u32 cChips; /* Number of chips. */ ++ u32 cMemTypes; /* Types of memory. */ ++ struct CFG_DSPMEMDESC aMemDesc[CFG_DSPMAXMEMTYPES]; ++ /* DSP Memory types */ ++ } ; ++ ++#endif /* CFGDEFS_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/chnl.h b/arch/arm/plat-omap/include/dspbridge/chnl.h +new file mode 100644 +index 0000000..f39e3f4 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/chnl.h +@@ -0,0 +1,170 @@ ++/* ++ * chnl.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== chnl.h ======== ++ * Description: ++ * WCD channel interface: multiplexes data streams through the single ++ * physical link managed by a mini-driver. ++ * ++ * Public Functions: ++ * CHNL_AddIOReq ++ * CHNL_AllocBuffer ++ * CHNL_CancelIO ++ * CHNL_Close ++ * CHNL_CloseOrphans ++ * CHNL_Create ++ * CHNL_Destroy ++ * CHNL_Exit ++ * CHNL_FlushIO ++ * CHNL_FreeBuffer ++ * CHNL_GetEventHandle ++ * CHNL_GetHandle ++ * CHNL_GetIOCompletion ++ * CHNL_GetId ++ * CHNL_GetMgr ++ * CHNL_GetMode ++ * CHNL_GetPosition ++ * CHNL_GetProcessHandle ++ * CHNL_Init ++ * CHNL_Open ++ * ++ * Notes: ++ * See DSP API chnl.h for more details. ++ * ++ *! Revision History: ++ *! ================ ++ *! 14-Jan-1997 gp: Updated based on code review feedback. ++ *! 24-Oct-1996 gp: Move CloseOrphans into here from dspsys. ++ *! 09-Sep-1996 gp: Added CHNL_GetProcessID() and CHNL_GetHandle(). ++ *! 10-Jul-1996 gp: Created. ++ */ ++ ++#ifndef CHNL_ ++#define CHNL_ ++ ++#include ++ ++/* ++ * ======== CHNL_Close ======== ++ * Purpose: ++ * Ensures all pending I/O on this channel is cancelled, discards all ++ * queued I/O completion notifications, then frees the resources allocated ++ * for this channel, and makes the corresponding logical channel id ++ * available for subsequent use. ++ * Parameters: ++ * hChnl: Channel object handle. ++ * Returns: ++ * DSP_SOK: Success; ++ * DSP_EHANDLE: Invalid hChnl. ++ * Requires: ++ * CHNL_Init(void) called. ++ * No thread must be blocked on this channel's I/O completion event. ++ * Ensures: ++ * DSP_SOK: The I/O completion event for this channel is freed. ++ * hChnl is no longer valid. ++ */ ++ extern DSP_STATUS CHNL_Close(struct CHNL_OBJECT *hChnl); ++ ++ ++/* ++ * ======== CHNL_Create ======== ++ * Purpose: ++ * Create a channel manager object, responsible for opening new channels ++ * and closing old ones for a given board. ++ * Parameters: ++ * phChnlMgr: Location to store a channel manager object on output. ++ * hDevObject: Handle to a device object. ++ * pMgrAttrs: Channel manager attributes. ++ * pMgrAttrs->cChannels: Max channels ++ * pMgrAttrs->bIRQ: Channel's I/O IRQ number. ++ * pMgrAttrs->fShared: TRUE if the IRQ is shareable. ++ * pMgrAttrs->uWordSize: DSP Word size in equivalent PC bytes.. ++ * Returns: ++ * DSP_SOK: Success; ++ * DSP_EHANDLE: hDevObject is invalid. ++ * DSP_EINVALIDARG: cChannels is 0. ++ * DSP_EMEMORY: Insufficient memory for requested resources. ++ * CHNL_E_ISR: Unable to plug channel ISR for configured IRQ. ++ * CHNL_E_MAXCHANNELS: This manager cannot handle this many channels. ++ * CHNL_E_INVALIDIRQ: Invalid IRQ number. Must be 0 <= bIRQ <= 15. ++ * CHNL_E_INVALIDWORDSIZE: Invalid DSP word size. Must be > 0. ++ * CHNL_E_INVALIDMEMBASE: Invalid base address for DSP communications. ++ * CHNL_E_MGREXISTS: Channel manager already exists for this device. ++ * Requires: ++ * CHNL_Init(void) called. ++ * phChnlMgr != NULL. ++ * pMgrAttrs != NULL. ++ * Ensures: ++ * DSP_SOK: Subsequent calls to CHNL_Create() for the same ++ * board without an intervening call to ++ * CHNL_Destroy() will fail. ++ */ ++ extern DSP_STATUS CHNL_Create(OUT struct CHNL_MGR **phChnlMgr, ++ struct DEV_OBJECT *hDevObject, ++ IN CONST struct CHNL_MGRATTRS *pMgrAttrs); ++ ++/* ++ * ======== CHNL_Destroy ======== ++ * Purpose: ++ * Close all open channels, and destroy the channel manager. ++ * Parameters: ++ * hChnlMgr: Channel manager object. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: hChnlMgr was invalid. ++ * Requires: ++ * CHNL_Init(void) called. ++ * Ensures: ++ * DSP_SOK: Cancels I/O on each open channel. ++ * Closes each open channel. ++ * CHNL_Create may subsequently be called for the ++ * same board. ++ */ ++ extern DSP_STATUS CHNL_Destroy(struct CHNL_MGR *hChnlMgr); ++ ++/* ++ * ======== CHNL_Exit ======== ++ * Purpose: ++ * Discontinue usage of the CHNL module. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * CHNL_Init(void) previously called. ++ * Ensures: ++ * Resources, if any acquired in CHNL_Init(void), are freed when the last ++ * client of CHNL calls CHNL_Exit(void). ++ */ ++ extern void CHNL_Exit(void); ++ ++ ++/* ++ * ======== CHNL_Init ======== ++ * Purpose: ++ * Initialize the CHNL module's private state. ++ * Parameters: ++ * Returns: ++ * TRUE if initialized; FALSE if error occurred. ++ * Requires: ++ * Ensures: ++ * A requirement for each of the other public CHNL functions. ++ */ ++ extern bool CHNL_Init(void); ++ ++ ++ ++#endif /* CHNL_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/chnl_sm.h b/arch/arm/plat-omap/include/dspbridge/chnl_sm.h +new file mode 100644 +index 0000000..789b9bd +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/chnl_sm.h +@@ -0,0 +1,168 @@ ++/* ++ * chnl_sm.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== chnl_sm.h ======== ++ * Description: ++ * Prototypes for channel lower edge functions for a WinBRIDGE mini driver ++ * implementing data transfer via shared memory. ++ * ++ * Public Functions: ++ * CHNLSM_DisableInterrupt; ++ * CHNLSM_EnableInterrupt; ++ * CHNLSM_ISR; ++ * CHNLSM_Read; ++ * CHNLSM_UpdateSHMLength; ++ * CHNLSM_Write; ++ * ++ * Notes: ++ * These lower edge functions must be implemented by the WMD writer. ++ * Currently, CHNLSM_Read() and CHNLSM_Write() are not called, but must ++ * be defined to link. ++ * ++ */ ++ ++#ifndef CHNLSM_ ++#define CHNLSM_ ++ ++#include ++ ++/* ++ * ======== CHNLSM_DisableInterrupt ======== ++ * Purpose: ++ * Disable interrupts from the DSP board to the PC. ++ * Parameters: ++ * hDevContext: Handle to mini-driver defined device info. ++ * Returns: ++ * Requires: ++ * Ensures: ++ */ ++ extern DSP_STATUS CHNLSM_DisableInterrupt(struct WMD_DEV_CONTEXT* ++ hDevContext); ++ ++/* ++ * ======== CHNLSM_EnableInterrupt ======== ++ * Purpose: ++ * Enable interrupts from the DSP board to the PC. ++ * Parameters: ++ * hDevContext: Handle to mini-driver defined device info. ++ * Returns: ++ * Requires: ++ * Ensures: ++ */ ++ extern DSP_STATUS CHNLSM_EnableInterrupt(struct WMD_DEV_CONTEXT* ++ hDevContext); ++ ++/* ++ * ======== CHNLSM_InterruptDSP2 ======== ++ * Purpose: ++ * Set interrupt value & send an interrupt to the DSP processor(s). ++ * This is typicaly used when mailbox interrupt mechanisms allow data ++ * to be associated with interrupt such as for OMAP's CMD/DATA regs. ++ * Parameters: ++ * hDevContext: Handle to mini-driver defined device info. ++ * wMbVal: Value associated with interrupt(e.g. mailbox value). ++ * Returns: ++ * DSP_SOK: Interrupt sent; ++ * else: Unable to send interrupt. ++ * Requires: ++ * Ensures: ++ */ ++ extern DSP_STATUS CHNLSM_InterruptDSP2(struct WMD_DEV_CONTEXT* ++ hDevContext, u16 wMbVal); ++ ++/* ++ * ======== CHNLSM_ISR ======== ++ * Purpose: ++ * Mini-driver's ISR, called by WCD when the board interrupts the host. ++ * Parameters: ++ * hDevContext: Handle to the mini-driver defined device info. ++ * pfSchedDPC: Set to TRUE to schedule a deferred procedure call ++ * to advance the channel protocol. The channel class ++ * library will call the WMD's CHNLSM_DPC routine during ++ * its own DPC, before dispatching I/O. ++ * The channel class library should ignore *pfSchedDPC when ++ * CHNLSM_ISR returns FALSE. ++ * pwMBRegVal: Value of mailbox register. ++ * Returns: ++ * TRUE if this interrupt is was generated by the DSP board. ++ * FALSE otherwise. ++ * Requires: ++ * Interrupts to the host processor are disabled on entry. ++ * Must only call functions which are in page locked memory. ++ * Must only call asynchronous OS services. ++ * The EOI for this interrupt has already been sent to the PIC. ++ * Ensures: ++ * If the interrupt is *not* shared, this routine must return TRUE. ++ */ ++ extern bool CHNLSM_ISR(struct WMD_DEV_CONTEXT *hDevContext, ++ OUT bool *pfSchedDPC, ++ OUT u16 *pwIntrVal); ++ ++/* ++ * ======== CHNLSM_Read ======== ++ * Purpose: ++ * Read data from DSP board memory into a Host buffer. ++ * Parameters: ++ * hDevContext: Handle to mini-driver defined device info. ++ * pHostBuf: Pointer to host buffer (Destination). ++ * dwDSPAddr: Address on DSP board (Source). ++ * ulNumBytes: Number of bytes to transfer. ++ * Returns: ++ * Requires: ++ * Ensures: ++ */ ++ extern DSP_STATUS CHNLSM_Read(struct WMD_DEV_CONTEXT *hDevContext, ++ OUT u8 *pHostBuf, ++ u32 dwDSPAddr, u32 ulNumBytes); ++ ++/* ++ * ======== CHNLSM_UpdateSHMLength ======== ++ * Purpose: ++ * Allow the minidriver a chance to override the SHM length as reported ++ * to the mini driver (chnl_sm.lib) by Windows Plug and Play. ++ * Parameters: ++ * hDevContext: Handle to mini-driver defined device info. ++ * pSHMLength: Pointer to size of SHM window (in DSP words). ++ * Returns: ++ * TRUE if pSHMLength updated; FALSE otherwise. ++ * Requires: ++ * pSHMLength != NULL. ++ * Ensures: ++ * No more than sizeof(u32) bytes written to *pSHMLength ++ */ ++ extern bool CHNLSM_UpdateSHMLength(struct WMD_DEV_CONTEXT *hDevContext, ++ IN OUT u32 *pSHMLength); ++ ++/* ++ * ======== CHNLSM_Write ======== ++ * Purpose: ++ * Write data from a Host buffer to DSP board memory. ++ * Parameters: ++ * hDevContext: Handle to mini-driver defined device info. ++ * pHostBuf: Pointer to host buffer (Source). ++ * dwDSPAddr: Address on DSP board (Destination). ++ * ulNumBytes: Number of bytes to transfer. ++ * Returns: ++ * Requires: ++ * Ensures: ++ */ ++ extern DSP_STATUS CHNLSM_Write(struct WMD_DEV_CONTEXT *hDevContext, ++ IN u8 *pHostBuf, ++ u32 dwDSPAddr, u32 ulNumBytes); ++ ++#endif /* CHNLSM_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/chnldefs.h b/arch/arm/plat-omap/include/dspbridge/chnldefs.h +new file mode 100644 +index 0000000..9f59229 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/chnldefs.h +@@ -0,0 +1,92 @@ ++/* ++ * chnldefs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== chnldefs.h ======== ++ * Purpose: ++ * System-wide channel objects and constants. ++ * ++ *! Revision History: ++ *! ================ ++ *! 19-Jan-2002 ag Added cBufSize to IOC. ++ *! 05-Jan-2000 ag: Text format cleanup. ++ *! 02-Dec-1999 ag: Added new chnl attribute pstrEventName. ++ *! 12-Nov-1999 kc: Enabled hEvent attribute for tests. ++ *! 01-Nov-1999 ag: hEvent attribute not supported(yet). ++ *! 16-Jan-1997 gp: Moved private stuff into chnlpriv.h ++ *! 14-Jan-1997 gp: Updated based on code review feedback: ++ *! Removed CHNL_MODENOWAIT, CHNL_MODEDIRECT, ++ *! 03-Jan-1997 gp: Added channel class library types. ++ *! 14-Dec-1996 gp: Moved uChnlId field from CHNL_ATTRS to CHNL_Open(). ++ *! 10-Dec-1996 gp: Added CHNL_IsTimedOut() macro. ++ *! 14-Nov-1996 gp: Renamed from wsxchnl.h. ++ *! 09-Sep-1996 gp: Added hReserved2 field to CHNL_ATTRS. Updated CHNL_INFO. ++ *! 10-Jul-1996 gp: Created from channel.h. ++ */ ++ ++#ifndef CHNLDEFS_ ++#define CHNLDEFS_ ++ ++/* Channel id option. */ ++#define CHNL_PICKFREE (~0UL) /* Let manager pick a free channel. */ ++ ++/* Channel manager limits: */ ++#define CHNL_INITIOREQS 4 /* Default # of I/O requests. */ ++ ++/* Channel modes */ ++#define CHNL_MODETODSP 0x0000 /* Data streaming to the DSP. */ ++#define CHNL_MODEFROMDSP 0x0001 /* Data streaming from the DSP. */ ++ ++/* GetIOCompletion flags */ ++#define CHNL_IOCINFINITE 0xffffffff /* Wait forever for IO completion. */ ++#define CHNL_IOCNOWAIT 0x0 /* Dequeue an IOC, if available. */ ++ ++/* IO Completion Record status: */ ++#define CHNL_IOCSTATCOMPLETE 0x0000 /* IO Completed. */ ++#define CHNL_IOCSTATCANCEL 0x0002 /* IO was cancelled */ ++#define CHNL_IOCSTATTIMEOUT 0x0008 /* Wait for IOC timed out. */ ++#define CHNL_IOCSTATEOS 0x8000 /* End Of Stream reached. */ ++ ++/* Macros for checking I/O Completion status: */ ++#define CHNL_IsEOS(ioc) (ioc.status & CHNL_IOCSTATEOS) ++#define CHNL_IsIOComplete(ioc) (!(ioc.status & ~CHNL_IOCSTATEOS)) ++#define CHNL_IsIOCancelled(ioc) (ioc.status & CHNL_IOCSTATCANCEL) ++#define CHNL_IsTimedOut(ioc) (ioc.status & CHNL_IOCSTATTIMEOUT) ++ ++/* CHNL types: */ ++ typedef u32 CHNL_MODE; /* Channel transfer mode. */ ++ ++/* Channel attributes: */ ++ struct CHNL_ATTRS { ++ u32 uIOReqs; /* Max # of preallocated I/O requests. */ ++ HANDLE hEvent; /* User supplied auto-reset event object. */ ++ char *pstrEventName; /* Ptr to name of user event object. */ ++ HANDLE hReserved1; /* Reserved for future use. */ ++ u32 hReserved2; /* Reserved for future use. */ ++ ++ }; ++ ++/* I/O completion record: */ ++ struct CHNL_IOC { ++ void *pBuf; /* Buffer to be filled/emptied. */ ++ u32 cBytes; /* Bytes transferred. */ ++ u32 cBufSize; /* Actual buffer size in bytes */ ++ u32 status; /* Status of IO completion. */ ++ u32 dwArg; /* User argument associated with pBuf. */ ++ } ; ++ ++#endif /* CHNLDEFS_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/chnlpriv.h b/arch/arm/plat-omap/include/dspbridge/chnlpriv.h +new file mode 100644 +index 0000000..fdcda24 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/chnlpriv.h +@@ -0,0 +1,136 @@ ++/* ++ * chnlpriv.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== chnlpriv.h ======== ++ * Description: ++ * Private channel header shared between DSPSYS, WCD and WMD modules. ++ * ++ * Public Functions: ++ * None. ++ * ++ * Notes: ++ * ++ *! Revision History: ++ *! ================ ++ *! 05-Jan-2002 ag Added cChannels(total # of chnls) to CHNL_MGRINFO struct. ++ *! Added private CHNL_[PCPY][ZCPY][DDMA]. ++ *! 17-Nov-2000 jeh Removed IRQ, shared memory from CHNL_MGRATTRS, since these ++ *! now belong to IO_ATTRS. ++ *! 21-Jan-2000 ag: Code review comments added. ++ *! 05-Jan-2000 ag: Text format cleanup. ++ *! 11-Dec-1999 ag: Added CHNL_MAXLOCKPAGES for CHNL_PrepareBuffer(). ++ *! 04-Dec-1999 ag: Added CHNL_MAXEVTNAMELEN for i/o compl named event support. ++ *! 01-Nov-1999 ag: CHNL_MAXCHANNELS set to 16 for 16-bit DSPs. ++ *! 27-Oct-1997 cr: Expanded CHNL_MAXIRQ from 0x0f to 0xff. ++ *! 16-Jan-1997 gp: Moved symbols into here from chnldefs.h. ++ *! 03-Jan-1997 gp: Added CHNL_MAXIRQ define. ++ *! 09-Dec-1996 gp: Removed CHNL_STATEIDLE. ++ *! 15-Jul-1996 gp: Created. ++ */ ++ ++#ifndef CHNLPRIV_ ++#define CHNLPRIV_ ++ ++#include ++#include ++#include ++ ++/* CHNL Object validation signatures: */ ++#define CHNL_MGRSIGNATURE 0x52474D43 /* "CMGR" (in reverse). */ ++#define CHNL_SIGNATURE 0x4C4E4843 /* "CHNL" (in reverse). */ ++ ++/* Channel manager limits: */ ++#define CHNL_MAXCHANNELS 32 /* Max channels available per transport */ ++ ++ ++/* ++ * Trans port channel Id definitions:(must match dsp-side). ++ * ++ * For CHNL_MAXCHANNELS = 16: ++ * ++ * ChnlIds: ++ * 0-15 (PCPY) - transport 0) ++ * 16-31 (DDMA) - transport 1) ++ * 32-47 (ZCPY) - transport 2) ++ */ ++#define CHNL_PCPY 0 /* Proc-copy transport 0 */ ++ ++#define CHNL_MAXIRQ 0xff /* Arbitrarily large number. */ ++ ++/* The following modes are private: */ ++#define CHNL_MODEUSEREVENT 0x1000 /* User provided the channel event. */ ++#define CHNL_MODEMASK 0x1001 ++ ++/* Higher level channel states: */ ++#define CHNL_STATEREADY 0x0000 /* Channel ready for I/O. */ ++#define CHNL_STATECANCEL 0x0001 /* I/O was cancelled. */ ++#define CHNL_STATEEOS 0x0002 /* End Of Stream reached. */ ++ ++/* Determine if user supplied an event for this channel: */ ++#define CHNL_IsUserEvent(mode) (mode & CHNL_MODEUSEREVENT) ++ ++/* Macros for checking mode: */ ++#define CHNL_IsInput(mode) (mode & CHNL_MODEFROMDSP) ++#define CHNL_IsOutput(mode) (!CHNL_IsInput(mode)) ++ ++/* Types of channel class libraries: */ ++#define CHNL_TYPESM 1 /* Shared memory driver. */ ++#define CHNL_TYPEBM 2 /* Bus Mastering driver. */ ++ ++/* Max string length of channel I/O completion event name - change if needed */ ++#define CHNL_MAXEVTNAMELEN 32 ++ ++/* Max memory pages lockable in CHNL_PrepareBuffer() - change if needed */ ++#define CHNL_MAXLOCKPAGES 64 ++ ++/* Channel info. */ ++ struct CHNL_INFO { ++ struct CHNL_MGR *hChnlMgr; /* Owning channel manager. */ ++ u32 dwID; /* Channel ID. */ ++ HANDLE hEvent; /* Channel I/O completion event. */ ++ /*Abstraction of I/O completion event.*/ ++ struct SYNC_OBJECT *hSyncEvent; ++ u32 dwMode; /* Channel mode. */ ++ u32 dwState; /* Current channel state. */ ++ u32 cPosition; /* Total bytes transferred. */ ++ u32 cIOCs; /* Number of IOCs in queue. */ ++ u32 cIOReqs; /* Number of IO Requests in queue. */ ++ u32 hProcess; /* Process owning this channel. */ ++ /* ++ * Name of channel I/O completion event. Not required in Linux ++ */ ++ char szEventName[CHNL_MAXEVTNAMELEN + 1]; ++ } ; ++ ++/* Channel manager info: */ ++ struct CHNL_MGRINFO { ++ u32 dwType; /* Type of channel class library. */ ++ /* Channel handle, given the channel id. */ ++ struct CHNL_OBJECT *hChnl; ++ u32 cOpenChannels; /* Number of open channels. */ ++ u32 cChannels; /* total # of chnls supported */ ++ } ; ++ ++/* Channel Manager Attrs: */ ++ struct CHNL_MGRATTRS { ++ /* Max number of channels this manager can use. */ ++ u32 cChannels; ++ u32 uWordSize; /* DSP Word size. */ ++ } ; ++ ++#endif /* CHNLPRIV_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/clk.h b/arch/arm/plat-omap/include/dspbridge/clk.h +new file mode 100644 +index 0000000..4a23dab +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/clk.h +@@ -0,0 +1,155 @@ ++/* ++ * clk.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== clk.h ======== ++ * Purpose: Provides Clock functions. ++ * ++ *! Revision History: ++ *! ================ ++ *! 08-May-2007 rg: Moved all clock functions from sync module. ++ */ ++ ++#ifndef _CLK_H ++#define _CLK_H ++ ++ /* Generic TIMER object: */ ++ struct TIMER_OBJECT; ++ enum SERVICES_ClkId { ++ SERVICESCLK_iva2_ck = 0, ++ SERVICESCLK_mailbox_ick, ++ SERVICESCLK_gpt5_fck, ++ SERVICESCLK_gpt5_ick, ++ SERVICESCLK_gpt6_fck, ++ SERVICESCLK_gpt6_ick, ++ SERVICESCLK_gpt7_fck, ++ SERVICESCLK_gpt7_ick, ++ SERVICESCLK_gpt8_fck, ++ SERVICESCLK_gpt8_ick, ++ SERVICESCLK_wdt3_fck, ++ SERVICESCLK_wdt3_ick, ++ SERVICESCLK_mcbsp1_fck, ++ SERVICESCLK_mcbsp1_ick, ++ SERVICESCLK_mcbsp2_fck, ++ SERVICESCLK_mcbsp2_ick, ++ SERVICESCLK_mcbsp3_fck, ++ SERVICESCLK_mcbsp3_ick, ++ SERVICESCLK_mcbsp4_fck, ++ SERVICESCLK_mcbsp4_ick, ++ SERVICESCLK_mcbsp5_fck, ++ SERVICESCLK_mcbsp5_ick, ++ SERVICESCLK_ssi_fck, ++ SERVICESCLK_ssi_ick, ++ SERVICESCLK_sys_32k_ck, ++ SERVICESCLK_sys_ck, ++ SERVICESCLK_NOT_DEFINED ++ } ; ++ ++/* ++ * ======== CLK_Exit ======== ++ * Purpose: ++ * Discontinue usage of module; free resources when reference count ++ * reaches 0. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * CLK initialized. ++ * Ensures: ++ * Resources used by module are freed when cRef reaches zero. ++ */ ++ extern void CLK_Exit(void); ++ ++/* ++ * ======== CLK_Init ======== ++ * Purpose: ++ * Initializes private state of CLK module. ++ * Parameters: ++ * Returns: ++ * TRUE if initialized; FALSE if error occured. ++ * Requires: ++ * Ensures: ++ * CLK initialized. ++ */ ++ extern bool CLK_Init(void); ++ ++ ++/* ++ * ======== CLK_Enable ======== ++ * Purpose: ++ * Enables the clock requested. ++ * Parameters: ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Error occured while enabling the clock. ++ * Requires: ++ * Ensures: ++ */ ++ extern DSP_STATUS CLK_Enable(IN enum SERVICES_ClkId clk_id); ++ ++/* ++ * ======== CLK_Disable ======== ++ * Purpose: ++ * Disables the clock requested. ++ * Parameters: ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Error occured while disabling the clock. ++ * Requires: ++ * Ensures: ++ */ ++ extern DSP_STATUS CLK_Disable(IN enum SERVICES_ClkId clk_id); ++ ++/* ++ * ======== CLK_GetRate ======== ++ * Purpose: ++ * Get the clock rate of requested clock. ++ * Parameters: ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Error occured while Getting the clock rate. ++ * Requires: ++ * Ensures: ++ */ ++ extern DSP_STATUS CLK_GetRate(IN enum SERVICES_ClkId clk_id, ++ u32 *speedMhz); ++/* ++ * ======== CLK_Set_32KHz ======== ++ * Purpose: ++ * Set the requested clock to 32KHz. ++ * Parameters: ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Error occured while setting the clock parent to 32KHz. ++ * Requires: ++ * Ensures: ++ */ ++ extern DSP_STATUS CLK_Set_32KHz(IN enum SERVICES_ClkId clk_id); ++ extern void SSI_Clk_Prepare(bool FLAG); ++ ++/* ++ * ======== CLK_Get_RefCnt ======== ++ * Purpose: ++ * get the reference count for the clock. ++ * Parameters: ++ * Returns: ++ * s32: Reference Count for the clock. ++ * DSP_EFAIL: Error occured while getting the reference count of a clock. ++ * Requires: ++ * Ensures: ++ */ ++ extern s32 CLK_Get_UseCnt(IN enum SERVICES_ClkId clk_id); ++ ++#endif /* _SYNC_H */ +diff --git a/arch/arm/plat-omap/include/dspbridge/cmm.h b/arch/arm/plat-omap/include/dspbridge/cmm.h +new file mode 100644 +index 0000000..0df8b83 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/cmm.h +@@ -0,0 +1,420 @@ ++/* ++ * cmm.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== cmm.h ======== ++ * Purpose: ++ * The Communication Memory Management(CMM) module provides shared memory ++ * management services for DSP/BIOS Bridge data streaming and messaging. ++ * Multiple shared memory segments can be registered with CMM. Memory is ++ * coelesced back to the appropriate pool when a buffer is freed. ++ * ++ * The CMM_Xlator[xxx] functions are used for node messaging and data ++ * streaming address translation to perform zero-copy inter-processor ++ * data transfer(GPP<->DSP). A "translator" object is created for a node or ++ * stream object that contains per thread virtual address information. This ++ * translator info is used at runtime to perform SM address translation ++ * to/from the DSP address space. ++ * ++ * ++ * Public Functions: ++ * CMM_CallocBuf ++ * CMM_Create ++ * CMM_Destroy ++ * CMM_Exit ++ * CMM_FreeBuf ++ * CMM_GetHandle ++ * CMM_GetInfo ++ * CMM_Init ++ * CMM_RegisterGPPSMSeg ++ * CMM_UnRegisterGPPSMSeg ++ * CMM_XlatorAllocBuf (Note #1 below) ++ * CMM_XlatorCreate " ++ * CMM_XlatorDelete " ++ * CMM_XlatorFreeBuf " ++ * CMM_XlatorTranslate " ++ * ++ * ++ * Notes: ++ * #1: Used by Node and Stream modules for SM address translation. ++ * ++ *! Revision History: ++ *! ================ ++ *! 30-Jan-2002 ag Removed unused CMM_Alloc[Free]Desc & CMM_XlatorRegisterPa. ++ *! Renamed CMM_AllocBuf() to CMM_CallocBuf(). ++ *! 29-Aug-2001 ag: Added dsp virt base and size to CMM_RegisterGPPSMSeg(). ++ *! 12-Aug-2001 ag: Added CMM_UnRegisterGPP[DSP}SMSeg[s](). ++ *! 05-Dec-2000 ag: Added param to CMM_XlatorDelete() to force buf cleanup. ++ *! 30-Oct-2000 ag: Added conversion factor to CMM_RegisterDSP[GPP]SMSeg(). ++ *! 12-Oct-2000 ag: Added CMM_Xlator[xxx] functions. ++ *! 10-Aug-2000 ag: Created. ++ *! ++ */ ++ ++#ifndef CMM_ ++#define CMM_ ++ ++#include ++ ++#include ++#include ++ ++/* ++ * ======== CMM_CallocBuf ======== ++ * Purpose: ++ * Allocate memory buffers that can be used for data streaming or ++ * messaging. ++ * Parameters: ++ * hCmmMgr: Cmm Mgr handle. ++ * uSize: Number of bytes to allocate. ++ * pAttr: Attributes of memory to allocate. ++ * ppBufVA: Address of where to place VA. ++ * Returns: ++ * Pointer to a zero'd block of SM memory; ++ * NULL if memory couldn't be allocated, ++ * or if cBytes == 0, ++ * Requires: ++ * Valid hCmmMgr. ++ * CMM initialized. ++ * Ensures: ++ * The returned pointer, if not NULL, points to a valid memory block of ++ * the size requested. ++ * ++ */ ++ extern void *CMM_CallocBuf(struct CMM_OBJECT *hCmmMgr, ++ u32 uSize, struct CMM_ATTRS *pAttrs, ++ OUT void **ppBufVA); ++ ++/* ++ * ======== CMM_Create ======== ++ * Purpose: ++ * Create a communication memory manager object. ++ * Parameters: ++ * phCmmMgr: Location to store a communication manager handle on output. ++ * hDevObject: Handle to a device object. ++ * pMgrAttrs: Comm mem manager attributes. ++ * Returns: ++ * DSP_SOK: Success; ++ * DSP_EMEMORY: Insufficient memory for requested resources. ++ * DSP_EFAIL: Failed to initialize critical sect sync object. ++ * ++ * Requires: ++ * CMM_Init(void) called. ++ * phCmmMgr != NULL. ++ * pMgrAttrs->ulMinBlockSize >= 4 bytes. ++ * Ensures: ++ * ++ */ ++ extern DSP_STATUS CMM_Create(OUT struct CMM_OBJECT **phCmmMgr, ++ struct DEV_OBJECT *hDevObject, ++ IN CONST struct CMM_MGRATTRS *pMgrAttrs); ++ ++/* ++ * ======== CMM_Destroy ======== ++ * Purpose: ++ * Destroy the communication memory manager object. ++ * Parameters: ++ * hCmmMgr: Cmm Mgr handle. ++ * bForce: Force deallocation of all cmm memory immediately if set TRUE. ++ * If FALSE, and outstanding allocations will return DSP_EFAIL ++ * status. ++ * Returns: ++ * DSP_SOK: CMM object & resources deleted. ++ * DSP_EFAIL: Unable to free CMM object due to outstanding allocation. ++ * DSP_EHANDLE: Unable to free CMM due to bad handle. ++ * Requires: ++ * CMM is initialized. ++ * hCmmMgr != NULL. ++ * Ensures: ++ * Memory resources used by Cmm Mgr are freed. ++ */ ++ extern DSP_STATUS CMM_Destroy(struct CMM_OBJECT *hCmmMgr, bool bForce); ++ ++/* ++ * ======== CMM_Exit ======== ++ * Purpose: ++ * Discontinue usage of module. Cleanup CMM module if CMM cRef reaches zero. ++ * Parameters: ++ * n/a ++ * Returns: ++ * n/a ++ * Requires: ++ * CMM is initialized. ++ * Ensures: ++ */ ++ extern void CMM_Exit(void); ++ ++/* ++ * ======== CMM_FreeBuf ======== ++ * Purpose: ++ * Free the given buffer. ++ * Parameters: ++ * hCmmMgr: Cmm Mgr handle. ++ * pBuf: Pointer to memory allocated by CMM_CallocBuf(). ++ * ulSegId: SM segment Id used in CMM_Calloc() attrs. ++ * Set to 0 to use default segment. ++ * Returns: ++ * DSP_SOK ++ * DSP_EFAIL ++ * Requires: ++ * CMM initialized. ++ * pBufPA != NULL ++ * Ensures: ++ * ++ */ ++ extern DSP_STATUS CMM_FreeBuf(struct CMM_OBJECT *hCmmMgr, ++ void *pBufPA, u32 ulSegId); ++ ++/* ++ * ======== CMM_GetHandle ======== ++ * Purpose: ++ * Return the handle to the cmm mgr for the given device obj. ++ * Parameters: ++ * hProcessor: Handle to a Processor. ++ * phCmmMgr: Location to store the shared memory mgr handle on output. ++ * ++ * Returns: ++ * DSP_SOK: Cmm Mgr opaque handle returned. ++ * DSP_EHANDLE: Invalid handle. ++ * Requires: ++ * phCmmMgr != NULL ++ * hDevObject != NULL ++ * Ensures: ++ */ ++ extern DSP_STATUS CMM_GetHandle(DSP_HPROCESSOR hProcessor, ++ OUT struct CMM_OBJECT **phCmmMgr); ++ ++/* ++ * ======== CMM_GetInfo ======== ++ * Purpose: ++ * Return the current SM and VM utilization information. ++ * Parameters: ++ * hCmmMgr: Handle to a Cmm Mgr. ++ * pCmmInfo: Location to store the Cmm information on output. ++ * ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid handle. ++ * DSP_EINVALIDARG Invalid input argument. ++ * Requires: ++ * Ensures: ++ * ++ */ ++ extern DSP_STATUS CMM_GetInfo(struct CMM_OBJECT *hCmmMgr, ++ OUT struct CMM_INFO *pCmmInfo); ++ ++/* ++ * ======== CMM_Init ======== ++ * Purpose: ++ * Initializes private state of CMM module. ++ * Parameters: ++ * Returns: ++ * TRUE if initialized; FALSE if error occured. ++ * Requires: ++ * Ensures: ++ * CMM initialized. ++ */ ++ extern bool CMM_Init(void); ++ ++/* ++ * ======== CMM_RegisterGPPSMSeg ======== ++ * Purpose: ++ * Register a block of SM with the CMM. ++ * Parameters: ++ * hCmmMgr: Handle to a Cmm Mgr. ++ * lpGPPBasePA: GPP Base Physical address. ++ * ulSize: Size in GPP bytes. ++ * dwDSPAddrOffset GPP PA to DSP PA Offset. ++ * cFactor: Add offset if CMM_ADDTODSPPA, sub if CMM_SUBFROMDSPPA. ++ * dwDSPBase: DSP virtual base byte address. ++ * ulDSPSize: Size of DSP segment in bytes. ++ * pulSegId: Address to store segment Id. ++ * ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hCmmMgr handle. ++ * DSP_EINVALIDARG: Invalid input argument. ++ * DSP_EFAIL: Unable to register. ++ * - On success *pulSegId is a valid SM segment ID. ++ * Requires: ++ * ulSize > 0 ++ * pulSegId != NULL ++ * dwGPPBasePA != 0 ++ * cFactor = CMM_ADDTODSPPA || cFactor = CMM_SUBFROMDSPPA ++ * Ensures: ++ * ++ */ ++ extern DSP_STATUS CMM_RegisterGPPSMSeg(struct CMM_OBJECT *hCmmMgr, ++ unsigned int dwGPPBasePA, ++ u32 ulSize, ++ u32 dwDSPAddrOffset, ++ enum CMM_CNVTTYPE cFactor, ++ unsigned int dwDSPBase, ++ u32 ulDSPSize, ++ u32 *pulSegId, ++ u32 dwGPPBaseBA); ++ ++/* ++ * ======== CMM_UnRegisterGPPSMSeg ======== ++ * Purpose: ++ * Unregister the given memory segment that was previously registered ++ * by CMM_RegisterGPPSMSeg. ++ * Parameters: ++ * hCmmMgr: Handle to a Cmm Mgr. ++ * ulSegId Segment identifier returned by CMM_RegisterGPPSMSeg. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid handle. ++ * DSP_EINVALIDARG: Invalid ulSegId. ++ * DSP_EFAIL: Unable to unregister for unknown reason. ++ * Requires: ++ * Ensures: ++ * ++ */ ++ extern DSP_STATUS CMM_UnRegisterGPPSMSeg(struct CMM_OBJECT *hCmmMgr, ++ u32 ulSegId); ++ ++/* ++ * ======== CMM_XlatorAllocBuf ======== ++ * Purpose: ++ * Allocate the specified SM buffer and create a local memory descriptor. ++ * Place on the descriptor on the translator's HaQ (Host Alloc'd Queue). ++ * Parameters: ++ * hXlator: Handle to a Xlator object. ++ * pVaBuf: Virtual address ptr(client context) ++ * uPaSize: Size of SM memory to allocate. ++ * Returns: ++ * Ptr to valid physical address(Pa) of uPaSize bytes, NULL if failed. ++ * Requires: ++ * pVaBuf != 0. ++ * uPaSize != 0. ++ * Ensures: ++ * ++ */ ++ extern void *CMM_XlatorAllocBuf(struct CMM_XLATOROBJECT *hXlator, ++ void *pVaBuf, u32 uPaSize); ++ ++/* ++ * ======== CMM_XlatorCreate ======== ++ * Purpose: ++ * Create a translator(xlator) object used for process specific Va<->Pa ++ * address translation. Node messaging and streams use this to perform ++ * inter-processor(GPP<->DSP) zero-copy data transfer. ++ * Parameters: ++ * phXlator: Address to place handle to a new Xlator handle. ++ * hCmmMgr: Handle to Cmm Mgr associated with this translator. ++ * pXlatorAttrs: Translator attributes used for the client NODE or STREAM. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EINVALIDARG: Bad input Attrs. ++ * DSP_EMEMORY: Insufficient memory(local) for requested resources. ++ * Requires: ++ * phXlator != NULL ++ * hCmmMgr != NULL ++ * pXlatorAttrs != NULL ++ * Ensures: ++ * ++ */ ++ extern DSP_STATUS CMM_XlatorCreate(OUT struct CMM_XLATOROBJECT **phXlator, ++ struct CMM_OBJECT *hCmmMgr, ++ struct CMM_XLATORATTRS *pXlatorAttrs); ++ ++/* ++ * ======== CMM_XlatorDelete ======== ++ * Purpose: ++ * Delete translator resources ++ * Parameters: ++ * hXlator: handle to translator. ++ * bForce: bForce = TRUE will free XLators SM buffers/dscriptrs. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Bad translator handle. ++ * DSP_EFAIL: Unable to free translator resources. ++ * Requires: ++ * cRefs > 0 ++ * Ensures: ++ * ++ */ ++ extern DSP_STATUS CMM_XlatorDelete(struct CMM_XLATOROBJECT *hXlator, ++ bool bForce); ++ ++/* ++ * ======== CMM_XlatorFreeBuf ======== ++ * Purpose: ++ * Free SM buffer and descriptor. ++ * Does not free client process VM. ++ * Parameters: ++ * hXlator: handle to translator. ++ * pBufVa Virtual address of PA to free. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Bad translator handle. ++ * Requires: ++ * Ensures: ++ * ++ */ ++ extern DSP_STATUS CMM_XlatorFreeBuf(struct CMM_XLATOROBJECT *hXlator, ++ void *pBufVa); ++ ++/* ++ * ======== CMM_XlatorInfo ======== ++ * Purpose: ++ * Set/Get process specific "translator" address info. ++ * This is used to perform fast virtaul address translation ++ * for shared memory buffers between the GPP and DSP. ++ * Parameters: ++ * hXlator: handle to translator. ++ * pAddr: Virtual base address of segment. ++ * ulSize: Size in bytes. ++ * uSegId: Segment identifier of SM segment(s) ++ * bSetInfo Set xlator fields if TRUE, else return base addr ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Bad translator handle. ++ * Requires: ++ * (cRefs > 0) ++ * (pAddr != NULL) ++ * (ulSize > 0) ++ * Ensures: ++ * ++ */ ++ extern DSP_STATUS CMM_XlatorInfo(struct CMM_XLATOROBJECT *hXlator, ++ IN OUT u8 **pAddr, ++ u32 ulSize, u32 uSegId, ++ bool bSetInfo); ++ ++/* ++ * ======== CMM_XlatorTranslate ======== ++ * Purpose: ++ * Perform address translation VA<->PA for the specified stream or ++ * message shared memory buffer. ++ * Parameters: ++ * hXlator: handle to translator. ++ * pAddr address of buffer to translate. ++ * xType Type of address xlation. CMM_PA2VA or CMM_VA2PA. ++ * Returns: ++ * Valid address on success, else NULL. ++ * Requires: ++ * cRefs > 0 ++ * pAddr != NULL ++ * xType >= CMM_VA2PA) && (xType <= CMM_DSPPA2PA) ++ * Ensures: ++ * ++ */ ++ extern void *CMM_XlatorTranslate(struct CMM_XLATOROBJECT *hXlator, ++ void *pAddr, enum CMM_XLATETYPE xType); ++ ++#endif /* CMM_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/cmmdefs.h b/arch/arm/plat-omap/include/dspbridge/cmmdefs.h +new file mode 100644 +index 0000000..a779377 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/cmmdefs.h +@@ -0,0 +1,135 @@ ++/* ++ * cmmdefs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== cmmdefs.h ======== ++ * Purpose: ++ * Global MEM constants and types. ++ * ++ *! Revision History: ++ *! ================ ++ *! 12-Nov-2001 ag CMM_KERNMAPTYPE added for dsp<->device process addr map'n. ++ *! This allows addr conversion from drvr process <-> DSP addr. ++ *! 29-Aug-2001 ag Added CMM_ALLSEGMENTS. ++ *! 08-Dec-2000 ag Added bus address conversion type CMM_POMAPEMIF2DSPBUS. ++ *! 05-Dec-2000 ag Added default CMM_DEFLTCONVFACTOR & CMM_DEFLTDSPADDROFFSET. ++ *! 29-Oct-2000 ag Added converstion factor for GPP DSP Pa translation. ++ *! 15-Oct-2000 ag Added address translator attributes and defaults. ++ *! 12-Jul-2000 ag Created. ++ */ ++ ++#ifndef CMMDEFS_ ++#define CMMDEFS_ ++ ++#include ++ ++/* Cmm attributes used in CMM_Create() */ ++ struct CMM_MGRATTRS { ++ /* Minimum SM allocation; default 32 bytes. */ ++ u32 ulMinBlockSize; ++ } ; ++ ++/* Attributes for CMM_AllocBuf() & CMM_AllocDesc() */ ++ struct CMM_ATTRS { ++ u32 ulSegId; /* 1,2... are SM segments. 0 is not. */ ++ u32 ulAlignment; /* 0,1,2,4....ulMinBlockSize */ ++ } ; ++ ++/* ++ * DSPPa to GPPPa Conversion Factor. ++ * ++ * For typical platforms: ++ * converted Address = PaDSP + ( cFactor * addressToConvert). ++ */ ++ enum CMM_CNVTTYPE { ++ CMM_SUBFROMDSPPA = -1, ++ /* PreOMAP is special case: not simple offset */ ++ CMM_POMAPEMIF2DSPBUS = 0, ++ CMM_ADDTODSPPA = 1 ++ } ; ++ ++#define CMM_DEFLTDSPADDROFFSET 0 ++#define CMM_DEFLTCONVFACTOR CMM_POMAPEMIF2DSPBUS /* PreOMAP DSPBUS<->EMIF */ ++#define CMM_ALLSEGMENTS 0xFFFFFF /* All SegIds */ ++#define CMM_MAXGPPSEGS 1 /* Maximum # of SM segs */ ++ ++/* ++ * SMSEGs are SM segments the DSP allocates from. ++ * ++ * This info is used by the GPP to xlate DSP allocated PAs. ++ */ ++ ++ struct CMM_SEGINFO { ++ u32 dwSegBasePa; /* Start Phys address of SM segment */ ++ /* Total size in bytes of segment: DSP+GPP */ ++ u32 ulTotalSegSize; ++ u32 dwGPPBasePA; /* Start Phys addr of Gpp SM seg */ ++ u32 ulGPPSize; /* Size of Gpp SM seg in bytes */ ++ u32 dwDSPBaseVA; /* DSP virt base byte address */ ++ u32 ulDSPSize; /* DSP seg size in bytes */ ++ /* # of current GPP allocations from this segment */ ++ u32 ulInUseCnt; ++ u32 dwSegBaseVa; /* Start Virt address of SM seg */ ++ ++ } ; ++ ++/* CMM useful information */ ++ struct CMM_INFO { ++ /* # of SM segments registered with this Cmm. */ ++ u32 ulNumGPPSMSegs; ++ /* Total # of allocations outstanding for CMM */ ++ u32 ulTotalInUseCnt; ++ /* Min SM block size allocation from CMM_Create() */ ++ u32 ulMinBlockSize; ++ /* Info per registered SM segment. */ ++ struct CMM_SEGINFO segInfo[CMM_MAXGPPSEGS]; ++ } ; ++ ++/* XlatorCreate attributes */ ++ struct CMM_XLATORATTRS { ++ u32 ulSegId; /* segment Id used for SM allocations */ ++ u32 dwDSPBufs; /* # of DSP-side bufs */ ++ u32 dwDSPBufSize; /* size of DSP-side bufs in GPP bytes */ ++ /* Vm base address alloc'd in client process context */ ++ void *pVmBase; ++ /* dwVmSize must be >= (dwMaxNumBufs * dwMaxSize) */ ++ u32 dwVmSize; ++ } ; ++ ++/* ++ * Cmm translation types. Use to map SM addresses to process context. ++ */ ++ enum CMM_XLATETYPE { ++ CMM_VA2PA = 0, /* Virtual to GPP physical address xlation */ ++ CMM_PA2VA = 1, /* GPP Physical to virtual */ ++ CMM_VA2DSPPA = 2, /* Va to DSP Pa */ ++ CMM_PA2DSPPA = 3, /* GPP Pa to DSP Pa */ ++ CMM_DSPPA2PA = 4, /* DSP Pa to GPP Pa */ ++ } ; ++ ++/* ++ * Used to "map" between device process virt addr and dsp addr. ++ */ ++ enum CMM_KERNMAPTYPE { ++ CMM_KERNVA2DSP = 0, /* Device process context to dsp address. */ ++ CMM_DSP2KERNVA = 1, /* Dsp address to device process context. */ ++ } ; ++ ++ struct CMM_OBJECT; ++ struct CMM_XLATOROBJECT; ++ ++#endif /* CMMDEFS_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/cod.h b/arch/arm/plat-omap/include/dspbridge/cod.h +new file mode 100644 +index 0000000..a8a12c6 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/cod.h +@@ -0,0 +1,433 @@ ++/* ++ * cod.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== cod.h ======== ++ * Description: ++ * Code management module for DSPs. This module provides an interface ++ * interface for loading both static and dynamic code objects onto DSP ++ * systems. ++ * ++ * Public Functions: ++ * COD_Close ++ * COD_Create ++ * COD_Delete ++ * COD_Exit ++ * COD_GetBaseLib ++ * COD_GetBaseName ++ * COD_GetLoader ++ * COD_GetSection ++ * COD_GetSymValue ++ * COD_Init ++ * COD_LoadBase ++ * COD_Open ++ * COD_OpenBase ++ * COD_ReadSection ++ * COD_UnloadSection ++ * ++ * Note: ++ * Currently, only static loading is supported. ++ * ++ *! Revision History ++ *! ================ ++ *! 08-Apr-2003 map: Changed DBL to DBLL ++ *! 07-Aug-2002 jeh: Added COD_GetBaseName(). ++ *! 17-Jul-2002 jeh: Added COD_Open(), COD_Close(). ++ *! 15-Mar-2002 jeh: Added DBL_Flags param to COD_OpenBase(). ++ *! 19-Oct-2001 jeh: Added COD_GetBaseLib, COD_GetLoader, (left in ++ *! COD_LoadSection(), COD_UnloadSection(), since they ++ *! may be needed for BridgeLite). ++ *! 07-Sep-2001 jeh: Added COD_LoadSection(), COD_UnloadSection(). ++ *! 11-Jan-2001 jeh: Added COD_OpenBase. ++ *! 29-Sep-2000 kc: Added size param to COD_ReadSection for input buffer ++ *! validation. ++ *! 02-Aug-2000 kc: Added COD_ReadSection. ++ *! 04-Sep-1997 gp: Added CDECL identifier to COD_WRITEFXN (for NT).. ++ *! 18-Aug-1997 cr: Added explicit CDECL identifier. ++ *! 28-Oct-1996 gp: Added COD_GetSection. ++ *! 30-Jul-1996 gp: Added envp[] argument to COD_LoadBase(). ++ *! 12-Jun-1996 gp: Moved OUT param first in _Create(). Updated _Create() ++ *! call to take a ZLFileName. Moved COD_ processor types ++ *! to CFG. ++ *! 29-May-1996 gp: Changed WCD_STATUS to DSP_STATUS. Removed include's. ++ *! 07-May-1996 mg: Created. ++ * ++ */ ++ ++#ifndef COD_ ++#define COD_ ++ ++#include ++ ++#define COD_MAXPATHLENGTH 255 ++#define COD_TRACEBEG "SYS_PUTCBEG" ++#define COD_TRACEEND "SYS_PUTCEND" ++#define COD_TRACESECT "trace" ++#define COD_TRACEBEGOLD "PUTCBEG" ++#define COD_TRACEENDOLD "PUTCEND" ++ ++#define COD_NOLOAD DBLL_NOLOAD ++#define COD_SYMB DBLL_SYMB ++ ++/* Flags passed to COD_Open */ ++ typedef DBLL_Flags COD_FLAGS; ++ ++/* COD code manager handle */ ++ struct COD_MANAGER; ++ ++/* COD library handle */ ++ struct COD_LIBRARYOBJ; ++ ++/* COD attributes */ ++ struct COD_ATTRS { ++ u32 ulReserved; ++ } ; ++ ++/* ++ * Function prototypes for writing memory to a DSP system, allocating ++ * and freeing DSP memory. ++ */ ++ typedef u32(*COD_WRITEFXN) (void *pPrivRef, u32 ulDspAddr, ++ void *pBuf, u32 ulNumBytes, ++ u32 nMemSpace); ++ ++ ++/* ++ * ======== COD_Close ======== ++ * Purpose: ++ * Close a library opened with COD_Open(). ++ * Parameters: ++ * lib - Library handle returned by COD_Open(). ++ * Returns: ++ * None. ++ * Requires: ++ * COD module initialized. ++ * valid lib. ++ * Ensures: ++ * ++ */ ++ extern void COD_Close(struct COD_LIBRARYOBJ *lib); ++ ++/* ++ * ======== COD_Create ======== ++ * Purpose: ++ * Create an object to manage code on a DSP system. This object can be ++ * used to load an initial program image with arguments that can later ++ * be expanded with dynamically loaded object files. ++ * Symbol table information is managed by this object and can be retrieved ++ * using the COD_GetSymValue() function. ++ * Parameters: ++ * phManager: created manager object ++ * pstrZLFile: ZL DLL filename, of length < COD_MAXPATHLENGTH. ++ * attrs: attributes to be used by this object. A NULL value ++ * will cause default attrs to be used. ++ * Returns: ++ * DSP_SOK: Success. ++ * COD_E_NOZLFUNCTIONS: Could not initialize ZL functions. ++ * COD_E_ZLCREATEFAILED: ZL_Create failed. ++ * DSP_ENOTIMPL: attrs was not NULL. We don't yet support ++ * non default values of attrs. ++ * Requires: ++ * COD module initialized. ++ * pstrZLFile != NULL ++ * Ensures: ++ */ ++ extern DSP_STATUS COD_Create(OUT struct COD_MANAGER **phManager, ++ char *pstrZLFile, ++ IN OPTIONAL CONST struct COD_ATTRS *attrs); ++ ++/* ++ * ======== COD_Delete ======== ++ * Purpose: ++ * Delete a code manager object. ++ * Parameters: ++ * hManager: handle of manager to be deleted ++ * Returns: ++ * None. ++ * Requires: ++ * COD module initialized. ++ * valid hManager. ++ * Ensures: ++ */ ++ extern void COD_Delete(struct COD_MANAGER *hManager); ++ ++/* ++ * ======== COD_Exit ======== ++ * Purpose: ++ * Discontinue usage of the COD module. ++ * Parameters: ++ * None. ++ * Returns: ++ * None. ++ * Requires: ++ * COD initialized. ++ * Ensures: ++ * Resources acquired in COD_Init(void) are freed. ++ */ ++ extern void COD_Exit(void); ++ ++/* ++ * ======== COD_GetBaseLib ======== ++ * Purpose: ++ * Get handle to the base image DBL library. ++ * Parameters: ++ * hManager: handle of manager to be deleted ++ * plib: location to store library handle on output. ++ * Returns: ++ * DSP_SOK: Success. ++ * Requires: ++ * COD module initialized. ++ * valid hManager. ++ * plib != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS COD_GetBaseLib(struct COD_MANAGER *hManager, ++ struct DBLL_LibraryObj **plib); ++ ++/* ++ * ======== COD_GetBaseName ======== ++ * Purpose: ++ * Get the name of the base image DBL library. ++ * Parameters: ++ * hManager: handle of manager to be deleted ++ * pszName: location to store library name on output. ++ * uSize: size of name buffer. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Buffer too small. ++ * Requires: ++ * COD module initialized. ++ * valid hManager. ++ * pszName != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS COD_GetBaseName(struct COD_MANAGER *hManager, ++ char *pszName, u32 uSize); ++ ++/* ++ * ======== COD_GetEntry ======== ++ * Purpose: ++ * Retrieve the entry point of a loaded DSP program image ++ * Parameters: ++ * hManager: handle of manager to be deleted ++ * pulEntry: pointer to location for entry point ++ * Returns: ++ * DSP_SOK: Success. ++ * Requires: ++ * COD module initialized. ++ * valid hManager. ++ * pulEntry != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS COD_GetEntry(struct COD_MANAGER *hManager, ++ u32 *pulEntry); ++ ++/* ++ * ======== COD_GetLoader ======== ++ * Purpose: ++ * Get handle to the DBL loader. ++ * Parameters: ++ * hManager: handle of manager to be deleted ++ * phLoader: location to store loader handle on output. ++ * Returns: ++ * DSP_SOK: Success. ++ * Requires: ++ * COD module initialized. ++ * valid hManager. ++ * phLoader != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS COD_GetLoader(struct COD_MANAGER *hManager, ++ struct DBLL_TarObj **phLoader); ++ ++/* ++ * ======== COD_GetSection ======== ++ * Purpose: ++ * Retrieve the starting address and length of a section in the COFF file ++ * given the section name. ++ * Parameters: ++ * lib Library handle returned from COD_Open(). ++ * pstrSect: name of the section, with or without leading "." ++ * puAddr: Location to store address. ++ * puLen: Location to store length. ++ * Returns: ++ * DSP_SOK: Success ++ * COD_E_NOSYMBOLSLOADED: Symbols have not been loaded onto the board. ++ * COD_E_SYMBOLNOTFOUND: The symbol could not be found. ++ * Requires: ++ * COD module initialized. ++ * valid hManager. ++ * pstrSect != NULL; ++ * puAddr != NULL; ++ * puLen != NULL; ++ * Ensures: ++ * DSP_SOK: *puAddr and *puLen contain the address and length of the ++ * section. ++ * else: *puAddr == 0 and *puLen == 0; ++ * ++ */ ++ extern DSP_STATUS COD_GetSection(struct COD_LIBRARYOBJ *lib, ++ IN char *pstrSect, ++ OUT u32 *puAddr, ++ OUT u32 *puLen); ++ ++/* ++ * ======== COD_GetSymValue ======== ++ * Purpose: ++ * Retrieve the value for the specified symbol. The symbol is first ++ * searched for literally and then, if not found, searched for as a ++ * C symbol. ++ * Parameters: ++ * lib: library handle returned from COD_Open(). ++ * pstrSymbol: name of the symbol ++ * value: value of the symbol ++ * Returns: ++ * DSP_SOK: Success. ++ * COD_E_NOSYMBOLSLOADED: Symbols have not been loaded onto the board. ++ * COD_E_SYMBOLNOTFOUND: The symbol could not be found. ++ * Requires: ++ * COD module initialized. ++ * Valid hManager. ++ * pstrSym != NULL. ++ * pulValue != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS COD_GetSymValue(struct COD_MANAGER *hManager, ++ IN char *pstrSym, ++ OUT u32 *pulValue); ++ ++/* ++ * ======== COD_Init ======== ++ * Purpose: ++ * Initialize the COD module's private state. ++ * Parameters: ++ * None. ++ * Returns: ++ * TRUE if initialized; FALSE if error occured. ++ * Requires: ++ * Ensures: ++ * A requirement for each of the other public COD functions. ++ */ ++ extern bool COD_Init(void); ++ ++/* ++ * ======== COD_LoadBase ======== ++ * Purpose: ++ * Load the initial program image, optionally with command-line arguments, ++ * on the DSP system managed by the supplied handle. The program to be ++ * loaded must be the first element of the args array and must be a fully ++ * qualified pathname. ++ * Parameters: ++ * hMgr: manager to load the code with ++ * nArgc: number of arguments in the args array ++ * args: array of strings for arguments to DSP program ++ * writeFxn: board-specific function to write data to DSP system ++ * pArb: arbitrary pointer to be passed as first arg to writeFxn ++ * envp: array of environment strings for DSP exec. ++ * Returns: ++ * DSP_SOK: Success. ++ * COD_E_OPENFAILED: Failed to open target code. ++ * COD_E_LOADFAILED: Failed to load code onto target. ++ * Requires: ++ * COD module initialized. ++ * hMgr is valid. ++ * nArgc > 0. ++ * aArgs != NULL. ++ * aArgs[0] != NULL. ++ * pfnWrite != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS COD_LoadBase(struct COD_MANAGER *hManager, ++ u32 nArgc, char *aArgs[], ++ COD_WRITEFXN pfnWrite, void *pArb, ++ char *envp[]); ++ ++ ++/* ++ * ======== COD_Open ======== ++ * Purpose: ++ * Open a library for reading sections. Does not load or set the base. ++ * Parameters: ++ * hMgr: manager to load the code with ++ * pszCoffPath: Coff file to open. ++ * flags: COD_NOLOAD (don't load symbols) or COD_SYMB (load ++ * symbols). ++ * pLib: Handle returned that can be used in calls to COD_Close ++ * and COD_GetSection. ++ * Returns: ++ * S_OK: Success. ++ * COD_E_OPENFAILED: Failed to open target code. ++ * Requires: ++ * COD module initialized. ++ * hMgr is valid. ++ * flags == COD_NOLOAD || flags == COD_SYMB. ++ * pszCoffPath != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS COD_Open(struct COD_MANAGER *hMgr, ++ IN char *pszCoffPath, ++ COD_FLAGS flags, ++ OUT struct COD_LIBRARYOBJ **pLib); ++ ++/* ++ * ======== COD_OpenBase ======== ++ * Purpose: ++ * Open base image for reading sections. Does not load the base. ++ * Parameters: ++ * hMgr: manager to load the code with ++ * pszCoffPath: Coff file to open. ++ * flags: Specifies whether to load symbols. ++ * Returns: ++ * DSP_SOK: Success. ++ * COD_E_OPENFAILED: Failed to open target code. ++ * Requires: ++ * COD module initialized. ++ * hMgr is valid. ++ * pszCoffPath != NULL. ++ * Ensures: ++ */ ++extern DSP_STATUS COD_OpenBase(struct COD_MANAGER *hMgr, IN char *pszCoffPath, ++ DBLL_Flags flags); ++ ++/* ++ * ======== COD_ReadSection ======== ++ * Purpose: ++ * Retrieve the content of a code section given the section name. ++ * Parameters: ++ * hManager - manager in which to search for the symbol ++ * pstrSect - name of the section, with or without leading "." ++ * pstrContent - buffer to store content of the section. ++ * Returns: ++ * DSP_SOK: on success, error code on failure ++ * COD_E_NOSYMBOLSLOADED: Symbols have not been loaded onto the board. ++ * COD_E_READFAILED: Failed to read content of code section. ++ * Requires: ++ * COD module initialized. ++ * valid hManager. ++ * pstrSect != NULL; ++ * pstrContent != NULL; ++ * Ensures: ++ * DSP_SOK: *pstrContent stores the content of the named section. ++ */ ++ extern DSP_STATUS COD_ReadSection(struct COD_LIBRARYOBJ *lib, ++ IN char *pstrSect, ++ OUT char *pstrContent, ++ IN u32 cContentSize); ++ ++ ++ ++#endif /* COD_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/csl.h b/arch/arm/plat-omap/include/dspbridge/csl.h +new file mode 100644 +index 0000000..b90d6ff +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/csl.h +@@ -0,0 +1,135 @@ ++/* ++ * csl.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== csl.h ======== ++ * Purpose: ++ * Platform independent C Standard library functions. ++ * ++ * Public Functions: ++ * CSL_AnsiToWchar ++ * CSL_ByteSwap ++ * CSL_Exit ++ * CSL_Init ++ * CSL_NumToAscii ++ * CSL_Strtok ++ * CSL_Strtokr ++ * CSL_WcharToAnsi ++ * ++ *! Revision History: ++ *! ================ ++ *! 07-Aug-2002 jeh: Added CSL_Strtokr(). ++ *! 21-Sep-2001 jeh: Added CSL_Strncmp. ++ *! 22-Nov-2000 map: Added CSL_Atoi and CSL_Strtok ++ *! 19-Nov-2000 kc: Added CSL_ByteSwap(). ++ *! 09-Nov-2000 kc: Added CSL_Strncat. ++ *! 29-Oct-1999 kc: Added CSL_Wstrlen(). ++ *! 20-Sep-1999 ag: Added CSL_Wchar2Ansi(). ++ *! 19-Jan-1998 cr: Code review cleanup (mostly documentation fixes). ++ *! 29-Dec-1997 cr: Changed CSL_lowercase to CSL_Uppercase, added ++ *! CSL_AnsiToWchar. ++ *! 30-Sep-1997 cr: Added explicit cdecl descriptors to fxn definitions. ++ *! 25-Jun-1997 cr: Added CSL_strcmp. ++ *! 12-Jun-1996 gp: Created. ++ */ ++ ++#ifndef CSL_ ++#define CSL_ ++ ++#include ++ ++/* ++ * ======== CSL_Exit ======== ++ * Purpose: ++ * Discontinue usage of the CSL module. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * CSL initialized. ++ * Ensures: ++ * Resources acquired in CSL_Init(void) are freed. ++ */ ++ extern void CSL_Exit(void); ++ ++/* ++ * ======== CSL_Init ======== ++ * Purpose: ++ * Initialize the CSL module's private state. ++ * Parameters: ++ * Returns: ++ * TRUE if initialized; FALSE if error occured. ++ * Requires: ++ * Ensures: ++ * A requirement for each of the other public CSL functions. ++ */ ++ extern bool CSL_Init(void); ++ ++/* ++ * ======== CSL_NumToAscii ======== ++ * Purpose: ++ * Convert a 1 or 2 digit number to a 2 digit string. ++ * Parameters: ++ * pstrNumber: Buffer to store converted string. ++ * dwNum: Number to convert. ++ * Returns: ++ * Requires: ++ * pstrNumber must be able to hold at least three characters. ++ * Ensures: ++ * pstrNumber will be null terminated. ++ */ ++ extern void CSL_NumToAscii(OUT char *pstrNumber, IN u32 dwNum); ++ ++ ++/* ++ * ======== CSL_Strtok ======== ++ * Purpose: ++ * Tokenize a NULL terminated string ++ * Parameters: ++ * ptstrSrc: pointer to string. ++ * szSeparators: pointer to a string of seperators ++ * Returns: ++ * char * ++ * Requires: ++ * CSL initialized. ++ * ptstrSrc is a valid string pointer. ++ * szSeparators is a valid string pointer. ++ * Ensures: ++ */ ++ extern char *CSL_Strtok(IN char *ptstrSrc, ++ IN CONST char *szSeparators); ++ ++/* ++ * ======== CSL_Strtokr ======== ++ * Purpose: ++ * Re-entrant version of strtok. ++ * Parameters: ++ * pstrSrc: Pointer to string. May be NULL on subsequent calls. ++ * szSeparators: Pointer to a string of seperators ++ * ppstrCur: Location to store start of string for next call to ++ * to CSL_Strtokr. ++ * Returns: ++ * char * (the token) ++ * Requires: ++ * CSL initialized. ++ * szSeparators != NULL ++ * ppstrCur != NULL ++ * Ensures: ++ */ ++ extern char *CSL_Strtokr(IN char *pstrSrc, ++ IN CONST char *szSeparators, ++ OUT char **ppstrCur); ++ ++#endif /* CSL_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/dbc.h b/arch/arm/plat-omap/include/dspbridge/dbc.h +new file mode 100644 +index 0000000..0e6a67d +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/dbc.h +@@ -0,0 +1,66 @@ ++/* ++ * dbc.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== dbc.h ======== ++ * Purpose: ++ * "Design by Contract" programming macros. ++ * ++ * Public Functions: ++ * DBC_Assert ++ * DBC_Require ++ * DBC_Ensure ++ * ++ * Notes: ++ * Requires that the GT->ERROR function has been defaulted to a valid ++ * error handler for the given execution environment. ++ * ++ * Does not require that GT_init() be called. ++ * ++ *! Revision History: ++ *! ================ ++ *! 11-Aug-2000 ag: Removed include ++ *! 22-Apr-1996 gp: Created. ++ */ ++ ++#ifndef DBC_ ++#define DBC_ ++ ++#ifndef GT_TRACE ++#define GT_TRACE 0 /* 0 = "trace compiled out"; 1 = "trace active" */ ++#endif ++ ++/* Assertion Macros: */ ++#if GT_TRACE ++ ++#include ++ ++#define DBC_Assert(exp) \ ++ if (!(exp)) \ ++ printk("%s, line %d: Assertion (" #exp ") failed.\n", \ ++ __FILE__, __LINE__) ++#define DBC_Require DBC_Assert /* Function Precondition. */ ++#define DBC_Ensure DBC_Assert /* Function Postcondition. */ ++ ++#else ++ ++#define DBC_Assert(exp) ++#define DBC_Require(exp) ++#define DBC_Ensure(exp) ++ ++#endif /* DEBUG */ ++ ++#endif /* DBC_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/dbdcd.h b/arch/arm/plat-omap/include/dspbridge/dbdcd.h +new file mode 100644 +index 0000000..fbc3870 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/dbdcd.h +@@ -0,0 +1,388 @@ ++/* ++ * dbdcd.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== dbdcd.h ======== ++ * Description: ++ * Defines the DSP/BIOS Bridge Configuration Database (DCD) API. ++ * ++ *! Revision History ++ *! ================ ++ *! 03-Dec-2003 map Changed DCD_OBJTYPE to DSP_DCDOBJTYPE ++ *! 24-Feb-2003 kc Updated DCD_AutoUnregister and DCD_GetObjects to simplify ++ *! DCD implementation. ++ *! 05-Aug-2002 jeh Added DCD_GetObjects(). ++ *! 11-Jul-2002 jeh Added DCD_GetDepLibs(), DCD_GetNumDepLibs(). ++ *! 22-Apr-2002 jeh Added DCD_GetLibraryName(). ++ *! 03-Apr-2001 sg Changed error names to have DCD_E* format. ++ *! 13-Feb-2001 kc Name changed from dcdbs.h to dbdcd.h. ++ *! 12-Dec-2000 kc Added DCD_AutoUnregister. ++ *! 09-Nov-2000 kc Updated usage of DCD_EnumerateObject. ++ *! 30-Oct-2000 kc Added DCD_AutoRegister. Updated error DCD error codes. ++ *! 29-Sep-2000 kc Incorporated code review comments. See ++ *! /src/reviews/dcd_review.txt. ++ *! 26-Jul-2000 kc Created. ++ *! ++ */ ++ ++#ifndef DBDCD_ ++#define DBDCD_ ++ ++#include ++#include ++#include ++ ++/* ++ * ======== DCD_AutoRegister ======== ++ * Purpose: ++ * This function automatically registers DCD objects specified in a ++ * special COFF section called ".dcd_register" ++ * Parameters: ++ * hDcdMgr: A DCD manager handle. ++ * pszCoffPath: Pointer to name of COFF file containing DCD ++ * objects to be registered. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EDCDNOAUTOREGISTER: Unable to find auto-registration section. ++ * DSP_EDCDREADSECT: Unable to read object code section. ++ * DSP_EDCDLOADBASE: Unable to load code base. ++ * DSP_EHANDLE: Invalid DCD_HMANAGER handle.. ++ * Requires: ++ * DCD initialized. ++ * Ensures: ++ * Note: ++ * Due to the DCD database construction, it is essential for a DCD-enabled ++ * COFF file to contain the right COFF sections, especially ++ * ".dcd_register", which is used for auto registration. ++ */ ++ extern DSP_STATUS DCD_AutoRegister(IN struct DCD_MANAGER *hDcdMgr, ++ IN char *pszCoffPath); ++ ++/* ++ * ======== DCD_AutoUnregister ======== ++ * Purpose: ++ * This function automatically unregisters DCD objects specified in a ++ * special COFF section called ".dcd_register" ++ * Parameters: ++ * hDcdMgr: A DCD manager handle. ++ * pszCoffPath: Pointer to name of COFF file containing ++ * DCD objects to be unregistered. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EDCDNOAUTOREGISTER: Unable to find auto-registration section. ++ * DSP_EDCDREADSECT: Unable to read object code section. ++ * DSP_EDCDLOADBASE: Unable to load code base. ++ * DSP_EHANDLE: Invalid DCD_HMANAGER handle.. ++ * Requires: ++ * DCD initialized. ++ * Ensures: ++ * Note: ++ * Due to the DCD database construction, it is essential for a DCD-enabled ++ * COFF file to contain the right COFF sections, especially ++ * ".dcd_register", which is used for auto unregistration. ++ */ ++ extern DSP_STATUS DCD_AutoUnregister(IN struct DCD_MANAGER *hDcdMgr, ++ IN char *pszCoffPath); ++ ++/* ++ * ======== DCD_CreateManager ======== ++ * Purpose: ++ * This function creates a DCD module manager. ++ * Parameters: ++ * pszZlDllName: Pointer to a DLL name string. ++ * phDcdMgr: A pointer to a DCD manager handle. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Unable to allocate memory for DCD manager handle. ++ * DSP_EFAIL: General failure. ++ * Requires: ++ * DCD initialized. ++ * pszZlDllName is non-NULL. ++ * phDcdMgr is non-NULL. ++ * Ensures: ++ * A DCD manager handle is created. ++ */ ++ extern DSP_STATUS DCD_CreateManager(IN char *pszZlDllName, ++ OUT struct DCD_MANAGER **phDcdMgr); ++ ++/* ++ * ======== DCD_DestroyManager ======== ++ * Purpose: ++ * This function destroys a DCD module manager. ++ * Parameters: ++ * hDcdMgr: A DCD manager handle. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid DCD manager handle. ++ * Requires: ++ * DCD initialized. ++ * Ensures: ++ */ ++ extern DSP_STATUS DCD_DestroyManager(IN struct DCD_MANAGER *hDcdMgr); ++ ++/* ++ * ======== DCD_EnumerateObject ======== ++ * Purpose: ++ * This function enumerates currently visible DSP/BIOS Bridge objects ++ * and returns the UUID and type of each enumerated object. ++ * Parameters: ++ * cIndex: The object enumeration index. ++ * objType: Type of object to enumerate. ++ * pUuid: Pointer to a DSP_UUID object. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Unable to enumerate through the DCD database. ++ * DSP_SENUMCOMPLETE: Enumeration completed. This is not an error code. ++ * Requires: ++ * DCD initialized. ++ * pUuid is a valid pointer. ++ * Ensures: ++ * Details: ++ * This function can be used in conjunction with DCD_GetObjectDef to ++ * retrieve object properties. ++ */ ++ extern DSP_STATUS DCD_EnumerateObject(IN s32 cIndex, ++ IN enum DSP_DCDOBJTYPE objType, ++ OUT struct DSP_UUID *pUuid); ++ ++/* ++ * ======== DCD_Exit ======== ++ * Purpose: ++ * This function cleans up the DCD module. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * DCD initialized. ++ * Ensures: ++ */ ++ extern void DCD_Exit(void); ++ ++/* ++ * ======== DCD_GetDepLibs ======== ++ * Purpose: ++ * Given the uuid of a library and size of array of uuids, this function ++ * fills the array with the uuids of all dependent libraries of the input ++ * library. ++ * Parameters: ++ * hDcdMgr: A DCD manager handle. ++ * pUuid: Pointer to a DSP_UUID for a library. ++ * numLibs: Size of uuid array (number of library uuids). ++ * pDepLibUuids: Array of dependent library uuids to be filled in. ++ * pPersistentDepLibs: Array indicating if corresponding lib is persistent. ++ * phase: phase to obtain correct input library ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Memory allocation failure. ++ * DSP_EDCDREADSECT: Failure to read section containing library info. ++ * DSP_EFAIL: General failure. ++ * Requires: ++ * DCD initialized. ++ * Valid hDcdMgr. ++ * pUuid != NULL ++ * pDepLibUuids != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS DCD_GetDepLibs(IN struct DCD_MANAGER *hDcdMgr, ++ IN struct DSP_UUID *pUuid, ++ u16 numLibs, ++ OUT struct DSP_UUID *pDepLibUuids, ++ OUT bool *pPersistentDepLibs, ++ IN enum NLDR_PHASE phase); ++ ++/* ++ * ======== DCD_GetNumDepLibs ======== ++ * Purpose: ++ * Given the uuid of a library, determine its number of dependent ++ * libraries. ++ * Parameters: ++ * hDcdMgr: A DCD manager handle. ++ * pUuid: Pointer to a DSP_UUID for a library. ++ * pNumLibs: Size of uuid array (number of library uuids). ++ * pNumPersLibs: number of persistent dependent library. ++ * phase: Phase to obtain correct input library ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Memory allocation failure. ++ * DSP_EDCDREADSECT: Failure to read section containing library info. ++ * DSP_EFAIL: General failure. ++ * Requires: ++ * DCD initialized. ++ * Valid hDcdMgr. ++ * pUuid != NULL ++ * pNumLibs != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS DCD_GetNumDepLibs(IN struct DCD_MANAGER *hDcdMgr, ++ IN struct DSP_UUID *pUuid, ++ OUT u16 *pNumLibs, ++ OUT u16 *pNumPersLibs, ++ IN enum NLDR_PHASE phase); ++ ++/* ++ * ======== DCD_GetLibraryName ======== ++ * Purpose: ++ * This function returns the name of a (dynamic) library for a given ++ * UUID. ++ * Parameters: ++ * hDcdMgr: A DCD manager handle. ++ * pUuid: Pointer to a DSP_UUID that represents a unique DSP/BIOS ++ * Bridge object. ++ * pstrLibName: Buffer to hold library name. ++ * pdwSize: Contains buffer size. Set to string size on output. ++ * phase: Which phase to load ++ * fPhaseSplit: Are phases in multiple libraries ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: General failure. ++ * Requires: ++ * DCD initialized. ++ * Valid hDcdMgr. ++ * pstrLibName != NULL. ++ * pUuid != NULL ++ * pdwSize != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS DCD_GetLibraryName(IN struct DCD_MANAGER *hDcdMgr, ++ IN struct DSP_UUID *pUuid, ++ IN OUT char *pstrLibName, ++ IN OUT u32 *pdwSize, ++ IN enum NLDR_PHASE phase, ++ OUT bool *fPhaseSplit); ++ ++/* ++ * ======== DCD_GetObjectDef ======== ++ * Purpose: ++ * This function returns the properties/attributes of a DSP/BIOS Bridge ++ * object. ++ * Parameters: ++ * hDcdMgr: A DCD manager handle. ++ * pUuid: Pointer to a DSP_UUID that represents a unique ++ * DSP/BIOS Bridge object. ++ * objType: The type of DSP/BIOS Bridge object to be ++ * referenced (node, processor, etc). ++ * pObjDef: Pointer to an object definition structure. A ++ * union of various possible DCD object types. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EDCDPARSESECT: Unable to parse content of object code section. ++ * DSP_EDCDREADSECT: Unable to read object code section. ++ * DSP_EDCDGETSECT: Unable to access object code section. ++ * DSP_EDCDLOADBASE: Unable to load code base. ++ * DSP_EFAIL: General failure. ++ * DSP_EHANDLE: Invalid DCD_HMANAGER handle. ++ * Requires: ++ * DCD initialized. ++ * pObjUuid is non-NULL. ++ * pObjDef is non-NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS DCD_GetObjectDef(IN struct DCD_MANAGER *hDcdMgr, ++ IN struct DSP_UUID *pObjUuid, ++ IN enum DSP_DCDOBJTYPE objType, ++ OUT struct DCD_GENERICOBJ *pObjDef); ++ ++/* ++ * ======== DCD_GetObjects ======== ++ * Purpose: ++ * This function finds all DCD objects specified in a special ++ * COFF section called ".dcd_register", and for each object, ++ * call a "register" function. The "register" function may perform ++ * various actions, such as 1) register nodes in the node database, 2) ++ * unregister nodes from the node database, and 3) add overlay nodes. ++ * Parameters: ++ * hDcdMgr: A DCD manager handle. ++ * pszCoffPath: Pointer to name of COFF file containing DCD ++ * objects. ++ * registerFxn: Callback fxn to be applied on each located ++ * DCD object. ++ * handle: Handle to pass to callback. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EDCDNOAUTOREGISTER: Unable to find .dcd_register section. ++ * DSP_EDCDREADSECT: Unable to read object code section. ++ * DSP_EDCDLOADBASE: Unable to load code base. ++ * DSP_EHANDLE: Invalid DCD_HMANAGER handle.. ++ * Requires: ++ * DCD initialized. ++ * Ensures: ++ * Note: ++ * Due to the DCD database construction, it is essential for a DCD-enabled ++ * COFF file to contain the right COFF sections, especially ++ * ".dcd_register", which is used for auto registration. ++ */ ++ extern DSP_STATUS DCD_GetObjects(IN struct DCD_MANAGER *hDcdMgr, ++ IN char *pszCoffPath, ++ DCD_REGISTERFXN registerFxn, ++ void *handle); ++ ++/* ++ * ======== DCD_Init ======== ++ * Purpose: ++ * This function initializes DCD. ++ * Parameters: ++ * Returns: ++ * FALSE: Initialization failed. ++ * TRUE: Initialization succeeded. ++ * Requires: ++ * Ensures: ++ * DCD initialized. ++ */ ++ extern bool DCD_Init(void); ++ ++/* ++ * ======== DCD_RegisterObject ======== ++ * Purpose: ++ * This function registers a DSP/BIOS Bridge object in the DCD database. ++ * Parameters: ++ * pUuid: Pointer to a DSP_UUID that identifies a DSP/BIOS ++ * Bridge object. ++ * objType: Type of object. ++ * pszPathName: Path to the object's COFF file. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Failed to register object. ++ * Requires: ++ * DCD initialized. ++ * pUuid and szPathName are non-NULL values. ++ * objType is a valid type value. ++ * Ensures: ++ */ ++ extern DSP_STATUS DCD_RegisterObject(IN struct DSP_UUID *pUuid, ++ IN enum DSP_DCDOBJTYPE objType, ++ IN char *pszPathName); ++ ++/* ++ * ======== DCD_UnregisterObject ======== ++ * Purpose: ++ * This function de-registers a valid DSP/BIOS Bridge object from the DCD ++ * database. ++ * Parameters: ++ * pUuid: Pointer to a DSP_UUID that identifies a DSP/BIOS Bridge ++ * object. ++ * objType: Type of object. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Unable to de-register the specified object. ++ * Requires: ++ * DCD initialized. ++ * pUuid is a non-NULL value. ++ * objType is a valid type value. ++ * Ensures: ++ */ ++ extern DSP_STATUS DCD_UnregisterObject(IN struct DSP_UUID *pUuid, ++ IN enum DSP_DCDOBJTYPE objType); ++ ++#endif /* _DBDCD_H */ +diff --git a/arch/arm/plat-omap/include/dspbridge/dbdcddef.h b/arch/arm/plat-omap/include/dspbridge/dbdcddef.h +new file mode 100644 +index 0000000..91b1c45 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/dbdcddef.h +@@ -0,0 +1,94 @@ ++/* ++ * dbdcddef.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== dbdcddef.h ======== ++ * Description: ++ * DCD (DSP/BIOS Bridge Configuration Database) constants and types. ++ * ++ *! Revision History: ++ *! ================ ++ *! 03-Dec-2003 map Moved and renamed DCD_OBJTYPE to DSP_DCDOBJTYPE in dbdefs.h ++ *! 05-Dec-2002 map Added DCD_CREATELIBTYPE, DCD_EXECUTELIBTYPE, ++ * DCD_DELETELIBTYPE ++ *! 24-Feb-2003 kc Updated REG entry names to DspBridge. ++ *! 22-Nov-2002 gp Cleaned up comments, formatting. ++ *! 05-Aug-2002 jeh Added DCD_REGISTERFXN. ++ *! 19-Apr-2002 jeh Added DCD_LIBRARYTYPE to DCD_OBJTYPE, dynamic load ++ *! properties to DCD_NODEPROPS. ++ *! 29-Jul-2001 ag Added extended procObj. ++ *! 13-Feb-2001 kc: Named changed from dcdbsdef.h dbdcddef.h. ++ *! 12-Dec-2000 jeh Added DAIS iAlg name to DCD_NODEPROPS. ++ *! 30-Oct-2000 kc: Added #defines for DCD_AutoRegister function. ++ *! 05-Sep-2000 jeh Added DCD_NODEPROPS. ++ *! 12-Aug-2000 kc: Incoroporated the use of types defined in . ++ *! 29-Jul-2000 kc: Created. ++ */ ++ ++#ifndef DBDCDDEF_ ++#define DBDCDDEF_ ++ ++#include ++#include /* for MGR_PROCESSOREXTINFO */ ++ ++/* ++ * The following defines are critical elements for the DCD module: ++ * ++ * - DCD_REGKEY enables DCD functions to locate registered DCD objects. ++ * - DCD_REGISTER_SECTION identifies the COFF section where the UUID of ++ * registered DCD objects are stored. ++ */ ++#define DCD_REGKEY "Software\\TexasInstruments\\DspBridge\\DCD" ++#define DCD_REGISTER_SECTION ".dcd_register" ++ ++/* DCD Manager Object */ ++ struct DCD_MANAGER; ++ ++/* DCD Node Properties */ ++ struct DCD_NODEPROPS { ++ struct DSP_NDBPROPS ndbProps; ++ u32 uMsgSegid; ++ u32 uMsgNotifyType; ++ char *pstrCreatePhaseFxn; ++ char *pstrDeletePhaseFxn; ++ char *pstrExecutePhaseFxn; ++ char *pstrIAlgName; ++ ++ /* Dynamic load properties */ ++ u16 usLoadType; /* Static, dynamic, overlay */ ++ u32 ulDataMemSegMask; /* Data memory requirements */ ++ u32 ulCodeMemSegMask; /* Code memory requirements */ ++ } ; ++ ++/* DCD Generic Object Type */ ++ struct DCD_GENERICOBJ { ++ union dcdObjUnion { ++ struct DCD_NODEPROPS nodeObj; /* node object. */ ++ /* processor object. */ ++ struct DSP_PROCESSORINFO procObj; ++ /* extended proc object (private) */ ++ struct MGR_PROCESSOREXTINFO extProcObj; ++ } objData; ++ } ; ++ ++/* DCD Internal Callback Type */ ++ typedef DSP_STATUS(*DCD_REGISTERFXN) (IN struct DSP_UUID *pUuid, ++ IN enum DSP_DCDOBJTYPE objType, ++ IN void *handle); ++ ++#endif /* DBDCDDEF_ */ ++ +diff --git a/arch/arm/plat-omap/include/dspbridge/dbdefs.h b/arch/arm/plat-omap/include/dspbridge/dbdefs.h +new file mode 100644 +index 0000000..9782693 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/dbdefs.h +@@ -0,0 +1,580 @@ ++/* ++ * dbdefs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== dbdefs.h ======== ++ * Description: ++ * Global definitions and constants for DSP/BIOS Bridge. ++ * ++ *! Revision History: ++ *! ================ ++ *! 19-Apr-2004 sb Aligned DMM definitions with Symbian ++ *! 08-Mar-2004 sb Added MAPATTR & ELEM_SIZE for Dynamic Memory Mapping feature ++ *! 09-Feb-2004 vp Added processor ID numbers for DSP and IVA ++ *! 06-Feb-2003 kc Removed DSP_POSTMESSAGE. Updated IsValid*Event macros. ++ *! 22-Nov-2002 gp Cleaned up comments, formatting. ++ *! Removed unused DSP_ENUMLASTNODE define. ++ *! 13-Feb-2002 jeh Added uSysStackSize to DSP_NDBPROPS. ++ *! 23-Jan-2002 ag Added #define DSP_SHMSEG0. ++ *! 12-Dec-2001 ag Added DSP_ESTRMMODE error code. ++ *! 04-Dec-2001 jeh Added DSP_ENOTCONNECTED error code. ++ *! 10-Dec-2001 kc: Modified macros and definitions to disable DSP_POSTMESSAGE. ++ *! 01-Nov-2001 jeh Added DSP_EOVERLAYMEMORY. ++ *! 18-Oct-2001 ag Added DSP_STRMMODE type. ++ *! Added DSP_ENOTSHAREDMEM. ++ *! 21-Sep-2001 ag Added additional error codes. ++ *! 07-Jun-2001 sg Made DSPStream_AllocateBuffer fxn name plural. ++ *! 11-May-2001 jeh Changed DSP_NODE_MIN_PRIORITY from 0 to 1. Removed hNode ++ *! from DSP_NODEINFO. ++ *! 02-Apr-2001 sg Added missing error codes, rearranged codes, switched to ++ *! hex offsets, renamed some codes to match API spec. ++ *! 16-Jan-2001 jeh Added DSP_ESYMBOL, DSP_EUUID. ++ *! 13-Feb-2001 kc: DSP/BIOS Bridge name updates. ++ *! 05-Dec-2000 ag: Added DSP_RMSxxx user available message command codes. ++ *! 09-Nov-2000 rr: Added DSP_PROCEESORRESTART define; Removed DSP_PBUFFER. ++ *! Added DSP_DCD_ENOAUTOREGISTER, DSP_EUSER1-16, DSP_ESTRMFUL ++ *! Removed DSP_EDONE. Macros's modified. ++ *! 23-Oct-2000 jeh Replaced DSP_STREAMSTATECHANGE with DSP_STREAMDONE. ++ *! 09-Oct-2000 jeh Updated to version 0.9 DSP Bridge API spec. ++ *! 29-Sep-2000 kc Added error codes for DCD and REG to simplify use of ++ *! these codes within the RM module. ++ *! 27-Sep-2000 jeh Added segid, alignment, uNumBufs to DSP_STREAMATTRIN. ++ *! 29-Aug-2000 jeh Added DSP_NODETYPE enum, changed DSP_EALREADYATTACHED to ++ *! DSP_EALREADYCONNECTED. Changed scStreamConnection[1] ++ *! to scStreamConnection[16] in DSP_NODEINFO structure. ++ *! Added DSP_NOTIFICATION, DSP_STRMATTR. PSTRING changed ++ *! back to TCHAR * and moved to dbtype.h. ++ *! 11-Aug-2000 rr: Macros to check valid events and notify masks added. ++ *! 09-Aug-2000 rr: Changed PSTRING to *s8 ++ *! 07-Aug-2000 rr: PROC_IDLE/SYNCINIT/UNKNOWN state removed. ++ *! 20-Jul-2000 rr: Updated to version 0.8 ++ *! 17-Jul-2000 rr: New PROC states added to the DSP_PROCSTATE. ++ *! 27-Jun-2000 rr: Created from dspapi.h ++ */ ++ ++#ifndef DBDEFS_ ++#define DBDEFS_ ++ ++#include ++ ++#include /* GPP side type definitions */ ++#include /* DSP/BIOS type definitions */ ++#include /* Types shared between GPP and DSP */ ++ ++#define PG_SIZE_4K 4096 ++#define PG_MASK(pg_size) (~((pg_size)-1)) ++#define PG_ALIGN_LOW(addr, pg_size) ((addr) & PG_MASK(pg_size)) ++#define PG_ALIGN_HIGH(addr, pg_size) (((addr)+(pg_size)-1) & PG_MASK(pg_size)) ++ ++/* API return value and calling convention */ ++#define DBAPI DSP_STATUS ++ ++/* Infinite time value for the uTimeout parameter to DSPStream_Select() */ ++#define DSP_FOREVER (-1) ++ ++/* Maximum length of node name, used in DSP_NDBPROPS */ ++#define DSP_MAXNAMELEN 32 ++ ++/* uNotifyType values for the RegisterNotify() functions. */ ++#define DSP_SIGNALEVENT 0x00000001 ++ ++/* Types of events for processors */ ++#define DSP_PROCESSORSTATECHANGE 0x00000001 ++#define DSP_PROCESSORATTACH 0x00000002 ++#define DSP_PROCESSORDETACH 0x00000004 ++#define DSP_PROCESSORRESTART 0x00000008 ++ ++/* DSP exception events (DSP/BIOS and DSP MMU fault) */ ++#define DSP_MMUFAULT 0x00000010 ++#define DSP_SYSERROR 0x00000020 ++#define DSP_EXCEPTIONABORT 0x00000300 ++ ++/* IVA exception events (IVA MMU fault) */ ++#define IVA_MMUFAULT 0x00000040 ++/* Types of events for nodes */ ++#define DSP_NODESTATECHANGE 0x00000100 ++#define DSP_NODEMESSAGEREADY 0x00000200 ++ ++/* Types of events for streams */ ++#define DSP_STREAMDONE 0x00001000 ++#define DSP_STREAMIOCOMPLETION 0x00002000 ++ ++/* Handle definition representing the GPP node in DSPNode_Connect() calls */ ++#define DSP_HGPPNODE 0xFFFFFFFF ++ ++/* Node directions used in DSPNode_Connect() */ ++#define DSP_TONODE 1 ++#define DSP_FROMNODE 2 ++ ++/* Define Node Minimum and Maximum Priorities */ ++#define DSP_NODE_MIN_PRIORITY 1 ++#define DSP_NODE_MAX_PRIORITY 15 ++ ++/* Pre-Defined Message Command Codes available to user: */ ++#define DSP_RMSUSERCODESTART RMS_USER /* Start of RMS user cmd codes */ ++/* end of user codes */ ++#define DSP_RMSUSERCODEEND (RMS_USER + RMS_MAXUSERCODES); ++#define DSP_RMSBUFDESC RMS_BUFDESC /* MSG contains SM buffer description */ ++ ++/* Shared memory identifier for MEM segment named "SHMSEG0" */ ++#define DSP_SHMSEG0 (u32)(-1) ++ ++/* Processor ID numbers */ ++#define DSP_UNIT 0 ++#define IVA_UNIT 1 ++ ++#define DSPWORD unsigned char ++#define DSPWORDSIZE sizeof(DSPWORD) ++ ++/* Success & Failure macros */ ++#define DSP_SUCCEEDED(Status) likely((s32)(Status) >= 0) ++#define DSP_FAILED(Status) unlikely((s32)(Status) < 0) ++ ++/* Power control enumerations */ ++#define PROC_PWRCONTROL 0x8070 ++ ++#define PROC_PWRMGT_ENABLE (PROC_PWRCONTROL + 0x3) ++#define PROC_PWRMGT_DISABLE (PROC_PWRCONTROL + 0x4) ++ ++/* Bridge Code Version */ ++#define BRIDGE_VERSION_CODE 333 ++ ++#define MAX_PROFILES 16 ++ ++/* Types defined for 'Bridge API */ ++ typedef u32 DSP_STATUS; /* API return code type */ ++ ++ typedef HANDLE DSP_HNODE; /* Handle to a DSP Node object */ ++ typedef HANDLE DSP_HPROCESSOR; /* Handle to a Processor object */ ++ typedef HANDLE DSP_HSTREAM; /* Handle to a Stream object */ ++ ++ typedef u32 DSP_PROCFAMILY; /* Processor family */ ++ typedef u32 DSP_PROCTYPE; /* Processor type (w/in family) */ ++ typedef u32 DSP_RTOSTYPE; /* Type of DSP RTOS */ ++ ++/* Handy Macros */ ++#define IsValidProcEvent(x) (((x) == 0) || (((x) & (DSP_PROCESSORSTATECHANGE | \ ++ DSP_PROCESSORATTACH | \ ++ DSP_PROCESSORDETACH | \ ++ DSP_PROCESSORRESTART | \ ++ DSP_NODESTATECHANGE | \ ++ DSP_STREAMDONE | \ ++ DSP_STREAMIOCOMPLETION | \ ++ DSP_MMUFAULT | \ ++ DSP_SYSERROR)) && \ ++ !((x) & ~(DSP_PROCESSORSTATECHANGE | \ ++ DSP_PROCESSORATTACH | \ ++ DSP_PROCESSORDETACH | \ ++ DSP_PROCESSORRESTART | \ ++ DSP_NODESTATECHANGE | \ ++ DSP_STREAMDONE | \ ++ DSP_STREAMIOCOMPLETION | \ ++ DSP_MMUFAULT | \ ++ DSP_SYSERROR)))) ++ ++#define IsValidNodeEvent(x) (((x) == 0) || (((x) & (DSP_NODESTATECHANGE | \ ++ DSP_NODEMESSAGEREADY)) && \ ++ !((x) & ~(DSP_NODESTATECHANGE | \ ++ DSP_NODEMESSAGEREADY)))) ++ ++#define IsValidStrmEvent(x) (((x) == 0) || (((x) & (DSP_STREAMDONE | \ ++ DSP_STREAMIOCOMPLETION)) && \ ++ !((x) & ~(DSP_STREAMDONE | \ ++ DSP_STREAMIOCOMPLETION)))) ++ ++#define IsValidNotifyMask(x) ((x) & DSP_SIGNALEVENT) ++ ++/* The Node UUID structure */ ++ struct DSP_UUID { ++ u32 ulData1; ++ u16 usData2; ++ u16 usData3; ++ u8 ucData4; ++ u8 ucData5; ++ u8 ucData6[6]; ++ }; ++ ++/* DCD types */ ++ enum DSP_DCDOBJTYPE { ++ DSP_DCDNODETYPE, ++ DSP_DCDPROCESSORTYPE, ++ DSP_DCDLIBRARYTYPE, ++ DSP_DCDCREATELIBTYPE, ++ DSP_DCDEXECUTELIBTYPE, ++ DSP_DCDDELETELIBTYPE ++ } ; ++ ++/* Processor states */ ++ enum DSP_PROCSTATE { ++ PROC_STOPPED, ++ PROC_LOADED, ++ PROC_RUNNING, ++ PROC_ERROR ++ } ; ++ ++/* ++ * Node types: Message node, task node, xDAIS socket node, and ++ * device node. _NODE_GPP is used when defining a stream connection ++ * between a task or socket node and the GPP. ++ * ++ */ ++ enum NODE_TYPE { ++ NODE_DEVICE, ++ NODE_TASK, ++ NODE_DAISSOCKET, ++ NODE_MESSAGE, ++ NODE_GPP ++ } ; ++ ++/* ++ * ======== NODE_STATE ======== ++ * Internal node states. ++ */ ++ enum NODE_STATE { ++ NODE_ALLOCATED, ++ NODE_CREATED, ++ NODE_RUNNING, ++ NODE_PAUSED, ++ NODE_DONE, ++ NODE_CREATING, ++ NODE_STARTING, ++ NODE_PAUSING, ++ NODE_TERMINATING, ++ NODE_DELETING, ++ } ; ++ ++/* Stream states */ ++ enum DSP_STREAMSTATE { ++ STREAM_IDLE, ++ STREAM_READY, ++ STREAM_PENDING, ++ STREAM_DONE ++ } ; ++ ++/* Stream connect types */ ++ enum DSP_CONNECTTYPE { ++ CONNECTTYPE_NODEOUTPUT, ++ CONNECTTYPE_GPPOUTPUT, ++ CONNECTTYPE_NODEINPUT, ++ CONNECTTYPE_GPPINPUT ++ } ; ++ ++/* Stream mode types */ ++ enum DSP_STRMMODE { ++ STRMMODE_PROCCOPY, /* Processor(s) copy stream data payloads */ ++ STRMMODE_ZEROCOPY, /* Strm buffer ptrs swapped no data copied */ ++ STRMMODE_LDMA, /* Local DMA : OMAP's System-DMA device */ ++ STRMMODE_RDMA /* Remote DMA: OMAP's DSP-DMA device */ ++ } ; ++ ++/* Resource Types */ ++ enum DSP_RESOURCEINFOTYPE { ++ DSP_RESOURCE_DYNDARAM = 0, ++ DSP_RESOURCE_DYNSARAM, ++ DSP_RESOURCE_DYNEXTERNAL, ++ DSP_RESOURCE_DYNSRAM, ++ DSP_RESOURCE_PROCLOAD ++ } ; ++ ++/* Memory Segment Types */ ++ enum DSP_MEMTYPE { ++ DSP_DYNDARAM = 0, ++ DSP_DYNSARAM, ++ DSP_DYNEXTERNAL, ++ DSP_DYNSRAM ++ } ; ++ ++/* Memory Flush Types */ ++ enum DSP_FLUSHTYPE { ++ PROC_INVALIDATE_MEM = 0, ++ PROC_WRITEBACK_MEM, ++ PROC_WRITEBACK_INVALIDATE_MEM, ++ } ; ++ ++/* Memory Segment Status Values */ ++ struct DSP_MEMSTAT { ++ u32 ulSize; ++ u32 ulTotalFreeSize; ++ u32 ulLenMaxFreeBlock; ++ u32 ulNumFreeBlocks; ++ u32 ulNumAllocBlocks; ++ } ; ++ ++/* Processor Load information Values */ ++ struct DSP_PROCLOADSTAT { ++ u32 uCurrLoad; ++ u32 uPredictedLoad; ++ u32 uCurrDspFreq; ++ u32 uPredictedFreq; ++ } ; ++ ++/* Attributes for STRM connections between nodes */ ++ struct DSP_STRMATTR { ++ u32 uSegid; /* Memory segment on DSP to allocate buffers */ ++ u32 uBufsize; /* Buffer size (DSP words) */ ++ u32 uNumBufs; /* Number of buffers */ ++ u32 uAlignment; /* Buffer alignment */ ++ u32 uTimeout; /* Timeout for blocking STRM calls */ ++ enum DSP_STRMMODE lMode; /* mode of stream when opened */ ++ /* DMA chnl id if DSP_STRMMODE is LDMA or RDMA */ ++ u32 uDMAChnlId; ++ u32 uDMAPriority; /* DMA channel priority 0=lowest, >0=high */ ++ } ; ++ ++/* The DSP_CBDATA structure */ ++ struct DSP_CBDATA { ++ u32 cbData; ++ u8 cData[1]; ++ } ; ++ ++/* The DSP_MSG structure */ ++ struct DSP_MSG { ++ u32 dwCmd; ++ u32 dwArg1; ++ u32 dwArg2; ++ } ; ++ ++/* The DSP_RESOURCEREQMTS structure for node's resource requirements */ ++ struct DSP_RESOURCEREQMTS { ++ u32 cbStruct; ++ u32 uStaticDataSize; ++ u32 uGlobalDataSize; ++ u32 uProgramMemSize; ++ u32 uWCExecutionTime; ++ u32 uWCPeriod; ++ u32 uWCDeadline; ++ u32 uAvgExectionTime; ++ u32 uMinimumPeriod; ++ } ; ++ ++/* ++ * The DSP_STREAMCONNECT structure describes a stream connection ++ * between two nodes, or between a node and the GPP ++ */ ++ struct DSP_STREAMCONNECT { ++ u32 cbStruct; ++ enum DSP_CONNECTTYPE lType; ++ u32 uThisNodeStreamIndex; ++ DSP_HNODE hConnectedNode; ++ struct DSP_UUID uiConnectedNodeID; ++ u32 uConnectedNodeStreamIndex; ++ } ; ++ ++ struct DSP_NODEPROFS { ++ u32 ulHeapSize; ++ } ; ++ ++/* The DSP_NDBPROPS structure reports the attributes of a node */ ++ struct DSP_NDBPROPS { ++ u32 cbStruct; ++ struct DSP_UUID uiNodeID; ++ char acName[DSP_MAXNAMELEN]; ++ enum NODE_TYPE uNodeType; ++ u32 bCacheOnGPP; ++ struct DSP_RESOURCEREQMTS dspResourceReqmts; ++ s32 iPriority; ++ u32 uStackSize; ++ u32 uSysStackSize; ++ u32 uStackSeg; ++ u32 uMessageDepth; ++ u32 uNumInputStreams; ++ u32 uNumOutputStreams; ++ u32 uTimeout; ++ u32 uCountProfiles; /* Number of supported profiles */ ++ /* Array of profiles */ ++ struct DSP_NODEPROFS aProfiles[MAX_PROFILES]; ++ u32 uStackSegName; /* Stack Segment Name */ ++ } ; ++ ++ /* The DSP_NODEATTRIN structure describes the attributes of a ++ * node client */ ++ struct DSP_NODEATTRIN { ++ u32 cbStruct; ++ s32 iPriority; ++ u32 uTimeout; ++ u32 uProfileID; ++ /* Reserved, for Bridge Internal use only */ ++ u32 uHeapSize; ++ void *pGPPVirtAddr; /* Reserved, for Bridge Internal use only */ ++ } ; ++ ++ /* The DSP_NODEINFO structure is used to retrieve information ++ * about a node */ ++ struct DSP_NODEINFO { ++ u32 cbStruct; ++ struct DSP_NDBPROPS nbNodeDatabaseProps; ++ u32 uExecutionPriority; ++ enum NODE_STATE nsExecutionState; ++ DSP_HNODE hDeviceOwner; ++ u32 uNumberStreams; ++ struct DSP_STREAMCONNECT scStreamConnection[16]; ++ u32 uNodeEnv; ++ } ; ++ ++ /* The DSP_NODEATTR structure describes the attributes of a node */ ++ struct DSP_NODEATTR { ++ u32 cbStruct; ++ struct DSP_NODEATTRIN inNodeAttrIn; ++ u32 uInputs; ++ u32 uOutputs; ++ struct DSP_NODEINFO iNodeInfo; ++ } ; ++ ++/* ++ * Notification type: either the name of an opened event, or an event or ++ * window handle. ++ */ ++ struct DSP_NOTIFICATION { ++ char *psName; ++ HANDLE handle; ++ } ; ++ ++/* The DSP_PROCESSORATTRIN structure describes the attributes of a processor */ ++ struct DSP_PROCESSORATTRIN{ ++ u32 cbStruct; ++ u32 uTimeout; ++ } ; ++ ++ enum chipTypes { ++ DSPTYPE_55 = 6, ++ IVA_ARM7 = 0x97, ++ DSPTYPE_64 = 0x99 ++ }; ++ ++/* ++ * The DSP_PROCESSORINFO structure describes basic capabilities of a ++ * DSP processor ++ */ ++ struct DSP_PROCESSORINFO { ++ u32 cbStruct; ++ DSP_PROCFAMILY uProcessorFamily; ++ DSP_PROCTYPE uProcessorType; ++ u32 uClockRate; ++ u32 ulInternalMemSize; ++ u32 ulExternalMemSize; ++ u32 uProcessorID; ++ DSP_RTOSTYPE tyRunningRTOS; ++ s32 nNodeMinPriority; ++ s32 nNodeMaxPriority; ++ } ; ++ ++/* Error information of last DSP exception signalled to the GPP */ ++ struct DSP_ERRORINFO { ++ u32 dwErrMask; ++ u32 dwVal1; ++ u32 dwVal2; ++ u32 dwVal3; ++ } ; ++ ++/* The DSP_PROCESSORSTATE structure describes the state of a DSP processor */ ++ struct DSP_PROCESSORSTATE { ++ u32 cbStruct; ++ enum DSP_PROCSTATE iState; ++ struct DSP_ERRORINFO errInfo; ++ } ; ++ ++/* ++ * The DSP_RESOURCEINFO structure is used to retrieve information about a ++ * processor's resources ++ */ ++ struct DSP_RESOURCEINFO { ++ u32 cbStruct; ++ enum DSP_RESOURCEINFOTYPE uResourceType; ++ union { ++ u32 ulResource; ++ struct DSP_MEMSTAT memStat; ++ struct DSP_PROCLOADSTAT procLoadStat; ++ } result; ++ } ; ++ ++/* ++ * The DSP_STREAMATTRIN structure describes the attributes of a stream, ++ * including segment and alignment of data buffers allocated with ++ * DSPStream_AllocateBuffers(), if applicable ++ */ ++ struct DSP_STREAMATTRIN { ++ u32 cbStruct; ++ u32 uTimeout; ++ u32 uSegment; ++ u32 uAlignment; ++ u32 uNumBufs; ++ enum DSP_STRMMODE lMode; ++ u32 uDMAChnlId; ++ u32 uDMAPriority; ++ } ; ++ ++/* The DSP_BUFFERATTR structure describes the attributes of a data buffer */ ++ struct DSP_BUFFERATTR { ++ u32 cbStruct; ++ u32 uSegment; ++ u32 uAlignment; ++ } ; ++ ++/* ++ * The DSP_STREAMINFO structure is used to retrieve information ++ * about a stream. ++ */ ++ struct DSP_STREAMINFO { ++ u32 cbStruct; ++ u32 uNumberBufsAllowed; ++ u32 uNumberBufsInStream; ++ u32 ulNumberBytes; ++ HANDLE hSyncObjectHandle; ++ enum DSP_STREAMSTATE ssStreamState; ++ } ; ++ ++/* DMM MAP attributes ++It is a bit mask with each bit value indicating a specific attribute ++bit 0 - GPP address type (user virtual=0, physical=1) ++bit 1 - MMU Endianism (Big Endian=1, Little Endian=0) ++bit 2 - MMU mixed page attribute (Mixed/ CPUES=1, TLBES =0) ++bit 3 - MMU element size = 8bit (valid only for non mixed page entries) ++bit 4 - MMU element size = 16bit (valid only for non mixed page entries) ++bit 5 - MMU element size = 32bit (valid only for non mixed page entries) ++bit 6 - MMU element size = 64bit (valid only for non mixed page entries) ++*/ ++ ++/* Types of mapping attributes */ ++ ++/* MPU address is virtual and needs to be translated to physical addr */ ++#define DSP_MAPVIRTUALADDR 0x00000000 ++#define DSP_MAPPHYSICALADDR 0x00000001 ++ ++/* Mapped data is big endian */ ++#define DSP_MAPBIGENDIAN 0x00000002 ++#define DSP_MAPLITTLEENDIAN 0x00000000 ++ ++/* Element size is based on DSP r/w access size */ ++#define DSP_MAPMIXEDELEMSIZE 0x00000004 ++ ++/* ++ * Element size for MMU mapping (8, 16, 32, or 64 bit) ++ * Ignored if DSP_MAPMIXEDELEMSIZE enabled ++ */ ++#define DSP_MAPELEMSIZE8 0x00000008 ++#define DSP_MAPELEMSIZE16 0x00000010 ++#define DSP_MAPELEMSIZE32 0x00000020 ++#define DSP_MAPELEMSIZE64 0x00000040 ++ ++#define DSP_MAPVMALLOCADDR 0x00000080 ++ ++#define DSP_MAPDONOTLOCK 0x00000100 ++ ++ ++#define GEM_CACHE_LINE_SIZE 128 ++#define GEM_L1P_PREFETCH_SIZE 128 ++ ++#endif /* DBDEFS_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/dbg.h b/arch/arm/plat-omap/include/dspbridge/dbg.h +new file mode 100644 +index 0000000..7f44ff9 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/dbg.h +@@ -0,0 +1,110 @@ ++/* ++ * dbg.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== dbg.h ======== ++ * Purpose: ++ * Provide debugging services for 'Bridge Mini Drivers. ++ * ++ * Public Functions: ++ * DBG_Exit ++ * DBG_Init ++ * DBG_Printf ++ * DBG_Trace ++ * ++ * Notes: ++ * WMD's must not call DBG_Init or DBG_Exit. ++ * ++ *! Revision History: ++ *! ================ ++ *! 03-Feb-2000 rr: DBG Levels redefined. ++ *! 29-Oct-1999 kc: Cleaned up for code review. ++ *! 10-Oct-1997 cr: Added DBG_Printf service. ++ *! 29-May-1996 gp: Removed WCD_ prefix. ++ *! 15-May-1996 gp: Created. ++ */ ++ ++#ifndef DBG_ ++#define DBG_ ++#include ++#include ++ ++/* Levels of trace debug messages: */ ++#define DBG_ENTER (u8)(0x01) /* Function entry point. */ ++#define DBG_LEVEL1 (u8)(0x02) /* Display debugging state/varibles */ ++#define DBG_LEVEL2 (u8)(0x04) /* Display debugging state/varibles */ ++#define DBG_LEVEL3 (u8)(0x08) /* Display debugging state/varibles */ ++#define DBG_LEVEL4 (u8)(0x10) /* Display debugging state/varibles */ ++#define DBG_LEVEL5 (u8)(0x20) /* Module Init, Exit */ ++#define DBG_LEVEL6 (u8)(0x40) /* Warn SERVICES Failures */ ++#define DBG_LEVEL7 (u8)(0x80) /* Warn Critical Errors */ ++ ++#if (defined(DEBUG) || defined(DDSP_DEBUG_PRODUCT)) && GT_TRACE ++ ++/* ++ * ======== DBG_Exit ======== ++ * Purpose: ++ * Discontinue usage of module; free resources when reference count ++ * reaches 0. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * DBG initialized. ++ * Ensures: ++ * Resources used by module are freed when cRef reaches zero. ++ */ ++ extern void DBG_Exit(void); ++ ++/* ++ * ======== DBG_Init ======== ++ * Purpose: ++ * Initializes private state of DBG module. ++ * Parameters: ++ * Returns: ++ * TRUE if initialized; FALSE if error occured. ++ * Requires: ++ * Ensures: ++ */ ++ extern bool DBG_Init(void); ++ ++/* ++ * ======== DBG_Trace ======== ++ * Purpose: ++ * Output a trace message to the debugger, if the given trace level ++ * is unmasked. ++ * Parameters: ++ * bLevel: Trace level. ++ * pstrFormat: sprintf-style format string. ++ * ...: Arguments for format string. ++ * Returns: ++ * DSP_SOK: Success, or trace level masked. ++ * DSP_EFAIL: On Error. ++ * Requires: ++ * DBG initialized. ++ * Ensures: ++ * Debug message is printed to debugger output window, if trace level ++ * is unmasked. ++ */ ++ extern DSP_STATUS DBG_Trace(IN u8 bLevel, IN char *pstrFormat, ...); ++#else ++ ++#define DBG_Exit(void) ++#define DBG_Init(void) true ++#define DBG_Trace(bLevel, pstrFormat, args...) ++ ++#endif /* (defined(DEBUG) || defined(DDSP_DEBUG_PRODUCT)) && GT_TRACE */ ++ ++#endif /* DBG_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/dbl.h b/arch/arm/plat-omap/include/dspbridge/dbl.h +new file mode 100644 +index 0000000..19847f9 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/dbl.h +@@ -0,0 +1,354 @@ ++/* ++ * dbl.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== dbl.h ======== ++ * ++ *! Revision History ++ *! ================ ++ *! 19-Mar-2002 jeh Pass DBL_Symbol pointer to DBL_getAddr, DBL_getCAddr ++ *! to accomodate dynamic loader library. ++ *! 20-Nov-2001 jeh Removed DBL_loadArgs(). ++ *! 24-Sep-2001 jeh Code review changes. ++ *! 07-Sep-2001 jeh Added DBL_LoadSect(), DBL_UnloadSect(). ++ *! 05-Jun-2001 jeh Created based on zl.h. ++ */ ++ ++#ifndef DBL_ ++#define DBL_ ++ ++#include ++#include ++ ++/* ++ * ======== DBL_close ======== ++ * Close library opened with DBL_open. ++ * Parameters: ++ * lib - Handle returned from DBL_open(). ++ * Returns: ++ * Requires: ++ * DBL initialized. ++ * Valid lib. ++ * Ensures: ++ */ ++ extern void DBL_close(struct DBL_LibraryObj *lib); ++ ++/* ++ * ======== DBL_create ======== ++ * Create a target object by specifying the alloc, free, and write ++ * functions for the target. ++ * Parameters: ++ * pTarget - Location to store target handle on output. ++ * pAttrs - Attributes. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Memory allocation failed. ++ * Requires: ++ * DBL initialized. ++ * pAttrs != NULL. ++ * pTarget != NULL; ++ * Ensures: ++ * Success: *pTarget != NULL. ++ * Failure: *pTarget == NULL. ++ */ ++ extern DSP_STATUS DBL_create(struct DBL_TargetObj **pTarget, ++ struct DBL_Attrs *pAttrs); ++ ++/* ++ * ======== DBL_delete ======== ++ * Delete target object and free resources for any loaded libraries. ++ * Parameters: ++ * target - Handle returned from DBL_Create(). ++ * Returns: ++ * Requires: ++ * DBL initialized. ++ * Valid target. ++ * Ensures: ++ */ ++ extern void DBL_delete(struct DBL_TargetObj *target); ++ ++/* ++ * ======== DBL_exit ======== ++ * Discontinue use of DBL module. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * cRefs > 0. ++ * Ensures: ++ * cRefs >= 0. ++ */ ++ extern void DBL_exit(void); ++ ++/* ++ * ======== DBL_getAddr ======== ++ * Get address of name in the specified library. ++ * Parameters: ++ * lib - Handle returned from DBL_open(). ++ * name - Name of symbol ++ * ppSym - Location to store symbol address on output. ++ * Returns: ++ * TRUE: Success. ++ * FALSE: Symbol not found. ++ * Requires: ++ * DBL initialized. ++ * Valid lib. ++ * name != NULL. ++ * pAddr != NULL. ++ * Ensures: ++ */ ++ extern bool DBL_getAddr(struct DBL_LibraryObj *lib, char *name, ++ struct DBL_Symbol **ppSym); ++ ++/* ++ * ======== DBL_getAttrs ======== ++ * Retrieve the attributes of the target. ++ * Parameters: ++ * target - Handle returned from DBL_Create(). ++ * pAttrs - Location to store attributes on output. ++ * Returns: ++ * Requires: ++ * DBL initialized. ++ * Valid target. ++ * pAttrs != NULL. ++ * Ensures: ++ */ ++ extern void DBL_getAttrs(struct DBL_TargetObj *target, ++ struct DBL_Attrs *pAttrs); ++ ++/* ++ * ======== DBL_getCAddr ======== ++ * Get address of "C" name in the specified library. ++ * Parameters: ++ * lib - Handle returned from DBL_open(). ++ * name - Name of symbol ++ * ppSym - Location to store symbol address on output. ++ * Returns: ++ * TRUE: Success. ++ * FALSE: Symbol not found. ++ * Requires: ++ * DBL initialized. ++ * Valid lib. ++ * name != NULL. ++ * pAddr != NULL. ++ * Ensures: ++ */ ++ extern bool DBL_getCAddr(struct DBL_LibraryObj *lib, char *name, ++ struct DBL_Symbol **ppSym); ++ ++/* ++ * ======== DBL_getEntry ======== ++ * Get program entry point. ++ * ++ * Parameters: ++ * lib - Handle returned from DBL_open(). ++ * pEntry - Location to store entry address on output. ++ * Returns: ++ * TRUE: Success. ++ * FALSE: Failure. ++ * Requires: ++ * DBL initialized. ++ * Valid lib. ++ * pEntry != NULL. ++ * Ensures: ++ */ ++ extern bool DBL_getEntry(struct DBL_LibraryObj *lib, u32 *pEntry); ++ ++/* ++ * ======== DBL_getSect ======== ++ * Get address and size of a named section. ++ * Parameters: ++ * lib - Library handle returned from DBL_open(). ++ * name - Name of section. ++ * pAddr - Location to store section address on output. ++ * pSize - Location to store section size on output. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_ENOSECT: Section not found. ++ * Requires: ++ * DBL initialized. ++ * Valid lib. ++ * name != NULL. ++ * pAddr != NULL; ++ * pSize != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS DBL_getSect(struct DBL_LibraryObj *lib, char *name, ++ u32 *pAddr, u32 *pSize); ++ ++/* ++ * ======== DBL_init ======== ++ * Initialize DBL module. ++ * Parameters: ++ * Returns: ++ * TRUE: Success. ++ * FALSE: Failure. ++ * Requires: ++ * cRefs >= 0. ++ * Ensures: ++ * Success: cRefs > 0. ++ * Failure: cRefs >= 0. ++ */ ++ extern bool DBL_init(void); ++ ++/* ++ * ======== DBL_load ======== ++ * Add symbols/code/data defined in file to that already present on ++ * the target. ++ * ++ * Parameters: ++ * lib - Library handle returned from DBL_open(). ++ * flags - Specifies whether loading code, data, and/or symbols. ++ * attrs - May contain write, alloc, and free functions. ++ * pulEntry - Location to store program entry on output. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFREAD: File read failed. ++ * DSP_EFWRITE: Write to target failed. ++ * Requires: ++ * DBL initialized. ++ * Valid lib. ++ * pEntry != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS DBL_load(struct DBL_LibraryObj *lib, DBL_Flags flags, ++ struct DBL_Attrs *attrs, u32 *pEntry); ++ ++/* ++ * ======== DBL_loadSect ======== ++ * Load a named section from an library (for overlay support). ++ * Parameters: ++ * lib - Handle returned from DBL_open(). ++ * sectName - Name of section to load. ++ * attrs - Contains write function and handle to pass to it. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_ENOSECT: Section not found. ++ * DSP_EFWRITE: Write function failed. ++ * Requires: ++ * Valid lib. ++ * sectName != NULL. ++ * attrs != NULL. ++ * attrs->write != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS DBL_loadSect(struct DBL_LibraryObj *lib, ++ char *sectName, ++ struct DBL_Attrs *attrs); ++ ++/* ++ * ======== DBL_open ======== ++ * DBL_open() returns a library handle that can be used to load/unload ++ * the symbols/code/data via DBL_load()/DBL_unload(). ++ * Parameters: ++ * target - Handle returned from DBL_create(). ++ * file - Name of file to open. ++ * flags - Specifies whether to load symbols now. ++ * pLib - Location to store library handle on output. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Memory allocation failure. ++ * DSP_EFOPEN: File open failure. ++ * DSP_EFREAD: File read failure. ++ * DSP_ECORRUPTFILE: Unable to determine target type. ++ * Requires: ++ * DBL initialized. ++ * Valid target. ++ * file != NULL. ++ * pLib != NULL. ++ * struct DBL_Attrs fopen function non-NULL. ++ * Ensures: ++ * Success: Valid *pLib. ++ * Failure: *pLib == NULL. ++ */ ++ extern DSP_STATUS DBL_open(struct DBL_TargetObj *target, char *file, ++ DBL_Flags flags, ++ struct DBL_LibraryObj **pLib); ++ ++/* ++ * ======== DBL_readSect ======== ++ * Read COFF section into a character buffer. ++ * Parameters: ++ * lib - Library handle returned from DBL_open(). ++ * name - Name of section. ++ * pBuf - Buffer to write section contents into. ++ * size - Buffer size ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_ENOSECT: Named section does not exists. ++ * Requires: ++ * DBL initialized. ++ * Valid lib. ++ * name != NULL. ++ * pBuf != NULL. ++ * size != 0. ++ * Ensures: ++ */ ++ extern DSP_STATUS DBL_readSect(struct DBL_LibraryObj *lib, char *name, ++ char *pBuf, u32 size); ++ ++/* ++ * ======== DBL_setAttrs ======== ++ * Set the attributes of the target. ++ * Parameters: ++ * target - Handle returned from DBL_create(). ++ * pAttrs - New attributes. ++ * Returns: ++ * Requires: ++ * DBL initialized. ++ * Valid target. ++ * pAttrs != NULL. ++ * Ensures: ++ */ ++ extern void DBL_setAttrs(struct DBL_TargetObj *target, ++ struct DBL_Attrs *pAttrs); ++ ++/* ++ * ======== DBL_unload ======== ++ * Remove the symbols/code/data corresponding to the library lib. ++ * Parameters: ++ * lib - Handle returned from DBL_open(). ++ * attrs - Contains free() function and handle to pass to it. ++ * Returns: ++ * Requires: ++ * DBL initialized. ++ * Valid lib. ++ * Ensures: ++ */ ++ extern void DBL_unload(struct DBL_LibraryObj *lib, ++ struct DBL_Attrs *attrs); ++ ++/* ++ * ======== DBL_unloadSect ======== ++ * Unload a named section from an library (for overlay support). ++ * Parameters: ++ * lib - Handle returned from DBL_open(). ++ * sectName - Name of section to load. ++ * attrs - Contains free() function and handle to pass to it. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_ENOSECT: Named section not found. ++ * Requires: ++ * DBL initialized. ++ * Valid lib. ++ * sectName != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS DBL_unloadSect(struct DBL_LibraryObj *lib, ++ char *sectName, ++ struct DBL_Attrs *attrs); ++ ++#endif /* DBL_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/dbldefs.h b/arch/arm/plat-omap/include/dspbridge/dbldefs.h +new file mode 100644 +index 0000000..79b9e54 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/dbldefs.h +@@ -0,0 +1,155 @@ ++/* ++ * dbldefs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== dbldefs.h ======== ++ * ++ *! Revision History ++ *! ================ ++ *! 19-Mar-2002 jeh Added DBL_Fxns type (to make it easier to switch ++ *! between different loaders). ++ *! 28-Sep-2001 jeh Created from zl.h. ++ */ ++#ifndef DBLDEFS_ ++#define DBLDEFS_ ++ ++/* ++ * Bit masks for DBL_Flags. ++ */ ++#define DBL_NOLOAD 0x0 /* Don't load symbols, code, or data */ ++#define DBL_SYMB 0x1 /* load symbols */ ++#define DBL_CODE 0x2 /* load code */ ++#define DBL_DATA 0x4 /* load data */ ++#define DBL_DYNAMIC 0x8 /* dynamic load */ ++#define DBL_BSS 0x20 /* Unitialized section */ ++ ++#define DBL_MAXPATHLENGTH 255 ++ ++ ++ ++/* ++ * ======== DBL_Flags ======== ++ * Specifies whether to load code, data, or symbols ++ */ ++typedef s32 DBL_Flags; ++ ++/* ++ * ======== DBL_SectInfo ======== ++ * For collecting info on overlay sections ++ */ ++struct DBL_SectInfo { ++ const char *name; /* name of section */ ++ u32 runAddr; /* run address of section */ ++ u32 loadAddr; /* load address of section */ ++ u32 size; /* size of section (target MAUs) */ ++ DBL_Flags type; /* Code, data, or BSS */ ++} ; ++ ++/* ++ * ======== DBL_Symbol ======== ++ * (Needed for dynamic load library) ++ */ ++struct DBL_Symbol { ++ u32 value; ++}; ++ ++/* ++ * ======== DBL_AllocFxn ======== ++ * Allocate memory function. Allocate or reserve (if reserved == TRUE) ++ * "size" bytes of memory from segment "space" and return the address in ++ * *dspAddr (or starting at *dspAddr if reserve == TRUE). Returns 0 on ++ * success, or an error code on failure. ++ */ ++typedef s32(*DBL_AllocFxn) (void *hdl, s32 space, u32 size, u32 align, ++ u32 *dspAddr, s32 segId, s32 req, bool reserved); ++ ++ ++ ++/* ++ * ======== DBL_FreeFxn ======== ++ * Free memory function. Free, or unreserve (if reserved == TRUE) "size" ++ * bytes of memory from segment "space" ++ */ ++typedef bool(*DBL_FreeFxn) (void *hdl, u32 addr, s32 space, u32 size, ++ bool reserved); ++ ++/* ++ * ======== DBL_LogWriteFxn ======== ++ * Function to call when writing data from a section, to log the info. ++ * Can be NULL if no logging is required. ++ */ ++typedef DSP_STATUS(*DBL_LogWriteFxn) (void *handle, struct DBL_SectInfo *sect, ++ u32 addr, u32 nBytes); ++ ++ ++/* ++ * ======== DBL_SymLookup ======== ++ * Symbol lookup function - Find the symbol name and return its value. ++ * ++ * Parameters: ++ * handle - Opaque handle ++ * pArg - Opaque argument. ++ * name - Name of symbol to lookup. ++ * sym - Location to store address of symbol structure. ++ * ++ * Returns: ++ * TRUE: Success (symbol was found). ++ * FALSE: Failed to find symbol. ++ */ ++typedef bool(*DBL_SymLookup) (void *handle, void *pArg, void *rmmHandle, ++ const char *name, struct DBL_Symbol **sym); ++ ++ ++/* ++ * ======== DBL_WriteFxn ======== ++ * Write memory function. Write "n" HOST bytes of memory to segment "mtype" ++ * starting at address "dspAddr" from the buffer "buf". The buffer is ++ * formatted as an array of words appropriate for the DSP. ++ */ ++typedef s32(*DBL_WriteFxn) (void *hdl, u32 dspAddr, void *buf, ++ u32 n, s32 mtype); ++ ++/* ++ * ======== DBL_Attrs ======== ++ */ ++struct DBL_Attrs { ++ DBL_AllocFxn alloc; ++ DBL_FreeFxn free; ++ void *rmmHandle; /* Handle to pass to alloc, free functions */ ++ DBL_WriteFxn write; ++ void *wHandle; /* Handle to pass to write, cinit function */ ++ ++ DBL_LogWriteFxn logWrite; ++ void *logWriteHandle; ++ ++ /* Symbol matching function and handle to pass to it */ ++ DBL_SymLookup symLookup; ++ void *symHandle; ++ void *symArg; ++ ++ /* ++ * These file manipulation functions should be compatible with the ++ * "C" run time library functions of the same name. ++ */ ++ s32(*fread) (void *, size_t, size_t, void *); ++ s32(*fseek) (void *, long, int); ++ s32(*ftell) (void *); ++ s32(*fclose) (void *); ++ void *(*fopen) (const char *, const char *); ++} ; ++ ++#endif /* DBLDEFS_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/dbll.h b/arch/arm/plat-omap/include/dspbridge/dbll.h +new file mode 100644 +index 0000000..c3aa212 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/dbll.h +@@ -0,0 +1,70 @@ ++/* ++ * dbll.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== dbll.h ======== ++ * DSP/BIOS Bridge Dynamic load library module interface. Function header ++ * comments are in the file dblldefs.h. ++ * ++ *! Revision History ++ *! ================ ++ *! 31-Jul-2002 jeh Removed function comments (now in dblldefs.h). ++ *! 17-Apr-2002 jeh Created based on zl.h. ++ */ ++ ++#ifndef DBLL_ ++#define DBLL_ ++ ++#include ++#include ++ ++ extern void DBLL_close(struct DBLL_LibraryObj *lib); ++ extern DSP_STATUS DBLL_create(struct DBLL_TarObj **pTarget, ++ struct DBLL_Attrs *pAttrs); ++ extern void DBLL_delete(struct DBLL_TarObj *target); ++ extern void DBLL_exit(void); ++ extern bool DBLL_getAddr(struct DBLL_LibraryObj *lib, char *name, ++ struct DBLL_Symbol **ppSym); ++ extern void DBLL_getAttrs(struct DBLL_TarObj *target, ++ struct DBLL_Attrs *pAttrs); ++ extern bool DBLL_getCAddr(struct DBLL_LibraryObj *lib, char *name, ++ struct DBLL_Symbol **ppSym); ++ extern DSP_STATUS DBLL_getSect(struct DBLL_LibraryObj *lib, char *name, ++ u32 *pAddr, u32 *pSize); ++ extern bool DBLL_init(void); ++ extern DSP_STATUS DBLL_load(struct DBLL_LibraryObj *lib, ++ DBLL_Flags flags, ++ struct DBLL_Attrs *attrs, u32 *pEntry); ++ extern DSP_STATUS DBLL_loadSect(struct DBLL_LibraryObj *lib, ++ char *sectName, ++ struct DBLL_Attrs *attrs); ++ extern DSP_STATUS DBLL_open(struct DBLL_TarObj *target, char *file, ++ DBLL_Flags flags, ++ struct DBLL_LibraryObj **pLib); ++ extern DSP_STATUS DBLL_readSect(struct DBLL_LibraryObj *lib, ++ char *name, ++ char *pBuf, u32 size); ++ extern void DBLL_setAttrs(struct DBLL_TarObj *target, ++ struct DBLL_Attrs *pAttrs); ++ extern void DBLL_unload(struct DBLL_LibraryObj *lib, ++ struct DBLL_Attrs *attrs); ++ extern DSP_STATUS DBLL_unloadSect(struct DBLL_LibraryObj *lib, ++ char *sectName, ++ struct DBLL_Attrs *attrs); ++ ++#endif /* DBLL_ */ ++ +diff --git a/arch/arm/plat-omap/include/dspbridge/dblldefs.h b/arch/arm/plat-omap/include/dspbridge/dblldefs.h +new file mode 100644 +index 0000000..2361ce8 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/dblldefs.h +@@ -0,0 +1,509 @@ ++/* ++ * dblldefs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== dblldefs.h ======== ++ * ++ *! Revision History ++ *! ================ ++ *! 08-Apr-2003 map Consolidated DBL into DBLL name ++ *! 19-Mar-2002 jeh Added DBL_Fxns type (to make it easier to switch ++ *! between different loaders). ++ *! 28-Sep-2001 jeh Created from zl.h. ++ */ ++#ifndef DBLLDEFS_ ++#define DBLLDEFS_ ++ ++/* ++ * Bit masks for DBL_Flags. ++ */ ++#define DBLL_NOLOAD 0x0 /* Don't load symbols, code, or data */ ++#define DBLL_SYMB 0x1 /* load symbols */ ++#define DBLL_CODE 0x2 /* load code */ ++#define DBLL_DATA 0x4 /* load data */ ++#define DBLL_DYNAMIC 0x8 /* dynamic load */ ++#define DBLL_BSS 0x20 /* Unitialized section */ ++ ++#define DBLL_MAXPATHLENGTH 255 ++ ++ ++/* ++ * ======== DBLL_Target ======== ++ * ++ */ ++struct DBLL_TarObj; ++ ++/* ++ * ======== DBLL_Flags ======== ++ * Specifies whether to load code, data, or symbols ++ */ ++typedef s32 DBLL_Flags; ++ ++/* ++ * ======== DBLL_Library ======== ++ * ++ */ ++struct DBLL_LibraryObj; ++ ++/* ++ * ======== DBLL_SectInfo ======== ++ * For collecting info on overlay sections ++ */ ++struct DBLL_SectInfo { ++ const char *name; /* name of section */ ++ u32 runAddr; /* run address of section */ ++ u32 loadAddr; /* load address of section */ ++ u32 size; /* size of section (target MAUs) */ ++ DBLL_Flags type; /* Code, data, or BSS */ ++} ; ++ ++/* ++ * ======== DBLL_Symbol ======== ++ * (Needed for dynamic load library) ++ */ ++struct DBLL_Symbol { ++ u32 value; ++}; ++ ++/* ++ * ======== DBLL_AllocFxn ======== ++ * Allocate memory function. Allocate or reserve (if reserved == TRUE) ++ * "size" bytes of memory from segment "space" and return the address in ++ * *dspAddr (or starting at *dspAddr if reserve == TRUE). Returns 0 on ++ * success, or an error code on failure. ++ */ ++typedef s32(*DBLL_AllocFxn) (void *hdl, s32 space, u32 size, u32 align, ++ u32 *dspAddr, s32 segId, s32 req, ++ bool reserved); ++ ++/* ++ * ======== DBLL_CloseFxn ======== ++ */ ++typedef s32(*DBLL_FCloseFxn) (void *); ++ ++/* ++ * ======== DBLL_FreeFxn ======== ++ * Free memory function. Free, or unreserve (if reserved == TRUE) "size" ++ * bytes of memory from segment "space" ++ */ ++typedef bool(*DBLL_FreeFxn) (void *hdl, u32 addr, s32 space, u32 size, ++ bool reserved); ++ ++/* ++ * ======== DBLL_FOpenFxn ======== ++ */ ++typedef void *(*DBLL_FOpenFxn) (const char *, const char *); ++ ++/* ++ * ======== DBLL_LogWriteFxn ======== ++ * Function to call when writing data from a section, to log the info. ++ * Can be NULL if no logging is required. ++ */ ++typedef DSP_STATUS(*DBLL_LogWriteFxn)(void *handle, struct DBLL_SectInfo *sect, ++ u32 addr, u32 nBytes); ++ ++/* ++ * ======== DBLL_ReadFxn ======== ++ */ ++typedef s32(*DBLL_ReadFxn) (void *, size_t, size_t, void *); ++ ++/* ++ * ======== DBLL_SeekFxn ======== ++ */ ++typedef s32(*DBLL_SeekFxn) (void *, long, int); ++ ++/* ++ * ======== DBLL_SymLookup ======== ++ * Symbol lookup function - Find the symbol name and return its value. ++ * ++ * Parameters: ++ * handle - Opaque handle ++ * pArg - Opaque argument. ++ * name - Name of symbol to lookup. ++ * sym - Location to store address of symbol structure. ++ * ++ * Returns: ++ * TRUE: Success (symbol was found). ++ * FALSE: Failed to find symbol. ++ */ ++typedef bool(*DBLL_SymLookup) (void *handle, void *pArg, void *rmmHandle, ++ const char *name, struct DBLL_Symbol **sym); ++ ++/* ++ * ======== DBLL_TellFxn ======== ++ */ ++typedef s32(*DBLL_TellFxn) (void *); ++ ++/* ++ * ======== DBLL_WriteFxn ======== ++ * Write memory function. Write "n" HOST bytes of memory to segment "mtype" ++ * starting at address "dspAddr" from the buffer "buf". The buffer is ++ * formatted as an array of words appropriate for the DSP. ++ */ ++typedef s32(*DBLL_WriteFxn) (void *hdl, u32 dspAddr, void *buf, ++ u32 n, s32 mtype); ++ ++/* ++ * ======== DBLL_Attrs ======== ++ */ ++struct DBLL_Attrs { ++ DBLL_AllocFxn alloc; ++ DBLL_FreeFxn free; ++ void *rmmHandle; /* Handle to pass to alloc, free functions */ ++ DBLL_WriteFxn write; ++ void *wHandle; /* Handle to pass to write, cinit function */ ++ bool baseImage; ++ DBLL_LogWriteFxn logWrite; ++ void *logWriteHandle; ++ ++ /* Symbol matching function and handle to pass to it */ ++ DBLL_SymLookup symLookup; ++ void *symHandle; ++ void *symArg; ++ ++ /* ++ * These file manipulation functions should be compatible with the ++ * "C" run time library functions of the same name. ++ */ ++ s32(*fread) (void *, size_t, size_t, void *); ++ s32(*fseek) (void *, long, int); ++ s32(*ftell) (void *); ++ s32(*fclose) (void *); ++ void *(*fopen) (const char *, const char *); ++} ; ++ ++/* ++ * ======== DBLL_close ======== ++ * Close library opened with DBLL_open. ++ * Parameters: ++ * lib - Handle returned from DBLL_open(). ++ * Returns: ++ * Requires: ++ * DBL initialized. ++ * Valid lib. ++ * Ensures: ++ */ ++typedef void(*DBLL_CloseFxn) (struct DBLL_LibraryObj *library); ++ ++/* ++ * ======== DBLL_create ======== ++ * Create a target object, specifying the alloc, free, and write functions. ++ * Parameters: ++ * pTarget - Location to store target handle on output. ++ * pAttrs - Attributes. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Memory allocation failed. ++ * Requires: ++ * DBL initialized. ++ * pAttrs != NULL. ++ * pTarget != NULL; ++ * Ensures: ++ * Success: *pTarget != NULL. ++ * Failure: *pTarget == NULL. ++ */ ++typedef DSP_STATUS(*DBLL_CreateFxn)(struct DBLL_TarObj **pTarget, ++ struct DBLL_Attrs *attrs); ++ ++/* ++ * ======== DBLL_delete ======== ++ * Delete target object and free resources for any loaded libraries. ++ * Parameters: ++ * target - Handle returned from DBLL_Create(). ++ * Returns: ++ * Requires: ++ * DBL initialized. ++ * Valid target. ++ * Ensures: ++ */ ++typedef void(*DBLL_DeleteFxn) (struct DBLL_TarObj *target); ++ ++/* ++ * ======== DBLL_exit ======== ++ * Discontinue use of DBL module. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * cRefs > 0. ++ * Ensures: ++ * cRefs >= 0. ++ */ ++typedef void(*DBLL_ExitFxn) (void); ++ ++/* ++ * ======== DBLL_getAddr ======== ++ * Get address of name in the specified library. ++ * Parameters: ++ * lib - Handle returned from DBLL_open(). ++ * name - Name of symbol ++ * ppSym - Location to store symbol address on output. ++ * Returns: ++ * TRUE: Success. ++ * FALSE: Symbol not found. ++ * Requires: ++ * DBL initialized. ++ * Valid library. ++ * name != NULL. ++ * ppSym != NULL. ++ * Ensures: ++ */ ++typedef bool(*DBLL_GetAddrFxn) (struct DBLL_LibraryObj *lib, char *name, ++ struct DBLL_Symbol **ppSym); ++ ++/* ++ * ======== DBLL_getAttrs ======== ++ * Retrieve the attributes of the target. ++ * Parameters: ++ * target - Handle returned from DBLL_Create(). ++ * pAttrs - Location to store attributes on output. ++ * Returns: ++ * Requires: ++ * DBL initialized. ++ * Valid target. ++ * pAttrs != NULL. ++ * Ensures: ++ */ ++typedef void(*DBLL_GetAttrsFxn) (struct DBLL_TarObj *target, ++ struct DBLL_Attrs *attrs); ++ ++/* ++ * ======== DBLL_getCAddr ======== ++ * Get address of "C" name on the specified library. ++ * Parameters: ++ * lib - Handle returned from DBLL_open(). ++ * name - Name of symbol ++ * ppSym - Location to store symbol address on output. ++ * Returns: ++ * TRUE: Success. ++ * FALSE: Symbol not found. ++ * Requires: ++ * DBL initialized. ++ * Valid target. ++ * name != NULL. ++ * ppSym != NULL. ++ * Ensures: ++ */ ++typedef bool(*DBLL_GetCAddrFxn) (struct DBLL_LibraryObj *lib, char *name, ++ struct DBLL_Symbol **ppSym); ++ ++/* ++ * ======== DBLL_getSect ======== ++ * Get address and size of a named section. ++ * Parameters: ++ * lib - Library handle returned from DBLL_open(). ++ * name - Name of section. ++ * pAddr - Location to store section address on output. ++ * pSize - Location to store section size on output. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_ENOSECT: Section not found. ++ * Requires: ++ * DBL initialized. ++ * Valid lib. ++ * name != NULL. ++ * pAddr != NULL; ++ * pSize != NULL. ++ * Ensures: ++ */ ++typedef DSP_STATUS(*DBLL_GetSectFxn) (struct DBLL_LibraryObj *lib, char *name, ++ u32 *addr, u32 *size); ++ ++/* ++ * ======== DBLL_init ======== ++ * Initialize DBL module. ++ * Parameters: ++ * Returns: ++ * TRUE: Success. ++ * FALSE: Failure. ++ * Requires: ++ * cRefs >= 0. ++ * Ensures: ++ * Success: cRefs > 0. ++ * Failure: cRefs >= 0. ++ */ ++typedef bool(*DBLL_InitFxn) (void); ++ ++/* ++ * ======== DBLL_load ======== ++ * Load library onto the target. ++ * ++ * Parameters: ++ * lib - Library handle returned from DBLL_open(). ++ * flags - Load code, data and/or symbols. ++ * attrs - May contain alloc, free, and write function. ++ * pulEntry - Location to store program entry on output. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFREAD: File read failed. ++ * DSP_EFWRITE: Write to target failed. ++ * DSP_EDYNLOAD: Failure in dynamic loader library. ++ * Requires: ++ * DBL initialized. ++ * Valid lib. ++ * pEntry != NULL. ++ * Ensures: ++ */ ++typedef DSP_STATUS(*DBLL_LoadFxn) (struct DBLL_LibraryObj *lib, ++ DBLL_Flags flags, ++ struct DBLL_Attrs *attrs, u32 *entry); ++ ++/* ++ * ======== DBLL_loadSect ======== ++ * Load a named section from an library (for overlay support). ++ * Parameters: ++ * lib - Handle returned from DBLL_open(). ++ * sectName - Name of section to load. ++ * attrs - Contains write function and handle to pass to it. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_ENOSECT: Section not found. ++ * DSP_EFWRITE: Write function failed. ++ * DSP_ENOTIMPL: Function not implemented. ++ * Requires: ++ * Valid lib. ++ * sectName != NULL. ++ * attrs != NULL. ++ * attrs->write != NULL. ++ * Ensures: ++ */ ++typedef DSP_STATUS(*DBLL_LoadSectFxn) (struct DBLL_LibraryObj *lib, ++ char *pszSectName, ++ struct DBLL_Attrs *attrs); ++ ++/* ++ * ======== DBLL_open ======== ++ * DBLL_open() returns a library handle that can be used to load/unload ++ * the symbols/code/data via DBLL_load()/DBLL_unload(). ++ * Parameters: ++ * target - Handle returned from DBLL_create(). ++ * file - Name of file to open. ++ * flags - If flags & DBLL_SYMB, load symbols. ++ * pLib - Location to store library handle on output. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Memory allocation failure. ++ * DSP_EFOPEN: File open failure. ++ * DSP_EFREAD: File read failure. ++ * DSP_ECORRUPTFILE: Unable to determine target type. ++ * Requires: ++ * DBL initialized. ++ * Valid target. ++ * file != NULL. ++ * pLib != NULL. ++ * DBLL_Attrs fopen function non-NULL. ++ * Ensures: ++ * Success: Valid *pLib. ++ * Failure: *pLib == NULL. ++ */ ++typedef DSP_STATUS(*DBLL_OpenFxn) (struct DBLL_TarObj *target, char *file, ++ DBLL_Flags flags, ++ struct DBLL_LibraryObj **pLib); ++ ++/* ++ * ======== DBLL_readSect ======== ++ * Read COFF section into a character buffer. ++ * Parameters: ++ * lib - Library handle returned from DBLL_open(). ++ * name - Name of section. ++ * pBuf - Buffer to write section contents into. ++ * size - Buffer size ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_ENOSECT: Named section does not exists. ++ * Requires: ++ * DBL initialized. ++ * Valid lib. ++ * name != NULL. ++ * pBuf != NULL. ++ * size != 0. ++ * Ensures: ++ */ ++typedef DSP_STATUS(*DBLL_ReadSectFxn) (struct DBLL_LibraryObj *lib, char *name, ++ char *content, u32 uContentSize); ++ ++/* ++ * ======== DBLL_setAttrs ======== ++ * Set the attributes of the target. ++ * Parameters: ++ * target - Handle returned from DBLL_create(). ++ * pAttrs - New attributes. ++ * Returns: ++ * Requires: ++ * DBL initialized. ++ * Valid target. ++ * pAttrs != NULL. ++ * Ensures: ++ */ ++typedef void(*DBLL_SetAttrsFxn)(struct DBLL_TarObj *target, ++ struct DBLL_Attrs *attrs); ++ ++/* ++ * ======== DBLL_unload ======== ++ * Unload library loaded with DBLL_load(). ++ * Parameters: ++ * lib - Handle returned from DBLL_open(). ++ * attrs - Contains free() function and handle to pass to it. ++ * Returns: ++ * Requires: ++ * DBL initialized. ++ * Valid lib. ++ * Ensures: ++ */ ++typedef void(*DBLL_UnloadFxn) (struct DBLL_LibraryObj *library, ++ struct DBLL_Attrs *attrs); ++ ++/* ++ * ======== DBLL_unloadSect ======== ++ * Unload a named section from an library (for overlay support). ++ * Parameters: ++ * lib - Handle returned from DBLL_open(). ++ * sectName - Name of section to load. ++ * attrs - Contains free() function and handle to pass to it. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_ENOSECT: Named section not found. ++ * DSP_ENOTIMPL ++ * Requires: ++ * DBL initialized. ++ * Valid lib. ++ * sectName != NULL. ++ * Ensures: ++ */ ++typedef DSP_STATUS(*DBLL_UnloadSectFxn) (struct DBLL_LibraryObj *lib, ++ char *pszSectName, ++ struct DBLL_Attrs *attrs); ++ ++struct DBLL_Fxns { ++ DBLL_CloseFxn closeFxn; ++ DBLL_CreateFxn createFxn; ++ DBLL_DeleteFxn deleteFxn; ++ DBLL_ExitFxn exitFxn; ++ DBLL_GetAttrsFxn getAttrsFxn; ++ DBLL_GetAddrFxn getAddrFxn; ++ DBLL_GetCAddrFxn getCAddrFxn; ++ DBLL_GetSectFxn getSectFxn; ++ DBLL_InitFxn initFxn; ++ DBLL_LoadFxn loadFxn; ++ DBLL_LoadSectFxn loadSectFxn; ++ DBLL_OpenFxn openFxn; ++ DBLL_ReadSectFxn readSectFxn; ++ DBLL_SetAttrsFxn setAttrsFxn; ++ DBLL_UnloadFxn unloadFxn; ++ DBLL_UnloadSectFxn unloadSectFxn; ++} ; ++ ++#endif /* DBLDEFS_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/dbof.h b/arch/arm/plat-omap/include/dspbridge/dbof.h +new file mode 100644 +index 0000000..54f4250 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/dbof.h +@@ -0,0 +1,117 @@ ++/* ++ * dbof.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== dbof.h ======== ++ * Description: ++ * Defines and typedefs for DSP/BIOS Bridge Object File Format (DBOF). ++ * ++ *! Revision History ++ *! ================ ++ *! 12-Jul-2002 jeh Added defines for DBOF_SectHdr page. ++ *! 12-Oct-2001 jeh Converted to std.h format. ++ *! 07-Sep-2001 jeh Added overlay support. ++ *! 06-Jul-2001 jeh Created. ++ */ ++ ++#ifndef DBOF_ ++#define DBOF_ ++ ++/* Enough to hold DCD section names: 32 digit ID + underscores */ ++#define DBOF_DCDSECTNAMELEN 40 ++ ++/* Values for DBOF_SectHdr page field. */ ++#define DBOF_PROGRAM 0 ++#define DBOF_DATA 1 ++#define DBOF_CINIT 2 ++ ++/* ++ * ======== DBOF_FileHdr ======== ++ */ ++ struct DBOF_FileHdr { ++ u32 magic; /* COFF magic number */ ++ u32 entry; /* Program entry point */ ++ u16 numSymbols; /* Number of bridge symbols */ ++ u16 numDCDSects; /* Number of DCD sections */ ++ u16 numSects; /* Number of sections to load */ ++ u16 numOvlySects; /* Number of overlay sections */ ++ u32 symOffset; /* Offset in file to symbols */ ++ u32 dcdSectOffset; /* Offset to DCD sections */ ++ u32 loadSectOffset; /* Offset to loadable sections */ ++ u32 ovlySectOffset; /* Offset to overlay data */ ++ u16 version; /* DBOF version number */ ++ u16 resvd; /* Reserved for future use */ ++ } ; ++ ++/* ++ * ======== DBOF_DCDSectHdr ======== ++ */ ++ struct DBOF_DCDSectHdr { ++ u32 size; /* Sect size (target MAUs) */ ++ char name[DBOF_DCDSECTNAMELEN]; /* DCD section name */ ++ } ; ++ ++/* ++ * ======== DBOF_OvlySectHdr ======== ++ */ ++ struct DBOF_OvlySectHdr { ++ u16 nameLen; /* Length of section name */ ++ u16 numCreateSects; /* # of sects loaded for create phase */ ++ u16 numDeleteSects; /* # of sects loaded for delete phase */ ++ u16 numExecuteSects; /* # of sects loaded for execute phase */ ++ ++ /* ++ * Number of sections where load/unload phase is not specified. ++ * These sections will be loaded when create phase sects are ++ * loaded, and unloaded when the delete phase is unloaded. ++ */ ++ u16 numOtherSects; ++ u16 resvd; /* Reserved for future use */ ++ }; ++ ++/* ++ * ======== DBOF_OvlySectData ======== ++ */ ++ struct DBOF_OvlySectData { ++ u32 loadAddr; /* Section load address */ ++ u32 runAddr; /* Section run address */ ++ u32 size; /* Section size (target MAUs) */ ++ u16 page; /* Memory page number */ ++ u16 resvd; /* Reserved */ ++ } ; ++ ++/* ++ * ======== DBOF_SectHdr ======== ++ */ ++ struct DBOF_SectHdr { ++ u32 addr; /* Section address */ ++ u32 size; /* Section size (target MAUs) */ ++ u16 page; /* Page number */ ++ u16 resvd; /* Reserved for future use */ ++ } ; ++ ++/* ++ * ======== DBOF_SymbolHdr ======== ++ */ ++ struct DBOF_SymbolHdr { ++ u32 value; /* Symbol value */ ++ u16 nameLen; /* Length of symbol name */ ++ u16 resvd; /* Reserved for future use */ ++ } ; ++ ++#endif /* DBOF_ */ ++ +diff --git a/arch/arm/plat-omap/include/dspbridge/dbreg.h b/arch/arm/plat-omap/include/dspbridge/dbreg.h +new file mode 100644 +index 0000000..d311b88 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/dbreg.h +@@ -0,0 +1,113 @@ ++/* ++ * dbreg.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== dbreg.h ======== ++ * Purpose: ++ * Registry keys for use in Linux. This is the clearinghouse for ++ * registry definitions, hopefully eliminating overlapping between ++ * modules. ++ * ++ *! Revision History: ++ *! ================ ++ *! 10-Apr-2003 vp: Added macro for subkey TCWORDSWAP. ++ *! 21-Mar-2003 sb: Added macro for subkey SHMSize ++ *! 27-Aug-2001 jeh Added WSXREG_LOADERFILENAME. ++ *! 13-Feb-2001 kc: DSP/BIOS Bridge name updates. ++ *! 29-Nov-2000 rr: Added WSXREG_DSPTYPE_55 as 6. ++ *! 06-Sep-2000 jeh: Added WSXREG_CHNLOFFSET, WSXREG_NUMCHNLS, ++ *! WSXREG_CHNLBUFSIZE. ++ *! 26-Aug-2000 rr: MEMBASE expanded to 9 entries. ++ *! 26-Jul-2000 rr: Added WSXREG_DCDNAME for the DCD Dll name. It will ++ *! live under WSXREG_WINSPOXCONFIG. ++ *! 17-Jul-2000 rr: REG_MGR_OBJECT and REG_DRV_OBJECT defined. They ++ *! are stored in the Registrty under WSXREG_WINSPOXCONFIG ++ *! when they are created in DSP_Init. WSXREG_DEVOBJECT ++ *! and WSXREG_MGROBJECT defined. ++ *! 11-Dec-1999 ag: Renamed Isa to IsaBus due to conflict with ceddk.h. ++ *! 12-Nov-1999 rr: New Registry Defnitions. ++ *! 15-Oct-1999 rr: New entry for DevObject created. WSXREG_DEVOBJECT ++ *! under WSXREG_DDSPDRIVERPATH ++ *! 10-Nov-1997 cr: Added WSXREG_INFPATH, WSXREG_WINDEVICEPATH, ++ *! WSXREG_WINCURVERSION ++ *! 21-Oct-1997 cr: Added WSXREG_BUSTYPE. ++ *! 08-Sep-1997 cr: Added WSXREG_SERVICES, WSXREG_SERVICENAME and ++ *! WSXREG_CLASSINDEX. ++ *! 30-Aug-1997 cr: Added WSXREG_SOFTWAREPATHNT & WSXREG_WBCLASSGUID. ++ *! 24-Mar-1997 gp: Added MAXCHIPINFOSUBKEY def. ++ *! 18-Feb-1997 cr: Changed Version1.1 -> Version1.0 ++ *! 12-Feb-1997 cr: Changed WinSPOX -> WinBRIDGE. ++ *! 11-Dec-1996 gp: Added Perf key name in WinSPOX Config. ++ *! 22-Jul-1996 gp: Added Trace key name. ++ *! 30-May-1996 cr: Created. ++ */ ++ ++#ifndef DBREG_ ++#define DBREG_ 1 /* Defined as "1" so InstallShield programs compile. */ ++ ++#define REG_MGR_OBJECT 1 ++#define REG_DRV_OBJECT 2 ++/* general registry definitions */ ++#define MAXREGPATHLENGTH 255 /* Max registry path length. Also the ++ max registry value length. */ ++#define DSPTYPE_55 6 /* This is the DSP Chip type for 55 */ ++#define DSPTYPE_64 0x99 ++#define IVA_ARM7 0x97 /* This is the DSP Chip type for IVA/ARM7 */ ++ ++#define DSPPROCTYPE_C55 5510 ++#define DSPPROCTYPE_C64 6410 ++#define IVAPROCTYPE_ARM7 470 ++/* registry */ ++#define DEVNODESTRING "DevNode" /* u32 devnode */ ++#define CONFIG "Software\\TexasInstruments\\DirectDSP\\Config" ++#define DRVOBJECT "DrvObject" ++#define MGROBJECT "MgrObject" ++#define CLASS "Device" /* device class */ ++#define TRACE "Trace" /* GT Trace settings. */ ++#define PERFR "Perf" /* Enable perf bool. */ ++#define ROOT "Root" /* root dir */ ++ ++/* MiniDriver related definitions */ ++/* The following definitions are under "Drivers\\DirectDSP\\Device\\XXX " ++ * Where XXX is the device or board name */ ++ ++#define WMDFILENAME "MiniDriver" /* WMD entry name */ ++#define CHIPTYPE "ChipType" /* Chip type */ ++#define CHIPNUM "NumChips" /* Number of chips */ ++#define NUMPROCS "NumOfProcessors" /* Number of processors */ ++#define DEFEXEC "DefaultExecutable" /* Default executable */ ++#define AUTOSTART "AutoStart" /* Statically load flag */ ++#define IVAAUTOSTART "IvaAutoStart" /* Statically load flag */ ++#define BOARDNAME "BoardName" /* Name of the Board */ ++#define UNITNUMBER "UnitNumber" /* Unit # of the Board */ ++#define BUSTYPE "BusType" /* Bus type board is on */ ++#define BUSNUMBER "BusNumber" /* Bus number board is on */ ++#define CURRENTCONFIG "CurrentConfig" /* Current resources */ ++#define PCIVENDEVID "VendorDeviceId" /* The board's id */ ++#define INFPATH "InfPath" /* wmd's inf filename */ ++#define DEVOBJECT "DevObject" ++#define ZLFILENAME "ZLFileName" /* Name of ZL file */ ++#define WORDSIZE "WordSize" /* NumBytes in DSP Word */ ++#define SHMSIZE "SHMSize" /* Size of SHM reservd on MPU */ ++#define IVAEXTMEMSIZE "IVAEXTMEMSize" /* IVA External Memeory size */ ++#define TCWORDSWAP "TCWordSwap" /* Traffic Contoller Word Swap */ ++#define DSPRESOURCES "DspTMSResources" /* C55 DSP resurces on OMAP */ ++#define IVA1RESOURCES "ARM7IvaResources" /* ARM7 IVA resurces on OMAP */ ++#define PHYSMEMPOOLBASE "PhysicalMemBase" /* Physical mem passed to driver */ ++#define PHYSMEMPOOLSIZE "PhysicalMemSize" /* Physical mem passed to driver */ ++ ++#endif /* DBREG_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/dbtype.h b/arch/arm/plat-omap/include/dspbridge/dbtype.h +new file mode 100644 +index 0000000..b4953a0 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/dbtype.h +@@ -0,0 +1,103 @@ ++/* ++ * dbtype.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== dbtype.h ======== ++ * Description: ++ * This header defines data types for DSP/BIOS Bridge APIs and device ++ * driver modules. It also defines the Hungarian ++ * prefix to use for each base type. ++ * ++ * ++ *! Revision History: ++ *! ================= ++ *! 23-Nov-2002 gp: Purpose -> Description in file header. ++ *! 13-Feb-2001 kc: Name changed from ddsptype.h dbtype.h. ++ *! 09-Oct-2000 jeh Added CHARACTER. ++ *! 11-Aug-2000 ag: Added 'typedef void void'. ++ *! 08-Apr-2000 ww: Cloned. ++ */ ++ ++#ifndef DBTYPE_ ++#define DBTYPE_ ++ ++/*============================================================================*/ ++/* Argument specification syntax */ ++/*============================================================================*/ ++ ++#ifndef IN ++#define IN /* Following parameter is for input. */ ++#endif ++ ++#ifndef OUT ++#define OUT /* Following parameter is for output. */ ++#endif ++ ++#ifndef OPTIONAL ++#define OPTIONAL /* Function may optionally use previous parameter. */ ++#endif ++ ++#ifndef CONST ++#define CONST const ++#endif ++ ++/*============================================================================*/ ++/* Boolean constants */ ++/*============================================================================*/ ++ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++#ifndef TRUE ++#define TRUE 1 ++#endif ++ ++/*============================================================================*/ ++/* NULL (Definition is language specific) */ ++/*============================================================================*/ ++ ++#ifndef NULL ++#define NULL ((void *)0) /* Null pointer. */ ++#endif ++ ++/*============================================================================*/ ++/* NULL character (normally used for string termination) */ ++/*============================================================================*/ ++ ++#ifndef NULL_CHAR ++#define NULL_CHAR '\0' /* Null character. */ ++#endif ++ ++/*============================================================================*/ ++/* Basic Type definitions (with Prefixes for Hungarian notation) */ ++/*============================================================================*/ ++ ++#ifndef OMAPBRIDGE_TYPES ++#define OMAPBRIDGE_TYPES ++typedef volatile unsigned short REG_UWORD16; ++#endif ++ ++typedef void *HANDLE; /* h */ ++ ++#define TEXT(x) x ++ ++#define DLLIMPORT ++#define DLLEXPORT ++ ++/* Define DSPAPIDLL correctly in dspapi.h */ ++#define _DSPSYSDLL32_ ++ ++#endif /* DBTYPE_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/dehdefs.h b/arch/arm/plat-omap/include/dspbridge/dehdefs.h +new file mode 100644 +index 0000000..06e5582 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/dehdefs.h +@@ -0,0 +1,42 @@ ++/* ++ * dehdefs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== dehdefs.h ======== ++ * Purpose: ++ * Definition for mini-driver module DEH. ++ * ++ *! Revision History: ++ *! ================ ++ *! 17-Dec-2001 ag: added #include for shared mailbox codes. ++ *! 10-Dec-2001 kc: added DEH error base value and error max value. ++ *! 11-Sep-2001 kc: created. ++ */ ++ ++#ifndef DEHDEFS_ ++#define DEHDEFS_ ++ ++#include /* shared mailbox codes */ ++ ++/* DEH object manager */ ++ struct DEH_MGR; ++ ++/* Magic code used to determine if DSP signaled exception. */ ++#define DEH_BASE MBX_DEH_BASE ++#define DEH_USERS_BASE MBX_DEH_USERS_BASE ++#define DEH_LIMIT MBX_DEH_LIMIT ++ ++#endif /* _DEHDEFS_H */ +diff --git a/arch/arm/plat-omap/include/dspbridge/dev.h b/arch/arm/plat-omap/include/dspbridge/dev.h +new file mode 100644 +index 0000000..5f468c9 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/dev.h +@@ -0,0 +1,785 @@ ++/* ++ * dev.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== dev.h ======== ++ * Description: ++ * 'Bridge Mini-driver device operations. ++ * ++ * Public Functions: ++ * DEV_BrdWriteFxn ++ * DEV_CreateDevice ++ * DEV_Create2 ++ * DEV_Destroy2 ++ * DEV_DestroyDevice ++ * DEV_GetChnlMgr ++ * DEV_GetCmmMgr ++ * DEV_GetCodMgr ++ * DEV_GetDehMgr ++ * DEV_GetDevNode ++ * DEV_GetDSPWordSize ++ * DEV_GetFirst ++ * DEV_GetIntfFxns ++ * DEV_GetIOMgr ++ * DEV_GetMsgMgr ++ * DEV_GetNext ++ * DEV_GetNodeManager ++ * DEV_GetSymbol ++ * DEV_GetWMDContext ++ * DEV_Exit ++ * DEV_Init ++ * DEV_InsertProcObject ++ * DEV_IsLocked ++ * DEV_NotifyClient ++ * DEV_RegisterNotify ++ * DEV_ReleaseCodMgr ++ * DEV_RemoveDevice ++ * DEV_RemoveProcObject ++ * DEV_SetChnlMgr ++ * DEV_SetMsgMgr ++ * DEV_SetLockOwner ++ * DEV_StartDevice ++ * ++ *! Revision History: ++ *! ================ ++ *! 08-Mar-2004 sb Added the Dynamic Memory Mapping feature - Dev_GetDmmMgr ++ *! 09-Feb-2004 vp Added functions required for IVA ++ *! 25-Feb-2003 swa PMGR Code Review changes incorporated ++ *! 05-Nov-2001 kc: Added DEV_GetDehMgr. ++ *! 05-Dec-2000 jeh Added DEV_SetMsgMgr. ++ *! 29-Nov-2000 rr: Incorporated code review changes. ++ *! 17-Nov-2000 jeh Added DEV_GetMsgMgr. ++ *! 05-Oct-2000 rr: DEV_Create2 & DEV_Destroy2 Added. ++ *! 02-Oct-2000 rr: Added DEV_GetNodeManager. ++ *! 11-Aug-2000 ag: Added DEV_GetCmmMgr() for shared memory management. ++ *! 10-Aug-2000 rr: DEV_InsertProcObject/RemoveProcObject added. ++ *! 06-Jun-2000 jeh Added DEV_GetSymbol(). ++ *! 05-Nov-1999 kc: Updated function prototypes. ++ *! 08-Oct-1997 cr: Added explicit CDECL function identifiers. ++ *! 07-Nov-1996 gp: Updated for code review. ++ *! 22-Oct-1996 gp: Added DEV_CleanupProcessState(). ++ *! 29-May-1996 gp: Changed DEV_HDEVNODE --> CFG_HDEVNODE. ++ *! 18-May-1996 gp: Created. ++ */ ++ ++#ifndef DEV_ ++#define DEV_ ++ ++/* ----------------------------------- Module Dependent Headers */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++ ++/* ++ * ======== DEV_BrdWriteFxn ======== ++ * Purpose: ++ * Exported function to be used as the COD write function. This function ++ * is passed a handle to a DEV_hObject by ZL in pArb, then calls the ++ * device's WMD_BRD_Write() function. ++ * Parameters: ++ * pArb: Handle to a Device Object. ++ * hDevContext: Handle to mini-driver defined device info. ++ * dwDSPAddr: Address on DSP board (Destination). ++ * pHostBuf: Pointer to host buffer (Source). ++ * ulNumBytes: Number of bytes to transfer. ++ * ulMemType: Memory space on DSP to which to transfer. ++ * Returns: ++ * Number of bytes written. Returns 0 if the DEV_hObject passed in via ++ * pArb is invalid. ++ * Requires: ++ * DEV Initialized. ++ * pHostBuf != NULL ++ * Ensures: ++ */ ++ extern u32 DEV_BrdWriteFxn(void *pArb, ++ u32 ulDspAddr, ++ void *pHostBuf, ++ u32 ulNumBytes, u32 nMemSpace); ++ ++/* ++ * ======== DEV_CreateDevice ======== ++ * Purpose: ++ * Called by the operating system to load the 'Bridge Mini Driver for a ++ * 'Bridge device. ++ * Parameters: ++ * phDevObject: Ptr to location to receive the device object handle. ++ * pstrWMDFileName: Name of WMD PE DLL file to load. If the absolute ++ * path is not provided, the file is loaded through ++ * 'Bridge's module search path. ++ * pHostConfig: Host configuration information, to be passed down ++ * to the WMD when WMD_DEV_Create() is called. ++ * pDspConfig: DSP resources, to be passed down to the WMD when ++ * WMD_DEV_Create() is called. ++ * hDevNode: Platform (Windows) specific device node. ++ * Returns: ++ * DSP_SOK: Module is loaded, device object has been created ++ * DSP_EMEMORY: Insufficient memory to create needed resources. ++ * DEV_E_NEWWMD: The WMD was compiled for a newer version of WCD. ++ * DEV_E_NULLWMDINTF: WMD passed back a NULL Fxn Interface Struct Ptr ++ * DEV_E_NOCODMODULE: No ZL file name was specified in the registry ++ * for this hDevNode. ++ * LDR_E_FILEUNABLETOOPEN: Unable to open the specified WMD. ++ * LDR_E_NOMEMORY: PELDR is out of resources. ++ * DSP_EFAIL: Unable to find WMD entry point function. ++ * COD_E_NOZLFUNCTIONS: One or more ZL functions exports not found. ++ * COD_E_ZLCREATEFAILED: Unable to load ZL DLL. ++ * Requires: ++ * DEV Initialized. ++ * phDevObject != NULL. ++ * pstrWMDFileName != NULL. ++ * pHostConfig != NULL. ++ * pDspConfig != NULL. ++ * Ensures: ++ * DSP_SOK: *phDevObject will contain handle to the new device object. ++ * Otherwise, does not create the device object, ensures the WMD module is ++ * unloaded, and sets *phDevObject to NULL. ++ */ ++ extern DSP_STATUS DEV_CreateDevice(OUT struct DEV_OBJECT ++ **phDevObject, ++ IN CONST char *pstrWMDFileName, ++ IN CONST struct CFG_HOSTRES ++ *pHostConfig, ++ IN CONST struct CFG_DSPRES ++ *pDspConfig, ++ struct CFG_DEVNODE *hDevNode); ++ ++/* ++ * ======== DEV_CreateIVADevice ======== ++ * Purpose: ++ * Called by the operating system to load the 'Bridge Mini Driver for IVA. ++ * Parameters: ++ * phDevObject: Ptr to location to receive the device object handle. ++ * pstrWMDFileName: Name of WMD PE DLL file to load. If the absolute ++ * path is not provided, the file is loaded through ++ * 'Bridge's module search path. ++ * pHostConfig: Host configuration information, to be passed down ++ * to the WMD when WMD_DEV_Create() is called. ++ * pDspConfig: DSP resources, to be passed down to the WMD when ++ * WMD_DEV_Create() is called. ++ * hDevNode: Platform (Windows) specific device node. ++ * Returns: ++ * DSP_SOK: Module is loaded, device object has been created ++ * DSP_EMEMORY: Insufficient memory to create needed resources. ++ * DEV_E_NEWWMD: The WMD was compiled for a newer version of WCD. ++ * DEV_E_NULLWMDINTF: WMD passed back a NULL Fxn Interface Struct Ptr ++ * DEV_E_NOCODMODULE: No ZL file name was specified in the registry ++ * for this hDevNode. ++ * LDR_E_FILEUNABLETOOPEN: Unable to open the specified WMD. ++ * LDR_E_NOMEMORY: PELDR is out of resources. ++ * DSP_EFAIL: Unable to find WMD entry point function. ++ * COD_E_NOZLFUNCTIONS: One or more ZL functions exports not found. ++ * COD_E_ZLCREATEFAILED: Unable to load ZL DLL. ++ * Requires: ++ * DEV Initialized. ++ * phDevObject != NULL. ++ * pstrWMDFileName != NULL. ++ * pHostConfig != NULL. ++ * pDspConfig != NULL. ++ * Ensures: ++ * DSP_SOK: *phDevObject will contain handle to the new device object. ++ * Otherwise, does not create the device object, ensures the WMD module is ++ * unloaded, and sets *phDevObject to NULL. ++ */ ++ extern DSP_STATUS DEV_CreateIVADevice(OUT struct DEV_OBJECT ++ **phDevObject, ++ IN CONST char *pstrWMDFileName, ++ IN CONST struct CFG_HOSTRES *pHostConfig, ++ IN CONST struct CFG_DSPRES *pDspConfig, ++ struct CFG_DEVNODE *hDevNode); ++ ++/* ++ * ======== DEV_Create2 ======== ++ * Purpose: ++ * After successful loading of the image from WCD_InitComplete2 ++ * (PROC Auto_Start) or PROC_Load this fxn is called. This creates ++ * the Node Manager and updates the DEV Object. ++ * Parameters: ++ * hDevObject: Handle to device object created with DEV_CreateDevice(). ++ * Returns: ++ * DSP_SOK: Successful Creation of Node Manager ++ * DSP_EFAIL: Some Error Occurred. ++ * Requires: ++ * DEV Initialized ++ * Valid hDevObject ++ * Ensures: ++ * DSP_SOK and hDevObject->hNodeMgr != NULL ++ * else hDevObject->hNodeMgr == NULL ++ */ ++ extern DSP_STATUS DEV_Create2(IN struct DEV_OBJECT *hDevObject); ++ ++/* ++ * ======== DEV_Destroy2 ======== ++ * Purpose: ++ * Destroys the Node manager for this device. ++ * Parameters: ++ * hDevObject: Handle to device object created with DEV_CreateDevice(). ++ * Returns: ++ * DSP_SOK: Successful Creation of Node Manager ++ * DSP_EFAIL: Some Error Occurred. ++ * Requires: ++ * DEV Initialized ++ * Valid hDevObject ++ * Ensures: ++ * DSP_SOK and hDevObject->hNodeMgr == NULL ++ * else DSP_EFAIL. ++ */ ++ extern DSP_STATUS DEV_Destroy2(IN struct DEV_OBJECT *hDevObject); ++ ++/* ++ * ======== DEV_DestroyDevice ======== ++ * Purpose: ++ * Destroys the channel manager for this device, if any, calls ++ * WMD_DEV_Destroy(), and then attempts to unload the WMD module. ++ * Parameters: ++ * hDevObject: Handle to device object created with ++ * DEV_CreateDevice(). ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hDevObject. ++ * DSP_EFAIL: The WMD failed it's WMD_DEV_Destroy() function. ++ * Requires: ++ * DEV Initialized. ++ * Ensures: ++ */ ++ extern DSP_STATUS DEV_DestroyDevice(struct DEV_OBJECT ++ *hDevObject); ++ ++/* ++ * ======== DEV_GetChnlMgr ======== ++ * Purpose: ++ * Retrieve the handle to the channel manager created for this device. ++ * Parameters: ++ * hDevObject: Handle to device object created with ++ * DEV_CreateDevice(). ++ * *phMgr: Ptr to location to store handle. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hDevObject. ++ * Requires: ++ * phMgr != NULL. ++ * DEV Initialized. ++ * Ensures: ++ * DSP_SOK: *phMgr contains a handle to a channel manager object, ++ * or NULL. ++ * else: *phMgr is NULL. ++ */ ++ extern DSP_STATUS DEV_GetChnlMgr(struct DEV_OBJECT *hDevObject, ++ OUT struct CHNL_MGR **phMgr); ++ ++/* ++ * ======== DEV_GetCmmMgr ======== ++ * Purpose: ++ * Retrieve the handle to the shared memory manager created for this ++ * device. ++ * Parameters: ++ * hDevObject: Handle to device object created with ++ * DEV_CreateDevice(). ++ * *phMgr: Ptr to location to store handle. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hDevObject. ++ * Requires: ++ * phMgr != NULL. ++ * DEV Initialized. ++ * Ensures: ++ * DSP_SOK: *phMgr contains a handle to a channel manager object, ++ * or NULL. ++ * else: *phMgr is NULL. ++ */ ++ extern DSP_STATUS DEV_GetCmmMgr(struct DEV_OBJECT *hDevObject, ++ OUT struct CMM_OBJECT **phMgr); ++ ++/* ++ * ======== DEV_GetDmmMgr ======== ++ * Purpose: ++ * Retrieve the handle to the dynamic memory manager created for this ++ * device. ++ * Parameters: ++ * hDevObject: Handle to device object created with ++ * DEV_CreateDevice(). ++ * *phMgr: Ptr to location to store handle. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hDevObject. ++ * Requires: ++ * phMgr != NULL. ++ * DEV Initialized. ++ * Ensures: ++ * DSP_SOK: *phMgr contains a handle to a channel manager object, ++ * or NULL. ++ * else: *phMgr is NULL. ++ */ ++ extern DSP_STATUS DEV_GetDmmMgr(struct DEV_OBJECT *hDevObject, ++ OUT struct DMM_OBJECT **phMgr); ++ ++/* ++ * ======== DEV_GetCodMgr ======== ++ * Purpose: ++ * Retrieve the COD manager create for this device. ++ * Parameters: ++ * hDevObject: Handle to device object created with ++ * DEV_CreateDevice(). ++ * *phCodMgr: Ptr to location to store handle. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hDevObject. ++ * Requires: ++ * phCodMgr != NULL. ++ * DEV Initialized. ++ * Ensures: ++ * DSP_SOK: *phCodMgr contains a handle to a COD manager object. ++ * else: *phCodMgr is NULL. ++ */ ++ extern DSP_STATUS DEV_GetCodMgr(struct DEV_OBJECT *hDevObject, ++ OUT struct COD_MANAGER **phCodMgr); ++ ++/* ++ * ======== DEV_GetDehMgr ======== ++ * Purpose: ++ * Retrieve the DEH manager created for this device. ++ * Parameters: ++ * hDevObject: Handle to device object created with DEV_CreateDevice(). ++ * *phDehMgr: Ptr to location to store handle. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hDevObject. ++ * Requires: ++ * phDehMgr != NULL. ++ * DEH Initialized. ++ * Ensures: ++ * DSP_SOK: *phDehMgr contains a handle to a DEH manager object. ++ * else: *phDehMgr is NULL. ++ */ ++ extern DSP_STATUS DEV_GetDehMgr(struct DEV_OBJECT *hDevObject, ++ OUT struct DEH_MGR **phDehMgr); ++ ++/* ++ * ======== DEV_GetDevNode ======== ++ * Purpose: ++ * Retrieve the platform specific device ID for this device. ++ * Parameters: ++ * hDevObject: Handle to device object created with ++ * DEV_CreateDevice(). ++ * phDevNode: Ptr to location to get the device node handle. ++ * Returns: ++ * DSP_SOK: In Win95, returns a DEVNODE in *hDevNode; In NT, ??? ++ * DSP_EHANDLE: Invalid hDevObject. ++ * Requires: ++ * phDevNode != NULL. ++ * DEV Initialized. ++ * Ensures: ++ * DSP_SOK: *phDevNode contains a platform specific device ID; ++ * else: *phDevNode is NULL. ++ */ ++ extern DSP_STATUS DEV_GetDevNode(struct DEV_OBJECT *hDevObject, ++ OUT struct CFG_DEVNODE **phDevNode); ++ ++/* ++ * ======== DEV_GetDevType ======== ++ * Purpose: ++ * Retrieve the platform specific device ID for this device. ++ * Parameters: ++ * hDevObject: Handle to device object created with ++ * DEV_CreateDevice(). ++ * phDevNode: Ptr to location to get the device node handle. ++ * Returns: ++ * DSP_SOK: Success ++ * DSP_EHANDLE: Invalid hDevObject. ++ * Requires: ++ * phDevNode != NULL. ++ * DEV Initialized. ++ * Ensures: ++ * DSP_SOK: *phDevNode contains a platform specific device ID; ++ * else: *phDevNode is NULL. ++ */ ++ extern DSP_STATUS DEV_GetDevType(struct DEV_OBJECT *hdevObject, ++ u32 *devType); ++ ++/* ++ * ======== DEV_GetFirst ======== ++ * Purpose: ++ * Retrieve the first Device Object handle from an internal linked list of ++ * of DEV_OBJECTs maintained by DEV. ++ * Parameters: ++ * Returns: ++ * NULL if there are no device objects stored; else ++ * a valid DEV_HOBJECT. ++ * Requires: ++ * No calls to DEV_CreateDevice or DEV_DestroyDevice (which my modify the ++ * internal device object list) may occur between calls to DEV_GetFirst ++ * and DEV_GetNext. ++ * Ensures: ++ * The DEV_HOBJECT returned is valid. ++ * A subsequent call to DEV_GetNext will return the next device object in ++ * the list. ++ */ ++ extern struct DEV_OBJECT *DEV_GetFirst(void); ++ ++/* ++ * ======== DEV_GetIntfFxns ======== ++ * Purpose: ++ * Retrieve the WMD interface function structure for the loaded WMD. ++ * Parameters: ++ * hDevObject: Handle to device object created with ++ * DEV_CreateDevice(). ++ * *ppIntfFxns: Ptr to location to store fxn interface. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hDevObject. ++ * Requires: ++ * ppIntfFxns != NULL. ++ * DEV Initialized. ++ * Ensures: ++ * DSP_SOK: *ppIntfFxns contains a pointer to the WMD interface; ++ * else: *ppIntfFxns is NULL. ++ */ ++ extern DSP_STATUS DEV_GetIntfFxns(struct DEV_OBJECT *hDevObject, ++ OUT struct WMD_DRV_INTERFACE **ppIntfFxns); ++ ++/* ++ * ======== DEV_GetIOMgr ======== ++ * Purpose: ++ * Retrieve the handle to the IO manager created for this device. ++ * Parameters: ++ * hDevObject: Handle to device object created with ++ * DEV_CreateDevice(). ++ * *phMgr: Ptr to location to store handle. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hDevObject. ++ * Requires: ++ * phMgr != NULL. ++ * DEV Initialized. ++ * Ensures: ++ * DSP_SOK: *phMgr contains a handle to an IO manager object. ++ * else: *phMgr is NULL. ++ */ ++ extern DSP_STATUS DEV_GetIOMgr(struct DEV_OBJECT *hDevObject, ++ OUT struct IO_MGR **phMgr); ++ ++/* ++ * ======== DEV_GetNext ======== ++ * Purpose: ++ * Retrieve the next Device Object handle from an internal linked list of ++ * of DEV_OBJECTs maintained by DEV, after having previously called ++ * DEV_GetFirst() and zero or more DEV_GetNext ++ * Parameters: ++ * hDevObject: Handle to the device object returned from a previous ++ * call to DEV_GetFirst() or DEV_GetNext(). ++ * Returns: ++ * NULL if there are no further device objects on the list or hDevObject ++ * was invalid; ++ * else the next valid DEV_HOBJECT in the list. ++ * Requires: ++ * No calls to DEV_CreateDevice or DEV_DestroyDevice (which my modify the ++ * internal device object list) may occur between calls to DEV_GetFirst ++ * and DEV_GetNext. ++ * Ensures: ++ * The DEV_HOBJECT returned is valid. ++ * A subsequent call to DEV_GetNext will return the next device object in ++ * the list. ++ */ ++ extern struct DEV_OBJECT *DEV_GetNext(struct DEV_OBJECT ++ *hDevObject); ++ ++/* ++ * ========= DEV_GetMsgMgr ======== ++ * Purpose: ++ * Retrieve the MSG Manager Handle from the DevObject. ++ * Parameters: ++ * hDevObject: Handle to the Dev Object ++ * phMsgMgr: Location where MSG Manager handle will be returned. ++ * Returns: ++ * Requires: ++ * DEV Initialized. ++ * Valid hDevObject. ++ * phNodeMgr != NULL. ++ * Ensures: ++ */ ++ extern void DEV_GetMsgMgr(struct DEV_OBJECT *hDevObject, ++ OUT struct MSG_MGR **phMsgMgr); ++ ++/* ++ * ========= DEV_GetNodeManager ======== ++ * Purpose: ++ * Retrieve the Node Manager Handle from the DevObject. It is an ++ * accessor function ++ * Parameters: ++ * hDevObject: Handle to the Dev Object ++ * phNodeMgr: Location where Handle to the Node Manager will be ++ * returned.. ++ * Returns: ++ * DSP_SOK: Success ++ * DSP_EHANDLE: Invalid Dev Object handle. ++ * Requires: ++ * DEV Initialized. ++ * phNodeMgr is not null ++ * Ensures: ++ * DSP_SOK: *phNodeMgr contains a handle to a Node manager object. ++ * else: *phNodeMgr is NULL. ++ */ ++ extern DSP_STATUS DEV_GetNodeManager(struct DEV_OBJECT ++ *hDevObject, ++ OUT struct NODE_MGR **phNodeMgr); ++ ++/* ++ * ======== DEV_GetSymbol ======== ++ * Purpose: ++ * Get the value of a symbol in the currently loaded program. ++ * Parameters: ++ * hDevObject: Handle to device object created with ++ * DEV_CreateDevice(). ++ * pstrSym: Name of symbol to look up. ++ * pulValue: Ptr to symbol value. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hDevObject. ++ * COD_E_NOSYMBOLSLOADED: Symbols have not been loaded onto the board. ++ * COD_E_SYMBOLNOTFOUND: The symbol could not be found. ++ * Requires: ++ * pstrSym != NULL. ++ * pulValue != NULL. ++ * DEV Initialized. ++ * Ensures: ++ * DSP_SOK: *pulValue contains the symbol value; ++ */ ++ extern DSP_STATUS DEV_GetSymbol(struct DEV_OBJECT *hDevObject, ++ IN CONST char *pstrSym, ++ OUT u32 *pulValue); ++ ++/* ++ * ======== DEV_GetWMDContext ======== ++ * Purpose: ++ * Retrieve the WMD Context handle, as returned by the WMD_Create fxn. ++ * Parameters: ++ * hDevObject: Handle to device object created with DEV_CreateDevice() ++ * *phWmdContext: Ptr to location to store context handle. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hDevObject. ++ * Requires: ++ * phWmdContext != NULL. ++ * DEV Initialized. ++ * Ensures: ++ * DSP_SOK: *phWmdContext contains context handle; ++ * else: *phWmdContext is NULL; ++ */ ++ extern DSP_STATUS DEV_GetWMDContext(struct DEV_OBJECT *hDevObject, ++ OUT struct WMD_DEV_CONTEXT **phWmdContext); ++ ++/* ++ * ======== DEV_Exit ======== ++ * Purpose: ++ * Decrement reference count, and free resources when reference count is ++ * 0. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * DEV is initialized. ++ * Ensures: ++ * When reference count == 0, DEV's private resources are freed. ++ */ ++ extern void DEV_Exit(void); ++ ++/* ++ * ======== DEV_Init ======== ++ * Purpose: ++ * Initialize DEV's private state, keeping a reference count on each call. ++ * Parameters: ++ * Returns: ++ * TRUE if initialized; FALSE if error occured. ++ * Requires: ++ * Ensures: ++ * TRUE: A requirement for the other public DEV functions. ++ */ ++ extern bool DEV_Init(void); ++ ++/* ++ * ======== DEV_IsLocked ======== ++ * Purpose: ++ * Predicate function to determine if the device has been ++ * locked by a client for exclusive access. ++ * Parameters: ++ * hDevObject: Handle to device object created with ++ * DEV_CreateDevice(). ++ * Returns: ++ * DSP_SOK: TRUE: device has been locked. ++ * DSP_SFALSE: FALSE: device not locked. ++ * DSP_EHANDLE: hDevObject was invalid. ++ * Requires: ++ * DEV Initialized. ++ * Ensures: ++ */ ++ extern DSP_STATUS DEV_IsLocked(IN struct DEV_OBJECT *hDevObject); ++ ++/* ++ * ======== DEV_InsertProcObject ======== ++ * Purpose: ++ * Inserts the Processor Object into the List of PROC Objects ++ * kept in the DEV Object ++ * Parameters: ++ * hProcObject: Handle to the Proc Object ++ * hDevObject Handle to the Dev Object ++ * bAttachedNew Specifies if there are already processors attached ++ * Returns: ++ * DSP_SOK: Successfully inserted into the list ++ * Requires: ++ * hProcObject is not NULL ++ * hDevObject is a valid handle to the DEV. ++ * DEV Initialized. ++ * List(of Proc object in Dev) Exists. ++ * Ensures: ++ * DSP_SOK & the PROC Object is inserted and the list is not empty ++ * Details: ++ * If the List of Proc Object is empty bAttachedNew is TRUE, it indicated ++ * this is the first Processor attaching. ++ * If it is False, there are already processors attached. ++ */ ++ extern DSP_STATUS DEV_InsertProcObject(IN struct DEV_OBJECT ++ *hDevObject, ++ IN u32 hProcObject, ++ OUT bool * ++ pbAlreadyAttached); ++ ++/* ++ * ======== DEV_RemoveProcObject ======== ++ * Purpose: ++ * Search for and remove a Proc object from the given list maintained ++ * by the DEV ++ * Parameters: ++ * pProcObject: Ptr to ProcObject to insert. ++ * pDevObject: Ptr to Dev Object where the list is. ++ * pbAlreadyAttached: Ptr to return the bool ++ * Returns: ++ * DSP_SOK: If successful. ++ * DSP_EFAIL Failure to Remove the PROC Object from the list ++ * Requires: ++ * DevObject is Valid ++ * hProcObject != 0 ++ * pDevObject->procList != NULL ++ * !LST_IsEmpty(pDevObject->procList) ++ * pbAlreadyAttached !=NULL ++ * Ensures: ++ * Details: ++ * List will be deleted when the DEV is destroyed. ++ * ++ */ ++ extern DSP_STATUS DEV_RemoveProcObject(struct DEV_OBJECT ++ *hDevObject, ++ u32 hProcObject); ++ ++/* ++ * ======== DEV_NotifyClients ======== ++ * Purpose: ++ * Notify all clients of this device of a change in device status. ++ * Clients may include multiple users of BRD, as well as CHNL. ++ * This function is asychronous, and may be called by a timer event ++ * set up by a watchdog timer. ++ * Parameters: ++ * hDevObject: Handle to device object created with DEV_CreateDevice(). ++ * ulStatus: A status word, most likely a BRD_STATUS. ++ * Returns: ++ * DSP_SOK: All registered clients were asynchronously notified. ++ * DSP_EINVALIDARG: Invalid hDevObject. ++ * Requires: ++ * DEV Initialized. ++ * Ensures: ++ * DSP_SOK: Notifications are queued by the operating system to be ++ * delivered to clients. This function does not ensure that ++ * the notifications will ever be delivered. ++ */ ++ extern DSP_STATUS DEV_NotifyClients(struct DEV_OBJECT *hDevObject, ++ u32 ulStatus); ++ ++ ++ ++/* ++ * ======== DEV_RemoveDevice ======== ++ * Purpose: ++ * Destroys the Device Object created by DEV_StartDevice. ++ * Parameters: ++ * hDevNode: Device node as it is know to OS. ++ * Returns: ++ * DSP_SOK: If success; ++ * Otherwise. ++ * Requires: ++ * Ensures: ++ */ ++ extern DSP_STATUS DEV_RemoveDevice(struct CFG_DEVNODE *hDevNode); ++ ++/* ++ * ======== DEV_SetChnlMgr ======== ++ * Purpose: ++ * Set the channel manager for this device. ++ * Parameters: ++ * hDevObject: Handle to device object created with ++ * DEV_CreateDevice(). ++ * hMgr: Handle to a channel manager, or NULL. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hDevObject. ++ * Requires: ++ * DEV Initialized. ++ * Ensures: ++ */ ++ extern DSP_STATUS DEV_SetChnlMgr(struct DEV_OBJECT *hDevObject, ++ struct CHNL_MGR *hMgr); ++ ++/* ++ * ======== DEV_SetMsgMgr ======== ++ * Purpose: ++ * Set the Message manager for this device. ++ * Parameters: ++ * hDevObject: Handle to device object created with DEV_CreateDevice(). ++ * hMgr: Handle to a message manager, or NULL. ++ * Returns: ++ * Requires: ++ * DEV Initialized. ++ * Ensures: ++ */ ++ extern void DEV_SetMsgMgr(struct DEV_OBJECT *hDevObject, ++ struct MSG_MGR *hMgr); ++ ++/* ++ * ======== DEV_StartDevice ======== ++ * Purpose: ++ * Initializes the new device with the WinBRIDGE environment. This ++ * involves querying CM for allocated resources, querying the registry ++ * for necessary dsp resources (requested in the INF file), and using ++ * this information to create a WinBRIDGE device object. ++ * Parameters: ++ * hDevNode: Device node as it is know to OS. ++ * Returns: ++ * DSP_SOK: If success; ++ * Otherwise. ++ * Requires: ++ * DEV initialized. ++ * Ensures: ++ */ ++ extern DSP_STATUS DEV_StartDevice(struct CFG_DEVNODE *hDevNode); ++ ++#endif /* DEV_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/devdefs.h b/arch/arm/plat-omap/include/dspbridge/devdefs.h +new file mode 100644 +index 0000000..e9ff725 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/devdefs.h +@@ -0,0 +1,35 @@ ++/* ++ * devdefs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== devdefs.h ======== ++ * Purpose: ++ * Definition of common include typedef between wmd.h and dev.h. Required ++ * to break circular dependency between WMD and DEV include files. ++ * ++ *! Revision History: ++ *! ================ ++ *! 12-Nov-1996 gp: Renamed from dev1.h. ++ *! 30-May-1996 gp: Broke out from dev.h ++ */ ++ ++#ifndef DEVDEFS_ ++#define DEVDEFS_ ++ ++/* WCD Device Object */ ++ struct DEV_OBJECT; ++ ++#endif /* DEVDEFS_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/disp.h b/arch/arm/plat-omap/include/dspbridge/disp.h +new file mode 100644 +index 0000000..e116734 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/disp.h +@@ -0,0 +1,236 @@ ++/* ++ * disp.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== disp.h ======== ++ * ++ * Description: ++ * DSP/BIOS Bridge Node Dispatcher. ++ * ++ * Public Functions: ++ * DISP_Create ++ * DISP_Delete ++ * DISP_Exit ++ * DISP_Init ++ * DISP_NodeChangePriority ++ * DISP_NodeCreate ++ * DISP_NodeDelete ++ * DISP_NodeRun ++ * ++ *! Revision History: ++ *! ================= ++ *! 28-Jan-2003 map Removed DISP_DoCinit(). ++ *! 15-May-2002 jeh Added DISP_DoCinit(). ++ *! 24-Apr-2002 jeh Added DISP_MemWrite(). ++ *! 07-Sep-2001 jeh Added DISP_MemCopy(). ++ *! 10-May-2001 jeh Code review cleanup. ++ *! 08-Aug-2000 jeh Removed DISP_NodeTerminate since it no longer uses RMS. ++ *! 17-Jul-2000 jeh Updates to function headers. ++ *! 19-Jun-2000 jeh Created. ++ */ ++ ++#ifndef DISP_ ++#define DISP_ ++ ++#include ++#include ++#include ++#include ++ ++/* ++ * ======== DISP_Create ======== ++ * Create a NODE Dispatcher object. This object handles the creation, ++ * deletion, and execution of nodes on the DSP target, through communication ++ * with the Resource Manager Server running on the target. Each NODE ++ * Manager object should have exactly one NODE Dispatcher. ++ * ++ * Parameters: ++ * phDispObject: Location to store node dispatcher object on output. ++ * hDevObject: Device for this processor. ++ * pDispAttrs: Node dispatcher attributes. ++ * Returns: ++ * DSP_SOK: Success; ++ * DSP_EMEMORY: Insufficient memory for requested resources. ++ * DSP_EFAIL: Unable to create dispatcher. ++ * Requires: ++ * DISP_Init(void) called. ++ * pDispAttrs != NULL. ++ * hDevObject != NULL. ++ * phDispObject != NULL. ++ * Ensures: ++ * DSP_SOK: IsValid(*phDispObject). ++ * error: *phDispObject == NULL. ++ */ ++ extern DSP_STATUS DISP_Create(OUT struct DISP_OBJECT **phDispObject, ++ struct DEV_OBJECT *hDevObject, ++ IN CONST struct DISP_ATTRS *pDispAttrs); ++ ++/* ++ * ======== DISP_Delete ======== ++ * Delete the NODE Dispatcher. ++ * ++ * Parameters: ++ * hDispObject: Node Dispatcher object. ++ * Returns: ++ * Requires: ++ * DISP_Init(void) called. ++ * Valid hDispObject. ++ * Ensures: ++ * hDispObject is invalid. ++ */ ++ extern void DISP_Delete(struct DISP_OBJECT *hDispObject); ++ ++/* ++ * ======== DISP_Exit ======== ++ * Discontinue usage of DISP module. ++ * ++ * Parameters: ++ * Returns: ++ * Requires: ++ * DISP_Init(void) previously called. ++ * Ensures: ++ * Any resources acquired in DISP_Init(void) will be freed when last DISP ++ * client calls DISP_Exit(void). ++ */ ++ extern void DISP_Exit(void); ++ ++/* ++ * ======== DISP_Init ======== ++ * Initialize the DISP module. ++ * ++ * Parameters: ++ * Returns: ++ * TRUE if initialization succeeded, FALSE otherwise. ++ * Ensures: ++ */ ++ extern bool DISP_Init(void); ++ ++/* ++ * ======== DISP_NodeChangePriority ======== ++ * Change the priority of a node currently running on the target. ++ * ++ * Parameters: ++ * hDispObject: Node Dispatcher object. ++ * hNode: Node object representing a node currently ++ * allocated or running on the DSP. ++ * ulFxnAddress: Address of RMS function for changing priority. ++ * nodeEnv: Address of node's environment structure. ++ * nPriority: New priority level to set node's priority to. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_ETIMEOUT: A timeout occurred before the DSP responded. ++ * Requires: ++ * DISP_Init(void) called. ++ * Valid hDispObject. ++ * hNode != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS DISP_NodeChangePriority(struct DISP_OBJECT ++ *hDispObject, ++ struct NODE_OBJECT *hNode, ++ u32 ulFxnAddr, ++ NODE_ENV nodeEnv, ++ s32 nPriority); ++ ++/* ++ * ======== DISP_NodeCreate ======== ++ * Create a node on the DSP by remotely calling the node's create function. ++ * ++ * Parameters: ++ * hDispObject: Node Dispatcher object. ++ * hNode: Node handle obtained from NODE_Allocate(). ++ * ulFxnAddr: Address or RMS create node function. ++ * ulCreateFxn: Address of node's create function. ++ * pArgs: Arguments to pass to RMS node create function. ++ * pNodeEnv: Location to store node environment pointer on ++ * output. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_ETASK: Unable to create the node's task or process on the DSP. ++ * DSP_ESTREAM: Stream creation failure on the DSP. ++ * DSP_ETIMEOUT: A timeout occurred before the DSP responded. ++ * DSP_EUSER: A user-defined failure occurred. ++ * DSP_EFAIL: A failure occurred, unable to create node. ++ * Requires: ++ * DISP_Init(void) called. ++ * Valid hDispObject. ++ * pArgs != NULL. ++ * hNode != NULL. ++ * pNodeEnv != NULL. ++ * NODE_GetType(hNode) != NODE_DEVICE. ++ * Ensures: ++ */ ++ extern DSP_STATUS DISP_NodeCreate(struct DISP_OBJECT *hDispObject, ++ struct NODE_OBJECT *hNode, ++ u32 ulFxnAddr, ++ u32 ulCreateFxn, ++ IN CONST struct NODE_CREATEARGS ++ *pArgs, ++ OUT NODE_ENV *pNodeEnv); ++ ++/* ++ * ======== DISP_NodeDelete ======== ++ * Delete a node on the DSP by remotely calling the node's delete function. ++ * ++ * Parameters: ++ * hDispObject: Node Dispatcher object. ++ * hNode: Node object representing a node currently ++ * loaded on the DSP. ++ * ulFxnAddr: Address or RMS delete node function. ++ * ulDeleteFxn: Address of node's delete function. ++ * nodeEnv: Address of node's environment structure. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_ETIMEOUT: A timeout occurred before the DSP responded. ++ * Requires: ++ * DISP_Init(void) called. ++ * Valid hDispObject. ++ * hNode != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS DISP_NodeDelete(struct DISP_OBJECT *hDispObject, ++ struct NODE_OBJECT *hNode, ++ u32 ulFxnAddr, ++ u32 ulDeleteFxn, NODE_ENV nodeEnv); ++ ++/* ++ * ======== DISP_NodeRun ======== ++ * Start execution of a node's execute phase, or resume execution of a node ++ * that has been suspended (via DISP_NodePause()) on the DSP. ++ * ++ * Parameters: ++ * hDispObject: Node Dispatcher object. ++ * hNode: Node object representing a node to be executed ++ * on the DSP. ++ * ulFxnAddr: Address or RMS node execute function. ++ * ulExecuteFxn: Address of node's execute function. ++ * nodeEnv: Address of node's environment structure. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_ETIMEOUT: A timeout occurred before the DSP responded. ++ * Requires: ++ * DISP_Init(void) called. ++ * Valid hDispObject. ++ * hNode != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS DISP_NodeRun(struct DISP_OBJECT *hDispObject, ++ struct NODE_OBJECT *hNode, ++ u32 ulFxnAddr, ++ u32 ulExecuteFxn, NODE_ENV nodeEnv); ++ ++#endif /* DISP_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/dispdefs.h b/arch/arm/plat-omap/include/dspbridge/dispdefs.h +new file mode 100644 +index 0000000..401ad4f +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/dispdefs.h +@@ -0,0 +1,45 @@ ++/* ++ * dispdefs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== dispdefs.h ======== ++ * Description: ++ * Global DISP constants and types, shared by PROCESSOR, NODE, and DISP. ++ * ++ *! Revision History ++ *! ================ ++ *! 08-Aug-2000 jeh Added fields to DISP_ATTRS. ++ *! 06-Jul-2000 jeh Created. ++ */ ++ ++#ifndef DISPDEFS_ ++#define DISPDEFS_ ++ ++ struct DISP_OBJECT; ++ ++/* Node Dispatcher attributes */ ++ struct DISP_ATTRS { ++ u32 ulChnlOffset; /* Offset of channel ids reserved for RMS */ ++ /* Size of buffer for sending data to RMS */ ++ u32 ulChnlBufSize; ++ DSP_PROCFAMILY procFamily; /* eg, 5000 */ ++ DSP_PROCTYPE procType; /* eg, 5510 */ ++ HANDLE hReserved1; /* Reserved for future use. */ ++ u32 hReserved2; /* Reserved for future use. */ ++ } ; ++ ++#endif /* DISPDEFS_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/dmm.h b/arch/arm/plat-omap/include/dspbridge/dmm.h +new file mode 100644 +index 0000000..ef37668 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/dmm.h +@@ -0,0 +1,85 @@ ++/* ++ * dmm.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== dmm.h ======== ++ * Purpose: ++ * The Dynamic Memory Mapping(DMM) module manages the DSP Virtual address ++ * space that can be directly mapped to any MPU buffer or memory region ++ * ++ * Public Functions: ++ * ++ *! Revision History: ++ *! ================ ++ *! 20-Feb-2004 sb: Created. ++ *! ++ */ ++ ++#ifndef DMM_ ++#define DMM_ ++ ++#include ++ ++ struct DMM_OBJECT; ++ ++/* DMM attributes used in DMM_Create() */ ++ struct DMM_MGRATTRS { ++ u32 reserved; ++ } ; ++ ++#define DMMPOOLSIZE 0x4000000 ++ ++/* ++ * ======== DMM_GetHandle ======== ++ * Purpose: ++ * Return the dynamic memory manager object for this device. ++ * This is typically called from the client process. ++ */ ++ ++ extern DSP_STATUS DMM_GetHandle(DSP_HPROCESSOR hProcessor, ++ OUT struct DMM_OBJECT **phDmmMgr); ++ ++ extern DSP_STATUS DMM_ReserveMemory(struct DMM_OBJECT *hDmmMgr, ++ u32 size, ++ u32 *pRsvAddr); ++ ++ extern DSP_STATUS DMM_UnReserveMemory(struct DMM_OBJECT *hDmmMgr, ++ u32 rsvAddr); ++ ++ extern DSP_STATUS DMM_MapMemory(struct DMM_OBJECT *hDmmMgr, u32 addr, ++ u32 size); ++ ++ extern DSP_STATUS DMM_UnMapMemory(struct DMM_OBJECT *hDmmMgr, ++ u32 addr, ++ u32 *pSize); ++ ++ extern DSP_STATUS DMM_Destroy(struct DMM_OBJECT *hDmmMgr); ++ ++ extern DSP_STATUS DMM_DeleteTables(struct DMM_OBJECT *hDmmMgr); ++ ++ extern DSP_STATUS DMM_Create(OUT struct DMM_OBJECT **phDmmMgr, ++ struct DEV_OBJECT *hDevObject, ++ IN CONST struct DMM_MGRATTRS *pMgrAttrs); ++ ++ extern bool DMM_Init(void); ++ ++ extern void DMM_Exit(void); ++ ++ extern DSP_STATUS DMM_CreateTables(struct DMM_OBJECT *hDmmMgr, ++ u32 addr, u32 size); ++ extern u32 *DMM_GetPhysicalAddrTable(void); ++#endif /* DMM_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/dpc.h b/arch/arm/plat-omap/include/dspbridge/dpc.h +new file mode 100644 +index 0000000..8c20506 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/dpc.h +@@ -0,0 +1,167 @@ ++/* ++ * dpc.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== dpc.h ======== ++ * Purpose: ++ * Deferred Procedure Call(DPC) Services. ++ * ++ * Public Functions: ++ * DPC_Cancel ++ * DPC_Create ++ * DPC_Destroy ++ * DPC_Exit ++ * DPC_Init ++ * DPC_Schedule ++ * ++ *! Revision History: ++ *! ================ ++ *! 31-Jan-2000 rr: DPC_Destroy ensures Suceess and DPC Object is NULL. ++ *! 21-Jan-2000 ag: Updated comments per code review. ++ *! 06-Jan-2000 ag: Removed DPC_[Lower|Raise]IRQL[From|To]DispatchLevel. ++ *! 14-Jan-1998 gp: Added DPC_[Lower|Raise]IRQL[From|To]DispatchLevel. ++ *! 18-Aug-1997 cr: Added explicit CDECL identifiers. ++ *! 28-Jul-1996 gp: Created. ++ */ ++ ++#ifndef DPC_ ++#define DPC_ ++ ++ struct DPC_OBJECT; ++ ++/* ++ * ======== DPC_PROC ======== ++ * Purpose: ++ * Deferred processing routine. Typically scheduled from an ISR to ++ * complete I/O processing. ++ * Parameters: ++ * pRefData: Ptr to user data: passed in via ISR_ScheduleDPC. ++ * Returns: ++ * Requires: ++ * The DPC should not block, or otherwise acquire resources. ++ * Interrupts to the processor are enabled. ++ * DPC_PROC executes in a critical section. ++ * Ensures: ++ * This DPC will not be reenterred on the same thread. ++ * However, the DPC may take hardware interrupts during execution. ++ * Interrupts to the processor are enabled. ++ */ ++ typedef void(*DPC_PROC) (void *pRefData); ++ ++/* ++ * ======== DPC_Cancel ======== ++ * Purpose: ++ * Cancel a DPC previously scheduled by DPC_Schedule. ++ * Parameters: ++ * hDPC: A DPC object handle created in DPC_Create(). ++ * Returns: ++ * DSP_SOK: Scheduled DPC, if any, is cancelled. ++ * DSP_SFALSE: No DPC is currently scheduled for execution. ++ * DSP_EHANDLE: Invalid hDPC. ++ * Requires: ++ * Ensures: ++ * If the DPC has already executed, is executing, or was not yet ++ * scheduled, this function will have no effect. ++ */ ++ extern DSP_STATUS DPC_Cancel(IN struct DPC_OBJECT *hDPC); ++ ++/* ++ * ======== DPC_Create ======== ++ * Purpose: ++ * Create a DPC object, allowing a client's own DPC procedure to be ++ * scheduled for a call with client reference data. ++ * Parameters: ++ * phDPC: Pointer to location to store DPC object. ++ * pfnDPC: Client's DPC procedure. ++ * pRefData: Pointer to user-defined reference data. ++ * Returns: ++ * DSP_SOK: DPC object created. ++ * DSP_EPOINTER: phDPC == NULL or pfnDPC == NULL. ++ * DSP_EMEMORY: Insufficient memory. ++ * Requires: ++ * Must not be called at interrupt time. ++ * Ensures: ++ * DSP_SOK: DPC object is created; ++ * else: *phDPC is set to NULL. ++ */ ++ extern DSP_STATUS DPC_Create(OUT struct DPC_OBJECT **phDPC, ++ IN DPC_PROC pfnDPC, ++ IN void *pRefData); ++ ++/* ++ * ======== DPC_Destroy ======== ++ * Purpose: ++ * Cancel the last scheduled DPC, and deallocate a DPC object previously ++ * allocated with DPC_Create().Frees the Object only if the thread and ++ * the events are terminated successfuly. ++ * Parameters: ++ * hDPC: A DPC object handle created in DPC_Create(). ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hDPC. ++ * Requires: ++ * All DPC's scheduled for the DPC object must have completed their ++ * processing. ++ * Ensures: ++ * (SUCCESS && hDPC is NULL) or DSP_EFAILED status ++ */ ++ extern DSP_STATUS DPC_Destroy(IN struct DPC_OBJECT *hDPC); ++ ++/* ++ * ======== DPC_Exit ======== ++ * Purpose: ++ * Discontinue usage of the DPC module. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * DPC_Init(void) was previously called. ++ * Ensures: ++ * Resources acquired in DPC_Init(void) are freed. ++ */ ++ extern void DPC_Exit(void); ++ ++/* ++ * ======== DPC_Init ======== ++ * Purpose: ++ * Initialize the DPC module's private state. ++ * Parameters: ++ * Returns: ++ * TRUE if initialized; FALSE if error occured. ++ * Requires: ++ * Ensures: ++ * A requirement for each of the other public DPC functions. ++ */ ++ extern bool DPC_Init(void); ++ ++/* ++ * ======== DPC_Schedule ======== ++ * Purpose: ++ * Schedule a deferred procedure call to be executed at a later time. ++ * Latency and order of DPC execution is platform specific. ++ * Parameters: ++ * hDPC: A DPC object handle created in DPC_Create(). ++ * Returns: ++ * DSP_SOK: An event is scheduled for deferred processing. ++ * DSP_EHANDLE: Invalid hDPC. ++ * Requires: ++ * See requirements for DPC_PROC. ++ * Ensures: ++ * DSP_SOK: The DPC will not be called before this function returns. ++ */ ++ extern DSP_STATUS DPC_Schedule(IN struct DPC_OBJECT *hDPC); ++ ++#endif /* DPC_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/drv.h b/arch/arm/plat-omap/include/dspbridge/drv.h +new file mode 100644 +index 0000000..c468461 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/drv.h +@@ -0,0 +1,449 @@ ++/* ++ * drv.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== drv.h ======== ++ * Purpose: ++ * DRV Resource allocation module. Driver Object gets Created ++ * at the time of Loading. It holds the List of Device Objects ++ * in the Syste, ++ * ++ * Public Functions: ++ * DRV_Create ++ * DRV_Destroy ++ * DRV_Exit ++ * DRV_GetDevObject ++ * DRV_GetDevExtension ++ * DRV_GetFirstDevObject ++ * DRV_GetNextDevObject ++ * DRV_GetNextDevExtension ++ * DRV_Init ++ * DRV_InsertDevObject ++ * DRV_RemoveDevObject ++ * DRV_RequestResources ++ * DRV_ReleaseResources ++ * ++ *! Revision History ++ *! ================ ++ *! 10-Feb-2004 vp: Added OMAP24xx specific definitions. ++ *! 14-Aug-2000 rr: Cleaned up. ++ *! 27-Jul-2000 rr: DRV_RequestResources split into two(Request and Release) ++ *! Device extension created to hold the DevNodeString. ++ *! 17-Jul-2000 rr: Driver Object holds the list of Device Objects. ++ *! Added DRV_Create, DRV_Destroy, DRV_GetDevObject, ++ *! DRV_GetFirst/NextDevObject, DRV_Insert/RemoveDevObject. ++ *! 12-Nov-1999 rr: New Flag defines for DRV_ASSIGN and DRV_RELEASE ++ *! 25-Oct-1999 rr: Resource Structure removed. ++ *! 15-Oct-1999 rr: New Resource structure created. ++ *! 05-Oct-1999 rr: Added DRV_RequestResources ++ *! Removed fxn'sDRV_RegisterMiniDriver(), ++ *! DRV_UnRegisterMiniDriver() ++ *! Removed Structures DSP_DRIVER & DRV_EXTENSION. ++ *! ++ *! 24-Sep-1999 rr: Added DRV_EXTENSION and DSP_DRIVER structures. ++ *! ++ */ ++ ++#ifndef DRV_ ++#define DRV_ ++ ++#include ++ ++#include ++ ++#define DRV_ASSIGN 1 ++#define DRV_RELEASE 0 ++ ++/* Provide the DSP Internal memory windows that can be accessed from L3 address ++ * space */ ++ ++#define OMAP_GEM_BASE 0x107F8000 ++#define OMAP_DSP_SIZE 0x00720000 ++ ++/* MEM1 is L2 RAM + L2 Cache space */ ++#define OMAP_DSP_MEM1_BASE 0x5C7F8000 ++#define OMAP_DSP_MEM1_SIZE 0x18000 ++#define OMAP_DSP_GEM1_BASE 0x107F8000 ++ ++ ++/* MEM2 is L1P RAM/CACHE space */ ++#define OMAP_DSP_MEM2_BASE 0x5CE00000 ++#define OMAP_DSP_MEM2_SIZE 0x8000 ++#define OMAP_DSP_GEM2_BASE 0x10E00000 ++ ++/* MEM3 is L1D RAM/CACHE space */ ++#define OMAP_DSP_MEM3_BASE 0x5CF04000 ++#define OMAP_DSP_MEM3_SIZE 0x14000 ++#define OMAP_DSP_GEM3_BASE 0x10F04000 ++ ++ ++#define OMAP_IVA2_PRM_BASE 0x48306000 ++#define OMAP_IVA2_PRM_SIZE 0x1000 ++ ++#define OMAP_IVA2_CM_BASE 0x48004000 ++#define OMAP_IVA2_CM_SIZE 0x1000 ++ ++#define OMAP_PER_CM_BASE 0x48005000 ++#define OMAP_PER_CM_SIZE 0x1000 ++ ++#define OMAP_PER_PRM_BASE 0x48307000 ++#define OMAP_PER_PRM_SIZE 0x1000 ++ ++#define OMAP_CORE_PRM_BASE 0x48306A00 ++#define OMAP_CORE_PRM_SIZE 0x1000 ++ ++#define OMAP_SYSC_BASE 0x48002000 ++#define OMAP_SYSC_SIZE 0x1000 ++ ++#define OMAP_MBOX_BASE 0x48094000 ++#define OMAP_MBOX_SIZE 0x1000 ++ ++#define OMAP_DMMU_BASE 0x5D000000 ++#define OMAP_DMMU_SIZE 0x1000 ++ ++#define OMAP_PRCM_VDD1_DOMAIN 1 ++#define OMAP_PRCM_VDD2_DOMAIN 2 ++ ++#ifndef RES_CLEANUP_DISABLE ++ ++/* GPP PROCESS CLEANUP Data structures */ ++ ++/* New structure (member of process context) abstracts NODE resource info */ ++struct NODE_RES_OBJECT { ++ DSP_HNODE hNode; ++ s32 nodeAllocated; /* Node status */ ++ s32 heapAllocated; /* Heap status */ ++ s32 streamsAllocated; /* Streams status */ ++ struct NODE_RES_OBJECT *next; ++} ; ++ ++/* New structure (member of process context) abstracts DMM resource info */ ++struct DMM_RES_OBJECT { ++ s32 dmmAllocated; /* DMM status */ ++ u32 ulMpuAddr; ++ u32 ulDSPAddr; ++ u32 ulDSPResAddr; ++ u32 dmmSize; ++ HANDLE hProcessor; ++ struct DMM_RES_OBJECT *next; ++} ; ++ ++/* New structure (member of process context) abstracts DMM resource info */ ++struct DSPHEAP_RES_OBJECT { ++ s32 heapAllocated; /* DMM status */ ++ u32 ulMpuAddr; ++ u32 ulDSPAddr; ++ u32 ulDSPResAddr; ++ u32 heapSize; ++ HANDLE hProcessor; ++ struct DSPHEAP_RES_OBJECT *next; ++} ; ++ ++/* New structure (member of process context) abstracts stream resource info */ ++struct STRM_RES_OBJECT { ++ s32 streamAllocated; /* Stream status */ ++ DSP_HSTREAM hStream; ++ u32 uNumBufs; ++ u32 uDir; ++ struct STRM_RES_OBJECT *next; ++} ; ++ ++/* Overall Bridge process resource usage state */ ++enum GPP_PROC_RES_STATE { ++ PROC_RES_ALLOCATED, ++ PROC_RES_FREED ++} ; ++ ++/* Process Context */ ++struct PROCESS_CONTEXT{ ++ /* Process State */ ++ enum GPP_PROC_RES_STATE resState; ++ ++ /* Process ID (Same as UNIX process ID) */ ++ u32 pid; ++ ++ /* Pointer to next process context ++ * (To maintain a linked list of process contexts) */ ++ struct PROCESS_CONTEXT *next; ++ ++ /* Processor info to which the process is related */ ++ DSP_HPROCESSOR hProcessor; ++ ++ /* DSP Node resources */ ++ struct NODE_RES_OBJECT *pNodeList; ++ ++ /* DMM resources */ ++ struct DMM_RES_OBJECT *pDMMList; ++ ++ /* DSP Heap resources */ ++ struct DSPHEAP_RES_OBJECT *pDSPHEAPList; ++ ++ /* Stream resources */ ++ struct STRM_RES_OBJECT *pSTRMList; ++} ; ++#endif ++ ++/* ++ * ======== DRV_Create ======== ++ * Purpose: ++ * Creates the Driver Object. This is done during the driver loading. ++ * There is only one Driver Object in the DSP/BIOS Bridge. ++ * Parameters: ++ * phDrvObject: Location to store created DRV Object handle. ++ * Returns: ++ * DSP_SOK: Sucess ++ * DSP_EMEMORY: Failed in Memory allocation ++ * DSP_EFAIL: General Failure ++ * Requires: ++ * DRV Initialized (cRefs > 0 ) ++ * phDrvObject != NULL. ++ * Ensures: ++ * DSP_SOK: - *phDrvObject is a valid DRV interface to the device. ++ * - List of DevObject Created and Initialized. ++ * - List of DevNode String created and intialized. ++ * - Registry is updated with the DRV Object. ++ * !DSP_SOK: DRV Object not created ++ * Details: ++ * There is one Driver Object for the Driver representing ++ * the driver itself. It contains the list of device ++ * Objects and the list of Device Extensions in the system. ++ * Also it can hold other neccessary ++ * information in its storage area. ++ */ ++ extern DSP_STATUS DRV_Create(struct DRV_OBJECT **phDrvObject); ++ ++/* ++ * ======== DRV_Destroy ======== ++ * Purpose: ++ * destroys the Dev Object list, DrvExt list ++ * and destroy the DRV object ++ * Called upon driver unLoading.or unsuccesful loading of the driver. ++ * Parameters: ++ * hDrvObject: Handle to Driver object . ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Failed to destroy DRV Object ++ * Requires: ++ * DRV Initialized (cRegs > 0 ) ++ * hDrvObject is not NULL and a valid DRV handle . ++ * List of DevObject is Empty. ++ * List of DrvExt is Empty ++ * Ensures: ++ * DSP_SOK: - DRV Object destroyed and hDrvObject is not a valid ++ * DRV handle. ++ * - Registry is updated with "0" as the DRV Object. ++ */ ++ extern DSP_STATUS DRV_Destroy(struct DRV_OBJECT *hDrvObject); ++ ++/* ++ * ======== DRV_Exit ======== ++ * Purpose: ++ * Exit the DRV module, freeing any modules initialized in DRV_Init. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * Ensures: ++ */ ++ extern void DRV_Exit(void); ++ ++/* ++ * ======== DRV_GetFirstDevObject ======== ++ * Purpose: ++ * Returns the Ptr to the FirstDev Object in the List ++ * Parameters: ++ * Requires: ++ * DRV Initialized ++ * Returns: ++ * dwDevObject: Ptr to the First Dev Object as a u32 ++ * 0 if it fails to retrieve the First Dev Object ++ * Ensures: ++ */ ++ extern u32 DRV_GetFirstDevObject(void); ++ ++/* ++ * ======== DRV_GetFirstDevExtension ======== ++ * Purpose: ++ * Returns the Ptr to the First Device Extension in the List ++ * Parameters: ++ * Requires: ++ * DRV Initialized ++ * Returns: ++ * dwDevExtension: Ptr to the First Device Extension as a u32 ++ * 0: Failed to Get the Device Extension ++ * Ensures: ++ */ ++ extern u32 DRV_GetFirstDevExtension(void); ++ ++/* ++ * ======== DRV_GetDevObject ======== ++ * Purpose: ++ * Given a index, returns a handle to DevObject from the list ++ * Parameters: ++ * hDrvObject: Handle to the Manager ++ * phDevObject: Location to store the Dev Handle ++ * Requires: ++ * DRV Initialized ++ * uIndex >= 0 ++ * hDrvObject is not NULL and Valid DRV Object ++ * phDevObject is not NULL ++ * Device Object List not Empty ++ * Returns: ++ * DSP_SOK: Success ++ * DSP_EFAIL: Failed to Get the Dev Object ++ * Ensures: ++ * DSP_SOK: *phDevObject != NULL ++ * DSP_EFAIL: *phDevObject = NULL ++ */ ++ extern DSP_STATUS DRV_GetDevObject(u32 uIndex, ++ struct DRV_OBJECT *hDrvObject, ++ struct DEV_OBJECT **phDevObject); ++ ++/* ++ * ======== DRV_GetNextDevObject ======== ++ * Purpose: ++ * Returns the Ptr to the Next Device Object from the the List ++ * Parameters: ++ * hDevObject: Handle to the Device Object ++ * Requires: ++ * DRV Initialized ++ * hDevObject != 0 ++ * Returns: ++ * dwDevObject: Ptr to the Next Dev Object as a u32 ++ * 0: If it fail to get the next Dev Object. ++ * Ensures: ++ */ ++ extern u32 DRV_GetNextDevObject(u32 hDevObject); ++ ++/* ++ * ======== DRV_GetNextDevExtension ======== ++ * Purpose: ++ * Returns the Ptr to the Next Device Extension from the the List ++ * Parameters: ++ * hDevExtension: Handle to the Device Extension ++ * Requires: ++ * DRV Initialized ++ * hDevExtension != 0. ++ * Returns: ++ * dwDevExtension: Ptr to the Next Dev Extension ++ * 0: If it fail to Get the next Dev Extension ++ * Ensures: ++ */ ++ extern u32 DRV_GetNextDevExtension(u32 hDevExtension); ++ ++/* ++ * ======== DRV_Init ======== ++ * Purpose: ++ * Initialize the DRV module. ++ * Parameters: ++ * Returns: ++ * TRUE if success; FALSE otherwise. ++ * Requires: ++ * Ensures: ++ */ ++ extern DSP_STATUS DRV_Init(void); ++ ++/* ++ * ======== DRV_InsertDevObject ======== ++ * Purpose: ++ * Insert a DeviceObject into the list of Driver object. ++ * Parameters: ++ * hDrvObject: Handle to DrvObject ++ * hDevObject: Handle to DeviceObject to insert. ++ * Returns: ++ * DSP_SOK: If successful. ++ * DSP_EFAIL: General Failure: ++ * Requires: ++ * hDrvObject != NULL and Valid DRV Handle. ++ * hDevObject != NULL. ++ * Ensures: ++ * DSP_SOK: Device Object is inserted and the List is not empty. ++ */ ++ extern DSP_STATUS DRV_InsertDevObject(struct DRV_OBJECT *hDrvObject, ++ struct DEV_OBJECT *hDevObject); ++ ++/* ++ * ======== DRV_RemoveDevObject ======== ++ * Purpose: ++ * Search for and remove a Device object from the given list of Device Obj ++ * objects. ++ * Parameters: ++ * hDrvObject: Handle to DrvObject ++ * hDevObject: Handle to DevObject to Remove ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Unable to find pDevObject. ++ * Requires: ++ * hDrvObject != NULL and a Valid DRV Handle. ++ * hDevObject != NULL. ++ * List exists and is not empty. ++ * Ensures: ++ * List either does not exist (NULL), or is not empty if it does exist. ++*/ ++ extern DSP_STATUS DRV_RemoveDevObject(struct DRV_OBJECT *hDrvObject, ++ struct DEV_OBJECT *hDevObject); ++ ++/* ++ * ======== DRV_RequestResources ======== ++ * Purpose: ++ * Assigns the Resources or Releases them. ++ * Parameters: ++ * dwContext: Path to the driver Registry Key. ++ * pDevNodeString: Ptr to DevNode String stored in the Device Ext. ++ * Returns: ++ * TRUE if success; FALSE otherwise. ++ * Requires: ++ * Ensures: ++ * The Resources are assigned based on Bus type. ++ * The hardware is initialized. Resource information is ++ * gathered from the Registry(ISA, PCMCIA)or scanned(PCI) ++ * Resource structure is stored in the registry which will be ++ * later used by the CFG module. ++ */ ++ extern DSP_STATUS DRV_RequestResources(IN u32 dwContext, ++ OUT u32 *pDevNodeString); ++ ++/* ++ * ======== DRV_ReleaseResources ======== ++ * Purpose: ++ * Assigns the Resources or Releases them. ++ * Parameters: ++ * dwContext: Path to the driver Registry Key. ++ * hDrvObject: Handle to the Driver Object. ++ * Returns: ++ * TRUE if success; FALSE otherwise. ++ * Requires: ++ * Ensures: ++ * The Resources are released based on Bus type. ++ * Resource structure is deleted from the registry ++ */ ++ extern DSP_STATUS DRV_ReleaseResources(IN u32 dwContext, ++ struct DRV_OBJECT *hDrvObject); ++ ++/* ++ * ======== DRV_ProcFreeDMMRes ======== ++ * Purpose: ++ * Actual DMM De-Allocation. ++ * Parameters: ++ * hPCtxt: Path to the driver Registry Key. ++ * Returns: ++ * DSP_SOK if success; ++ */ ++ ++ ++ extern DSP_STATUS DRV_ProcFreeDMMRes(HANDLE hPCtxt); ++ ++#endif /* DRV_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/drvdefs.h b/arch/arm/plat-omap/include/dspbridge/drvdefs.h +new file mode 100644 +index 0000000..ed86010 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/drvdefs.h +@@ -0,0 +1,34 @@ ++/* ++ * drvdefs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== drvdefs.h ======== ++ * Purpose: ++ * Definition of common include typedef between wmd.h and drv.h. ++ * ++ *! Revision History: ++ *! ================ ++ *! 17-Jul-2000 rr: Created ++ */ ++ ++#ifndef DRVDEFS_ ++#define DRVDEFS_ ++ ++/* WCD Driver Object */ ++ struct DRV_OBJECT; ++ ++#endif /* DRVDEFS_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/dspdrv.h b/arch/arm/plat-omap/include/dspbridge/dspdrv.h +new file mode 100644 +index 0000000..f500ffb +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/dspdrv.h +@@ -0,0 +1,106 @@ ++/* ++ * dspdrv.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== dspdrv.h ======== ++ * Purpose: ++ * This is the Stream Interface for the DDSP Class driver. ++ * All Device operations are performed via DeviceIOControl. ++ * Read, Seek and Write not used. ++ * ++ * Public Functions ++ * DSP_Close ++ * DSP_Deinit ++ * DSP_Init ++ * DSP_IOControl ++ * DSP_Open ++ * DSP_PowerUp ++ * DSP_PowerDown ++ * ++ *! Revision History ++ *! ================ ++ *! 28-Jan-2000 rr: Type void changed to Void. ++ *! 02-Dec-1999 rr: MAX_DEV define moved from wcdce.c file.Code cleaned up. ++ *! 12-Nov-1999 rr: "#include removed. ++ *! 05-Oct-1999 rr Renamed the file name to wcdce.h Removed Bus Specific ++ *! code and #defines to PCCARD.h. ++ *! 24-Sep-1999 rr Changed the DSP_COMMON_WINDOW_SIZE to 0x4000(16k) for the ++ *! Memory windows. ++ *! 16-Jul-1999 ag Adapted from rkw's CAC Bullet driver. ++ *! ++ */ ++ ++#if !defined __DSPDRV_h__ ++#define __DSPDRV_h__ ++ ++#define MAX_DEV 10 /* Max support of 10 devices */ ++ ++/* ++ * ======== DSP_Close ======== ++ * Purpose: ++ * Called when the client application/driver unloads the DDSP DLL. Upon ++ * unloading, the DDSP DLL will call CloseFile(). ++ * Parameters: ++ * dwDeviceContext: Handle returned by XXX_Open used to identify ++ * the open context of the device ++ * Returns: ++ * TRUE indicates the device is successfully closed. FALSE indicates ++ * otherwise. ++ * Requires: ++ * dwOpenContext!= NULL. ++ * Ensures:The Application instance owned objects are cleaned up. ++ */ ++extern bool DSP_Close(u32 dwDeviceContext); ++ ++/* ++ * ======== DSP_Deinit ======== ++ * Purpose: ++ * This function is called by Device Manager to de-initialize a device. ++ * This function is not called by applications. ++ * Parameters: ++ * dwDeviceContext:Handle to the device context. The XXX_Init function ++ * creates and returns this identifier. ++ * Returns: ++ * TRUE indicates the device successfully de-initialized. Otherwise it ++ * returns FALSE. ++ * Requires: ++ * dwDeviceContext!= NULL. For a built in device this should never ++ * get called. ++ * Ensures: ++ */ ++extern bool DSP_Deinit(u32 dwDeviceContext); ++ ++/* ++ * ======== DSP_Init ======== ++ * Purpose: ++ * This function is called by Device Manager to initialize a device. ++ * This function is not called by applications ++ * Parameters: ++ * dwContext: Specifies a pointer to a string containing the registry ++ * path to the active key for the stream interface driver. ++ * HKEY_LOCAL_MACHINE\Drivers\Active ++ * Returns: ++ * Returns a handle to the device context created. This is the our actual ++ * Device Object representing the DSP Device instance. ++ * Requires: ++ * Ensures: ++ * Succeeded: device context > 0 ++ * Failed: device Context = 0 ++ */ ++extern u32 DSP_Init(OUT u32 *initStatus); ++ ++#endif +diff --git a/arch/arm/plat-omap/include/dspbridge/dynamic_loader.h b/arch/arm/plat-omap/include/dspbridge/dynamic_loader.h +new file mode 100644 +index 0000000..ea5f77f +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/dynamic_loader.h +@@ -0,0 +1,505 @@ ++/* ++ * dynamic_loader.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++ ++#ifndef _DYNAMIC_LOADER_H_ ++#define _DYNAMIC_LOADER_H_ ++#include ++#include ++ ++/* ++ * Dynamic Loader ++ * ++ * The function of the dynamic loader is to load a "module" containing ++ * instructions for a "target" processor into that processor. In the process ++ * it assigns memory for the module, resolves symbol references made by the ++ * module, and remembers symbols defined by the module. ++ * ++ * The dynamic loader is parameterized for a particular system by 4 classes ++ * that supply the module and system specific functions it requires ++ */ ++ /* The read functions for the module image to be loaded */ ++ struct Dynamic_Loader_Stream; ++ ++ /* This class defines "host" symbol and support functions */ ++ struct Dynamic_Loader_Sym; ++ ++ /* This class defines the allocator for "target" memory */ ++ struct Dynamic_Loader_Allocate; ++ ++ /* This class defines the copy-into-target-memory functions */ ++ struct Dynamic_Loader_Initialize; ++ ++/* ++ * Option flags to modify the behavior of module loading ++ */ ++#define DLOAD_INITBSS 0x1 /* initialize BSS sections to zero */ ++#define DLOAD_BIGEND 0x2 /* require big-endian load module */ ++#define DLOAD_LITTLE 0x4 /* require little-endian load module */ ++ ++ typedef void *DLOAD_mhandle; /* module handle for loaded modules */ ++ ++/***************************************************************************** ++ * Procedure Dynamic_Load_Module ++ * ++ * Parameters: ++ * module The input stream that supplies the module image ++ * syms Host-side symbol table and malloc/free functions ++ * alloc Target-side memory allocation ++ * init Target-side memory initialization, or NULL for symbol read only ++ * options Option flags DLOAD_* ++ * mhandle A module handle for use with Dynamic_Unload ++ * ++ * Effect: ++ * The module image is read using *module. Target storage for the new image is ++ * obtained from *alloc. Symbols defined and referenced by the module are ++ * managed using *syms. The image is then relocated and references resolved ++ * as necessary, and the resulting executable bits are placed into target memory ++ * using *init. ++ * ++ * Returns: ++ * On a successful load, a module handle is placed in *mhandle, and zero is ++ * returned. On error, the number of errors detected is returned. Individual ++ * errors are reported during the load process using syms->Error_Report(). ++ *****************************************************************************/ ++ extern int Dynamic_Load_Module( ++ /* the source for the module image*/ ++ struct Dynamic_Loader_Stream *module, ++ /* host support for symbols and storage*/ ++ struct Dynamic_Loader_Sym *syms, ++ /* the target memory allocator*/ ++ struct Dynamic_Loader_Allocate *alloc, ++ /* the target memory initializer*/ ++ struct Dynamic_Loader_Initialize *init, ++ unsigned options, /* option flags*/ ++ /* the returned module handle*/ ++ DLOAD_mhandle *mhandle ++ ); ++ ++/***************************************************************************** ++ * Procedure Dynamic_Open_Module ++ * ++ * Parameters: ++ * module The input stream that supplies the module image ++ * syms Host-side symbol table and malloc/free functions ++ * alloc Target-side memory allocation ++ * init Target-side memory initialization, or NULL for symbol read only ++ * options Option flags DLOAD_* ++ * mhandle A module handle for use with Dynamic_Unload ++ * ++ * Effect: ++ * The module image is read using *module. Target storage for the new image is ++ * obtained from *alloc. Symbols defined and referenced by the module are ++ * managed using *syms. The image is then relocated and references resolved ++ * as necessary, and the resulting executable bits are placed into target memory ++ * using *init. ++ * ++ * Returns: ++ * On a successful load, a module handle is placed in *mhandle, and zero is ++ * returned. On error, the number of errors detected is returned. Individual ++ * errors are reported during the load process using syms->Error_Report(). ++ *****************************************************************************/ ++ extern int Dynamic_Open_Module( ++ /* the source for the module image */ ++ struct Dynamic_Loader_Stream *module, ++ /* host support for symbols and storage */ ++ struct Dynamic_Loader_Sym *syms, ++ /* the target memory allocator */ ++ struct Dynamic_Loader_Allocate *alloc, ++ /* the target memory initializer */ ++ struct Dynamic_Loader_Initialize *init, ++ unsigned options, /* option flags */ ++ /* the returned module handle */ ++ DLOAD_mhandle *mhandle ++ ); ++ ++/***************************************************************************** ++ * Procedure Dynamic_Unload_Module ++ * ++ * Parameters: ++ * mhandle A module handle from Dynamic_Load_Module ++ * syms Host-side symbol table and malloc/free functions ++ * alloc Target-side memory allocation ++ * ++ * Effect: ++ * The module specified by mhandle is unloaded. Unloading causes all ++ * target memory to be deallocated, all symbols defined by the module to ++ * be purged, and any host-side storage used by the dynamic loader for ++ * this module to be released. ++ * ++ * Returns: ++ * Zero for success. On error, the number of errors detected is returned. ++ * Individual errors are reported using syms->Error_Report(). ++ *****************************************************************************/ ++ extern int Dynamic_Unload_Module(DLOAD_mhandle mhandle, /* the module ++ * handle*/ ++ /* host support for symbols and ++ * storage */ ++ struct Dynamic_Loader_Sym *syms, ++ /* the target memory allocator*/ ++ struct Dynamic_Loader_Allocate *alloc, ++ /* the target memory initializer*/ ++ struct Dynamic_Loader_Initialize *init ++ ); ++ ++/***************************************************************************** ++ ***************************************************************************** ++ * A class used by the dynamic loader for input of the module image ++ ***************************************************************************** ++ *****************************************************************************/ ++ struct Dynamic_Loader_Stream { ++/* public: */ ++ /************************************************************************* ++ * read_buffer ++ * ++ * PARAMETERS : ++ * buffer Pointer to the buffer to fill ++ * bufsiz Amount of data desired in sizeof() units ++ * ++ * EFFECT : ++ * Reads the specified amount of data from the module input stream ++ * into the specified buffer. Returns the amount of data read in sizeof() ++ * units (which if less than the specification, represents an error). ++ * ++ * NOTES: ++ * In release 1 increments the file position by the number of bytes read ++ * ++ *************************************************************************/ ++ int (*read_buffer) (struct Dynamic_Loader_Stream *thisptr, ++ void *buffer, unsigned bufsiz); ++ ++ /************************************************************************* ++ * set_file_posn (release 1 only) ++ * ++ * PARAMETERS : ++ * posn Desired file position relative to start of file in sizeof() units. ++ * ++ * EFFECT : ++ * Adjusts the internal state of the stream object so that the next ++ * read_buffer call will begin to read at the specified offset from ++ * the beginning of the input module. Returns 0 for success, non-zero ++ * for failure. ++ * ++ *************************************************************************/ ++ int (*set_file_posn) (struct Dynamic_Loader_Stream *thisptr, ++ /* to be eliminated in release 2*/ ++ unsigned int posn); ++ ++ }; ++ ++/***************************************************************************** ++ ***************************************************************************** ++ * A class used by the dynamic loader for symbol table support and ++ * miscellaneous host-side functions ++ ***************************************************************************** ++ *****************************************************************************/ ++ ++ typedef u32 LDR_ADDR; ++ ++/* ++ * the structure of a symbol known to the dynamic loader ++ */ ++ struct dynload_symbol { ++ LDR_ADDR value; ++ } ; ++ ++ struct Dynamic_Loader_Sym { ++/* public: */ ++ /************************************************************************* ++ * Find_Matching_Symbol ++ * ++ * PARAMETERS : ++ * name The name of the desired symbol ++ * ++ * EFFECT : ++ * Locates a symbol matching the name specified. A pointer to the ++ * symbol is returned if it exists; 0 is returned if no such symbol is ++ * found. ++ * ++ *************************************************************************/ ++ struct dynload_symbol *(*Find_Matching_Symbol) ++ (struct Dynamic_Loader_Sym * ++ thisptr, ++ const char *name); ++ ++ /************************************************************************* ++ * Add_To_Symbol_Table ++ * ++ * PARAMETERS : ++ * nname Pointer to the name of the new symbol ++ * moduleid An opaque module id assigned by the dynamic loader ++ * ++ * EFFECT : ++ * The new symbol is added to the table. A pointer to the symbol is ++ * returned, or NULL is returned for failure. ++ * ++ * NOTES: ++ * It is permissible for this function to return NULL; the effect is that ++ * the named symbol will not be available to resolve references in ++ * subsequent loads. Returning NULL will not cause the current load ++ * to fail. ++ *************************************************************************/ ++ struct dynload_symbol *(*Add_To_Symbol_Table) ++ (struct Dynamic_Loader_Sym * ++ thisptr, ++ const char *nname, ++ unsigned moduleid); ++ ++ /************************************************************************* ++ * Purge_Symbol_Table ++ * ++ * PARAMETERS : ++ * moduleid An opaque module id assigned by the dynamic loader ++ * ++ * EFFECT : ++ * Each symbol in the symbol table whose moduleid matches the argument ++ * is removed from the table. ++ *************************************************************************/ ++ void (*Purge_Symbol_Table) (struct Dynamic_Loader_Sym *thisptr, ++ unsigned moduleid); ++ ++ /************************************************************************* ++ * Allocate ++ * ++ * PARAMETERS : ++ * memsiz size of desired memory in sizeof() units ++ * ++ * EFFECT : ++ * Returns a pointer to some "host" memory for use by the dynamic ++ * loader, or NULL for failure. ++ * This function is serves as a replaceable form of "malloc" to ++ * allow the user to configure the memory usage of the dynamic loader. ++ *************************************************************************/ ++ void *(*Allocate) (struct Dynamic_Loader_Sym *thisptr, ++ unsigned memsiz); ++ ++ /************************************************************************* ++ * Deallocate ++ * ++ * PARAMETERS : ++ * memptr pointer to previously allocated memory ++ * ++ * EFFECT : ++ * Releases the previously allocated "host" memory. ++ *************************************************************************/ ++ void (*Deallocate) (struct Dynamic_Loader_Sym *thisptr, ++ void *memptr); ++ ++ /************************************************************************* ++ * Error_Report ++ * ++ * PARAMETERS : ++ * errstr pointer to an error string ++ * args additional arguments ++ * ++ * EFFECT : ++ * This function provides an error reporting interface for the dynamic ++ * loader. The error string and arguments are designed as for the ++ * library function vprintf. ++ *************************************************************************/ ++ void (*Error_Report) (struct Dynamic_Loader_Sym *thisptr, ++ const char *errstr, va_list args); ++ ++ }; /* class Dynamic_Loader_Sym */ ++ ++/***************************************************************************** ++ ***************************************************************************** ++ * A class used by the dynamic loader to allocate and deallocate target memory. ++ ***************************************************************************** ++ *****************************************************************************/ ++ ++ struct LDR_SECTION_INFO { ++ /* Name of the memory section assigned at build time */ ++ const char *name; ++ LDR_ADDR run_addr; /* execution address of the section */ ++ LDR_ADDR load_addr; /* load address of the section */ ++ LDR_ADDR size; /* size of the section in addressable units */ ++#ifndef _BIG_ENDIAN ++ u16 page; /* memory page or view */ ++ u16 type; /* one of the section types below */ ++#else ++ u16 type; /* one of the section types below */ ++ u16 page; /* memory page or view */ ++#endif ++ /* a context field for use by Dynamic_Loader_Allocate; ++ * ignored but maintained by the dynamic loader */ ++ u32 context; ++ } ; ++ ++/* use this macro to extract type of section from LDR_SECTION_INFO.type field */ ++#define DLOAD_SECTION_TYPE(typeinfo) (typeinfo & 0xF) ++ ++/* type of section to be allocated */ ++#define DLOAD_TEXT 0 ++#define DLOAD_DATA 1 ++#define DLOAD_BSS 2 ++ /* internal use only, run-time cinit will be of type DLOAD_DATA */ ++#define DLOAD_CINIT 3 ++ ++ struct Dynamic_Loader_Allocate { ++/* public: */ ++ ++ /************************************************************************* ++ * Function allocate ++ * ++ * Parameters: ++ * info A pointer to an information block for the section ++ * align The alignment of the storage in target AUs ++ * ++ * Effect: ++ * Allocates target memory for the specified section and fills in the ++ * load_addr and run_addr fields of the section info structure. Returns TRUE ++ * for success, FALSE for failure. ++ * ++ * Notes: ++ * Frequently load_addr and run_addr are the same, but if they are not ++ * load_addr is used with Dynamic_Loader_Initialize, and run_addr is ++ * used for almost all relocations. This function should always initialize ++ * both fields. ++ *************************************************************************/ ++ int (*Allocate) (struct Dynamic_Loader_Allocate *thisptr, ++ struct LDR_SECTION_INFO *info, unsigned align); ++ ++ /************************************************************************* ++ * Function deallocate ++ * ++ * Parameters: ++ * info A pointer to an information block for the section ++ * ++ * Effect: ++ * Releases the target memory previously allocated. ++ * ++ * Notes: ++ * The content of the info->name field is undefined on call to this function. ++ *************************************************************************/ ++ void (*Deallocate) (struct Dynamic_Loader_Allocate *thisptr, ++ struct LDR_SECTION_INFO *info); ++ ++ }; /* class Dynamic_Loader_Allocate */ ++ ++/***************************************************************************** ++ ***************************************************************************** ++ * A class used by the dynamic loader to load data into a target. This class ++ * provides the interface-specific functions needed to load data. ++ ***************************************************************************** ++ *****************************************************************************/ ++ ++ struct Dynamic_Loader_Initialize { ++/* public: */ ++ /************************************************************************* ++ * Function connect ++ * ++ * Parameters: ++ * none ++ * ++ * Effect: ++ * Connect to the initialization interface. Returns TRUE for success, ++ * FALSE for failure. ++ * ++ * Notes: ++ * This function is called prior to use of any other functions in ++ * this interface. ++ *************************************************************************/ ++ int (*connect) (struct Dynamic_Loader_Initialize *thisptr); ++ ++ /************************************************************************* ++ * Function readmem ++ * ++ * Parameters: ++ * bufr Pointer to a word-aligned buffer for the result ++ * locn Target address of first data element ++ * info Section info for the section in which the address resides ++ * bytsiz Size of the data to be read in sizeof() units ++ * ++ * Effect: ++ * Fills the specified buffer with data from the target. Returns TRUE for ++ * success, FALSE for failure. ++ *************************************************************************/ ++ int (*readmem) (struct Dynamic_Loader_Initialize *thisptr, ++ void *bufr, ++ LDR_ADDR locn, ++ struct LDR_SECTION_INFO *info, ++ unsigned bytsiz); ++ ++ /************************************************************************* ++ * Function writemem ++ * ++ * Parameters: ++ * bufr Pointer to a word-aligned buffer of data ++ * locn Target address of first data element to be written ++ * info Section info for the section in which the address resides ++ * bytsiz Size of the data to be written in sizeof() units ++ * ++ * Effect: ++ * Writes the specified buffer to the target. Returns TRUE for success, ++ * FALSE for failure. ++ *************************************************************************/ ++ int (*writemem) (struct Dynamic_Loader_Initialize *thisptr, ++ void *bufr, ++ LDR_ADDR locn, ++ struct LDR_SECTION_INFO *info, ++ unsigned bytsiz); ++ ++ /************************************************************************* ++ * Function fillmem ++ * ++ * Parameters: ++ * locn Target address of first data element to be written ++ * info Section info for the section in which the address resides ++ * bytsiz Size of the data to be written in sizeof() units ++ * val Value to be written in each byte ++ * Effect: ++ * Fills the specified area of target memory. Returns TRUE for success, ++ * FALSE for failure. ++ *************************************************************************/ ++ int (*fillmem) (struct Dynamic_Loader_Initialize *thisptr, ++ LDR_ADDR locn, struct LDR_SECTION_INFO *info, ++ unsigned bytsiz, unsigned val); ++ ++ /************************************************************************* ++ * Function execute ++ * ++ * Parameters: ++ * start Starting address ++ * ++ * Effect: ++ * The target code at the specified starting address is executed. ++ * ++ * Notes: ++ * This function is called at the end of the dynamic load process ++ * if the input module has specified a starting address. ++ *************************************************************************/ ++ int (*execute) (struct Dynamic_Loader_Initialize *thisptr, ++ LDR_ADDR start); ++ ++ /************************************************************************* ++ * Function release ++ * ++ * Parameters: ++ * none ++ * ++ * Effect: ++ * Releases the connection to the load interface. ++ * ++ * Notes: ++ * This function is called at the end of the dynamic load process. ++ *************************************************************************/ ++ void (*release) (struct Dynamic_Loader_Initialize *thisptr); ++ ++ }; /* class Dynamic_Loader_Initialize */ ++ ++#endif /* _DYNAMIC_LOADER_H_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/errbase.h b/arch/arm/plat-omap/include/dspbridge/errbase.h +new file mode 100644 +index 0000000..f04c005 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/errbase.h +@@ -0,0 +1,509 @@ ++/* ++ * errbase.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== errbase.h ======== ++ * Description: ++ * Central repository for DSP/BIOS Bridge error and status code. ++ * ++ * Error codes are of the form: ++ * []_E ++ * ++ * Success codes are of the form: ++ * []_S ++ * ++ *! Revision History: ++ *! ================ ++ *! 24-Jan-2003 map Added DSP_SALREADYLOADED for persistent library checking ++ *! 23-Nov-2002 gp: Minor comment cleanup. ++ *! 13-May-2002 sg Added DSP_SALREADYASLEEP and DSP_SALREADYWAKE. ++ *! 18-Feb-2002 mk: Added DSP_EOVERLAYMEMORY, EFWRITE, ENOSECT. ++ *! 31-Jan-2002 mk: Added definitions of DSP_STRUE and DSP_SFALSE. ++ *! 29-Jan-2002 mk: Added definition of CFG_E_INSUFFICIENTBUFSIZE. ++ *! 24-Oct-2001 sp: Consolidated all the error codes into this file. ++ *! 24-Jul-2001 mk: Type-casted all definitions of WSX_STATUS types for ++ *! removal of compile warnings. ++ *! 22-Nov-1999 kc: Changes from code review. ++ *! 18-Aug-1999 rr: Ported From WSX. ++ *! 29-May-1996 gp: Removed WCD_ and WMD_ error ranges. Redefined format of ++ *! error codes. ++ *! 10-May-1996 gp: Created. ++ */ ++ ++#ifndef ERRBASE_ ++#define ERRBASE_ ++ ++/* Base of generic errors and component errors */ ++#define DSP_SBASE (DSP_STATUS)0x00008000 ++#define DSP_EBASE (DSP_STATUS)0x80008000 ++ ++#define DSP_COMP_EBASE (DSP_STATUS)0x80040200 ++#define DSP_COMP_ELAST (DSP_STATUS)0x80047fff ++ ++/* SUCCESS Codes */ ++ ++/* Generic success code */ ++#define DSP_SOK (DSP_SBASE + 0) ++ ++/* GPP is already attached to this DSP processor */ ++#define DSP_SALREADYATTACHED (DSP_SBASE + 1) ++ ++/* This is the last object available for enumeration. */ ++#define DSP_SENUMCOMPLETE (DSP_SBASE + 2) ++ ++/* The DSP is already asleep. */ ++#define DSP_SALREADYASLEEP (DSP_SBASE + 3) ++ ++/* The DSP is already awake. */ ++#define DSP_SALREADYAWAKE (DSP_SBASE + 4) ++ ++/* TRUE */ ++#define DSP_STRUE (DSP_SBASE + 5) ++ ++/* FALSE */ ++#define DSP_SFALSE (DSP_SBASE + 6) ++ ++/* A library contains no dependent library references */ ++#define DSP_SNODEPENDENTLIBS (DSP_SBASE + 7) ++ ++/* A persistent library is already loaded by the dynamic loader */ ++#define DSP_SALREADYLOADED (DSP_SBASE + 8) ++ ++/* Some error occured, but it is OK to continue */ ++#define DSP_OKTO_CONTINUE (DSP_SBASE + 9) ++ ++/* FAILURE Codes */ ++ ++/* The caller does not have access privileges to call this function */ ++#define DSP_EACCESSDENIED (DSP_EBASE + 0) ++ ++/* The Specified Connection already exists */ ++#define DSP_EALREADYCONNECTED (DSP_EBASE + 1) ++ ++/* The GPP must be detached from the DSP before this function is called */ ++#define DSP_EATTACHED (DSP_EBASE + 2) ++ ++/* During enumeration a change in the number or properties of the objects ++ * has occurred. */ ++#define DSP_ECHANGEDURINGENUM (DSP_EBASE + 3) ++ ++/* An error occurred while parsing the DSP executable file */ ++#define DSP_ECORRUPTFILE (DSP_EBASE + 4) ++ ++/* A failure occurred during a delete operation */ ++#define DSP_EDELETE (DSP_EBASE + 5) ++ ++/* The specified direction is invalid */ ++#define DSP_EDIRECTION (DSP_EBASE + 6) ++ ++/* A stream has been issued the maximum number of buffers allowed in the ++ * stream at once ; buffers must be reclaimed from the stream before any ++ * more can be issued. */ ++#define DSP_ESTREAMFULL (DSP_EBASE + 7) ++ ++/* A general failure occurred */ ++#define DSP_EFAIL (DSP_EBASE + 8) ++ ++/* The specified executable file could not be found. */ ++#define DSP_EFILE (DSP_EBASE + 9) ++ ++/* The specified handle is invalid. */ ++#define DSP_EHANDLE (DSP_EBASE + 0xa) ++ ++/* An invalid argument was specified. */ ++#define DSP_EINVALIDARG (DSP_EBASE + 0xb) ++ ++/* A memory allocation failure occurred. */ ++#define DSP_EMEMORY (DSP_EBASE + 0xc) ++ ++/* The requested operation is invalid for this node type. */ ++#define DSP_ENODETYPE (DSP_EBASE + 0xd) ++ ++/* No error text was found for the specified error code. */ ++#define DSP_ENOERRTEXT (DSP_EBASE + 0xe) ++ ++/* No more connections can be made for this node. */ ++#define DSP_ENOMORECONNECTIONS (DSP_EBASE + 0xf) ++ ++/* The indicated operation is not supported. */ ++#define DSP_ENOTIMPL (DSP_EBASE + 0x10) ++ ++/* I/O is currently pending. */ ++#define DSP_EPENDING (DSP_EBASE + 0x11) ++ ++/* An invalid pointer was specified. */ ++#define DSP_EPOINTER (DSP_EBASE + 0x12) ++ ++/* A parameter is specified outside its valid range. */ ++#define DSP_ERANGE (DSP_EBASE + 0x13) ++ ++/* An invalid size parameter was specified. */ ++#define DSP_ESIZE (DSP_EBASE + 0x14) ++ ++/* A stream creation failure occurred on the DSP. */ ++#define DSP_ESTREAM (DSP_EBASE + 0x15) ++ ++/* A task creation failure occurred on the DSP. */ ++#define DSP_ETASK (DSP_EBASE + 0x16) ++ ++/* A timeout occurred before the requested operation could complete. */ ++ ++#define DSP_ETIMEOUT (DSP_EBASE + 0x17) ++ ++/* A data truncation occurred, e.g., when requesting a descriptive error ++ * string, not enough space was allocated for the complete error message. */ ++ ++#define DSP_ETRUNCATED (DSP_EBASE + 0x18) ++ ++/* A parameter is invalid. */ ++#define DSP_EVALUE (DSP_EBASE + 0x1a) ++ ++/* The state of the specified object is incorrect for the requested ++ * operation. */ ++#define DSP_EWRONGSTATE (DSP_EBASE + 0x1b) ++ ++/* Symbol not found in the COFF file. DSPNode_Create will return this if ++ * the iAlg function table for an xDAIS socket is not found in the COFF file. ++ * In this case, force the symbol to be linked into the COFF file. ++ * DSPNode_Create, DSPNode_Execute, and DSPNode_Delete will return this if ++ * the create, execute, or delete phase function, respectively, could not be ++ * found in the COFF file. */ ++#define DSP_ESYMBOL (DSP_EBASE + 0x1c) ++ ++/* UUID not found in registry. */ ++#define DSP_EUUID (DSP_EBASE + 0x1d) ++ ++/* Unable to read content of DCD data section ; this is typically caused by ++ * improperly configured nodes. */ ++#define DSP_EDCDREADSECT (DSP_EBASE + 0x1e) ++ ++/* Unable to decode DCD data section content ; this is typically caused by ++ * changes to DSP/BIOS Bridge data structures. */ ++#define DSP_EDCDPARSESECT (DSP_EBASE + 0x1f) ++ ++/* Unable to get pointer to DCD data section ; this is typically caused by ++ * improperly configured UUIDs. */ ++#define DSP_EDCDGETSECT (DSP_EBASE + 0x20) ++ ++/* Unable to load file containing DCD data section ; this is typically ++ * caused by a missing COFF file. */ ++#define DSP_EDCDLOADBASE (DSP_EBASE + 0x21) ++ ++/* The specified COFF file does not contain a valid node registration ++ * section. */ ++#define DSP_EDCDNOAUTOREGISTER (DSP_EBASE + 0x22) ++ ++/* A requested resource is not available. */ ++#define DSP_ERESOURCE (DSP_EBASE + 0x28) ++ ++/* A critical error has occurred, and the DSP is being re-started. */ ++#define DSP_ERESTART (DSP_EBASE + 0x29) ++ ++/* A DSP memory free operation failed. */ ++#define DSP_EFREE (DSP_EBASE + 0x2a) ++ ++/* A DSP I/O free operation failed. */ ++#define DSP_EIOFREE (DSP_EBASE + 0x2b) ++ ++/* Multiple instances are not allowed. */ ++#define DSP_EMULINST (DSP_EBASE + 0x2c) ++ ++/* A specified entity was not found. */ ++#define DSP_ENOTFOUND (DSP_EBASE + 0x2d) ++ ++/* A DSP I/O resource is not available. */ ++#define DSP_EOUTOFIO (DSP_EBASE + 0x2e) ++ ++/* A shared memory buffer contained in a message or stream could not be ++ * mapped to the GPP client process's virtual space. */ ++#define DSP_ETRANSLATE (DSP_EBASE + 0x2f) ++ ++/* File or section load write function failed to write to DSP */ ++#define DSP_EFWRITE (DSP_EBASE + 0x31) ++ ++/* Unable to find a named section in DSP executable */ ++#define DSP_ENOSECT (DSP_EBASE + 0x32) ++ ++/* Unable to open file */ ++#define DSP_EFOPEN (DSP_EBASE + 0x33) ++ ++/* Unable to read file */ ++#define DSP_EFREAD (DSP_EBASE + 0x34) ++ ++/* A non-existent memory segment identifier was specified */ ++#define DSP_EOVERLAYMEMORY (DSP_EBASE + 0x37) ++ ++/* Invalid segment ID */ ++#define DSP_EBADSEGID (DSP_EBASE + 0x38) ++ ++/* Invalid alignment */ ++#define DSP_EALIGNMENT (DSP_EBASE + 0x39) ++ ++/* Invalid stream mode */ ++#define DSP_ESTRMMODE (DSP_EBASE + 0x3a) ++ ++/* Nodes not connected */ ++#define DSP_ENOTCONNECTED (DSP_EBASE + 0x3b) ++ ++/* Not shared memory */ ++#define DSP_ENOTSHAREDMEM (DSP_EBASE + 0x3c) ++ ++/* Error occurred in a dynamic loader library function */ ++#define DSP_EDYNLOAD (DSP_EBASE + 0x3d) ++ ++/* Device in 'sleep/suspend' mode due to DPM */ ++#define DSP_EDPMSUSPEND (DSP_EBASE + 0x3e) ++ ++/* A node-specific error has occurred. */ ++#define DSP_EUSER1 (DSP_EBASE + 0x40) ++#define DSP_EUSER2 (DSP_EBASE + 0x41) ++#define DSP_EUSER3 (DSP_EBASE + 0x42) ++#define DSP_EUSER4 (DSP_EBASE + 0x43) ++#define DSP_EUSER5 (DSP_EBASE + 0x44) ++#define DSP_EUSER6 (DSP_EBASE + 0x45) ++#define DSP_EUSER7 (DSP_EBASE + 0x46) ++#define DSP_EUSER8 (DSP_EBASE + 0x47) ++#define DSP_EUSER9 (DSP_EBASE + 0x48) ++#define DSP_EUSER10 (DSP_EBASE + 0x49) ++#define DSP_EUSER11 (DSP_EBASE + 0x4a) ++#define DSP_EUSER12 (DSP_EBASE + 0x4b) ++#define DSP_EUSER13 (DSP_EBASE + 0x4c) ++#define DSP_EUSER14 (DSP_EBASE + 0x4d) ++#define DSP_EUSER15 (DSP_EBASE + 0x4e) ++#define DSP_EUSER16 (DSP_EBASE + 0x4f) ++ ++/* FAILURE Codes : DEV */ ++#define DEV_EBASE (DSP_COMP_EBASE + 0x000) ++ ++/* The mini-driver expected a newer version of the class driver. */ ++#define DEV_E_NEWWMD (DEV_EBASE + 0x00) ++ ++/* WMD_DRV_Entry function returned a NULL function interface table. */ ++#define DEV_E_NULLWMDINTF (DEV_EBASE + 0x01) ++ ++/* FAILURE Codes : LDR */ ++#define LDR_EBASE (DSP_COMP_EBASE + 0x100) ++ ++/* Insufficient memory to export class driver services. */ ++#define LDR_E_NOMEMORY (LDR_EBASE + 0x00) ++ ++/* Unable to find WMD file in system directory. */ ++#define LDR_E_FILEUNABLETOOPEN (LDR_EBASE + 0x01) ++ ++/* FAILURE Codes : CFG */ ++#define CFG_EBASE (DSP_COMP_EBASE + 0x200) ++ ++/* Invalid pointer passed into a configuration module function */ ++#define CFG_E_INVALIDPOINTER (CFG_EBASE + 0x00) ++ ++/* Invalid device node handle passed into a configuration module function. */ ++#define CFG_E_INVALIDHDEVNODE (CFG_EBASE + 0x01) ++ ++/* Unable to retrieve resource information from the registry. */ ++#define CFG_E_RESOURCENOTAVAIL (CFG_EBASE + 0x02) ++ ++/* Unable to find board name key in registry. */ ++#define CFG_E_INVALIDBOARDNAME (CFG_EBASE + 0x03) ++ ++/* Unable to find a device node in registry with given unit number. */ ++#define CFG_E_INVALIDUNITNUM (CFG_EBASE + 0x04) ++ ++/* Insufficient buffer size */ ++#define CFG_E_INSUFFICIENTBUFSIZE (CFG_EBASE + 0x05) ++ ++/* FAILURE Codes : BRD */ ++#define BRD_EBASE (DSP_COMP_EBASE + 0x300) ++ ++/* Board client does not have sufficient access rights for this operation. */ ++#define BRD_E_ACCESSDENIED (BRD_EBASE + 0x00) ++ ++/* Unable to find trace buffer symbols in the DSP executable COFF file. */ ++#define BRD_E_NOTRACEBUFFER (BRD_EBASE + 0x01) ++ ++/* Attempted to auto-start board, but no default DSP executable configured. */ ++#define BRD_E_NOEXEC (BRD_EBASE + 0x02) ++ ++/* The operation failed because it was started from a wrong state */ ++#define BRD_E_WRONGSTATE (BRD_EBASE + 0x03) ++ ++/* FAILURE Codes : COD */ ++#define COD_EBASE (DSP_COMP_EBASE + 0x400) ++ ++/* No symbol table is loaded for this board. */ ++#define COD_E_NOSYMBOLSLOADED (COD_EBASE + 0x00) ++ ++/* Symbol not found in for this board. */ ++#define COD_E_SYMBOLNOTFOUND (COD_EBASE + 0x01) ++ ++/* ZL DLL module is not exporting the correct function interface. */ ++#define COD_E_NOZLFUNCTIONS (COD_EBASE + 0x02) ++ ++/* Unable to initialize the ZL COFF parsing module. */ ++#define COD_E_ZLCREATEFAILED (COD_EBASE + 0x03) ++ ++/* Unable to open DSP executable COFF file. */ ++#define COD_E_OPENFAILED (COD_EBASE + 0x04) ++ ++/* Unable to parse DSP executable COFF file. */ ++#define COD_E_LOADFAILED (COD_EBASE + 0x05) ++ ++/* Unable to read DSP executable COFF file. */ ++#define COD_E_READFAILED (COD_EBASE + 0x06) ++ ++/* FAILURE Codes : CHNL */ ++#define CHNL_EBASE (DSP_COMP_EBASE + 0x500) ++ ++/* Attempt to created channel manager with too many channels. */ ++#define CHNL_E_MAXCHANNELS (CHNL_EBASE + 0x00) ++ ++/* No channel manager exists for this mini-driver. */ ++#define CHNL_E_NOMGR (CHNL_EBASE + 0x01) ++ ++/* No free channels are available. */ ++#define CHNL_E_OUTOFSTREAMS (CHNL_EBASE + 0x02) ++ ++/* Channel ID is out of range. */ ++#define CHNL_E_BADCHANID (CHNL_EBASE + 0x03) ++ ++/* Channel is already in use. */ ++#define CHNL_E_CHANBUSY (CHNL_EBASE + 0x04) ++ ++/* Invalid channel mode argument. */ ++#define CHNL_E_BADMODE (CHNL_EBASE + 0x05) ++ ++/* dwTimeOut parameter was CHNL_IOCNOWAIT, yet no I/O completions were ++ * queued. */ ++#define CHNL_E_NOIOC (CHNL_EBASE + 0x06) ++ ++/* I/O has been cancelled on this channel. */ ++#define CHNL_E_CANCELLED (CHNL_EBASE + 0x07) ++ ++/* End of stream was already requested on this output channel. */ ++#define CHNL_E_EOS (CHNL_EBASE + 0x09) ++ ++/* Unable to create the channel event object. */ ++#define CHNL_E_CREATEEVENT (CHNL_EBASE + 0x0A) ++ ++/* Board name and unit number do not identify a valid board name. */ ++#define CHNL_E_BRDID (CHNL_EBASE + 0x0B) ++ ++/* Invalid IRQ configured for this WMD for this system. */ ++#define CHNL_E_INVALIDIRQ (CHNL_EBASE + 0x0C) ++ ++/* DSP word size of zero configured for this device. */ ++#define CHNL_E_INVALIDWORDSIZE (CHNL_EBASE + 0x0D) ++ ++/* A zero length memory base was specified for a shared memory class driver. */ ++#define CHNL_E_INVALIDMEMBASE (CHNL_EBASE + 0x0E) ++ ++/* Memory map is not configured, or unable to map physical to linear ++ * address. */ ++#define CHNL_E_NOMEMMAP (CHNL_EBASE + 0x0F) ++ ++/* Attempted to create a channel manager when one already exists. */ ++#define CHNL_E_MGREXISTS (CHNL_EBASE + 0x10) ++ ++/* Unable to plug channel ISR for configured IRQ. */ ++#define CHNL_E_ISR (CHNL_EBASE + 0x11) ++ ++/* No free I/O request packets are available. */ ++#define CHNL_E_NOIORPS (CHNL_EBASE + 0x12) ++ ++/* Buffer size is larger than the size of physical channel. */ ++#define CHNL_E_BUFSIZE (CHNL_EBASE + 0x13) ++ ++/* User cannot mark end of stream on an input channel. */ ++#define CHNL_E_NOEOS (CHNL_EBASE + 0x14) ++ ++/* Wait for flush operation on an output channel timed out. */ ++#define CHNL_E_WAITTIMEOUT (CHNL_EBASE + 0x15) ++ ++/* User supplied hEvent must be specified with pstrEventName attribute */ ++#define CHNL_E_BADUSEREVENT (CHNL_EBASE + 0x16) ++ ++/* Illegal user event name specified */ ++#define CHNL_E_USEREVENTNAME (CHNL_EBASE + 0x17) ++ ++/* Unable to prepare buffer specified */ ++#define CHNL_E_PREPFAILED (CHNL_EBASE + 0x18) ++ ++/* Unable to Unprepare buffer specified */ ++#define CHNL_E_UNPREPFAILED (CHNL_EBASE + 0x19) ++ ++/* FAILURE Codes : SYNC */ ++#define SYNC_EBASE (DSP_COMP_EBASE + 0x600) ++ ++/* Wait on a kernel event failed. */ ++#define SYNC_E_FAIL (SYNC_EBASE + 0x00) ++ ++/* Timeout expired while waiting for event to be signalled. */ ++#define SYNC_E_TIMEOUT (SYNC_EBASE + 0x01) ++ ++/* FAILURE Codes : WMD */ ++#define WMD_EBASE (DSP_COMP_EBASE + 0x700) ++ ++/* A test of hardware assumptions or integrity failed. */ ++#define WMD_E_HARDWARE (WMD_EBASE + 0x00) ++ ++/* One or more configuration parameters violated WMD hardware assumptions. */ ++#define WMD_E_BADCONFIG (WMD_EBASE + 0x01) ++ ++/* Timeout occurred waiting for a response from the hardware. */ ++#define WMD_E_TIMEOUT (WMD_EBASE + 0x02) ++ ++/* FAILURE Codes : REG */ ++#define REG_EBASE (DSP_COMP_EBASE + 0x800) ++ ++/* Invalid subkey parameter. */ ++#define REG_E_INVALIDSUBKEY (REG_EBASE + 0x00) ++ ++/* Invalid entry parameter. */ ++#define REG_E_INVALIDENTRY (REG_EBASE + 0x01) ++ ++/* No more registry values. */ ++#define REG_E_NOMOREITEMS (REG_EBASE + 0x02) ++ ++/* Insufficient space to hold data in registry value. */ ++#define REG_E_MOREDATA (REG_EBASE + 0x03) ++ ++/* FAILURE Codes : KFILE */ ++#define KFILE_EBASE (DSP_COMP_EBASE + 0x900) ++ ++/* Invalid file handle. */ ++#define E_KFILE_INVALIDHANDLE (KFILE_EBASE + 0x01) ++ ++/* Bad file name. */ ++#define E_KFILE_BADFILENAME (KFILE_EBASE + 0x02) ++ ++/* Invalid file mode. */ ++#define E_KFILE_INVALIDMODE (KFILE_EBASE + 0x03) ++ ++/* No resources available. */ ++#define E_KFILE_NORESOURCES (KFILE_EBASE + 0x04) ++ ++/* Invalid file buffer . */ ++#define E_KFILE_INVALIDBUFFER (KFILE_EBASE + 0x05) ++ ++/* Bad origin argument. */ ++#define E_KFILE_BADORIGINFLAG (KFILE_EBASE + 0x06) ++ ++/* Invalid file offset value. */ ++#define E_KFILE_INVALIDOFFSET (KFILE_EBASE + 0x07) ++ ++/* General KFILE error condition */ ++#define E_KFILE_ERROR (KFILE_EBASE + 0x08) ++ ++#endif /* ERRBASE_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/gb.h b/arch/arm/plat-omap/include/dspbridge/gb.h +new file mode 100644 +index 0000000..f147751 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/gb.h +@@ -0,0 +1,85 @@ ++/* ++ * gb.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== gb.h ======== ++ * Generic bitmap manager. ++ * ++ *! Revision History ++ *! ================ ++ */ ++ ++#ifndef GB_ ++#define GB_ ++ ++#define GB_NOBITS (~0) ++#include ++typedef s32 GB_BitNum; ++struct GB_TMap; ++ ++/* ++ * ======== GB_clear ======== ++ * Clear the bit in position bitn in the bitmap map. Bit positions are ++ * zero based. ++ */ ++ ++extern void GB_clear(struct GB_TMap *map, GB_BitNum bitn); ++ ++/* ++ * ======== GB_create ======== ++ * Create a bit map with len bits. Initially all bits are cleared. ++ */ ++ ++extern struct GB_TMap *GB_create(GB_BitNum len); ++ ++/* ++ * ======== GB_delete ======== ++ * Delete previously created bit map ++ */ ++ ++extern void GB_delete(struct GB_TMap *map); ++ ++/* ++ * ======== GB_findandset ======== ++ * Finds a clear bit, sets it, and returns the position ++ */ ++ ++extern GB_BitNum GB_findandset(struct GB_TMap *map); ++ ++/* ++ * ======== GB_minclear ======== ++ * GB_minclear returns the minimum clear bit position. If no bit is ++ * clear, GB_minclear returns -1. ++ */ ++extern GB_BitNum GB_minclear(struct GB_TMap *map); ++ ++/* ++ * ======== GB_set ======== ++ * Set the bit in position bitn in the bitmap map. Bit positions are ++ * zero based. ++ */ ++ ++extern void GB_set(struct GB_TMap *map, GB_BitNum bitn); ++ ++/* ++ * ======== GB_test ======== ++ * Returns TRUE if the bit in position bitn is set in map; otherwise ++ * GB_test returns FALSE. Bit positions are zero based. ++ */ ++ ++extern bool GB_test(struct GB_TMap *map, GB_BitNum bitn); ++ ++#endif /*GB_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/getsection.h b/arch/arm/plat-omap/include/dspbridge/getsection.h +new file mode 100644 +index 0000000..33ff50d +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/getsection.h +@@ -0,0 +1,118 @@ ++/* ++ * getsection.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++#ifndef _GETSECTION_H_ ++#define _GETSECTION_H_ ++ ++ ++#include "dynamic_loader.h" ++ ++/* ++ * Get Section Information ++ * ++ * This file provides an API add-on to the dynamic loader that allows the user ++ * to query section information and extract section data from dynamic load ++ * modules. ++ * ++ * NOTE: ++ * Functions in this API assume that the supplied Dynamic_Loader_Stream object ++ * supports the set_file_posn method. ++ */ ++ ++ /* opaque handle for module information */ ++ typedef void *DLOAD_module_info; ++ ++/* ++ * Procedure DLOAD_module_open ++ * ++ * Parameters: ++ * module The input stream that supplies the module image ++ * syms Host-side malloc/free and error reporting functions. ++ * Other methods are unused. ++ * ++ * Effect: ++ * Reads header information from a dynamic loader module using the specified ++ * stream object, and returns a handle for the module information. This ++ * handle may be used in subsequent query calls to obtain information ++ * contained in the module. ++ * ++ * Returns: ++ * NULL if an error is encountered, otherwise a module handle for use ++ * in subsequent operations. ++ */ ++ extern DLOAD_module_info DLOAD_module_open(struct Dynamic_Loader_Stream ++ *module, ++ struct Dynamic_Loader_Sym ++ *syms); ++ ++/* ++ * Procedure DLOAD_GetSectionInfo ++ * ++ * Parameters: ++ * minfo Handle from DLOAD_module_open for this module ++ * sectionName Pointer to the string name of the section desired ++ * sectionInfo Address of a section info structure pointer to be initialized ++ * ++ * Effect: ++ * Finds the specified section in the module information, and fills in ++ * the provided LDR_SECTION_INFO structure. ++ * ++ * Returns: ++ * TRUE for success, FALSE for section not found ++ */ ++ extern int DLOAD_GetSectionInfo(DLOAD_module_info minfo, ++ const char *sectionName, ++ const struct LDR_SECTION_INFO ++ ** const sectionInfo); ++ ++/* ++ * Procedure DLOAD_GetSection ++ * ++ * Parameters: ++ * minfo Handle from DLOAD_module_open for this module ++ * sectionInfo Pointer to a section info structure for the desired section ++ * sectionData Buffer to contain the section initialized data ++ * ++ * Effect: ++ * Copies the initialized data for the specified section into the ++ * supplied buffer. ++ * ++ * Returns: ++ * TRUE for success, FALSE for section not found ++ */ ++ extern int DLOAD_GetSection(DLOAD_module_info minfo, ++ const struct LDR_SECTION_INFO *sectionInfo, ++ void *sectionData); ++ ++/* ++ * Procedure DLOAD_module_close ++ * ++ * Parameters: ++ * minfo Handle from DLOAD_module_open for this module ++ * ++ * Effect: ++ * Releases any storage associated with the module handle. On return, ++ * the module handle is invalid. ++ * ++ * Returns: ++ * Zero for success. On error, the number of errors detected is returned. ++ * Individual errors are reported using syms->Error_Report(), where syms was ++ * an argument to DLOAD_module_open ++ */ ++ extern void DLOAD_module_close(DLOAD_module_info minfo); ++ ++#endif /* _GETSECTION_H_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/gh.h b/arch/arm/plat-omap/include/dspbridge/gh.h +new file mode 100644 +index 0000000..089a042 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/gh.h +@@ -0,0 +1,37 @@ ++/* ++ * gh.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== gh.h ======== ++ * ++ *! Revision History ++ *! ================ ++ */ ++ ++#ifndef GH_ ++#define GH_ ++#include ++ ++extern struct GH_THashTab *GH_create(u16 maxBucket, u16 valSize, ++ u16(*hash) (void *, u16), bool(*match) (void *, void *), ++ void(*delete) (void *)); ++extern void GH_delete(struct GH_THashTab *hashTab); ++extern void GH_exit(void); ++extern void *GH_find(struct GH_THashTab *hashTab, void *key); ++extern void GH_init(void); ++extern void *GH_insert(struct GH_THashTab *hashTab, void *key, void *value); ++#endif /* GH_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/gs.h b/arch/arm/plat-omap/include/dspbridge/gs.h +new file mode 100644 +index 0000000..fd5ef27 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/gs.h +@@ -0,0 +1,64 @@ ++/* ++ * gs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== gs.h ======== ++ * Memory allocation/release wrappers. This module allows clients to ++ * avoid OS spacific issues related to memory allocation. It also provides ++ * simple diagnostic capabilities to assist in the detection of memory ++ * leaks. ++ *! Revision History ++ *! ================ ++ */ ++ ++#ifndef GS_ ++#define GS_ ++ ++/* ++ * ======== GS_alloc ======== ++ * Alloc size bytes of space. Returns pointer to space ++ * allocated, otherwise NULL. ++ */ ++extern void *GS_alloc(u32 size); ++ ++/* ++ * ======== GS_exit ======== ++ * Module exit. Do not change to "#define GS_init()"; in ++ * some environments this operation must actually do some work! ++ */ ++extern void GS_exit(void); ++ ++/* ++ * ======== GS_free ======== ++ * Free space allocated by GS_alloc() or GS_calloc(). ++ */ ++extern void GS_free(void *ptr); ++ ++/* ++ * ======== GS_frees ======== ++ * Free space allocated by GS_alloc() or GS_calloc() and assert that ++ * the size of the allocation is size bytes. ++ */ ++extern void GS_frees(void *ptr, u32 size); ++ ++/* ++ * ======== GS_init ======== ++ * Module initialization. Do not change to "#define GS_init()"; in ++ * some environments this operation must actually do some work! ++ */ ++extern void GS_init(void); ++ ++#endif /*GS_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/gt.h b/arch/arm/plat-omap/include/dspbridge/gt.h +new file mode 100644 +index 0000000..456c866 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/gt.h +@@ -0,0 +1,315 @@ ++/* ++ * gt.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== gt.h ======== ++ * Purpose: ++ * There are two definitions that affect which portions of trace ++ * are acutally compiled into the client: GT_TRACE and GT_ASSERT. If ++ * GT_TRACE is set to 0 then all trace statements (except for assertions) ++ * will be compiled out of the client. If GT_ASSERT is set to 0 then ++ * assertions will be compiled out of the client. GT_ASSERT can not be ++ * set to 0 unless GT_TRACE is also set to 0 (i.e. GT_TRACE == 1 implies ++ * GT_ASSERT == 1). ++ * ++ *! Revision History ++ *! ================ ++ *! 02-Feb-2000 rr: Renamed this file to gtce.h. GT CLASS and trace definitions ++ *! are WinCE Specific. ++ *! 03-Jan-1997 ge Replaced "GT_" prefix to GT_Config structure members ++ *! to eliminate preprocessor confusion with other macros. ++ */ ++#include ++#ifndef GT_ ++#define GT_ ++ ++#ifndef GT_TRACE ++#define GT_TRACE 0 /* 0 = "trace compiled out"; 1 = "trace active" */ ++#endif ++ ++#include ++ ++#if !defined(GT_ASSERT) || GT_TRACE ++#define GT_ASSERT 1 ++#endif ++ ++struct GT_Config { ++ Fxn PRINTFXN; ++ Fxn PIDFXN; ++ Fxn TIDFXN; ++ Fxn ERRORFXN; ++}; ++ ++extern struct GT_Config *GT; ++ ++struct GT_Mask { ++ char *modName; ++ u8 *flags; ++} ; ++ ++/* ++ * New GT Class defenitions. ++ * ++ * The following are the explanations and how it could be used in the code ++ * ++ * - GT_ENTER On Entry to Functions ++ * ++ * - GT_1CLASS Display level of debugging status- Object/Automatic ++ * variables ++ * - GT_2CLASS ---- do ---- ++ * ++ * - GT_3CLASS ---- do ---- + It can be used(recommended) for debug ++ * status in the ISR, IST ++ * - GT_4CLASS ---- do ---- ++ * ++ * - GT_5CLASS Display entry for module init/exit functions ++ * ++ * - GT_6CLASS Warn whenever SERVICES function fails ++ * ++ * - GT_7CLASS Warn failure of Critical failures ++ * ++ */ ++ ++#define GT_ENTER ((u8)0x01) ++#define GT_1CLASS ((u8)0x02) ++#define GT_2CLASS ((u8)0x04) ++#define GT_3CLASS ((u8)0x08) ++#define GT_4CLASS ((u8)0x10) ++#define GT_5CLASS ((u8)0x20) ++#define GT_6CLASS ((u8)0x40) ++#define GT_7CLASS ((u8)0x80) ++ ++#ifdef _LINT_ ++ ++/* LINTLIBRARY */ ++ ++/* ++ * ======== GT_assert ======== ++ */ ++/* ARGSUSED */ ++void GT_assert(struct GT_Mask mask, s32 expr) ++{ ++} ++ ++/* ++ * ======== GT_config ======== ++ */ ++/* ARGSUSED */ ++void GT_config(struct GT_Config config) ++{ ++} ++ ++/* ++ * ======== GT_create ======== ++ */ ++/* ARGSUSED */ ++void GT_create(struct GT_Mask *mask, char *modName) ++{ ++} ++ ++/* ++ * ======== GT_curLine ======== ++ * Purpose: ++ * Returns the current source code line number. Is useful for performing ++ * branch testing using trace. For example, ++ * ++ * GT_1trace(curTrace, GT_1CLASS, ++ * "in module XX_mod, executing line %u\n", GT_curLine()); ++ */ ++/* ARGSUSED */ ++u16 GT_curLine(void) ++{ ++ return (u16)NULL; ++} ++ ++/* ++ * ======== GT_exit ======== ++ */ ++/* ARGSUSED */ ++void GT_exit(void) ++{ ++} ++ ++/* ++ * ======== GT_init ======== ++ */ ++/* ARGSUSED */ ++void GT_init(void) ++{ ++} ++ ++/* ++ * ======== GT_query ======== ++ */ ++/* ARGSUSED */ ++bool GT_query(struct GT_Mask mask, u8 class) ++{ ++ return false; ++} ++ ++/* ++ * ======== GT_set ======== ++ * sets trace mask according to settings ++ */ ++ ++/* ARGSUSED */ ++void GT_set(char *settings) ++{ ++} ++ ++/* ++ * ======== GT_setprintf ======== ++ * sets printf function ++ */ ++ ++/* ARGSUSED */ ++void GT_setprintf(Fxn fxn) ++{ ++} ++ ++/* ARGSUSED */ ++void GT_0trace(struct GT_Mask mask, u8 class, char *format) ++{ ++} ++ ++/* ARGSUSED */ ++void GT_1trace(struct GT_Mask mask, u8 class, char *format, ...) ++{ ++} ++ ++/* ARGSUSED */ ++void GT_2trace(struct GT_Mask mask, u8 class, char *format, ...) ++{ ++} ++ ++/* ARGSUSED */ ++void GT_3trace(struct GT_Mask mask, u8 class, char *format, ...) ++{ ++} ++ ++/* ARGSUSED */ ++void GT_4trace(struct GT_Mask mask, u8 class, char *format, ...) ++{ ++} ++ ++/* ARGSUSED */ ++void GT_5trace(struct GT_Mask mask, u8 class, char *format, ...) ++{ ++} ++ ++/* ARGSUSED */ ++void GT_6trace(struct GT_Mask mask, u8 class, char *format, ...) ++{ ++} ++ ++#else ++ ++#define GT_BOUND 26 /* 26 letters in alphabet */ ++ ++extern void _GT_create(struct GT_Mask *mask, char *modName); ++ ++#define GT_exit() ++ ++extern void GT_init(void); ++extern void _GT_set(char *str); ++extern s32 _GT_trace(struct GT_Mask *mask, char *format, ...); ++ ++#if GT_ASSERT == 0 ++ ++#define GT_assert(mask, expr) ++#define GT_config(config) ++#define GT_configInit(config) ++#define GT_seterror(fxn) ++ ++#else ++ ++extern struct GT_Config _GT_params; ++ ++#define GT_assert(mask, expr) \ ++ (!(expr) ? \ ++ printk("assertion violation: %s, line %d\n", \ ++ __FILE__, __LINE__), NULL : NULL) ++ ++#define GT_config(config) (_GT_params = *(config)) ++#define GT_configInit(config) (*(config) = _GT_params) ++#define GT_seterror(fxn) (_GT_params.ERRORFXN = (Fxn)(fxn)) ++ ++#endif ++ ++#if GT_TRACE == 0 ++ ++#define GT_curLine() ((u16)__LINE__) ++#define GT_create(mask, modName) ++#define GT_exit() ++#define GT_init() ++#define GT_set(settings) ++#define GT_setprintf(fxn) ++ ++#define GT_query(mask, class) false ++ ++#define GT_0trace(mask, class, format) ++#define GT_1trace(mask, class, format, arg1) ++#define GT_2trace(mask, class, format, arg1, arg2) ++#define GT_3trace(mask, class, format, arg1, arg2, arg3) ++#define GT_4trace(mask, class, format, arg1, arg2, arg3, arg4) ++#define GT_5trace(mask, class, format, arg1, arg2, arg3, arg4, arg5) ++#define GT_6trace(mask, class, format, arg1, arg2, arg3, arg4, arg5, arg6) ++ ++#else /* GT_TRACE == 1 */ ++ ++ ++#define GT_create(mask, modName) _GT_create((mask), (modName)) ++#define GT_curLine() ((u16)__LINE__) ++#define GT_set(settings) _GT_set(settings) ++#define GT_setprintf(fxn) (_GT_params.PRINTFXN = (Fxn)(fxn)) ++ ++#define GT_query(mask, class) ((*(mask).flags & (class))) ++ ++#define GT_0trace(mask, class, format) \ ++ ((*(mask).flags & (class)) ? \ ++ _GT_trace(&(mask), (format)) : 0) ++ ++#define GT_1trace(mask, class, format, arg1) \ ++ ((*(mask).flags & (class)) ? \ ++ _GT_trace(&(mask), (format), (arg1)) : 0) ++ ++#define GT_2trace(mask, class, format, arg1, arg2) \ ++ ((*(mask).flags & (class)) ? \ ++ _GT_trace(&(mask), (format), (arg1), (arg2)) : 0) ++ ++#define GT_3trace(mask, class, format, arg1, arg2, arg3) \ ++ ((*(mask).flags & (class)) ? \ ++ _GT_trace(&(mask), (format), (arg1), (arg2), (arg3)) : 0) ++ ++#define GT_4trace(mask, class, format, arg1, arg2, arg3, arg4) \ ++ ((*(mask).flags & (class)) ? \ ++ _GT_trace(&(mask), (format), (arg1), (arg2), (arg3), (arg4)) : 0) ++ ++#define GT_5trace(mask, class, format, arg1, arg2, arg3, arg4, arg5) \ ++ ((*(mask).flags & (class)) ? \ ++ _GT_trace(&(mask), (format), (arg1), (arg2), (arg3), (arg4), (arg5)) : 0) ++ ++#define GT_6trace(mask, class, format, arg1, arg2, arg3, arg4, arg5, arg6) \ ++ ((*(mask).flags & (class)) ? \ ++ _GT_trace(&(mask), (format), (arg1), (arg2), (arg3), (arg4), (arg5), \ ++ (arg6)) : 0) ++ ++#endif /* GT_TRACE */ ++ ++#endif /* _LINT_ */ ++ ++#endif /* GTCE_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/host_os.h b/arch/arm/plat-omap/include/dspbridge/host_os.h +new file mode 100644 +index 0000000..f539bd0 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/host_os.h +@@ -0,0 +1,96 @@ ++/* ++ * host_os.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== windows.h ======== ++ * ++ *! Revision History ++ *! ================ ++ *! 08-Mar-2004 sb Added cacheflush.h to support Dynamic Memory Mapping feature ++ *! 16-Feb-2004 sb Added headers required for consistent_alloc ++ */ ++ ++#ifndef _HOST_OS_H_ ++#define _HOST_OS_H_ ++ ++#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 ++#include ++#include ++#include ++ ++/* ----------------------------------- Macros */ ++ ++#define SEEK_SET 0 /* Seek from beginning of file. */ ++#define SEEK_CUR 1 /* Seek from current position. */ ++#define SEEK_END 2 /* Seek from end of file. */ ++ ++/* TODO -- Remove, once BP defines them */ ++#define INT_MAIL_MPU_IRQ 26 ++#define INT_DSP_MMU_IRQ 28 ++ ++struct dspbridge_platform_data { ++ void (*dsp_set_min_opp)(u8 opp_id); ++ u8 (*dsp_get_opp)(void); ++ void (*cpu_set_freq)(unsigned long f); ++ unsigned long (*cpu_get_freq)(void); ++ unsigned long mpu_speed[6]; ++ ++ u32 phys_mempool_base; ++ u32 phys_mempool_size; ++}; ++ ++#define PRCM_VDD1 1 ++ ++extern struct platform_device *omap_dspbridge_dev; ++ ++#if defined(CONFIG_MPU_BRIDGE) || defined(CONFIG_MPU_BRIDGE_MODULE) ++extern void dspbridge_reserve_sdram(void); ++#else ++static inline void dspbridge_reserve_sdram(void) {} ++#endif ++ ++extern unsigned long dspbridge_get_mempool_base(void); ++#endif ++ +diff --git a/arch/arm/plat-omap/include/dspbridge/io.h b/arch/arm/plat-omap/include/dspbridge/io.h +new file mode 100644 +index 0000000..6dc63f2 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/io.h +@@ -0,0 +1,132 @@ ++/* ++ * io.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== io.h ======== ++ * Description: ++ * The io module manages IO between CHNL and MSG. ++ * ++ * Public Functions: ++ * IO_Create ++ * IO_Destroy ++ * IO_Exit ++ * IO_Init ++ * IO_OnLoaded ++ * ++ * ++ *! Revision History: ++ *! ================ ++ *! 07-Nov-2000 jeh Created. ++ */ ++ ++#ifndef IO_ ++#define IO_ ++ ++#include ++#include ++ ++#include ++ ++/* ++ * ======== IO_Create ======== ++ * Purpose: ++ * Create an IO manager object, responsible for managing IO between ++ * CHNL and MSG. ++ * Parameters: ++ * phChnlMgr: Location to store a channel manager object on ++ * output. ++ * hDevObject: Handle to a device object. ++ * pMgrAttrs: IO manager attributes. ++ * pMgrAttrs->bIRQ: I/O IRQ number. ++ * pMgrAttrs->fShared: TRUE if the IRQ is shareable. ++ * pMgrAttrs->uWordSize: DSP Word size in equivalent PC bytes.. ++ * Returns: ++ * DSP_SOK: Success; ++ * DSP_EMEMORY: Insufficient memory for requested resources. ++ * CHNL_E_ISR: Unable to plug channel ISR for configured IRQ. ++ * CHNL_E_INVALIDIRQ: Invalid IRQ number. Must be 0 <= bIRQ <= 15. ++ * CHNL_E_INVALIDWORDSIZE: Invalid DSP word size. Must be > 0. ++ * CHNL_E_INVALIDMEMBASE: Invalid base address for DSP communications. ++ * Requires: ++ * IO_Init(void) called. ++ * phIOMgr != NULL. ++ * pMgrAttrs != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS IO_Create(OUT struct IO_MGR **phIOMgr, ++ struct DEV_OBJECT *hDevObject, ++ IN CONST struct IO_ATTRS *pMgrAttrs); ++ ++/* ++ * ======== IO_Destroy ======== ++ * Purpose: ++ * Destroy the IO manager. ++ * Parameters: ++ * hIOMgr: IOmanager object. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: hIOMgr was invalid. ++ * Requires: ++ * IO_Init(void) called. ++ * Ensures: ++ */ ++ extern DSP_STATUS IO_Destroy(struct IO_MGR *hIOMgr); ++ ++/* ++ * ======== IO_Exit ======== ++ * Purpose: ++ * Discontinue usage of the IO module. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * IO_Init(void) previously called. ++ * Ensures: ++ * Resources, if any acquired in IO_Init(void), are freed when the last ++ * client of IO calls IO_Exit(void). ++ */ ++ extern void IO_Exit(void); ++ ++/* ++ * ======== IO_Init ======== ++ * Purpose: ++ * Initialize the IO module's private state. ++ * Parameters: ++ * Returns: ++ * TRUE if initialized; FALSE if error occurred. ++ * Requires: ++ * Ensures: ++ * A requirement for each of the other public CHNL functions. ++ */ ++ extern bool IO_Init(void); ++ ++/* ++ * ======== IO_OnLoaded ======== ++ * Purpose: ++ * Called when a program is loaded so IO manager can update its ++ * internal state. ++ * Parameters: ++ * hIOMgr: IOmanager object. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: hIOMgr was invalid. ++ * Requires: ++ * IO_Init(void) called. ++ * Ensures: ++ */ ++ extern DSP_STATUS IO_OnLoaded(struct IO_MGR *hIOMgr); ++ ++#endif /* CHNL_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/io_sm.h b/arch/arm/plat-omap/include/dspbridge/io_sm.h +new file mode 100644 +index 0000000..3dcbf74 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/io_sm.h +@@ -0,0 +1,335 @@ ++/* ++ * io_sm.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== io_sm.h ======== ++ * Description: ++ * IO dispatcher for a shared memory channel driver. ++ * Also, includes macros to simulate SHM via port io calls. ++ * ++ * Public Functions: ++ * IO_Dispatch ++ * IO_DPC ++ * IO_ISR ++ * IO_RequestChnl ++ * ++ * Notes: ++ * ++ *! Revision History: ++ *! ================ ++ *! 01-Mar-2004 vp: Added IVA releated functions. ++ *! 23-Apr-2003 sb: Fixed mailbox deadlock ++ *! 06-Feb-2003 kc Added IO_DDMAClearChnlDesc and IO_DDZCClearChnlDesc. ++ *! 21-Dec-2001 ag Removed unused param in IO_DDMAInitChnlDesc(). ++ * Updated comments. Removed #ifdef CHNL_NOIPCINTR. ++ *! 05-Nov-2001 kc Updated IO_CALLISR macro. ++ *! 01-May-2001 jeh Removed IO_RequestMsg. ++ *! 29-Mar-2001 ag Added #ifdef CHNL_NOIPCINTR. ++ *! 04-Dec-2000 jeh Added IO_RequestMsg. ++ *! 26-Oct-2000 jeh Added IO_GetLong, IO_SetLong, IO_ReadValueLong, and ++ *! IO_WriteValueLong, for passing arg in SHM structure. ++ *! 20-Jan-2000 ag: Updated header comments per code review. ++ *! 05-Jan-2000 ag: Text format clean-up. ++ *! 02-Nov-1999 ag: Updated header descriptions. ++ *! 25-May-1999 jg: Removed assumption of 4 bytes / word. ++ *! 12-Aug-1996 gp: Created. ++ */ ++ ++#ifndef IOSM_ ++#define IOSM_ ++ ++#include ++#include ++ ++#include ++ ++#define IO_INPUT 0 ++#define IO_OUTPUT 1 ++#define IO_SERVICE 2 ++#define IO_MAXSERVICE IO_SERVICE ++ ++#define IO_MGRSIGNATURE 0x494f4D43 /* "IOGR" */ ++ ++#define DSPFieldAddr(type, field, base, wordsize) \ ++ ((((s32)&(((type *)0)->field)) / wordsize) + (u32)base) ++ ++/* Access can be different SM access word size (e.g. 16/32 bit words) */ ++#define IO_SetValue(pContext, type, base, field, value) (base->field = value) ++#define IO_GetValue(pContext, type, base, field) (base->field) ++#define IO_OrValue(pContext, type, base, field, value) (base->field |= value) ++#define IO_AndValue(pContext, type, base, field, value) (base->field &= value) ++#define IO_SetLong(pContext, type, base, field, value) (base->field = value) ++#define IO_GetLong(pContext, type, base, field) (base->field) ++ ++#define IO_DisableInterrupt(h) CHNLSM_DisableInterrupt(h) ++#define IO_EnableInterrupt(h) CHNLSM_EnableInterrupt(h) ++#define IO_CALLISR(h, pFlag, pwMBRegVal) CHNLSM_ISR(h, pFlag, pwMBRegVal) ++ ++/* ++ * ======== IO_CancelChnl ======== ++ * Purpose: ++ * Cancel IO on a given channel. ++ * Parameters: ++ * hIOMgr: IO Manager. ++ * ulChnl: Index of channel to cancel IO on. ++ * Returns: ++ * Requires: ++ * Valid hIOMgr. ++ * Ensures: ++ */ ++ extern void IO_CancelChnl(struct IO_MGR *hIOMgr, u32 ulChnl); ++ ++/* ++ * ======== IO_DPC ======== ++ * Purpose: ++ * Deferred procedure call for shared memory channel driver ISR. Carries ++ * out the dispatch of I/O. ++ * Parameters: ++ * pRefData: Pointer to reference data registered via a call to ++ * DPC_Create(). ++ * Returns: ++ * Requires: ++ * Must not block. ++ * Must not acquire resources. ++ * All data touched must be locked in memory if running in kernel mode. ++ * Ensures: ++ * Non-preemptible (but interruptible). ++ */ ++ extern void IO_DPC(IN OUT void *pRefData); ++ ++/* ++ * ======== IO_ISR ======== ++ * Purpose: ++ * Main interrupt handler for the shared memory WMD channel manager. ++ * Calls the WMD's CHNLSM_ISR to determine if this interrupt is ours, then ++ * schedules a DPC to dispatch I/O.. ++ * Parameters: ++ * pRefData: Pointer to the channel manager object for this board. ++ * Set in an initial call to ISR_Install(). ++ * Returns: ++ * TRUE if interrupt handled; FALSE otherwise. ++ * Requires: ++ * Must be in locked memory if executing in kernel mode. ++ * Must only call functions which are in locked memory if Kernel mode. ++ * Must only call asynchronous services. ++ * Interrupts are disabled and EOI for this interrupt has been sent. ++ * Ensures: ++ */ ++ irqreturn_t IO_ISR(int irq, IN void *pRefData); ++/* ++ * ======== IO_RequestChnl ======== ++ * Purpose: ++ * Request I/O from the DSP. Sets flags in shared memory, then interrupts ++ * the DSP. ++ * Parameters: ++ * hIOMgr: IO manager handle. ++ * pChnl: Ptr to the channel requesting I/O. ++ * iMode: Mode of channel: {IO_INPUT | IO_OUTPUT}. ++ * Returns: ++ * Requires: ++ * pChnl != NULL ++ * Ensures: ++ */ ++ extern void IO_RequestChnl(struct IO_MGR *hIOMgr, ++ struct CHNL_OBJECT *pChnl, ++ u32 iMode, OUT u16 *pwMbVal); ++ ++/* ++ * ======== IO_Schedule ======== ++ * Purpose: ++ * Schedule DPC for IO. ++ * Parameters: ++ * pIOMgr: Ptr to a I/O manager. ++ * Returns: ++ * Requires: ++ * pChnl != NULL ++ * Ensures: ++ */ ++ extern void IO_Schedule(struct IO_MGR *hIOMgr); ++ ++/* ++ * DSP-DMA IO functions ++ */ ++ ++/* ++ * ======== IO_DDMAInitChnlDesc ======== ++ * Purpose: ++ * Initialize DSP DMA channel descriptor. ++ * Parameters: ++ * hIOMgr: Handle to a I/O manager. ++ * uDDMAChnlId: DDMA channel identifier. ++ * uNumDesc: Number of buffer descriptors(equals # of IOReqs & ++ * Chirps) ++ * pDsp: Dsp address; ++ * Returns: ++ * Requires: ++ * uDDMAChnlId < DDMA_MAXDDMACHNLS ++ * uNumDesc > 0 ++ * pVa != NULL ++ * pDspPa != NULL ++ * ++ * Ensures: ++ */ ++ extern void IO_DDMAInitChnlDesc(struct IO_MGR *hIOMgr, u32 uDDMAChnlId, ++ u32 uNumDesc, void *pDsp); ++ ++/* ++ * ======== IO_DDMAClearChnlDesc ======== ++ * Purpose: ++ * Clear DSP DMA channel descriptor. ++ * Parameters: ++ * hIOMgr: Handle to a I/O manager. ++ * uDDMAChnlId: DDMA channel identifier. ++ * Returns: ++ * Requires: ++ * uDDMAChnlId < DDMA_MAXDDMACHNLS ++ * Ensures: ++ */ ++ extern void IO_DDMAClearChnlDesc(struct IO_MGR *hIOMgr, ++ u32 uDDMAChnlId); ++ ++/* ++ * ======== IO_DDMARequestChnl ======== ++ * Purpose: ++ * Request channel DSP-DMA from the DSP. Sets up SM descriptors and ++ * control fields in shared memory. ++ * Parameters: ++ * hIOMgr: Handle to a I/O manager. ++ * pChnl: Ptr to channel object ++ * pChirp: Ptr to channel i/o request packet. ++ * Returns: ++ * Requires: ++ * pChnl != NULL ++ * pChnl->cIOReqs > 0 ++ * pChirp != NULL ++ * Ensures: ++ */ ++ extern void IO_DDMARequestChnl(struct IO_MGR *hIOMgr, ++ struct CHNL_OBJECT *pChnl, ++ struct CHNL_IRP *pChirp, ++ OUT u16 *pwMbVal); ++ ++/* ++ * Zero-copy IO functions ++ */ ++ ++/* ++ * ======== IO_DDZCInitChnlDesc ======== ++ * Purpose: ++ * Initialize ZCPY channel descriptor. ++ * Parameters: ++ * hIOMgr: Handle to a I/O manager. ++ * uZId: zero-copy channel identifier. ++ * Returns: ++ * Requires: ++ * uDDMAChnlId < DDMA_MAXZCPYCHNLS ++ * hIOMgr != Null ++ * Ensures: ++ */ ++ extern void IO_DDZCInitChnlDesc(struct IO_MGR *hIOMgr, u32 uZId); ++ ++/* ++ * ======== IO_DDZCClearChnlDesc ======== ++ * Purpose: ++ * Clear DSP ZC channel descriptor. ++ * Parameters: ++ * hIOMgr: Handle to a I/O manager. ++ * uChnlId: ZC channel identifier. ++ * Returns: ++ * Requires: ++ * hIOMgr is valid ++ * uChnlId < DDMA_MAXZCPYCHNLS ++ * Ensures: ++ */ ++ extern void IO_DDZCClearChnlDesc(struct IO_MGR *hIOMgr, u32 uChnlId); ++ ++/* ++ * ======== IO_DDZCRequestChnl ======== ++ * Purpose: ++ * Request zero-copy channel transfer. Sets up SM descriptors and ++ * control fields in shared memory. ++ * Parameters: ++ * hIOMgr: Handle to a I/O manager. ++ * pChnl: Ptr to channel object ++ * pChirp: Ptr to channel i/o request packet. ++ * Returns: ++ * Requires: ++ * pChnl != NULL ++ * pChnl->cIOReqs > 0 ++ * pChirp != NULL ++ * Ensures: ++ */ ++ extern void IO_DDZCRequestChnl(struct IO_MGR *hIOMgr, ++ struct CHNL_OBJECT *pChnl, ++ struct CHNL_IRP *pChirp, ++ OUT u16 *pwMbVal); ++ ++/* ++ * ======== IO_SHMsetting ======== ++ * Purpose: ++ * Sets the shared memory setting ++ * Parameters: ++ * hIOMgr: Handle to a I/O manager. ++ * desc: Shared memory type ++ * pArgs: Ptr to SHM setting ++ * Returns: ++ * Requires: ++ * hIOMgr != NULL ++ * pArgs != NULL ++ * Ensures: ++ */ ++ extern DSP_STATUS IO_SHMsetting(IN struct IO_MGR *hIOMgr, ++ IN enum SHM_DESCTYPE desc, ++ IN void *pArgs); ++ ++/* ++ * Misc functions for the CHNL_IO shared memory library: ++ */ ++ ++/* Maximum channel bufsize that can be used. */ ++ extern u32 IO_BufSize(struct IO_MGR *hIOMgr); ++ ++ extern u32 IO_ReadValue(struct WMD_DEV_CONTEXT *hDevContext, ++ u32 dwDSPAddr); ++ ++ extern void IO_WriteValue(struct WMD_DEV_CONTEXT *hDevContext, ++ u32 dwDSPAddr, u32 dwValue); ++ ++ extern u32 IO_ReadValueLong(struct WMD_DEV_CONTEXT *hDevContext, ++ u32 dwDSPAddr); ++ ++ extern void IO_WriteValueLong(struct WMD_DEV_CONTEXT *hDevContext, ++ u32 dwDSPAddr, u32 dwValue); ++ ++ extern void IO_OrSetValue(struct WMD_DEV_CONTEXT *hDevContext, ++ u32 dwDSPAddr, u32 dwValue); ++ ++ extern void IO_AndSetValue(struct WMD_DEV_CONTEXT *hDevContext, ++ u32 dwDSPAddr, u32 dwValue); ++ ++ extern void IO_IntrDSP2(IN struct IO_MGR *pIOMgr, IN u16 wMbVal); ++ ++ extern void IO_SM_init(void); ++ ++/* ++ * ========PrintDspTraceBuffer ======== ++ * Print DSP tracebuffer. ++ */ ++ extern DSP_STATUS PrintDspTraceBuffer(struct WMD_DEV_CONTEXT ++ *hWmdContext); ++ ++#endif /* IOSM_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/iodefs.h b/arch/arm/plat-omap/include/dspbridge/iodefs.h +new file mode 100644 +index 0000000..f45890a +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/iodefs.h +@@ -0,0 +1,45 @@ ++/* ++ * iodefs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== iodefs.h ======== ++ * Description: ++ * System-wide channel objects and constants. ++ * ++ *! Revision History: ++ *! ================ ++ *! 07-Nov-2000 jeh Created. ++ */ ++ ++#ifndef IODEFS_ ++#define IODEFS_ ++ ++#define IO_MAXIRQ 0xff /* Arbitrarily large number. */ ++ ++/* IO Objects: */ ++ struct IO_MGR; ++ ++/* IO manager attributes: */ ++ struct IO_ATTRS { ++ u8 bIRQ; /* Channel's I/O IRQ number. */ ++ bool fShared; /* TRUE if the IRQ is shareable. */ ++ u32 uWordSize; /* DSP Word size. */ ++ u32 dwSMBase; /* Physical base address of shared memory. */ ++ u32 uSMLength; /* Size (in bytes) of shared memory. */ ++ } ; ++ ++#endif /* IODEFS_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/kfile.h b/arch/arm/plat-omap/include/dspbridge/kfile.h +new file mode 100644 +index 0000000..23c89b0 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/kfile.h +@@ -0,0 +1,216 @@ ++/* ++ * kfile.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== kfile.h ======== ++ * Purpose: ++ * Provide file I/O management capabilities. ++ * ++ * Public Functions: ++ * KFILE_Close ++ * KFILE_Exit ++ * KFILE_Init ++ * KFILE_Open ++ * KFILE_Read ++ * KFILE_Seek ++ * KFILE_Tell ++ * KFILE_Write ++ * ++ * Notes: ++ * The KFILE module is not like most of the other DSP/BIOS Bridge modules ++ * in that it doesn't return WSX_STATUS type values. Rather, it's ++ * prototypes are meant to match the stdio file prototypes ++ * (ie, fopen, fclose, etc.). ++ * ++ *! Revision History ++ *! ================ ++ *! 29-Oct-1999 kc: Clean up for code review. ++ *! 07-Jan-1998 cr: Clean up for code review. ++ *! 15-Aug-1997 cr: Added E_KFILE_ERROR for general error condition. ++ *! 04-Aug-1997 cr: Added explicit CDECL descriptions. ++ *! 11-Nov-1996 cr: Implemented changes based on code review. ++ *! 05-Nov-1996 cr: Cleaned up for code review. ++ *! 29-May-1996 gp: Added requirement that size != 0 in _Write() and _Read(). ++ *! 28-May-1996 mg: Changed return values for Read/Write. ++ *! 14-Dec-1995 cr: Created. ++ */ ++ ++#ifndef KFILE_ ++#define KFILE_ ++ ++/* ++ * Constants for KFILE_Seek. Note that these MUST be the same definitions as ++ * those defined for fseek. ++ */ ++#define KFILE_SEEK_SET 0x00 /* seek from beginning of file */ ++#define KFILE_SEEK_CUR 0x01 /* seek from current position */ ++#define KFILE_SEEK_END 0x02 /* seek from end of file */ ++ ++ struct KFILE_FileObj; ++ ++/* ++ * ======== KFILE_Close ======== ++ * Purpose: ++ * This function closes a file's stream. ++ * Parameters: ++ * hFile: Handle of the file stream returned by KFILE_Open. ++ * Returns: ++ * E_KFILE_INVALIDHANDLE: bad handle. ++ * 0: success. ++ * E_KFILE_ERROR: unable to close specified handle. ++ * Requires: ++ * KFILE initialized. ++ * Ensures: ++ */ ++ extern s32 KFILE_Close(IN struct KFILE_FileObj *hFile); ++ ++/* ++ * ======== KFILE_Exit ======== ++ * Purpose: ++ * Discontinue usage of module; free resources when reference count ++ * reaches 0. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * KFILE initialized. ++ * Ensures: ++ * Resources used by module are freed when cRef reaches zero. ++ */ ++ extern void KFILE_Exit(void); ++ ++/* ++ * ======== KFILE_Init ======== ++ * Purpose: ++ * Initializes private state of KFILE module. ++ * Parameters: ++ * Returns: ++ * TRUE if success, else FALSE. ++ * Requires: ++ * Ensures: ++ * KFILE initialized. ++ */ ++ extern bool KFILE_Init(void); ++ ++/* ++ * ======== KFILE_Open ======== ++ * Purpose: ++ * Opens a file for use. ++ * Parameters: ++ * pszFileName: Full path to name of the file to open. ++ * pszMode: String containing open status. Only the first ++ * character of the string is examined, for either ++ * "r" (read) or "w" (write) mode. ++ * Returns: ++ * A valid file handle if success, else NULL. ++ * Requires: ++ * - KFILE initialized. ++ * - pszMode != NULL. ++ * - pszFileName != NULL. ++ * Ensures: ++ */ ++ extern struct KFILE_FileObj *KFILE_Open(IN CONST char *filename, ++ IN CONST char *mode); ++ ++/* ++ * ======== KFILE_Read ======== ++ * Purpose: ++ * This function reads a specified number of bytes into a buffer. ++ * Parameters: ++ * pBuffer: Array to which the file data is copied. ++ * cSize: Number of characters in each object. ++ * cCount: Number of objects to read in. ++ * hFile: Handle of the file stream returned by KFILE_Open. ++ * Returns: ++ * E_KFILE_INVALIDHANDLE: bad file handle. ++ * E_KFILE_ERROR: general failure. ++ * > 0: success; # of objects read from file. ++ * Requires: ++ * KFILE initialized. ++ * pBuffer is a valid pointer. ++ * Ensures: ++ */ ++ extern s32 KFILE_Read(OUT void __user*buffer, ++ IN s32 size, IN s32 count, ++ IN struct KFILE_FileObj *hFile); ++ ++/* ++ * ======== KFILE_Seek ======== ++ * Purpose: ++ * This function sets the file position indicator. NOTE: we don't ++ * support seeking beyond the boundaries of a file. ++ * Parameters: ++ * hFile: Handle of the file stream returned by KFILE_Open. ++ * offset: Number of bytes from the origin to move. ++ * origin: File reference point, one of the following values: ++ * KFILE_SEEK_SET: Seek from beginning of file. ++ * KFILE_SEEK_CUR: Seek from current position. ++ * KFILE_SEEK_END: Seek from end of file. ++ * Returns: ++ * 0: success. ++ * E_KFILE_INVALIDHANDLE: bad handle. ++ * E_KFILE_BADORIGIN: invalid origin paramater. ++ * E_KFILE_ERROR: general failure. ++ * Requires: ++ * KFILE initialized. ++ * Ensures: ++ */ ++ extern s32 KFILE_Seek(IN struct KFILE_FileObj *hFile, ++ IN s32 offset, IN s32 origin); ++ ++/* ++ * ======== KFILE_Tell ======== ++ * Purpose: ++ * This function reports the current value of the position indicator. ++ * Parameters: ++ * hFile: Handle of the file stream returned by KFILE_Open. ++ * Return value: ++ * > 0: success; returns # of bytes the position indicator is from ++ * beginning of file. ++ * E_KFILE_ERROR: general failure. ++ * E_KFILE_INVALIDHANDLE: bad file handle. ++ * Requires: ++ * KFILE initialized. ++ * Ensures: ++ */ ++ extern s32 KFILE_Tell(IN struct KFILE_FileObj *hFile); ++ ++/* ++ * ======== KFILE_Write ======== ++ * Purpose: ++ * This function writes a number of objects to the stream. ++ * Parameters: ++ * pBuffer: Array from which the file data is written. ++ * cSize: Number of characters in each object. ++ * cCount: Number of objects to write out. ++ * hFile: Handle of the file stream returned by KFILE_Open. ++ * Returns: ++ * E_KFILE_INVALIDHANDLE: bad file handle. ++ * E_KFILE_ERROR: general failure. ++ * > 0: success; # of objects written to file. ++ * Requires: ++ * KFILE initialized. ++ * pBuffer != NULL. ++ * Postcondition: ++ * The file position indicator is advanced by the number of ++ * characters written. ++ */ ++ extern s32 KFILE_Write(OUT void *buffer, ++ IN s32 size, ++ IN s32 count, ++ IN struct KFILE_FileObj *hFile); ++ ++#endif /* KFILE_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/ldr.h b/arch/arm/plat-omap/include/dspbridge/ldr.h +new file mode 100644 +index 0000000..7e13c93 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/ldr.h +@@ -0,0 +1,51 @@ ++/* ++ * ldr.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== ldr.h ======== ++ * Purpose: ++ * Provide module loading services and symbol export services. ++ * ++ * Public Functions: ++ * LDR_Exit ++ * LDR_FreeModule ++ * LDR_GetProcAddress ++ * LDR_Init ++ * LDR_LoadModule ++ * ++ * Notes: ++ * This service is meant to be used by modules of the DSP/BIOS Bridge ++ * class driver. ++ * ++ *! Revision History: ++ *! ================ ++ *! 22-Nov-1999 kc: Changes from code review. ++ *! 12-Nov-1999 kc: Removed declaration of unused loader object. ++ *! 29-Oct-1999 kc: Cleaned up for code review. ++ *! 12-Jan-1998 cr: Cleaned up for code review. ++ *! 04-Aug-1997 cr: Added explicit CDECL identifiers. ++ *! 11-Nov-1996 cr: Cleaned up for code review. ++ *! 16-May-1996 gp: Created. ++ */ ++ ++#ifndef LDR_ ++#define LDR_ ++ ++/* Loader objects: */ ++ struct LDR_MODULE; ++ ++#endif /* LDR_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/list.h b/arch/arm/plat-omap/include/dspbridge/list.h +new file mode 100644 +index 0000000..2e3f995 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/list.h +@@ -0,0 +1,296 @@ ++/* ++ * list.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== list.h ======== ++ * Purpose: ++ * Declarations of list management control structures and definitions ++ * of inline list management functions. ++ * ++ * Public Functions: ++ * LST_Create ++ * LST_Delete ++ * LST_Exit ++ * LST_First ++ * LST_GetHead ++ * LST_InitElem ++ * LST_Init ++ * LST_InsertBefore ++ * LST_IsEmpty ++ * LST_Next ++ * LST_PutTail ++ * LST_RemoveElem ++ * ++ * Notes: ++ * ++ *! Revision History ++ *! ================ ++ *! 10-Aug-2000 ag: Added LST_InsertBefore(). ++ *! 29-Oct-1999 kc: Cleaned up for code review. ++ *! 16-Aug-1997 cr: added explicit identifiers. ++ *! 10-Aug-1996 gp: Acquired from SMM for WinSPOX v.1.1; renamed identifiers. ++ *! 21-Oct-1994 dh4: Cleaned / commented for code review. ++ *! 08-Jun-1994 dh4: Converted to SPM (added extern "C"). ++ */ ++ ++#ifndef LIST_ ++#define LIST_ ++ ++#include ++ ++#define LST_IsEmpty(l) (((l)->head.next == &(l)->head)) ++ ++ struct LST_ELEM { ++ struct LST_ELEM *next; ++ struct LST_ELEM *prev; ++ struct LST_ELEM *self; ++ } ; ++ ++ struct LST_LIST { ++ struct LST_ELEM head; ++ } ; ++ ++/* ++ * ======== LST_Create ======== ++ * Purpose: ++ * Allocates and initializes a circular list. ++ * Details: ++ * Uses portable MEM_Calloc() function to allocate a list containing ++ * a single element and initializes that element to indicate that it ++ * is the "end of the list" (i.e., the list is empty). ++ * An empty list is indicated by the "next" pointer in the element ++ * at the head of the list pointing to the head of the list, itself. ++ * Parameters: ++ * Returns: ++ * Pointer to beginning of created list (success) ++ * NULL --> Allocation failed ++ * Requires: ++ * LST initialized. ++ * Ensures: ++ * Notes: ++ * The created list contains a single element. This element is the ++ * "empty" element, because its "next" and "prev" pointers point at ++ * the same location (the element itself). ++ */ ++ extern struct LST_LIST *LST_Create(void); ++ ++/* ++ * ======== LST_Delete ======== ++ * Purpose: ++ * Removes a list by freeing its control structure's memory space. ++ * Details: ++ * Uses portable MEM_Free() function to deallocate the memory ++ * block pointed at by the input parameter. ++ * Parameters: ++ * pList: Pointer to list control structure of list to be deleted ++ * Returns: ++ * Void ++ * Requires: ++ * - LST initialized. ++ * - pList != NULL. ++ * Ensures: ++ * Notes: ++ * Must ONLY be used for empty lists, because it does not walk the ++ * chain of list elements. Calling this function on a non-empty list ++ * will cause a memory leak. ++ */ ++ extern void LST_Delete(IN struct LST_LIST *pList); ++ ++/* ++ * ======== LST_Exit ======== ++ * Purpose: ++ * Discontinue usage of module; free resources when reference count ++ * reaches 0. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * LST initialized. ++ * Ensures: ++ * Resources used by module are freed when cRef reaches zero. ++ */ ++ extern void LST_Exit(void); ++ ++/* ++ * ======== LST_First ======== ++ * Purpose: ++ * Returns a pointer to the first element of the list, or NULL if the list ++ * is empty. ++ * Parameters: ++ * pList: Pointer to list control structure. ++ * Returns: ++ * Pointer to first list element, or NULL. ++ * Requires: ++ * - LST initialized. ++ * - pList != NULL. ++ * Ensures: ++ */ ++ extern struct LST_ELEM *LST_First(IN struct LST_LIST *pList); ++ ++/* ++ * ======== LST_GetHead ======== ++ * Purpose: ++ * Pops the head off the list and returns a pointer to it. ++ * Details: ++ * If the list is empty, returns NULL. ++ * Else, removes the element at the head of the list, making the next ++ * element the head of the list. ++ * The head is removed by making the tail element of the list point its ++ * "next" pointer at the next element after the head, and by making the ++ * "prev" pointer of the next element after the head point at the tail ++ * element. So the next element after the head becomes the new head of ++ * the list. ++ * Parameters: ++ * pList: Pointer to list control structure of list whose head ++ * element is to be removed ++ * Returns: ++ * Pointer to element that was at the head of the list (success) ++ * NULL No elements in list ++ * Requires: ++ * - head.self must be correctly set to &head. ++ * - LST initialized. ++ * - pList != NULL. ++ * Ensures: ++ * Notes: ++ * Because the tail of the list points forward (its "next" pointer) to ++ * the head of the list, and the head of the list points backward (its ++ * "prev" pointer) to the tail of the list, this list is circular. ++ */ ++ extern struct LST_ELEM *LST_GetHead(IN struct LST_LIST *pList); ++ ++/* ++ * ======== LST_Init ======== ++ * Purpose: ++ * Initializes private state of LST module. ++ * Parameters: ++ * Returns: ++ * TRUE if initialized; FALSE otherwise. ++ * Requires: ++ * Ensures: ++ * LST initialized. ++ */ ++ extern bool LST_Init(void); ++ ++/* ++ * ======== LST_InitElem ======== ++ * Purpose: ++ * Initializes a list element to default (cleared) values ++ * Details: ++ * Parameters: ++ * pElem: Pointer to list element to be reset ++ * Returns: ++ * Requires: ++ * LST initialized. ++ * Ensures: ++ * Notes: ++ * This function must not be called to "reset" an element in the middle ++ * of a list chain -- that would break the chain. ++ * ++ */ ++ extern void LST_InitElem(IN struct LST_ELEM *pListElem); ++ ++/* ++ * ======== LST_InsertBefore ======== ++ * Purpose: ++ * Insert the element before the existing element. ++ * Parameters: ++ * pList: Pointer to list control structure. ++ * pElem: Pointer to element in list to insert. ++ * pElemExisting: Pointer to existing list element. ++ * Returns: ++ * Requires: ++ * - LST initialized. ++ * - pList != NULL. ++ * - pElem != NULL. ++ * - pElemExisting != NULL. ++ * Ensures: ++ */ ++ extern void LST_InsertBefore(IN struct LST_LIST *pList, ++ IN struct LST_ELEM *pElem, ++ IN struct LST_ELEM *pElemExisting); ++ ++/* ++ * ======== LST_Next ======== ++ * Purpose: ++ * Returns a pointer to the next element of the list, or NULL if the next ++ * element is the head of the list or the list is empty. ++ * Parameters: ++ * pList: Pointer to list control structure. ++ * pCurElem: Pointer to element in list to remove. ++ * Returns: ++ * Pointer to list element, or NULL. ++ * Requires: ++ * - LST initialized. ++ * - pList != NULL. ++ * - pCurElem != NULL. ++ * Ensures: ++ */ ++ extern struct LST_ELEM *LST_Next(IN struct LST_LIST *pList, ++ IN struct LST_ELEM *pCurElem); ++ ++/* ++ * ======== LST_PutTail ======== ++ * Purpose: ++ * Adds the specified element to the tail of the list ++ * Details: ++ * Sets new element's "prev" pointer to the address previously held by ++ * the head element's prev pointer. This is the previous tail member of ++ * the list. ++ * Sets the new head's prev pointer to the address of the element. ++ * Sets next pointer of the previous tail member of the list to point to ++ * the new element (rather than the head, which it had been pointing at). ++ * Sets new element's next pointer to the address of the head element. ++ * Sets head's prev pointer to the address of the new element. ++ * Parameters: ++ * pList: Pointer to list control structure to which *pElem will be ++ * added ++ * pElem: Pointer to list element to be added ++ * Returns: ++ * Void ++ * Requires: ++ * *pElem and *pList must both exist. ++ * pElem->self = pElem before pElem is passed to this function. ++ * LST initialized. ++ * Ensures: ++ * Notes: ++ * Because the tail is always "just before" the head of the list (the ++ * tail's "next" pointer points at the head of the list, and the head's ++ * "prev" pointer points at the tail of the list), the list is circular. ++ * Warning: if pElem->self is not set beforehand, LST_GetHead() will ++ * return an erroneous pointer when it is called for this element. ++ */ ++ extern void LST_PutTail(IN struct LST_LIST *pList, ++ IN struct LST_ELEM *pListElem); ++ ++/* ++ * ======== LST_RemoveElem ======== ++ * Purpose: ++ * Removes (unlinks) the given element from the list, if the list is not ++ * empty. Does not free the list element. ++ * Parameters: ++ * pList: Pointer to list control structure. ++ * pCurElem: Pointer to element in list to remove. ++ * Returns: ++ * Requires: ++ * - LST initialized. ++ * - pList != NULL. ++ * - pCurElem != NULL. ++ * Ensures: ++ */ ++extern void LST_RemoveElem(IN struct LST_LIST *pList, ++ IN struct LST_ELEM *pCurElem); ++ ++#endif /* LIST_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/mbx_sh.h b/arch/arm/plat-omap/include/dspbridge/mbx_sh.h +new file mode 100644 +index 0000000..be0909e +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/mbx_sh.h +@@ -0,0 +1,213 @@ ++/* ++ * mbx_sh.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== mbx_sh.h ======== ++ * Definitions for shared mailbox cmd/data values.(used on both ++ * the GPP and DSP sides). ++ * ++ * Bridge usage of OMAP mailbox 1 is determined by the "class" of the ++ * mailbox interrupt's cmd value received. The class value are defined ++ * as a bit (10 thru 15) being set. ++ * ++ * Note: Only 16 bits of each is used. Other 16 bit data reg available. ++ * ++ * 16 bit Mbx bit defns: ++ * ++ * A). Exception/Error handling (Module DEH) : class = 0. ++ * ++ * 15 10 0 ++ * --------------------------------- ++ * |0|0|0|0|0|0|x|x|x|x|x|x|x|x|x|x| ++ * --------------------------------- ++ * | (class) | (module specific) | ++ * ++ * ++ * ++ * B: DSP-DMA link driver channels (DDMA) : class = 1. ++ * ++ * 15 10 0 ++ * --------------------------------- ++ * |0|0|0|0|0|1|b|b|b|b|b|c|c|c|c|c| ++ * --------------------------------- ++ * | (class) | (module specific) | ++ * ++ * where b -> buffer index (32 DDMA buffers/chnl max) ++ * c -> channel Id (32 DDMA chnls max) ++ * ++ * ++ * ++ * ++ * C: Proc-copy link driver channels (PCPY) : class = 2. ++ * ++ * 15 10 0 ++ * --------------------------------- ++ * |0|0|0|0|1|0|x|x|x|x|x|x|x|x|x|x| ++ * --------------------------------- ++ * | (class) | (module specific) | ++ * ++ * ++ * D: Zero-copy link driver channels (DDZC) : class = 4. ++ * ++ * 15 10 0 ++ * --------------------------------- ++ * |0|0|0|1|0|0|x|x|x|x|x|c|c|c|c|c| ++ * --------------------------------- ++ * | (class) | (module specific) | ++ * ++ * where x -> not used ++ * c -> channel Id (32 ZCPY chnls max) ++ * ++ * ++ * E: Power management : class = 8. ++ * ++ * 15 10 0 ++ * --------------------------------- ++ * |0|0|1|0|0|0|x|x|x|x|x|c|c|c|c|c| ++ ++ * 0010 00xx xxxc cccc ++ * 0010 00nn pppp qqqq ++ * nn: ++ * 00 = reserved ++ * 01 = pwr state change ++ * 10 = opp pre-change ++ * 11 = opp post-change ++ * ++ * if nn = pwr state change: ++ * pppp = don't care ++ * qqqq: ++ * 0010 = hibernate ++ * 0010 0001 0000 0010 ++ * 0110 = retention ++ * 0010 0001 0000 0110 ++ * others reserved ++ * ++ * if nn = opp pre-change: ++ * pppp = current opp ++ * qqqq = next opp ++ * ++ * if nn = opp post-change: ++ * pppp = prev opp ++ * qqqq = current opp ++ * ++ * --------------------------------- ++ * | (class) | (module specific) | ++ * ++ * where x -> not used ++ * c -> Power management command ++ * ++ * ++ * ++ *! Revision History: ++ *! ================ ++ *! 19-Sep-2002 mr Added DEH reset const ++ *! 24-Apr-2002 sg Added more PM commands. ++ *! 04-Mar-2002 gv Added MBX_PM_CLASS ++ *! 22-Jan-2002 ag Bug fix in MBX_SETZCPYVAL(x) macro. ++ *! 21-Dec-2001 ag Added bit masks defns. ++ *! 17-Dec-2001 ag: created. ++ */ ++ ++#ifndef _MBX_SH_H ++#define _MBX_SH_H ++ ++#define MBX_CLASS_MSK 0xFC00 /* Class bits are 10 thru 15 */ ++#define MBX_VALUE_MSK 0x03FF /* Value is 0 thru 9 */ ++ ++#define MBX_DEH_CLASS 0x0000 /* DEH owns Mbx INTR */ ++#define MBX_DDMA_CLASS 0x0400 /* DSP-DMA link drvr chnls owns INTR */ ++#define MBX_PCPY_CLASS 0x0800 /* PROC-COPY " */ ++#define MBX_ZCPY_CLASS 0x1000 /* ZERO-COPY " */ ++#define MBX_PM_CLASS 0x2000 /* Power Management */ ++#define MBX_DBG_CLASS 0x4000 /* For debugging purpose */ ++ ++/* ++ * Exception Handler codes ++ * Magic code used to determine if DSP signaled exception. ++ */ ++#define MBX_DEH_BASE 0x0 ++#define MBX_DEH_USERS_BASE 0x100 /* 256 */ ++#define MBX_DEH_LIMIT 0x3FF /* 1023 */ ++#define MBX_DEH_RESET 0x101 /* DSP RESET (DEH) */ ++#define MBX_DEH_EMMU 0X103 /*DSP MMU FAULT RECOVERY*/ ++ ++/* ++ * Link driver command/status codes. ++ */ ++/* DSP-DMA */ ++#define MBX_DDMA_NUMCHNLBITS 5 /* # chnl Id: # bits available */ ++#define MBX_DDMA_CHNLSHIFT 0 /* # of bits to shift */ ++#define MBX_DDMA_CHNLMSK 0x01F /* bits 0 thru 4 */ ++ ++#define MBX_DDMA_NUMBUFBITS 5 /* buffer index: # of bits avail */ ++#define MBX_DDMA_BUFSHIFT (MBX_DDMA_NUMCHNLBITS + MBX_DDMA_CHNLSHIFT) ++#define MBX_DDMA_BUFMSK 0x3E0 /* bits 5 thru 9 */ ++ ++/* Zero-Copy */ ++#define MBX_ZCPY_NUMCHNLBITS 5 /* # chnl Id: # bits available */ ++#define MBX_ZCPY_CHNLSHIFT 0 /* # of bits to shift */ ++#define MBX_ZCPY_CHNLMSK 0x01F /* bits 0 thru 4 */ ++ ++/* Power Management Commands */ ++#define MBX_PM_DSPIDLE (MBX_PM_CLASS + 0x0) ++#define MBX_PM_DSPWAKEUP (MBX_PM_CLASS + 0x1) ++#define MBX_PM_EMERGENCYSLEEP (MBX_PM_CLASS + 0x2) ++#define MBX_PM_SLEEPUNTILRESTART (MBX_PM_CLASS + 0x3) ++#define MBX_PM_DSPGLOBALIDLE_OFF (MBX_PM_CLASS + 0x4) ++#define MBX_PM_DSPGLOBALIDLE_ON (MBX_PM_CLASS + 0x5) ++#define MBX_PM_SETPOINT_PRENOTIFY (MBX_PM_CLASS + 0x6) ++#define MBX_PM_SETPOINT_POSTNOTIFY (MBX_PM_CLASS + 0x7) ++#define MBX_PM_DSPRETN (MBX_PM_CLASS + 0x8) ++#define MBX_PM_DSPRETENTION (MBX_PM_CLASS + 0x8) ++#define MBX_PM_DSPHIBERNATE (MBX_PM_CLASS + 0x9) ++#define MBX_PM_HIBERNATE_EN (MBX_PM_CLASS + 0xA) ++#define MBX_PM_OPP_REQ (MBX_PM_CLASS + 0xB) ++#define MBX_PM_OPP_CHG (MBX_PM_CLASS + 0xC) ++ ++#define MBX_PM_TYPE_MASK 0x0300 ++#define MBX_PM_TYPE_PWR_CHNG 0x0100 ++#define MBX_PM_TYPE_OPP_PRECHNG 0x0200 ++#define MBX_PM_TYPE_OPP_POSTCHNG 0x0300 ++#define MBX_PM_TYPE_OPP_MASK 0x0300 ++#define MBX_PM_OPP_PRECHNG (MBX_PM_CLASS | MBX_PM_TYPE_OPP_PRECHNG) ++/* DSP to MPU */ ++#define MBX_PM_OPP_CHNG(OPP) (MBX_PM_CLASS | MBX_PM_TYPE_OPP_PRECHNG | (OPP)) ++#define MBX_PM_RET (MBX_PM_CLASS | MBX_PM_TYPE_PWR_CHNG | 0x0006) ++#define MBX_PM_HIB (MBX_PM_CLASS | MBX_PM_TYPE_PWR_CHNG | 0x0002) ++#define MBX_PM_OPP_1 0 ++#define MBX_PM_OPP_2 1 ++#define MBX_PM_OPP_3 2 ++#define MBX_PM_OPP_4 3 ++#define MBX_OLDOPP_EXTRACT(OPPMSG) ((0x00F0 & (OPPMSG)) >> 4) ++#define MBX_NEWOPP_EXTRACT(OPPMSG) (0x000F & (OPPMSG)) ++#define MBX_PREVOPP_EXTRACT(OPPMSG) ((0x00F0 & (OPPMSG)) >> 4) ++#define MBX_CUROPP_EXTRACT(OPPMSG) (0x000F & (OPPMSG)) ++ ++/* Bridge Debug Commands */ ++#define MBX_DBG_SYSPRINTF (MBX_DBG_CLASS + 0x0) ++ ++/* ++ * Useful macros ++ */ ++/* DSP-DMA channel */ ++#define MBX_SETDDMAVAL(x, y) (MBX_DDMA_CLASS | (x << MBX_DDMA_BUFSHIFT) | \ ++ (y << MBX_DDMA_CHNLSHIFT)) ++ ++/* Zero-Copy channel */ ++#define MBX_SETZCPYVAL(x) (MBX_ZCPY_CLASS | (x << MBX_ZCPY_CHNLSHIFT)) ++ ++#endif /* _MBX_SH_H */ +diff --git a/arch/arm/plat-omap/include/dspbridge/mem.h b/arch/arm/plat-omap/include/dspbridge/mem.h +new file mode 100644 +index 0000000..535ac3a +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/mem.h +@@ -0,0 +1,340 @@ ++/* ++ * mem.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== mem.h ======== ++ * Purpose: ++ * Memory management and address mapping services for the DSP/BIOS Bridge ++ * class driver and mini-driver. ++ * ++ * Public Functions: ++ * MEM_Alloc ++ * MEM_AllocObject ++ * MEM_AllocPhysMem ++ * MEM_Calloc ++ * MEM_Exit ++ * MEM_FlushCache ++ * MEM_Free ++ * MEM_FreeObject ++ * MEM_FreePhysMem ++ * MEM_GetNumPages ++ * MEM_Init ++ * MEM_IsValidHandle ++ * MEM_LinearAddress ++ * MEM_PageLock ++ * MEM_PageUnlock ++ * MEM_UnMapLinearAddress ++ * MEM_VirtualToPhysical ++ * ++ * Notes: ++ * ++ *! Revision History: ++ *! ================ ++ *! 19-Apr-2004 sb: Added Alloc/Free PhysMem, FlushCache, VirtualToPhysical ++ *! 01-Sep-2001 ag: Cleaned up notes for MEM_LinearAddress() does not ++ *! require phys address to be page aligned! ++ *! 02-Dec-1999 rr: stdwin.h included for retail build ++ *! 12-Nov-1999 kc: Added warning about use of MEM_LinearAddress. ++ *! 29-Oct-1999 kc: Cleaned up for code review. ++ *! 10-Aug-1999 kc: Based on wsx-c18. ++ *! 07-Jan-1998 gp: Added MEM_AllocUMB and MEM_UMBFree for User Mapped Buffers ++ *! used by WMD_CHNL. ++ *! 23-Dec-1997 cr: Code review cleanup, removed dead Ring 3 code. ++ *! 04-Aug-1997 cr: Added explicit CDECL identifiers. ++ *! 01-Nov-1996 gp: Updated based on code review. ++ *! 04-Sep-1996 gp: Added MEM_PageLock() and MEM_PageUnlock() services. ++ *! 14-Aug-1996 mg: Added MEM_GetPhysAddr() and MEM_GetNumPages() ++ *! 25-Jul-1996 gp: Added MEM_IsValidHandle() macro. ++ *! 10-May-1996 gp: Added MEM_Calloc(). ++ *! 25-Apr-1996 gp: Added MEM_PhysicalAddress() ++ *! 17-Apr-1996 gp: Added MEM_Exit function; updated to latest naming standard. ++ *! 08-Apr-1996 gp: Created. ++ */ ++ ++#ifndef MEM_ ++#define MEM_ ++ ++#include ++#include ++ ++/* ++ * ======== MEM_Alloc ======== ++ * Purpose: ++ * Allocate memory from the paged or non-paged pools. ++ * Parameters: ++ * cBytes: Number of bytes to allocate. ++ * type: Type of memory to allocate; one of: ++ * MEM_PAGED: Allocate from pageable memory. ++ * MEM_NONPAGED: Allocate from page locked memory. ++ * Returns: ++ * Pointer to a block of memory; ++ * NULL if memory couldn't be allocated, if cBytes == 0, or if type is ++ * not one of MEM_PAGED or MEM_NONPAGED. ++ * Requires: ++ * MEM initialized. ++ * Ensures: ++ * The returned pointer, if not NULL, points to a valid memory block of ++ * the size requested. ++ */ ++ extern void *MEM_Alloc(IN u32 cBytes, IN enum MEM_POOLATTRS type); ++ ++/* ++ * ======== MEM_AllocObject ======== ++ * Purpose: ++ * Allocate an object, and set it's signature. ++ * Parameters: ++ * pObj: Pointer to the new object. ++ * Obj: Type of the object to allocate. ++ * Signature: Magic field value. Must be non-zero. ++ * Returns: ++ * Requires: ++ * Same requirements as MEM_Calloc(); and ++ * The object structure has a dwSignature field. The compiler ensures ++ * this requirement. ++ * Ensures: ++ * A subsequent call to MEM_IsValidHandle() will succeed for this object. ++ */ ++#define MEM_AllocObject(pObj, Obj, Signature) \ ++{ \ ++ pObj = MEM_Calloc(sizeof(Obj), MEM_NONPAGED); \ ++ if (pObj) { \ ++ pObj->dwSignature = Signature; \ ++ } \ ++} ++ ++/* ======== MEM_AllocPhysMem ======== ++ * Purpose: ++ * Allocate physically contiguous, uncached memory ++ * Parameters: ++ * cBytes: Number of bytes to allocate. ++ * ulAlign: Alignment Mask. ++ * pPhysicalAddress: Physical address of allocated memory. ++ * Returns: ++ * Pointer to a block of memory; ++ * NULL if memory couldn't be allocated, or if cBytes == 0. ++ * Requires: ++ * MEM initialized. ++ * Ensures: ++ * The returned pointer, if not NULL, points to a valid memory block of ++ * the size requested. Returned physical address refers to physical ++ * location of memory. ++ */ ++ extern void *MEM_AllocPhysMem(IN u32 cBytes, ++ IN u32 ulAlign, ++ OUT u32 *pPhysicalAddress); ++ ++/* ++ * ======== MEM_Calloc ======== ++ * Purpose: ++ * Allocate zero-initialized memory from the paged or non-paged pools. ++ * Parameters: ++ * cBytes: Number of bytes to allocate. ++ * type: Type of memory to allocate; one of: ++ * MEM_PAGED: Allocate from pageable memory. ++ * MEM_NONPAGED: Allocate from page locked memory. ++ * Returns: ++ * Pointer to a block of zeroed memory; ++ * NULL if memory couldn't be allocated, if cBytes == 0, or if type is ++ * not one of MEM_PAGED or MEM_NONPAGED. ++ * Requires: ++ * MEM initialized. ++ * Ensures: ++ * The returned pointer, if not NULL, points to a valid memory block ++ * of the size requested. ++ */ ++ extern void *MEM_Calloc(IN u32 cBytes, IN enum MEM_POOLATTRS type); ++ ++/* ++ * ======== MEM_Exit ======== ++ * Purpose: ++ * Discontinue usage of module; free resources when reference count ++ * reaches 0. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * MEM is initialized. ++ * Ensures: ++ * Resources used by module are freed when cRef reaches zero. ++ */ ++ extern void MEM_Exit(void); ++ ++/* ++ * ======== MEM_FlushCache ======== ++ * Purpose: ++ * Performs system cache sync with discard ++ * Parameters: ++ * pMemBuf: Pointer to memory region to be flushed. ++ * pMemBuf: Size of the memory region to be flushed. ++ * Returns: ++ * Requires: ++ * MEM is initialized. ++ * Ensures: ++ * Cache is synchronized ++ */ ++ extern void MEM_FlushCache(void *pMemBuf, u32 cBytes, s32 FlushType); ++ ++/* ++ * ======== MEM_Free ======== ++ * Purpose: ++ * Free the given block of system memory. ++ * Parameters: ++ * pMemBuf: Pointer to memory allocated by MEM_Calloc/Alloc(). ++ * Returns: ++ * Requires: ++ * MEM initialized. ++ * pMemBuf is a valid memory address returned by MEM_Calloc/Alloc(). ++ * Ensures: ++ * pMemBuf is no longer a valid pointer to memory. ++ */ ++ extern void MEM_Free(IN void *pMemBuf); ++ ++/* ++ * ======== MEM_FreePhysMem ======== ++ * Purpose: ++ * Free the given block of physically contiguous memory. ++ * Parameters: ++ * pVirtualAddress: Pointer to virtual memory region allocated ++ * by MEM_AllocPhysMem(). ++ * pPhysicalAddress: Pointer to physical memory region allocated ++ * by MEM_AllocPhysMem(). ++ * cBytes: Size of the memory region allocated by MEM_AllocPhysMem(). ++ * Returns: ++ * Requires: ++ * MEM initialized. ++ * pVirtualAddress is a valid memory address returned by ++ * MEM_AllocPhysMem() ++ * Ensures: ++ * pVirtualAddress is no longer a valid pointer to memory. ++ */ ++ extern void MEM_FreePhysMem(void *pVirtualAddress, ++ u32 pPhysicalAddress, u32 cBytes); ++ ++/* ++ * ======== MEM_FreeObject ======== ++ * Purpose: ++ * Utility macro to invalidate an object's signature, and deallocate it. ++ * Parameters: ++ * pObj: Pointer to the object to free. ++ * Returns: ++ * Requires: ++ * Same requirements as MEM_Free(). ++ * Ensures: ++ * A subsequent call to MEM_IsValidHandle() will fail for this object. ++ */ ++#define MEM_FreeObject(pObj) \ ++{ \ ++ pObj->dwSignature = 0x00; \ ++ MEM_Free(pObj); \ ++} ++ ++/* ++ * ======== MEM_GetNumPages ======== ++ * Purpose: ++ * Calculate the number of pages corresponding to the supplied buffer. ++ * Parameters: ++ * pAddr: Linear (virtual) address of the buffer. ++ * cBytes: Number of bytes in the buffer. ++ * Returns: ++ * Number of pages. ++ * Requires: ++ * MEM initialized. ++ * Ensures: ++ * If cBytes > 0, number of pages returned > 0. ++ */ ++ extern s32 MEM_GetNumPages(IN void *pAddr, IN u32 cBytes); ++ ++/* ++ * ======== MEM_Init ======== ++ * Purpose: ++ * Initializes private state of MEM module. ++ * Parameters: ++ * Returns: ++ * TRUE if initialized; FALSE if error occured. ++ * Requires: ++ * Ensures: ++ * MEM initialized. ++ */ ++ extern bool MEM_Init(void); ++ ++/* ++ * ======== MEM_IsValidHandle ======== ++ * Purpose: ++ * Validate the object handle. ++ * Parameters: ++ * hObj: Handle to object created with MEM_AllocObject(). ++ * Sig: Expected signature u32. ++ * Returns: ++ * TRUE if handle is valid; FALSE otherwise. ++ * Requires: ++ * The object structure has a dwSignature field. Ensured by compiler. ++ * Ensures: ++ */ ++#define MEM_IsValidHandle(hObj, Sig) \ ++ ((hObj != NULL) && (hObj->dwSignature == Sig)) ++ ++/* ++ * ======== MEM_LinearAddress ======== ++ * Purpose: ++ * Get the linear address corresponding to the given physical address. ++ * Parameters: ++ * pPhysAddr: Physical address to be mapped. ++ * cBytes: Number of bytes in physical range to map. ++ * Returns: ++ * The corresponding linear address, or NULL if unsuccessful. ++ * Requires: ++ * MEM initialized. ++ * Ensures: ++ * Notes: ++ * If valid linear address is returned, be sure to call ++ * MEM_UnmapLinearAddress(). ++ */ ++#define MEM_LinearAddress(pPhyAddr, cBytes) pPhyAddr ++ ++/* ++ * ======== MEM_UnmapLinearAddress ======== ++ * Purpose: ++ * Unmap the linear address mapped in MEM_LinearAddress. ++ * Parameters: ++ * pBaseAddr: Ptr to mapped memory (as returned by MEM_LinearAddress()). ++ * Returns: ++ * Requires: ++ * - MEM initialized. ++ * - pBaseAddr is a valid linear address mapped in MEM_LinearAddress. ++ * Ensures: ++ * - pBaseAddr no longer points to a valid linear address. ++ */ ++#define MEM_UnmapLinearAddress(pBaseAddr) ++ ++/* ++ * ======== MEM_ExtPhysPoolInit ======== ++ * Purpose: ++ * Uses the physical memory chunk passed for internal consitent memory ++ * allocations. ++ * physical address based on the page frame address. ++ * Parameters: ++ * poolPhysBase starting address of the physical memory pool. ++ * poolSize size of the physical memory pool. ++ * Returns: ++ * none. ++ * Requires: ++ * - MEM initialized. ++ * - valid physical address for the base and size > 0 ++ */ ++ extern void MEM_ExtPhysPoolInit(IN u32 poolPhysBase, ++ IN u32 poolSize); ++ ++#endif /* MEM_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/memdefs.h b/arch/arm/plat-omap/include/dspbridge/memdefs.h +new file mode 100644 +index 0000000..a5bb259 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/memdefs.h +@@ -0,0 +1,52 @@ ++/* ++ * memdefs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== memdefs.h ======== ++ * Purpose: ++ * Global MEM constants and types, shared between WSX, WCD, and WMD. ++ * ++ *! Revision History: ++ *! ================ ++ *! 28-Aug-2001 ag: Added MEM_[SET][GET]VIRTUALSEGID. ++ *! 10-Aug-1999 kc: Based on wsx-c18. ++ *! 15-Nov-1996 gp: Renamed from wsxmem.h and moved to kwinos. ++ *! 21-Aug-1996 cr: Created from mem.h. ++ */ ++ ++#ifndef MEMDEFS_ ++#define MEMDEFS_ ++ ++/* Memory Pool Attributes: */ ++ enum MEM_POOLATTRS { ++ MEM_PAGED = 0, ++ MEM_NONPAGED = 1, ++ MEM_LARGEVIRTMEM = 2 ++ } ; ++ ++/* ++ * MEM_VIRTUALSEGID is used by Node & Strm to access virtual address space in ++ * the correct client process context. ++ */ ++#define MEM_SETVIRTUALSEGID 0x10000000 ++#define MEM_GETVIRTUALSEGID 0x20000000 ++#define MEM_MASKVIRTUALSEGID (MEM_SETVIRTUALSEGID | MEM_GETVIRTUALSEGID) ++ ++#define TO_VIRTUAL_UNCACHED(x) x ++#define INTREG_TO_VIRTUAL_UNCACHED(x) x ++ ++#endif /* MEMDEFS_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/mgr.h b/arch/arm/plat-omap/include/dspbridge/mgr.h +new file mode 100644 +index 0000000..24c4472 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/mgr.h +@@ -0,0 +1,234 @@ ++/* ++ * mgr.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== mgr.h ======== ++ * Description: ++ * This is the Class driver RM module interface. ++ * ++ * Public Functions: ++ * MGR_Create ++ * MGR_Destroy ++ * MGR_EnumNodeInfo ++ * MGR_EnumProcessorInfo ++ * MGR_Exit ++ * MGR_GetDCDHandle ++ * MGR_Init ++ * ++ * Notes: ++ * ++ *! Revision History: ++ *! ================ ++ *! 15-Oct-2002 kc: Removed legacy PERF definitions. ++ *! 11-Jul-2001 jeh Added CFG_HDEVNODE parameter to MGR_Create(). ++ *! 22-Nov-2000 kc: Added MGR_GetPerfData for acquiring PERF stats. ++ *! 03-Nov-2000 rr: Added MGR_GetDCDHandle. Modified after code review. ++ *! 25-Sep-2000 rr: Updated to Version 0.9 ++ *! 14-Aug-2000 rr: Cleaned up. ++ *! 07-Aug-2000 rr: MGR_Create does the job of Loading DCD Dll. ++ *! 27-Jul-2000 rr: Updated to ver 0.8 of DSPAPI(types). ++ *! 20-Jun-2000 rr: Created. ++ */ ++ ++#ifndef MGR_ ++#define MGR_ ++ ++#include ++ ++#define MAX_EVENTS 32 ++ ++/* ++ * ======== MGR_WaitForBridgeEvents ======== ++ * Purpose: ++ * Block on any Bridge event(s) ++ * Parameters: ++ * aNotifications : array of pointers to notification objects. ++ * uCount : number of elements in above array ++ * puIndex : index of signaled event object ++ * uTimeout : timeout interval in milliseocnds ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_ETIMEOUT : Wait timed out. *puIndex is undetermined. ++ * Details: ++ */ ++ ++ DSP_STATUS MGR_WaitForBridgeEvents(struct DSP_NOTIFICATION ++ **aNotifications, ++ u32 uCount, OUT u32 *puIndex, ++ u32 uTimeout); ++ ++/* ++ * ======== MGR_Create ======== ++ * Purpose: ++ * Creates the Manager Object. This is done during the driver loading. ++ * There is only one Manager Object in the DSP/BIOS Bridge. ++ * Parameters: ++ * phMgrObject: Location to store created MGR Object handle. ++ * hDevNode: Device object as known to Windows system. ++ * Returns: ++ * DSP_SOK: Success ++ * DSP_EMEMORY: Failed to Create the Object ++ * DSP_EFAIL: General Failure ++ * Requires: ++ * MGR Initialized (cRefs > 0 ) ++ * phMgrObject != NULL. ++ * Ensures: ++ * DSP_SOK: *phMgrObject is a valid MGR interface to the device. ++ * MGR Object stores the DCD Manager Handle. ++ * MGR Object stored in the Regsitry. ++ * !DSP_SOK: MGR Object not created ++ * Details: ++ * DCD Dll is loaded and MGR Object stores the handle of the DLL. ++ */ ++ extern DSP_STATUS MGR_Create(OUT struct MGR_OBJECT **hMgrObject, ++ struct CFG_DEVNODE *hDevNode); ++ ++/* ++ * ======== MGR_Destroy ======== ++ * Purpose: ++ * Destroys the MGR object. Called upon driver unloading. ++ * Parameters: ++ * hMgrObject: Handle to Manager object . ++ * Returns: ++ * DSP_SOK: Success. ++ * DCD Manager freed; MGR Object destroyed; ++ * MGR Object deleted from the Registry. ++ * DSP_EFAIL: Failed to destroy MGR Object ++ * Requires: ++ * MGR Initialized (cRefs > 0 ) ++ * hMgrObject is a valid MGR handle . ++ * Ensures: ++ * DSP_SOK: MGR Object destroyed and hMgrObject is Invalid MGR ++ * Handle. ++ */ ++ extern DSP_STATUS MGR_Destroy(struct MGR_OBJECT *hMgrObject); ++ ++/* ++ * ======== MGR_EnumNodeInfo ======== ++ * Purpose: ++ * Enumerate and get configuration information about nodes configured ++ * in the node database. ++ * Parameters: ++ * uNode: The node index (base 0). ++ * pNDBProps: Ptr to the DSP_NDBPROPS structure for output. ++ * uNDBPropsSize: Size of the DSP_NDBPROPS structure. ++ * puNumNodes: Location where the number of nodes configured ++ * in the database will be returned. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EINVALIDARG: Parameter uNode is > than the number of nodes. ++ * configutred in the system ++ * DSP_ECHANGEDURINGENUM: During Enumeration there has been a change in ++ * the number of nodes configured or in the ++ * the properties of the enumerated nodes. ++ * DSP_EFAIL: Failed to querry the Node Data Base ++ * Requires: ++ * pNDBPROPS is not null ++ * uNDBPropsSize >= sizeof(DSP_NDBPROPS) ++ * puNumNodes is not null ++ * MGR Initialized (cRefs > 0 ) ++ * Ensures: ++ * SUCCESS on successful retreival of data and *puNumNodes > 0 OR ++ * DSP_FAILED && *puNumNodes == 0. ++ * Details: ++ */ ++ extern DSP_STATUS MGR_EnumNodeInfo(u32 uNode, ++ OUT struct DSP_NDBPROPS *pNDBProps, ++ u32 uNDBPropsSize, ++ OUT u32 *puNumNodes); ++ ++/* ++ * ======== MGR_EnumProcessorInfo ======== ++ * Purpose: ++ * Enumerate and get configuration information about available DSP ++ * processors ++ * Parameters: ++ * uProcessor: The processor index (zero-based). ++ * pProcessorInfo: Ptr to the DSP_PROCESSORINFO structure . ++ * uProcessorInfoSize: Size of DSP_PROCESSORINFO structure. ++ * puNumProcs: Location where the number of DSPs configured ++ * in the database will be returned ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EINVALIDARG: Parameter uProcessor is > than the number of ++ * DSP Processors in the system. ++ * DSP_EFAIL: Failed to querry the Node Data Base ++ * Requires: ++ * pProcessorInfo is not null ++ * puNumProcs is not null ++ * uProcessorInfoSize >= sizeof(DSP_PROCESSORINFO) ++ * MGR Initialized (cRefs > 0 ) ++ * Ensures: ++ * SUCCESS on successful retreival of data and *puNumProcs > 0 OR ++ * DSP_FAILED && *puNumProcs == 0. ++ * Details: ++ */ ++ extern DSP_STATUS MGR_EnumProcessorInfo(u32 uProcessor, ++ OUT struct DSP_PROCESSORINFO * ++ pProcessorInfo, ++ u32 uProcessorInfoSize, ++ OUT u32 *puNumProcs); ++/* ++ * ======== MGR_Exit ======== ++ * Purpose: ++ * Decrement reference count, and free resources when reference count is ++ * 0. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * MGR is initialized. ++ * Ensures: ++ * When reference count == 0, MGR's private resources are freed. ++ */ ++ extern void MGR_Exit(void); ++ ++/* ++ * ======== MGR_GetDCDHandle ======== ++ * Purpose: ++ * Retrieves the MGR handle. Accessor Function ++ * Parameters: ++ * hMGRHandle: Handle to the Manager Object ++ * phDCDHandle: Ptr to receive the DCD Handle. ++ * Returns: ++ * DSP_SOK: Sucess ++ * DSP_EFAIL: Failure to get the Handle ++ * Requires: ++ * MGR is initialized. ++ * phDCDHandle != NULL ++ * Ensures: ++ * DSP_SOK and *phDCDHandle != NULL || ++ * DSP_EFAIL and *phDCDHandle == NULL ++ */ ++ extern DSP_STATUS MGR_GetDCDHandle(IN struct MGR_OBJECT ++ *hMGRHandle, ++ OUT u32 *phDCDHandle); ++ ++/* ++ * ======== MGR_Init ======== ++ * Purpose: ++ * Initialize MGR's private state, keeping a reference count on each ++ * call. Intializes the DCD. ++ * Parameters: ++ * Returns: ++ * TRUE if initialized; FALSE if error occured. ++ * Requires: ++ * Ensures: ++ * TRUE: A requirement for the other public MGR functions. ++ */ ++ extern bool MGR_Init(void); ++ ++#endif /* MGR_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/mgrpriv.h b/arch/arm/plat-omap/include/dspbridge/mgrpriv.h +new file mode 100644 +index 0000000..4a34086 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/mgrpriv.h +@@ -0,0 +1,55 @@ ++/* ++ * mgrpriv.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== mgrpriv.h ======== ++ * Description: ++ * Global MGR constants and types, shared by PROC, MGR, and WCD. ++ * ++ *! Revision History: ++ *! ================ ++ *! 29-July-2001 ag: added MGR_PROCESSOREXTINFO. ++ *! 05-July-2000 rr: Created ++ */ ++ ++#ifndef MGRPRIV_ ++#define MGRPRIV_ ++ ++/* ++ * OMAP1510 specific ++ */ ++#define MGR_MAXTLBENTRIES 32 ++ ++/* RM MGR Object */ ++ struct MGR_OBJECT; ++ ++ struct MGR_TLBENTRY { ++ u32 ulDspVirt; /* DSP virtual address */ ++ u32 ulGppPhys; /* GPP physical address */ ++ } ; ++ ++/* ++ * The DSP_PROCESSOREXTINFO structure describes additional extended ++ * capabilities of a DSP processor not exposed to user. ++ */ ++ struct MGR_PROCESSOREXTINFO { ++ struct DSP_PROCESSORINFO tyBasic; /* user processor info */ ++ /* private dsp mmu entries */ ++ struct MGR_TLBENTRY tyTlb[MGR_MAXTLBENTRIES]; ++ } ; ++ ++#endif /* MGRPRIV_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/msg.h b/arch/arm/plat-omap/include/dspbridge/msg.h +new file mode 100644 +index 0000000..f2872cc +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/msg.h +@@ -0,0 +1,106 @@ ++/* ++ * msg.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== msg.h ======== ++ * Description: ++ * DSP/BIOS Bridge MSG Module. ++ * ++ * Public Functions: ++ * MSG_Create ++ * MSG_Delete ++ * MSG_Exit ++ * MSG_Init ++ * ++ * Notes: ++ * ++ *! Revision History: ++ *! ================= ++ *! 17-Nov-2000 jeh Removed MSG_Get, MSG_Put, MSG_CreateQueue, ++ *! MSG_DeleteQueue, and MSG_RegisterNotify, since these ++ *! are now part of mini-driver. ++ *! 12-Sep-2000 jeh Created. ++ */ ++ ++#ifndef MSG_ ++#define MSG_ ++ ++#include ++#include ++ ++/* ++ * ======== MSG_Create ======== ++ * Purpose: ++ * Create an object to manage message queues. Only one of these objects ++ * can exist per device object. The MSG manager must be created before ++ * the IO Manager. ++ * Parameters: ++ * phMsgMgr: Location to store MSG manager handle on output. ++ * hDevObject: The device object. ++ * msgCallback: Called whenever an RMS_EXIT message is received. ++ * Returns: ++ * Requires: ++ * MSG_Init(void) called. ++ * phMsgMgr != NULL. ++ * hDevObject != NULL. ++ * msgCallback != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS MSG_Create(OUT struct MSG_MGR **phMsgMgr, ++ struct DEV_OBJECT *hDevObject, ++ MSG_ONEXIT msgCallback); ++ ++/* ++ * ======== MSG_Delete ======== ++ * Purpose: ++ * Delete a MSG manager allocated in MSG_Create(). ++ * Parameters: ++ * hMsgMgr: Handle returned from MSG_Create(). ++ * Returns: ++ * Requires: ++ * MSG_Init(void) called. ++ * Valid hMsgMgr. ++ * Ensures: ++ */ ++ extern void MSG_Delete(struct MSG_MGR *hMsgMgr); ++ ++/* ++ * ======== MSG_Exit ======== ++ * Purpose: ++ * Discontinue usage of MSG module. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * MSG_Init(void) successfully called before. ++ * Ensures: ++ * Any resources acquired in MSG_Init(void) will be freed when last MSG ++ * client calls MSG_Exit(void). ++ */ ++ extern void MSG_Exit(void); ++ ++/* ++ * ======== MSG_Init ======== ++ * Purpose: ++ * Initialize the MSG module. ++ * Parameters: ++ * Returns: ++ * TRUE if initialization succeeded, FALSE otherwise. ++ * Ensures: ++ */ ++ extern bool MSG_Init(void); ++ ++#endif /* MSG_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/msgdefs.h b/arch/arm/plat-omap/include/dspbridge/msgdefs.h +new file mode 100644 +index 0000000..8ea4551 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/msgdefs.h +@@ -0,0 +1,43 @@ ++/* ++ * msgdefs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== msgdefs.h ======== ++ * Description: ++ * Global MSG constants and types. ++ * ++ *! Revision History ++ *! ================ ++ *! 09-May-2001 jeh Removed MSG_TODSP, MSG_FROMDSP. ++ *! 17-Nov-2000 jeh Added MSGMGR_SIGNATURE. ++ *! 12-Sep-2000 jeh Created. ++ */ ++ ++#ifndef MSGDEFS_ ++#define MSGDEFS_ ++ ++#define MSGMGR_SIGNATURE 0x4d47534d /* "MGSM" */ ++ ++/* MSG Objects: */ ++ struct MSG_MGR; ++ struct MSG_QUEUE; ++ ++/* Function prototype for callback to be called on RMS_EXIT message received */ ++ typedef void(*MSG_ONEXIT) (HANDLE h, s32 nStatus); ++ ++#endif /* MSGDEFS_ */ ++ +diff --git a/arch/arm/plat-omap/include/dspbridge/nldr.h b/arch/arm/plat-omap/include/dspbridge/nldr.h +new file mode 100644 +index 0000000..0915846 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/nldr.h +@@ -0,0 +1,81 @@ ++/* ++ * nldr.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== nldr.h ======== ++ * ++ * Description: ++ * DSP/BIOS Bridge dynamic loader interface. See the file dldrdefs.h ++ * for a description of these functions. ++ * ++ * Public Functions: ++ * NLDR_Allocate ++ * NLDR_Create ++ * NLDR_Delete ++ * NLDR_Exit ++ * NLDR_Free ++ * NLDR_GetFxnAddr ++ * NLDR_Init ++ * NLDR_Load ++ * NLDR_Unload ++ * ++ * Notes: ++ * ++ *! Revision History ++ *! ================ ++ *! 31-Jul-2002 jeh Removed function header comments. ++ *! 17-Apr-2002 jeh Created. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifndef NLDR_ ++#define NLDR_ ++ ++ extern DSP_STATUS NLDR_Allocate(struct NLDR_OBJECT *hNldr, ++ void *pPrivRef, ++ IN CONST struct DCD_NODEPROPS ++ *pNodeProps, ++ OUT struct NLDR_NODEOBJECT **phNldrNode, ++ IN bool *pfPhaseSplit); ++ ++ extern DSP_STATUS NLDR_Create(OUT struct NLDR_OBJECT **phNldr, ++ struct DEV_OBJECT *hDevObject, ++ IN CONST struct NLDR_ATTRS *pAttrs); ++ ++ extern void NLDR_Delete(struct NLDR_OBJECT *hNldr); ++ extern void NLDR_Exit(void); ++ extern void NLDR_Free(struct NLDR_NODEOBJECT *hNldrNode); ++ ++ extern DSP_STATUS NLDR_GetFxnAddr(struct NLDR_NODEOBJECT *hNldrNode, ++ char *pstrFxn, u32 *pulAddr); ++ ++ extern DSP_STATUS NLDR_GetRmmManager(struct NLDR_OBJECT *hNldrObject, ++ OUT struct RMM_TargetObj ++ **phRmmMgr); ++ ++ extern bool NLDR_Init(void); ++ extern DSP_STATUS NLDR_Load(struct NLDR_NODEOBJECT *hNldrNode, ++ enum NLDR_PHASE phase); ++ extern DSP_STATUS NLDR_Unload(struct NLDR_NODEOBJECT *hNldrNode, ++ enum NLDR_PHASE phase); ++ ++#endif /* NLDR_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/nldrdefs.h b/arch/arm/plat-omap/include/dspbridge/nldrdefs.h +new file mode 100644 +index 0000000..84b36a3 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/nldrdefs.h +@@ -0,0 +1,307 @@ ++/* ++ * nldrdefs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== nldrdefs.h ======== ++ * Description: ++ * Global Dynamic + static/overlay Node loader (NLDR) constants and types. ++ * ++ *! Revision History ++ *! ================ ++ *! 07-Apr-2003 map Consolidated dldrdefs.h into nldrdefs.h ++ *! 05-Aug-2002 jeh Created. ++ */ ++ ++#ifndef NLDRDEFS_ ++#define NLDRDEFS_ ++ ++#include ++#include ++ ++#define NLDR_MAXPATHLENGTH 255 ++/* NLDR Objects: */ ++ struct NLDR_OBJECT; ++ struct NLDR_NODEOBJECT; ++ ++/* ++ * ======== NLDR_LOADTYPE ======== ++ * Load types for a node. Must match values in node.h55. ++ */ ++ enum NLDR_LOADTYPE { ++ NLDR_STATICLOAD, /* Linked in base image, not overlay */ ++ NLDR_DYNAMICLOAD, /* Dynamically loaded node */ ++ NLDR_OVLYLOAD /* Linked in base image, overlay node */ ++ } ; ++ ++/* ++ * ======== NLDR_OVLYFXN ======== ++ * Causes code or data to be copied from load address to run address. This ++ * is the "COD_WRITEFXN" that gets passed to the DBLL_Library and is used as ++ * the ZL write function. ++ * ++ * Parameters: ++ * pPrivRef: Handle to identify the node. ++ * ulDspRunAddr: Run address of code or data. ++ * ulDspLoadAddr: Load address of code or data. ++ * ulNumBytes: Number of (GPP) bytes to copy. ++ * nMemSpace: RMS_CODE or RMS_DATA. ++ * Returns: ++ * ulNumBytes: Success. ++ * 0: Failure. ++ * Requires: ++ * Ensures: ++ */ ++ typedef u32(*NLDR_OVLYFXN) (void *pPrivRef, u32 ulDspRunAddr, ++ u32 ulDspLoadAddr, ++ u32 ulNumBytes, u32 nMemSpace); ++ ++/* ++ * ======== NLDR_WRITEFXN ======== ++ * Write memory function. Used for dynamic load writes. ++ * Parameters: ++ * pPrivRef: Handle to identify the node. ++ * ulDspAddr: Address of code or data. ++ * pBuf: Code or data to be written ++ * ulNumBytes: Number of (GPP) bytes to write. ++ * nMemSpace: DBLL_DATA or DBLL_CODE. ++ * Returns: ++ * ulNumBytes: Success. ++ * 0: Failure. ++ * Requires: ++ * Ensures: ++ */ ++ typedef u32(*NLDR_WRITEFXN) (void *pPrivRef, ++ u32 ulDspAddr, void *pBuf, ++ u32 ulNumBytes, u32 nMemSpace); ++ ++/* ++ * ======== NLDR_ATTRS ======== ++ * Attributes passed to NLDR_Create function. ++ */ ++ struct NLDR_ATTRS { ++ NLDR_OVLYFXN pfnOvly; ++ NLDR_WRITEFXN pfnWrite; ++ u16 usDSPWordSize; ++ u16 usDSPMauSize; ++ } ; ++ ++/* ++ * ======== NLDR_PHASE ======== ++ * Indicates node create, delete, or execute phase function. ++ */ ++ enum NLDR_PHASE { ++ NLDR_CREATE, ++ NLDR_DELETE, ++ NLDR_EXECUTE, ++ NLDR_NOPHASE ++ } ; ++ ++/* ++ * Typedefs of loader functions imported from a DLL, or defined in a ++ * function table. ++ */ ++ ++/* ++ * ======== NLDR_Allocate ======== ++ * Allocate resources to manage the loading of a node on the DSP. ++ * ++ * Parameters: ++ * hNldr: Handle of loader that will load the node. ++ * pPrivRef: Handle to identify the node. ++ * pNodeProps: Pointer to a DCD_NODEPROPS for the node. ++ * phNldrNode: Location to store node handle on output. This handle ++ * will be passed to NLDR_Load/NLDR_Unload. ++ * pfPhaseSplit: pointer to boolean variable referenced in node.c ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Insufficient memory on GPP. ++ * Requires: ++ * NLDR_Init(void) called. ++ * Valid hNldr. ++ * pNodeProps != NULL. ++ * phNldrNode != NULL. ++ * Ensures: ++ * DSP_SOK: IsValidNode(*phNldrNode). ++ * error: *phNldrNode == NULL. ++ */ ++ typedef DSP_STATUS(*NLDR_ALLOCATEFXN) (struct NLDR_OBJECT *hNldr, ++ void *pPrivRef, ++ IN CONST struct DCD_NODEPROPS ++ *pNodeProps, ++ OUT struct NLDR_NODEOBJECT ++ **phNldrNode, ++ OUT bool *pfPhaseSplit); ++ ++/* ++ * ======== NLDR_Create ======== ++ * Create a loader object. This object handles the loading and unloading of ++ * create, delete, and execute phase functions of nodes on the DSP target. ++ * ++ * Parameters: ++ * phNldr: Location to store loader handle on output. ++ * hDevObject: Device for this processor. ++ * pAttrs: Loader attributes. ++ * Returns: ++ * DSP_SOK: Success; ++ * DSP_EMEMORY: Insufficient memory for requested resources. ++ * Requires: ++ * NLDR_Init(void) called. ++ * phNldr != NULL. ++ * hDevObject != NULL. ++ * pAttrs != NULL. ++ * Ensures: ++ * DSP_SOK: Valid *phNldr. ++ * error: *phNldr == NULL. ++ */ ++ typedef DSP_STATUS(*NLDR_CREATEFXN) (OUT struct NLDR_OBJECT **phNldr, ++ struct DEV_OBJECT *hDevObject, ++ IN CONST struct NLDR_ATTRS ++ *pAttrs); ++ ++/* ++ * ======== NLDR_Delete ======== ++ * Delete the NLDR loader. ++ * ++ * Parameters: ++ * hNldr: Node manager object. ++ * Returns: ++ * Requires: ++ * NLDR_Init(void) called. ++ * Valid hNldr. ++ * Ensures: ++ * hNldr invalid ++ */ ++ typedef void(*NLDR_DELETEFXN) (struct NLDR_OBJECT *hNldr); ++ ++/* ++ * ======== NLDR_Exit ======== ++ * Discontinue usage of NLDR module. ++ * ++ * Parameters: ++ * Returns: ++ * Requires: ++ * NLDR_Init(void) successfully called before. ++ * Ensures: ++ * Any resources acquired in NLDR_Init(void) will be freed when last NLDR ++ * client calls NLDR_Exit(void). ++ */ ++ typedef void(*NLDR_EXITFXN) (void); ++ ++/* ++ * ======== NLDR_Free ======== ++ * Free resources allocated in NLDR_Allocate. ++ * ++ * Parameters: ++ * hNldrNode: Handle returned from NLDR_Allocate(). ++ * Returns: ++ * Requires: ++ * NLDR_Init(void) called. ++ * Valid hNldrNode. ++ * Ensures: ++ */ ++ typedef void(*NLDR_FREEFXN) (struct NLDR_NODEOBJECT *hNldrNode); ++ ++/* ++ * ======== NLDR_GetFxnAddr ======== ++ * Get address of create, delete, or execute phase function of a node on ++ * the DSP. ++ * ++ * Parameters: ++ * hNldrNode: Handle returned from NLDR_Allocate(). ++ * pstrFxn: Name of function. ++ * pulAddr: Location to store function address. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_ESYMBOL: Address of function not found. ++ * Requires: ++ * NLDR_Init(void) called. ++ * Valid hNldrNode. ++ * pulAddr != NULL; ++ * pstrFxn != NULL; ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*NLDR_GETFXNADDRFXN) (struct NLDR_NODEOBJECT ++ *hNldrNode, ++ char *pstrFxn, u32 *pulAddr); ++ ++/* ++ * ======== NLDR_Init ======== ++ * Initialize the NLDR module. ++ * ++ * Parameters: ++ * Returns: ++ * TRUE if initialization succeeded, FALSE otherwise. ++ * Ensures: ++ */ ++ typedef bool(*NLDR_INITFXN) (void); ++ ++/* ++ * ======== NLDR_Load ======== ++ * Load create, delete, or execute phase function of a node on the DSP. ++ * ++ * Parameters: ++ * hNldrNode: Handle returned from NLDR_Allocate(). ++ * phase: Type of function to load (create, delete, or execute). ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Insufficient memory on GPP. ++ * DSP_EOVERLAYMEMORY: Can't overlay phase because overlay memory ++ * is already in use. ++ * DSP_EDYNLOAD: Failure in dynamic loader library. ++ * DSP_EFWRITE: Failed to write phase's code or date to target. ++ * Requires: ++ * NLDR_Init(void) called. ++ * Valid hNldrNode. ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*NLDR_LOADFXN) (struct NLDR_NODEOBJECT *hNldrNode, ++ enum NLDR_PHASE phase); ++ ++/* ++ * ======== NLDR_Unload ======== ++ * Unload create, delete, or execute phase function of a node on the DSP. ++ * ++ * Parameters: ++ * hNldrNode: Handle returned from NLDR_Allocate(). ++ * phase: Node function to unload (create, delete, or execute). ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Insufficient memory on GPP. ++ * Requires: ++ * NLDR_Init(void) called. ++ * Valid hNldrNode. ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*NLDR_UNLOADFXN) (struct NLDR_NODEOBJECT *hNldrNode, ++ enum NLDR_PHASE phase); ++ ++/* ++ * ======== NLDR_FXNS ======== ++ */ ++ struct NLDR_FXNS { ++ NLDR_ALLOCATEFXN pfnAllocate; ++ NLDR_CREATEFXN pfnCreate; ++ NLDR_DELETEFXN pfnDelete; ++ NLDR_EXITFXN pfnExit; ++ NLDR_FREEFXN pfnFree; ++ NLDR_GETFXNADDRFXN pfnGetFxnAddr; ++ NLDR_INITFXN pfnInit; ++ NLDR_LOADFXN pfnLoad; ++ NLDR_UNLOADFXN pfnUnload; ++ } ; ++ ++#endif /* NLDRDEFS_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/node.h b/arch/arm/plat-omap/include/dspbridge/node.h +new file mode 100644 +index 0000000..d253962 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/node.h +@@ -0,0 +1,619 @@ ++/* ++ * node.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== node.h ======== ++ * Description: ++ * DSP/BIOS Bridge Node Manager. ++ * ++ * Public Functions: ++ * NODE_Allocate ++ * NODE_AllocMsgBuf ++ * NODE_ChangePriority ++ * NODE_Connect ++ * NODE_Create ++ * NODE_CreateMgr ++ * NODE_Delete ++ * NODE_DeleteMgr ++ * NODE_EnumNodes ++ * NODE_Exit ++ * NODE_FreeMsgBuf ++ * NODE_GetAttr ++ * NODE_GetMessage ++ * NODE_GetProcessor ++ * NODE_Init ++ * NODE_OnExit ++ * NODE_Pause ++ * NODE_PutMessage ++ * NODE_RegisterNotify ++ * NODE_Run ++ * NODE_Terminate ++ * ++ * Notes: ++ * ++ *! Revision History: ++ *! ================= ++ *! 23-Apr-2001 jeh Updated with code review changes. ++ *! 16-Jan-2001 jeh Added DSP_ESYMBOL, DSP_EUUID to return codes. ++ *! 17-Nov-2000 jeh Added NODE_OnExit(). ++ *! 27-Oct-2000 jeh Added timeouts to NODE_GetMessage, NODE_PutMessage. ++ *! 12-Oct-2000 jeh Changed NODE_EnumNodeInfo to NODE_EnumNodes. Removed ++ *! NODE_RegisterAllNodes(). ++ *! 07-Sep-2000 jeh Changed type HANDLE in NODE_RegisterNotify to ++ *! DSP_HNOTIFICATION. Added DSP_STRMATTR param to ++ *! NODE_Connect(). Removed NODE_GetMessageStream(). ++ *! 17-Jul-2000 jeh Updated function header descriptions. ++ *! 19-Jun-2000 jeh Created. ++ */ ++ ++#ifndef NODE_ ++#define NODE_ ++ ++#include ++ ++#include ++#include ++#include ++ ++/* ++ * ======== NODE_Allocate ======== ++ * Purpose: ++ * Allocate GPP resources to manage a node on the DSP. ++ * Parameters: ++ * hProcessor: Handle of processor that is allocating the node. ++ * pNodeId: Pointer to a DSP_UUID for the node. ++ * pArgs: Optional arguments to be passed to the node. ++ * pAttrIn: Optional pointer to node attributes (priority, ++ * timeout...) ++ * phNode: Location to store node handle on output. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Insufficient memory on GPP. ++ * DSP_EUUID: Node UUID has not been registered. ++ * DSP_ESYMBOL: iAlg functions not found for a DAIS node. ++ * DSP_ERANGE: pAttrIn != NULL and pAttrIn->iPriority out of ++ * range. ++ * DSP_EFAIL: A failure occured, unable to allocate node. ++ * DSP_EWRONGSTATE: Proccessor is not in the running state. ++ * Requires: ++ * NODE_Init(void) called. ++ * hProcessor != NULL. ++ * pNodeId != NULL. ++ * phNode != NULL. ++ * Ensures: ++ * DSP_SOK: IsValidNode(*phNode). ++ * error: *phNode == NULL. ++ */ ++ extern DSP_STATUS NODE_Allocate(struct PROC_OBJECT *hProcessor, ++ IN CONST struct DSP_UUID *pNodeId, ++ OPTIONAL IN CONST struct DSP_CBDATA ++ *pArgs, ++ OPTIONAL IN CONST struct DSP_NODEATTRIN ++ *pAttrIn, ++ OUT struct NODE_OBJECT **phNode); ++ ++/* ++ * ======== NODE_AllocMsgBuf ======== ++ * Purpose: ++ * Allocate and Prepare a buffer whose descriptor will be passed to a ++ * Node within a (DSP_MSG)message ++ * Parameters: ++ * hNode: The node handle. ++ * uSize: The size of the buffer to be allocated. ++ * pAttr: Pointer to a DSP_BUFFERATTR structure. ++ * pBuffer: Location to store the address of the allocated ++ * buffer on output. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid node handle. ++ * DSP_EMEMORY: Insufficent memory. ++ * DSP_EFAIL: General Failure. ++ * DSP_ESIZE: Invalid Size. ++ * Requires: ++ * NODE_Init(void) called. ++ * pBuffer != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS NODE_AllocMsgBuf(struct NODE_OBJECT *hNode, ++ u32 uSize, ++ OPTIONAL struct DSP_BUFFERATTR ++ *pAttr, ++ OUT u8 **pBuffer); ++ ++/* ++ * ======== NODE_ChangePriority ======== ++ * Purpose: ++ * Change the priority of an allocated node. ++ * Parameters: ++ * hNode: Node handle returned from NODE_Allocate. ++ * nPriority: New priority level to set node's priority to. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hNode. ++ * DSP_ERANGE: nPriority is out of range. ++ * DSP_ENODETYPE: The specified node is not a task node. ++ * DSP_EWRONGSTATE: Node is not in the NODE_ALLOCATED, NODE_PAUSED, ++ * or NODE_RUNNING state. ++ * DSP_ETIMEOUT: A timeout occurred before the DSP responded. ++ * DSP_ERESTART: A critical error has occurred and the DSP is ++ * being restarted. ++ * DSP_EFAIL: Unable to change node's runtime priority level. ++ * Requires: ++ * NODE_Init(void) called. ++ * Ensures: ++ * DSP_SOK && (Node's current priority == nPriority) ++ */ ++ extern DSP_STATUS NODE_ChangePriority(struct NODE_OBJECT *hNode, ++ s32 nPriority); ++ ++/* ++ * ======== NODE_CloseOrphans ======== ++ * Purpose: ++ * Delete all nodes whose owning processor is being destroyed. ++ * Parameters: ++ * hNodeMgr: Node manager object. ++ * hProc: Handle to processor object being destroyed. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Unable to delete all nodes belonging to hProc. ++ * Requires: ++ * Valid hNodeMgr. ++ * hProc != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS NODE_CloseOrphans(struct NODE_MGR *hNodeMgr, ++ struct PROC_OBJECT *hProc); ++ ++/* ++ * ======== NODE_Connect ======== ++ * Purpose: ++ * Connect two nodes on the DSP, or a node on the DSP to the GPP. In the ++ * case that the connnection is being made between a node on the DSP and ++ * the GPP, one of the node handles (either hNode1 or hNode2) must be ++ * the constant NODE_HGPPNODE. ++ * Parameters: ++ * hNode1: Handle of first node to connect to second node. If ++ * this is a connection from the GPP to hNode2, hNode1 ++ * must be the constant NODE_HGPPNODE. Otherwise, hNode1 ++ * must be a node handle returned from a successful call ++ * to Node_Allocate(). ++ * hNode2: Handle of second node. Must be either NODE_HGPPNODE ++ * if this is a connection from DSP node to GPP, or a ++ * node handle returned from a successful call to ++ * NODE_Allocate(). ++ * uStream1: Output stream index on first node, to be connected ++ * to second node's input stream. Value must range from ++ * 0 <= uStream1 < number of output streams. ++ * uStream2: Input stream index on second node. Value must range ++ * from 0 <= uStream2 < number of input streams. ++ * pAttrs: Stream attributes (NULL ==> use defaults). ++ * pConnParam: A pointer to a DSP_CBDATA structure that defines ++ * connection parameter for device nodes to pass to DSP ++ * side. ++ * If the value of this parameter is NULL, then this API ++ * behaves like DSPNode_Connect. This parameter will have ++ * length of the string and the null terminated string in ++ * DSP_CBDATA struct. This can be extended in future tp ++ * pass binary data. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hNode1 or hNode2. ++ * DSP_EMEMORY: Insufficient host memory. ++ * DSP_EVALUE: A stream index parameter is invalid. ++ * DSP_EALREADYCONNECTED: A connection already exists for one of the ++ * indices uStream1 or uStream2. ++ * DSP_EWRONGSTATE: Either hNode1 or hNode2 is not in the ++ * NODE_ALLOCATED state. ++ * DSP_ENOMORECONNECTIONS: No more connections available. ++ * DSP_EFAIL: Attempt to make an illegal connection (eg, ++ * Device node to device node, or device node to ++ * GPP), the two nodes are on different DSPs. ++ * Requires: ++ * NODE_Init(void) called. ++ * Ensures: ++ */ ++ extern DSP_STATUS NODE_Connect(struct NODE_OBJECT *hNode1, ++ u32 uStream1, ++ struct NODE_OBJECT *hNode2, ++ u32 uStream2, ++ OPTIONAL IN struct DSP_STRMATTR *pAttrs, ++ OPTIONAL IN struct DSP_CBDATA ++ *pConnParam); ++ ++/* ++ * ======== NODE_Create ======== ++ * Purpose: ++ * Create a node on the DSP by remotely calling the node's create ++ * function. If necessary, load code that contains the node's create ++ * function. ++ * Parameters: ++ * hNode: Node handle returned from NODE_Allocate(). ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hNode. ++ * DSP_ESYMBOL: Create function not found in the COFF file. ++ * DSP_EWRONGSTATE: Node is not in the NODE_ALLOCATED state. ++ * DSP_EMEMORY: Memory allocation failure on the DSP. ++ * DSP_ETASK: Unable to create node's task or process on the DSP. ++ * DSP_ESTREAM: Stream creation failure on the DSP. ++ * DSP_ETIMEOUT: A timeout occurred before the DSP responded. ++ * DSP_EUSER1-16: A user-defined failure occurred on the DSP. ++ * DSP_EFAIL: A failure occurred, unable to create node. ++ * Requires: ++ * NODE_Init(void) called. ++ * Ensures: ++ */ ++ extern DSP_STATUS NODE_Create(struct NODE_OBJECT *hNode); ++ ++/* ++ * ======== NODE_CreateMgr ======== ++ * Purpose: ++ * Create a NODE Manager object. This object handles the creation, ++ * deletion, and execution of nodes on the DSP target. The NODE Manager ++ * also maintains a pipe map of used and available node connections. ++ * Each DEV object should have exactly one NODE Manager object. ++ * ++ * Parameters: ++ * phNodeMgr: Location to store node manager handle on output. ++ * hDevObject: Device for this processor. ++ * Returns: ++ * DSP_SOK: Success; ++ * DSP_EMEMORY: Insufficient memory for requested resources. ++ * DSP_EFAIL: General failure. ++ * Requires: ++ * NODE_Init(void) called. ++ * phNodeMgr != NULL. ++ * hDevObject != NULL. ++ * Ensures: ++ * DSP_SOK: Valide *phNodeMgr. ++ * error: *phNodeMgr == NULL. ++ */ ++ extern DSP_STATUS NODE_CreateMgr(OUT struct NODE_MGR **phNodeMgr, ++ struct DEV_OBJECT *hDevObject); ++ ++/* ++ * ======== NODE_Delete ======== ++ * Purpose: ++ * Delete resources allocated in NODE_Allocate(). If the node was ++ * created, delete the node on the DSP by remotely calling the node's ++ * delete function. Loads the node's delete function if necessary. ++ * GPP side resources are freed after node's delete function returns. ++ * Parameters: ++ * hNode: Node handle returned from NODE_Allocate(). ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hNode. ++ * DSP_ETIMEOUT: A timeout occurred before the DSP responded. ++ * DSP_EDELETE: A deletion failure occurred. ++ * DSP_EUSER1-16: Node specific failure occurred on the DSP. ++ * DSP_EFAIL: A failure occurred in deleting the node. ++ * DSP_ESYMBOL: Delete function not found in the COFF file. ++ * Requires: ++ * NODE_Init(void) called. ++ * Ensures: ++ * DSP_SOK: hNode is invalid. ++ */ ++ extern DSP_STATUS NODE_Delete(struct NODE_OBJECT *hNode); ++ ++/* ++ * ======== NODE_DeleteMgr ======== ++ * Purpose: ++ * Delete the NODE Manager. ++ * Parameters: ++ * hNodeMgr: Node manager object. ++ * Returns: ++ * DSP_SOK: Success. ++ * Requires: ++ * NODE_Init(void) called. ++ * Valid hNodeMgr. ++ * Ensures: ++ */ ++ extern DSP_STATUS NODE_DeleteMgr(struct NODE_MGR *hNodeMgr); ++ ++/* ++ * ======== NODE_EnumNodes ======== ++ * Purpose: ++ * Enumerate the nodes currently allocated for the DSP. ++ * Parameters: ++ * hNodeMgr: Node manager returned from NODE_CreateMgr(). ++ * aNodeTab: Array to copy node handles into. ++ * uNodeTabSize: Number of handles that can be written to aNodeTab. ++ * puNumNodes: Location where number of node handles written to ++ * aNodeTab will be written. ++ * puAllocated: Location to write total number of allocated nodes. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_ESIZE: aNodeTab is too small to hold all node handles. ++ * Requires: ++ * Valid hNodeMgr. ++ * aNodeTab != NULL || uNodeTabSize == 0. ++ * puNumNodes != NULL. ++ * puAllocated != NULL. ++ * Ensures: ++ * - (DSP_ESIZE && *puNumNodes == 0) ++ * - || (DSP_SOK && *puNumNodes <= uNodeTabSize) && ++ * (*puAllocated == *puNumNodes) ++ */ ++ extern DSP_STATUS NODE_EnumNodes(struct NODE_MGR *hNodeMgr, ++ IN DSP_HNODE *aNodeTab, ++ u32 uNodeTabSize, ++ OUT u32 *puNumNodes, ++ OUT u32 *puAllocated); ++ ++/* ++ * ======== NODE_Exit ======== ++ * Purpose: ++ * Discontinue usage of NODE module. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * NODE_Init(void) successfully called before. ++ * Ensures: ++ * Any resources acquired in NODE_Init(void) will be freed when last NODE ++ * client calls NODE_Exit(void). ++ */ ++ extern void NODE_Exit(void); ++ ++/* ++ * ======== NODE_FreeMsgBuf ======== ++ * Purpose: ++ * Free a message buffer previously allocated with NODE_AllocMsgBuf. ++ * Parameters: ++ * hNode: The node handle. ++ * pBuffer: (Address) Buffer allocated by NODE_AllocMsgBuf. ++ * pAttr: Same buffer attributes passed to NODE_AllocMsgBuf. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid node handle. ++ * DSP_EFAIL: Failure to free the buffer. ++ * Requires: ++ * NODE_Init(void) called. ++ * pBuffer != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS NODE_FreeMsgBuf(struct NODE_OBJECT *hNode, ++ IN u8 *pBuffer, ++ OPTIONAL struct DSP_BUFFERATTR ++ *pAttr); ++ ++/* ++ * ======== NODE_GetAttr ======== ++ * Purpose: ++ * Copy the current attributes of the specified node into a DSP_NODEATTR ++ * structure. ++ * Parameters: ++ * hNode: Node object allocated from NODE_Allocate(). ++ * pAttr: Pointer to DSP_NODEATTR structure to copy node's ++ * attributes. ++ * uAttrSize: Size of pAttr. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hNode. ++ * Requires: ++ * NODE_Init(void) called. ++ * pAttr != NULL. ++ * Ensures: ++ * DSP_SOK: *pAttrs contains the node's current attributes. ++ */ ++ extern DSP_STATUS NODE_GetAttr(struct NODE_OBJECT *hNode, ++ OUT struct DSP_NODEATTR *pAttr, ++ u32 uAttrSize); ++ ++/* ++ * ======== NODE_GetMessage ======== ++ * Purpose: ++ * Retrieve a message from a node on the DSP. The node must be either a ++ * message node, task node, or XDAIS socket node. ++ * If a message is not available, this function will block until a ++ * message is available, or the node's timeout value is reached. ++ * Parameters: ++ * hNode: Node handle returned from NODE_Allocate(). ++ * pMessage: Pointer to DSP_MSG structure to copy the ++ * message into. ++ * uTimeout: Timeout in milliseconds to wait for message. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hNode. ++ * DSP_ENODETYPE: Cannot retrieve messages from this type of node. ++ * DSP_ETIMEOUT: Timeout occurred and no message is available. ++ * DSP_EFAIL: Error occurred while trying to retrieve a message. ++ * Requires: ++ * NODE_Init(void) called. ++ * pMessage != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS NODE_GetMessage(struct NODE_OBJECT *hNode, ++ OUT struct DSP_MSG *pMessage, ++ u32 uTimeout); ++ ++/* ++ * ======== NODE_GetNldrObj ======== ++ * Purpose: ++ * Retrieve the Nldr manager ++ * Parameters: ++ * hNodeMgr: Node Manager ++ * phNldrObj: Pointer to a Nldr manager handle ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hNode. ++ * Ensures: ++ */ ++ extern DSP_STATUS NODE_GetNldrObj(struct NODE_MGR *hNodeMgr, ++ OUT struct NLDR_OBJECT **phNldrObj); ++ ++/* ++ * ======== NODE_Init ======== ++ * Purpose: ++ * Initialize the NODE module. ++ * Parameters: ++ * Returns: ++ * TRUE if initialization succeeded, FALSE otherwise. ++ * Ensures: ++ */ ++ extern bool NODE_Init(void); ++ ++/* ++ * ======== NODE_OnExit ======== ++ * Purpose: ++ * Gets called when RMS_EXIT is received for a node. PROC needs to pass ++ * this function as a parameter to MSG_Create(). This function then gets ++ * called by the mini-driver when an exit message for a node is received. ++ * Parameters: ++ * hNode: Handle of the node that the exit message is for. ++ * nStatus: Return status of the node's execute phase. ++ * Returns: ++ * Ensures: ++ */ ++ void NODE_OnExit(struct NODE_OBJECT *hNode, s32 nStatus); ++ ++/* ++ * ======== NODE_Pause ======== ++ * Purpose: ++ * Suspend execution of a node currently running on the DSP. ++ * Parameters: ++ * hNode: Node object representing a node currently ++ * running on the DSP. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hNode. ++ * DSP_ENODETYPE: Node is not a task or socket node. ++ * DSP_ETIMEOUT: A timeout occurred before the DSP responded. ++ * DSP_EWRONGSTSATE: Node is not in NODE_RUNNING state. ++ * DSP_EFAIL: Failed to pause node. ++ * Requires: ++ * NODE_Init(void) called. ++ * Ensures: ++ */ ++ extern DSP_STATUS NODE_Pause(struct NODE_OBJECT *hNode); ++ ++/* ++ * ======== NODE_PutMessage ======== ++ * Purpose: ++ * Send a message to a message node, task node, or XDAIS socket node. ++ * This function will block until the message stream can accommodate ++ * the message, or a timeout occurs. The message will be copied, so Msg ++ * can be re-used immediately after return. ++ * Parameters: ++ * hNode: Node handle returned by NODE_Allocate(). ++ * pMsg: Location of message to be sent to the node. ++ * uTimeout: Timeout in msecs to wait. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hNode. ++ * DSP_ENODETYPE: Messages can't be sent to this type of node. ++ * DSP_ETIMEOUT: Timeout occurred before message could be set. ++ * DSP_EWRONGSTATE: Node is in invalid state for sending messages. ++ * DSP_EFAIL: Unable to send message. ++ * Requires: ++ * NODE_Init(void) called. ++ * pMsg != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS NODE_PutMessage(struct NODE_OBJECT *hNode, ++ IN CONST struct DSP_MSG *pMsg, ++ u32 uTimeout); ++ ++/* ++ * ======== NODE_RegisterNotify ======== ++ * Purpose: ++ * Register to be notified on specific events for this node. ++ * Parameters: ++ * hNode: Node handle returned by NODE_Allocate(). ++ * uEventMask: Mask of types of events to be notified about. ++ * uNotifyType: Type of notification to be sent. ++ * hNotification: Handle to be used for notification. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hNode. ++ * DSP_EMEMORY: Insufficient memory on GPP. ++ * DSP_EVALUE: uEventMask is invalid. ++ * DSP_ENOTIMPL: Notification type specified by uNotifyType is not ++ * supported. ++ * Requires: ++ * NODE_Init(void) called. ++ * hNotification != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS NODE_RegisterNotify(struct NODE_OBJECT *hNode, ++ u32 uEventMask, u32 uNotifyType, ++ struct DSP_NOTIFICATION ++ *hNotification); ++ ++/* ++ * ======== NODE_Run ======== ++ * Purpose: ++ * Start execution of a node's execute phase, or resume execution of ++ * a node that has been suspended (via NODE_Pause()) on the DSP. Load ++ * the node's execute function if necessary. ++ * Parameters: ++ * hNode: Node object representing a node currently ++ * running on the DSP. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hNode. ++ * DSP_ENODETYPE: hNode doesn't represent a message, task or dais ++ * socket node. ++ * DSP_ETIMEOUT: A timeout occurred before the DSP responded. ++ * DSP_EWRONGSTSATE: Node is not in NODE_PAUSED or NODE_CREATED state. ++ * DSP_EFAIL: Unable to start or resume execution. ++ * DSP_ESYMBOL: Execute function not found in the COFF file. ++ * Requires: ++ * NODE_Init(void) called. ++ * Ensures: ++ */ ++ extern DSP_STATUS NODE_Run(struct NODE_OBJECT *hNode); ++ ++/* ++ * ======== NODE_Terminate ======== ++ * Purpose: ++ * Signal a node running on the DSP that it should exit its execute ++ * phase function. ++ * Parameters: ++ * hNode: Node object representing a node currently ++ * running on the DSP. ++ * pStatus: Location to store execute-phase function return ++ * value (DSP_EUSER1-16). ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hNode. ++ * DSP_ETIMEOUT: A timeout occurred before the DSP responded. ++ * DSP_ENODETYPE: Type of node specified cannot be terminated. ++ * DSP_EWRONGSTATE: Operation not valid for the current node state. ++ * DSP_EFAIL: Unable to terminate the node. ++ * Requires: ++ * NODE_Init(void) called. ++ * pStatus != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS NODE_Terminate(struct NODE_OBJECT *hNode, ++ OUT DSP_STATUS *pStatus); ++ ++ ++ ++/* ++ * ======== NODE_GetUUIDProps ======== ++ * Purpose: ++ * Fetch Node properties given the UUID ++ * Parameters: ++ * ++ */ ++ extern DSP_STATUS NODE_GetUUIDProps(DSP_HPROCESSOR hProcessor, ++ IN CONST struct DSP_UUID *pNodeId, ++ OUT struct DSP_NDBPROPS ++ *pNodeProps); ++ ++#endif /* NODE_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/nodedefs.h b/arch/arm/plat-omap/include/dspbridge/nodedefs.h +new file mode 100644 +index 0000000..cdc0c4b +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/nodedefs.h +@@ -0,0 +1,40 @@ ++/* ++ * nodedefs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== nodedefs.h ======== ++ * Description: ++ * Global NODE constants and types, shared by PROCESSOR, NODE, and DISP. ++ * ++ *! Revision History ++ *! ================ ++ *! 23-Apr-2001 jeh Removed NODE_MGRATTRS. ++ *! 21-Sep-2000 jeh Removed NODE_TYPE enum. ++ *! 17-Jul-2000 jeh Changed order of node types to match rms_sh.h. ++ *! 20-Jun-2000 jeh Created. ++ */ ++ ++#ifndef NODEDEFS_ ++#define NODEDEFS_ ++ ++#define NODE_SUSPENDEDPRI -1 ++ ++/* NODE Objects: */ ++ struct NODE_MGR; ++ struct NODE_OBJECT; ++ ++#endif /* NODEDEFS_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/nodepriv.h b/arch/arm/plat-omap/include/dspbridge/nodepriv.h +new file mode 100644 +index 0000000..d28b29b +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/nodepriv.h +@@ -0,0 +1,202 @@ ++/* ++ * nodepriv.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== nodepriv.h ======== ++ * Description: ++ * Private node header shared by NODE and DISP. ++ * ++ * Public Functions: ++ * NODE_GetChannelId ++ * NODE_GetStrmMgr ++ * NODE_GetTimeout ++ * NODE_GetType ++ * NODE_GetLoadType ++ * ++ *! Revision History ++ *! ================ ++ *! 19-Nov-2002 map Added NODE_GetLoadType ++ *! 13-Feb-2002 jeh Added uSysStackSize to NODE_TASKARGS. ++ *! 23-Apr-2001 jeh Removed unused typedefs, defines. ++ *! 10-Oct-2000 jeh Added alignment to NODE_STRMDEF. ++ *! 20-Jun-2000 jeh Created. ++ */ ++ ++#ifndef NODEPRIV_ ++#define NODEPRIV_ ++ ++#include ++#include ++#include ++ ++/* DSP address of node environment structure */ ++ typedef u32 NODE_ENV; ++ ++/* ++ * Node create structures ++ */ ++ ++/* Message node */ ++ struct NODE_MSGARGS { ++ u32 uMaxMessages; /* Max # of simultaneous messages for node */ ++ u32 uSegid; /* Segment for allocating message buffers */ ++ u32 uNotifyType; /* Notify type (SEM_post, SWI_post, etc.) */ ++ u32 uArgLength; /* Length in 32-bit words of arg data block */ ++ u8 *pData; /* Argument data for node */ ++ } ; ++ ++ struct NODE_STRMDEF { ++ u32 uBufsize; /* Size of buffers for SIO stream */ ++ u32 uNumBufs; /* max # of buffers in SIO stream at once */ ++ u32 uSegid; /* Memory segment id to allocate buffers */ ++ u32 uTimeout; /* Timeout for blocking SIO calls */ ++ u32 uAlignment; /* Buffer alignment */ ++ char *szDevice; /* Device name for stream */ ++ } ; ++ ++/* Task node */ ++ struct NODE_TASKARGS { ++ struct NODE_MSGARGS msgArgs; ++ s32 nPriority; ++ u32 uStackSize; ++ u32 uSysStackSize; ++ u32 uStackSeg; ++ u32 uDSPHeapResAddr; /* DSP virtual heap address */ ++ u32 uDSPHeapAddr; /* DSP virtual heap address */ ++ u32 uHeapSize; /* Heap size */ ++ u32 uGPPHeapAddr; /* GPP virtual heap address */ ++ u32 uProfileID; /* Profile ID */ ++ u32 uNumInputs; ++ u32 uNumOutputs; ++ u32 ulDaisArg; /* Address of iAlg object */ ++ struct NODE_STRMDEF *strmInDef; ++ struct NODE_STRMDEF *strmOutDef; ++ } ; ++ ++/* ++ * ======== NODE_CREATEARGS ======== ++ */ ++ struct NODE_CREATEARGS { ++ union { ++ struct NODE_MSGARGS msgArgs; ++ struct NODE_TASKARGS taskArgs; ++ } asa; ++ } ; ++ ++/* ++ * ======== NODE_GetChannelId ======== ++ * Purpose: ++ * Get the channel index reserved for a stream connection between the ++ * host and a node. This index is reserved when NODE_Connect() is called ++ * to connect the node with the host. This index should be passed to ++ * the CHNL_Open function when the stream is actually opened. ++ * Parameters: ++ * hNode: Node object allocated from NODE_Allocate(). ++ * uDir: Input (DSP_TONODE) or output (DSP_FROMNODE). ++ * uIndex: Stream index. ++ * pulId: Location to store channel index. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hNode. ++ * DSP_ENODETYPE: Not a task or DAIS socket node. ++ * DSP_EVALUE: The node's stream corresponding to uIndex and uDir ++ * is not a stream to or from the host. ++ * Requires: ++ * NODE_Init(void) called. ++ * Valid uDir. ++ * pulId != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS NODE_GetChannelId(struct NODE_OBJECT *hNode, ++ u32 uDir, ++ u32 uIndex, OUT u32 *pulId); ++ ++/* ++ * ======== NODE_GetStrmMgr ======== ++ * Purpose: ++ * Get the STRM manager for a node. ++ * Parameters: ++ * hNode: Node allocated with NODE_Allocate(). ++ * phStrmMgr: Location to store STRM manager on output. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hNode. ++ * Requires: ++ * phStrmMgr != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS NODE_GetStrmMgr(struct NODE_OBJECT *hNode, ++ struct STRM_MGR **phStrmMgr); ++ ++/* ++ * ======== NODE_GetTimeout ======== ++ * Purpose: ++ * Get the timeout value of a node. ++ * Parameters: ++ * hNode: Node allocated with NODE_Allocate(), or DSP_HGPPNODE. ++ * Returns: ++ * Node's timeout value. ++ * Requires: ++ * Valid hNode. ++ * Ensures: ++ */ ++ extern u32 NODE_GetTimeout(struct NODE_OBJECT *hNode); ++ ++/* ++ * ======== NODE_GetType ======== ++ * Purpose: ++ * Get the type (device, message, task, or XDAIS socket) of a node. ++ * Parameters: ++ * hNode: Node allocated with NODE_Allocate(), or DSP_HGPPNODE. ++ * Returns: ++ * Node type: NODE_DEVICE, NODE_TASK, NODE_XDAIS, or NODE_GPP. ++ * Requires: ++ * Valid hNode. ++ * Ensures: ++ */ ++ extern enum NODE_TYPE NODE_GetType(struct NODE_OBJECT *hNode); ++ ++/* ++ * ======== GetNodeInfo ======== ++ * Purpose: ++ * Get node information without holding semaphore. ++ * Parameters: ++ * hNode: Node allocated with NODE_Allocate(), or DSP_HGPPNODE. ++ * Returns: ++ * Node info: priority, device owner, no. of streams, execution state ++ * NDB properties. ++ * Requires: ++ * Valid hNode. ++ * Ensures: ++ */ ++ extern void GetNodeInfo(struct NODE_OBJECT *hNode, ++ struct DSP_NODEINFO *pNodeInfo); ++ ++/* ++ * ======== NODE_GetLoadType ======== ++ * Purpose: ++ * Get the load type (dynamic, overlay, static) of a node. ++ * Parameters: ++ * hNode: Node allocated with NODE_Allocate(), or DSP_HGPPNODE. ++ * Returns: ++ * Node type: NLDR_DYNAMICLOAD, NLDR_OVLYLOAD, NLDR_STATICLOAD ++ * Requires: ++ * Valid hNode. ++ * Ensures: ++ */ ++ extern enum NLDR_LOADTYPE NODE_GetLoadType(struct NODE_OBJECT *hNode); ++ ++#endif /* NODEPRIV_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/ntfy.h b/arch/arm/plat-omap/include/dspbridge/ntfy.h +new file mode 100644 +index 0000000..5a0992a +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/ntfy.h +@@ -0,0 +1,146 @@ ++/* ++ * ntfy.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== ntfy.h ======== ++ * Purpose: ++ * Manage lists of notification events. ++ * ++ * Public Functions: ++ * NTFY_Create ++ * NTFY_Delete ++ * NTFY_Exit ++ * NTFY_Init ++ * NTFY_Notify ++ * NTFY_Register ++ * ++ *! Revision History: ++ *! ================= ++ *! 05-Nov-2001 kc: Updated NTFY_Register. ++ *! 07-Sep-2000 jeh Created. ++ */ ++ ++#ifndef NTFY_ ++#define NTFY_ ++ ++ struct NTFY_OBJECT; ++ ++/* ++ * ======== NTFY_Create ======== ++ * Purpose: ++ * Create an empty list of notifications. ++ * Parameters: ++ * phNtfy: Location to store handle on output. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Memory allocation failure. ++ * Requires: ++ * NTFY_Init(void) called. ++ * phNtfy != NULL. ++ * Ensures: ++ * DSP_SUCCEEDED(status) <==> IsValid(*phNtfy). ++ */ ++ extern DSP_STATUS NTFY_Create(OUT struct NTFY_OBJECT **phNtfy); ++ ++/* ++ * ======== NTFY_Delete ======== ++ * Purpose: ++ * Free resources allocated in NTFY_Create. ++ * Parameters: ++ * hNtfy: Handle returned from NTFY_Create(). ++ * Returns: ++ * Requires: ++ * NTFY_Init(void) called. ++ * IsValid(hNtfy). ++ * Ensures: ++ */ ++ extern void NTFY_Delete(IN struct NTFY_OBJECT *hNtfy); ++ ++/* ++ * ======== NTFY_Exit ======== ++ * Purpose: ++ * Discontinue usage of NTFY module. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * NTFY_Init(void) successfully called before. ++ * Ensures: ++ */ ++ extern void NTFY_Exit(void); ++ ++/* ++ * ======== NTFY_Init ======== ++ * Purpose: ++ * Initialize the NTFY module. ++ * Parameters: ++ * Returns: ++ * TRUE if initialization succeeded, FALSE otherwise. ++ * Ensures: ++ */ ++ extern bool NTFY_Init(void); ++ ++/* ++ * ======== NTFY_Notify ======== ++ * Purpose: ++ * Execute notify function (signal event or post message) for every ++ * element in the notification list that is to be notified about the ++ * event specified in uEventMask. ++ * Parameters: ++ * hNtfy: Handle returned from NTFY_Create(). ++ * uEventMask: The type of event that has occurred. ++ * Returns: ++ * Requires: ++ * NTFY_Init(void) called. ++ * IsValid(hNtfy). ++ * Ensures: ++ */ ++ extern void NTFY_Notify(IN struct NTFY_OBJECT *hNtfy, ++ IN u32 uEventMask); ++ ++/* ++ * ======== NTFY_Register ======== ++ * Purpose: ++ * Add a notification element to the list. If the notification is already ++ * registered, and uEventMask != 0, the notification will get posted for ++ * events specified in the new event mask. If the notification is already ++ * registered and uEventMask == 0, the notification will be unregistered. ++ * Parameters: ++ * hNtfy: Handle returned from NTFY_Create(). ++ * hNotification: Handle to a DSP_NOTIFICATION object. ++ * uEventMask: Events to be notified about. ++ * uNotifyType: Type of notification: DSP_SIGNALEVENT. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Insufficient memory. ++ * DSP_EVALUE: uEventMask is 0 and hNotification was not ++ * previously registered. ++ * DSP_EHANDLE: NULL hNotification, hNotification event name ++ * too long, or hNotification event name NULL. ++ * Requires: ++ * NTFY_Init(void) called. ++ * IsValid(hNtfy). ++ * hNotification != NULL. ++ * uNotifyType is DSP_SIGNALEVENT ++ * Ensures: ++ */ ++ extern DSP_STATUS NTFY_Register(IN struct NTFY_OBJECT *hNtfy, ++ IN struct DSP_NOTIFICATION ++ *hNotification, ++ IN u32 uEventMask, ++ IN u32 uNotifyType); ++ ++#endif /* NTFY_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/proc.h b/arch/arm/plat-omap/include/dspbridge/proc.h +new file mode 100644 +index 0000000..486652e +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/proc.h +@@ -0,0 +1,648 @@ ++/* ++ * proc.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== proc.h ======== ++ * Description: ++ * This is the Class driver RM module interface. ++ * ++ * Public Functions: ++ * PROC_Attach ++ * PROC_Create ++ * PROC_Ctrl (OEM-function) ++ * PROC_Destroy ++ * PROC_Detach ++ * PROC_EnumNodes ++ * PROC_Exit ++ * PROC_FlushMemory ++ * PROC_GetDevObject (OEM-function) ++ * PROC_GetResourceInfo ++ * PROC_GetState ++ * PROC_GetProcessorId ++ * PROC_GetTrace (OEM-function) ++ * PROC_Init ++ * PROC_Load (OEM-function) ++ * PROC_Map ++ * PROC_NotifyAllclients ++ * PROC_NotifyClients (OEM-function) ++ * PROC_RegisterNotify ++ * PROC_ReserveMemory ++ * PROC_Start (OEM-function) ++ * PROC_UnMap ++ * PROC_UnReserveMemory ++ * ++ * Notes: ++ * ++ *! Revision History: ++ *! ================ ++ *! 19-Apr-2004 sb Aligned DMM definitions with Symbian ++ *! 08-Mar-2004 sb Added the Dynamic Memory Mapping APIs ++ *! 09-Feb-2003 vp: Added PROC_GetProcessorID function ++ *! 29-Nov-2000 rr: Incorporated code review changes. ++ *! 28-Sep-2000 rr: Updated to Version 0.9. ++ *! 10-Aug-2000 rr: PROC_NotifyClients, PROC_GetProcessorHandle Added ++ *! 27-Jul-2000 rr: Updated to ver 0.8 of DSPAPI(types). GetTrace added. ++ *! 27-Jun-2000 rr: Created from dspapi.h ++ */ ++ ++#ifndef PROC_ ++#define PROC_ ++ ++#include ++#include ++ ++/* ++ * ======== PROC_Attach ======== ++ * Purpose: ++ * Prepare for communication with a particular DSP processor, and return ++ * a handle to the processor object. The PROC Object gets created ++ * Parameters: ++ * uProcessor : The processor index (zero-based). ++ * hMgrObject : Handle to the Manager Object ++ * pAttrIn : Ptr to the DSP_PROCESSORATTRIN structure. ++ * A NULL value means use default values. ++ * phProcessor : Ptr to location to store processor handle. ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_EFAIL : General failure. ++ * DSP_EHANDLE : Invalid processor handle. ++ * DSP_SALREADYATTACHED: Success; Processor already attached. ++ * Requires: ++ * phProcessor != NULL. ++ * PROC Initialized. ++ * Ensures: ++ * DSP_EFAIL, and *phProcessor == NULL, OR ++ * Success and *phProcessor is a Valid Processor handle OR ++ * DSP_SALREADYATTACHED and *phProcessor is a Valid Processor. ++ * Details: ++ * When pAttrIn is NULL, the default timeout value is 10 seconds. ++ */ ++ extern DSP_STATUS PROC_Attach(u32 uProcessor, ++ OPTIONAL CONST struct DSP_PROCESSORATTRIN ++ *pAttrIn, ++ OUT DSP_HPROCESSOR *phProcessor); ++ ++/* ++ * ======== PROC_AutoStart ========= ++ * Purpose: ++ * A Particular device gets loaded with the default image ++ * if the AutoStart flag is set. ++ * Parameters: ++ * hDevObject : Handle to the Device ++ * Returns: ++ * DSP_SOK : On Successful Loading ++ * DSP_EFILE : No DSP exec file found. ++ * DSP_EFAIL : General Failure ++ * Requires: ++ * hDevObject != NULL. ++ * hDevNode != NULL. ++ * PROC Initialized. ++ * Ensures: ++ */ ++ extern DSP_STATUS PROC_AutoStart(struct CFG_DEVNODE *hDevNode, ++ struct DEV_OBJECT *hDevObject); ++ ++/* ++ * ======== PROC_Ctrl ======== ++ * Purpose: ++ * Pass control information to the GPP device driver managing the DSP ++ * processor. This will be an OEM-only function, and not part of the ++ * 'Bridge application developer's API. ++ * Parameters: ++ * hProcessor : The processor handle. ++ * dwCmd : Private driver IOCTL cmd ID. ++ * pArgs : Ptr to an driver defined argument structure. ++ * Returns: ++ * DSP_SOK : SUCCESS ++ * DSP_EHANDLE : Invalid processor handle. ++ * DSP_ETIMEOUT: A Timeout Occured before the Control information ++ * could be sent. ++ * DSP_EACCESSDENIED: Client does not have the access rights required ++ * to call this function. ++ * DSP_ERESTART: A Critical error has occured and the DSP is being ++ * restarted. ++ * DSP_EFAIL : General Failure. ++ * Requires: ++ * PROC Initialized. ++ * Ensures ++ * Details: ++ * This function Calls WMD_BRD_Ioctl. ++ */ ++ extern DSP_STATUS PROC_Ctrl(DSP_HPROCESSOR hProcessor, ++ u32 dwCmd, IN struct DSP_CBDATA *pArgs); ++ ++/* ++ * ======== PROC_Detach ======== ++ * Purpose: ++ * Close a DSP processor and de-allocate all (GPP) resources reserved ++ * for it. The Processor Object is deleted. ++ * Parameters: ++ * hProcessor : The processor handle. ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_EHANDLE : InValid Handle. ++ * DSP_EFAIL : General failure. ++ * Requires: ++ * PROC Initialized. ++ * Ensures: ++ * PROC Object is destroyed. ++ */ ++ extern DSP_STATUS PROC_Detach(DSP_HPROCESSOR hProcessor); ++ ++/* ++ * ======== PROC_EnumNodes ======== ++ * Purpose: ++ * Enumerate the nodes currently allocated on a processor. ++ * Parameters: ++ * hProcessor : The processor handle. ++ * aNodeTab : The first Location of an array allocated for node ++ * handles. ++ * uNodeTabSize: The number of (DSP_HNODE) handles that can be held ++ * to the memory the client has allocated for aNodeTab ++ * puNumNodes : Location where DSPProcessor_EnumNodes will return ++ * the number of valid handles written to aNodeTab ++ * puAllocated : Location where DSPProcessor_EnumNodes will return ++ * the number of nodes that are allocated on the DSP. ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_EHANDLE : Invalid processor handle. ++ * DSP_ESIZE : The amount of memory allocated for aNodeTab is ++ * insufficent. That is the number of nodes actually ++ * allocated on the DSP is greater than the value ++ * specified for uNodeTabSize. ++ * DSP_EFAIL : Unable to get Resource Information. ++ * Details: ++ * Requires ++ * puNumNodes is not NULL. ++ * puAllocated is not NULL. ++ * aNodeTab is not NULL. ++ * PROC Initialized. ++ * Ensures: ++ * Details: ++ */ ++ extern DSP_STATUS PROC_EnumNodes(DSP_HPROCESSOR hProcessor, ++ IN DSP_HNODE *aNodeTab, ++ IN u32 uNodeTabSize, ++ OUT u32 *puNumNodes, ++ OUT u32 *puAllocated); ++ ++/* ++ * ======== PROC_GetResourceInfo ======== ++ * Purpose: ++ * Enumerate the resources currently available on a processor. ++ * Parameters: ++ * hProcessor : The processor handle. ++ * uResourceType: Type of resource . ++ * pResourceInfo: Ptr to the DSP_RESOURCEINFO structure. ++ * uResourceInfoSize: Size of the structure. ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_EHANDLE : Invalid processor handle. ++ * DSP_EWRONGSTATE: The processor is not in the PROC_RUNNING state. ++ * DSP_ETIMEOUT: A timeout occured before the DSP responded to the ++ * querry. ++ * DSP_ERESTART: A Critical error has occured and the DSP is being ++ * restarted. ++ * DSP_EFAIL : Unable to get Resource Information ++ * Requires: ++ * pResourceInfo is not NULL. ++ * Parameter uResourceType is Valid.[TBD] ++ * uResourceInfoSize is >= sizeof DSP_RESOURCEINFO struct. ++ * PROC Initialized. ++ * Ensures: ++ * Details: ++ * This function currently returns ++ * DSP_ENOTIMPL, and does not write any data to the pResourceInfo struct. ++ */ ++ extern DSP_STATUS PROC_GetResourceInfo(DSP_HPROCESSOR hProcessor, ++ u32 uResourceType, ++ OUT struct DSP_RESOURCEINFO * ++ pResourceInfo, ++ u32 uResourceInfoSize); ++ ++/* ++ * ======== PROC_Exit ======== ++ * Purpose: ++ * Decrement reference count, and free resources when reference count is ++ * 0. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * PROC is initialized. ++ * Ensures: ++ * When reference count == 0, PROC's private resources are freed. ++ */ ++ extern void PROC_Exit(void); ++ ++/* ++ * ======== PROC_GetDevObject ========= ++ * Purpose: ++ * Returns the DEV Hanlde for a given Processor handle ++ * Parameters: ++ * hProcessor : Processor Handle ++ * phDevObject : Location to store the DEV Handle. ++ * Returns: ++ * DSP_SOK : Success; *phDevObject has Dev handle ++ * DSP_EFAIL : Failure; *phDevObject is zero. ++ * Requires: ++ * phDevObject is not NULL ++ * PROC Initialized. ++ * Ensures: ++ * DSP_SOK : *phDevObject is not NULL ++ * DSP_EFAIL : *phDevObject is NULL. ++ */ ++ extern DSP_STATUS PROC_GetDevObject(DSP_HPROCESSOR hProcessor, ++ struct DEV_OBJECT **phDevObject); ++ ++/* ++ * ======== PROC_Init ======== ++ * Purpose: ++ * Initialize PROC's private state, keeping a reference count on each ++ * call. ++ * Parameters: ++ * Returns: ++ * TRUE if initialized; FALSE if error occured. ++ * Requires: ++ * Ensures: ++ * TRUE: A requirement for the other public PROC functions. ++ */ ++ extern bool PROC_Init(void); ++ ++/* ++ * ======== PROC_GetState ======== ++ * Purpose: ++ * Report the state of the specified DSP processor. ++ * Parameters: ++ * hProcessor : The processor handle. ++ * pProcStatus : Ptr to location to store the DSP_PROCESSORSTATE ++ * structure. ++ * uStateInfoSize: Size of DSP_PROCESSORSTATE. ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_EHANDLE : Invalid processor handle. ++ * DSP_EFAIL : General failure while querying processor state. ++ * Requires: ++ * pProcStatus is not NULL ++ * uStateInfoSize is >= than the size of DSP_PROCESSORSTATE structure. ++ * PROC Initialized. ++ * Ensures: ++ * Details: ++ */ ++ extern DSP_STATUS PROC_GetState(DSP_HPROCESSOR hProcessor, ++ OUT struct DSP_PROCESSORSTATE ++ *pProcStatus, ++ u32 uStateInfoSize); ++ ++/* ++ * ======== PROC_GetProcessorID ======== ++ * Purpose: ++ * Report the state of the specified DSP processor. ++ * Parameters: ++ * hProcessor : The processor handle. ++ * procID : Processor ID ++ * ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_EHANDLE : Invalid processor handle. ++ * DSP_EFAIL : General failure while querying processor state. ++ * Requires: ++ * pProcStatus is not NULL ++ * uStateInfoSize is >= than the size of DSP_PROCESSORSTATE structure. ++ * PROC Initialized. ++ * Ensures: ++ * Details: ++ */ ++ extern DSP_STATUS PROC_GetProcessorId(DSP_HPROCESSOR hProcessor, ++ u32 *procID); ++ ++/* ++ * ======== PROC_GetTrace ======== ++ * Purpose: ++ * Retrieve the trace buffer from the specified DSP processor. ++ * Parameters: ++ * hProcessor : The processor handle. ++ * pBuf : Ptr to buffer to hold trace output. ++ * uMaxSize : Maximum size of the output buffer. ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_EHANDLE : Invalid processor handle. ++ * DSP_EFAIL : General failure while retireving processor trace ++ * Buffer. ++ * Requires: ++ * pBuf is not NULL ++ * uMaxSize is > 0. ++ * PROC Initialized. ++ * Ensures: ++ * Details: ++ */ ++ extern DSP_STATUS PROC_GetTrace(DSP_HPROCESSOR hProcessor, u8 *pBuf, ++ u32 uMaxSize); ++ ++/* ++ * ======== PROC_Load ======== ++ * Purpose: ++ * Reset a processor and load a new base program image. ++ * This will be an OEM-only function. ++ * Parameters: ++ * hProcessor : The processor handle. ++ * iArgc : The number of Arguments(strings)in the aArgV[] ++ * aArgv : An Array of Arguments(Unicode Strings) ++ * aEnvp : An Array of Environment settings(Unicode Strings) ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_EFILE : The DSP Execuetable was not found. ++ * DSP_EHANDLE : Invalid processor handle. ++ * DSP_ECORRUTFILE: Unable to Parse the DSP Execuetable ++ * DSP_EATTACHED: Abort because a GPP Client is attached to the ++ * specified Processor ++ * DSP_EACCESSDENIED: Client does not have the required access rights ++ * to reset and load the Processor ++ * DSP_EFAIL : Unable to Load the Processor ++ * Requires: ++ * aArgv is not NULL ++ * iArgc is > 0 ++ * PROC Initialized. ++ * Ensures: ++ * Success and ProcState == PROC_LOADED ++ * or DSP_FAILED status. ++ * Details: ++ * Does not implement access rights to control which GPP application ++ * can load the processor. ++ */ ++ extern DSP_STATUS PROC_Load(DSP_HPROCESSOR hProcessor, ++ IN CONST s32 iArgc, IN CONST char **aArgv, ++ IN CONST char **aEnvp); ++ ++/* ++ * ======== PROC_RegisterNotify ======== ++ * Purpose: ++ * Register to be notified of specific processor events ++ * Parameters: ++ * hProcessor : The processor handle. ++ * uEventMask : Mask of types of events to be notified about. ++ * uNotifyType : Type of notification to be sent. ++ * hNotification: Handle to be used for notification. ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_EHANDLE : Invalid processor handle or hNotification. ++ * DSP_EVALUE : Parameter uEventMask is Invalid ++ * DSP_ENOTIMP : The notification type specified in uNotifyMask ++ * is not supported. ++ * DSP_EFAIL : Unable to register for notification. ++ * Requires: ++ * hNotification is not NULL ++ * PROC Initialized. ++ * Ensures: ++ * Details: ++ */ ++ extern DSP_STATUS PROC_RegisterNotify(DSP_HPROCESSOR hProcessor, ++ u32 uEventMask, u32 uNotifyType, ++ struct DSP_NOTIFICATION ++ *hNotification); ++ ++/* ++ * ======== PROC_NotifyClients ======== ++ * Purpose: ++ * Notify the Processor Clients ++ * Parameters: ++ * hProc : The processor handle. ++ * uEvents : Event to be notified about. ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_EHANDLE : Invalid processor handle. ++ * DSP_EFAIL : Failure to Set or Reset the Event ++ * Requires: ++ * uEvents is Supported or Valid type of Event ++ * hProc is a valid handle ++ * PROC Initialized. ++ * Ensures: ++ */ ++ extern DSP_STATUS PROC_NotifyClients(DSP_HPROCESSOR hProc, ++ u32 uEvents); ++ ++/* ++ * ======== PROC_NotifyAllClients ======== ++ * Purpose: ++ * Notify the Processor Clients ++ * Parameters: ++ * hProc : The processor handle. ++ * uEvents : Event to be notified about. ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_EHANDLE : Invalid processor handle. ++ * DSP_EFAIL : Failure to Set or Reset the Event ++ * Requires: ++ * uEvents is Supported or Valid type of Event ++ * hProc is a valid handle ++ * PROC Initialized. ++ * Ensures: ++ * Details: ++ * NODE And STRM would use this function to notify their clients ++ * about the state changes in NODE or STRM. ++ */ ++ extern DSP_STATUS PROC_NotifyAllClients(DSP_HPROCESSOR hProc, ++ u32 uEvents); ++ ++/* ++ * ======== PROC_Start ======== ++ * Purpose: ++ * Start a processor running. ++ * Processor must be in PROC_LOADED state. ++ * This will be an OEM-only function, and not part of the 'Bridge ++ * application developer's API. ++ * Parameters: ++ * hProcessor : The processor handle. ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_EHANDLE : Invalid processor handle. ++ * DSP_EWRONGSTATE: Processor is not in PROC_LOADED state. ++ * DSP_EFAIL : Unable to start the processor. ++ * Requires: ++ * PROC Initialized. ++ * Ensures: ++ * Success and ProcState == PROC_RUNNING or DSP_FAILED status. ++ * Details: ++ */ ++ extern DSP_STATUS PROC_Start(DSP_HPROCESSOR hProcessor); ++ ++/* ++ * ======== PROC_Stop ======== ++ * Purpose: ++ * Start a processor running. ++ * Processor must be in PROC_LOADED state. ++ * This will be an OEM-only function, and not part of the 'Bridge ++ * application developer's API. ++ * Parameters: ++ * hProcessor : The processor handle. ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_EHANDLE : Invalid processor handle. ++ * DSP_EWRONGSTATE: Processor is not in PROC_LOADED state. ++ * DSP_EFAIL : Unable to start the processor. ++ * Requires: ++ * PROC Initialized. ++ * Ensures: ++ * Success and ProcState == PROC_RUNNING or DSP_FAILED status. ++ * Details: ++ */ ++ extern DSP_STATUS PROC_Stop(DSP_HPROCESSOR hProcessor); ++ ++/* ++ * ======== PROC_FlushMemory ======== ++ * Purpose: ++ * Flushes a buffer from the MPU data cache. ++ * Parameters: ++ * hProcessor : The processor handle. ++ * pMpuAddr : Buffer start address ++ * ulSize : Buffer size ++ * ulFlags : Reserved. ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_EHANDLE : Invalid processor handle. ++ * DSP_EFAIL : General failure. ++ * Requires: ++ * PROC Initialized. ++ * Ensures: ++ * Details: ++ * All the arguments are currently ignored. ++ */ ++ extern DSP_STATUS PROC_FlushMemory(DSP_HPROCESSOR hProcessor, ++ void *pMpuAddr, ++ u32 ulSize, u32 ulFlags); ++ ++ ++/* ++ * ======== PROC_InvalidateMemory ======== ++ * Purpose: ++ * Invalidates a buffer from the MPU data cache. ++ * Parameters: ++ * hProcessor : The processor handle. ++ * pMpuAddr : Buffer start address ++ * ulSize : Buffer size ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_EHANDLE : Invalid processor handle. ++ * DSP_EFAIL : General failure. ++ * Requires: ++ * PROC Initialized. ++ * Ensures: ++ * Details: ++ * All the arguments are currently ignored. ++ */ ++ extern DSP_STATUS PROC_InvalidateMemory(DSP_HPROCESSOR hProcessor, ++ void *pMpuAddr, ++ u32 ulSize); ++ ++/* ++ * ======== PROC_Map ======== ++ * Purpose: ++ * Maps a MPU buffer to DSP address space. ++ * Parameters: ++ * hProcessor : The processor handle. ++ * pMpuAddr : Starting address of the memory region to map. ++ * ulSize : Size of the memory region to map. ++ * pReqAddr : Requested DSP start address. Offset-adjusted actual ++ * mapped address is in the last argument. ++ * ppMapAddr : Ptr to DSP side mapped u8 address. ++ * ulMapAttr : Optional endianness attributes, virt to phys flag. ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_EHANDLE : Invalid processor handle. ++ * DSP_EFAIL : General failure. ++ * DSP_EMEMORY : MPU side memory allocation error. ++ * DSP_ENOTFOUND : Cannot find a reserved region starting with this ++ * : address. ++ * Requires: ++ * pMpuAddr is not NULL ++ * ulSize is not zero ++ * ppMapAddr is not NULL ++ * PROC Initialized. ++ * Ensures: ++ * Details: ++ */ ++ extern DSP_STATUS PROC_Map(DSP_HPROCESSOR hProcessor, ++ void *pMpuAddr, ++ u32 ulSize, ++ void *pReqAddr, ++ void **ppMapAddr, u32 ulMapAttr); ++ ++/* ++ * ======== PROC_ReserveMemory ======== ++ * Purpose: ++ * Reserve a virtually contiguous region of DSP address space. ++ * Parameters: ++ * hProcessor : The processor handle. ++ * ulSize : Size of the address space to reserve. ++ * ppRsvAddr : Ptr to DSP side reserved u8 address. ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_EHANDLE : Invalid processor handle. ++ * DSP_EFAIL : General failure. ++ * DSP_EMEMORY : Cannot reserve chunk of this size. ++ * Requires: ++ * ppRsvAddr is not NULL ++ * PROC Initialized. ++ * Ensures: ++ * Details: ++ */ ++ extern DSP_STATUS PROC_ReserveMemory(DSP_HPROCESSOR hProcessor, ++ u32 ulSize, void **ppRsvAddr); ++ ++/* ++ * ======== PROC_UnMap ======== ++ * Purpose: ++ * Removes a MPU buffer mapping from the DSP address space. ++ * Parameters: ++ * hProcessor : The processor handle. ++ * pMapAddr : Starting address of the mapped memory region. ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_EHANDLE : Invalid processor handle. ++ * DSP_EFAIL : General failure. ++ * DSP_ENOTFOUND : Cannot find a mapped region starting with this ++ * : address. ++ * Requires: ++ * pMapAddr is not NULL ++ * PROC Initialized. ++ * Ensures: ++ * Details: ++ */ ++ extern DSP_STATUS PROC_UnMap(DSP_HPROCESSOR hProcessor, void *pMapAddr); ++ ++/* ++ * ======== PROC_UnReserveMemory ======== ++ * Purpose: ++ * Frees a previously reserved region of DSP address space. ++ * Parameters: ++ * hProcessor : The processor handle. ++ * pRsvAddr : Ptr to DSP side reservedBYTE address. ++ * Returns: ++ * DSP_SOK : Success. ++ * DSP_EHANDLE : Invalid processor handle. ++ * DSP_EFAIL : General failure. ++ * DSP_ENOTFOUND : Cannot find a reserved region starting with this ++ * : address. ++ * Requires: ++ * pRsvAddr is not NULL ++ * PROC Initialized. ++ * Ensures: ++ * Details: ++ */ ++ extern DSP_STATUS PROC_UnReserveMemory(DSP_HPROCESSOR hProcessor, ++ void *pRsvAddr); ++ ++#endif /* PROC_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/procpriv.h b/arch/arm/plat-omap/include/dspbridge/procpriv.h +new file mode 100644 +index 0000000..21d4b3e +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/procpriv.h +@@ -0,0 +1,35 @@ ++/* ++ * procpriv.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== procpriv.h ======== ++ * Description: ++ * Global PROC constants and types, shared by PROC, MGR, and WCD. ++ * ++ *! Revision History: ++ *! ================ ++ *! 05-July-2000 rr: Created ++ */ ++ ++#ifndef PROCPRIV_ ++#define PROCPRIV_ ++ ++/* RM PROC Object */ ++ struct PROC_OBJECT; ++ ++#endif /* PROCPRIV_ */ ++ +diff --git a/arch/arm/plat-omap/include/dspbridge/pwr.h b/arch/arm/plat-omap/include/dspbridge/pwr.h +new file mode 100644 +index 0000000..a6645ca +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/pwr.h +@@ -0,0 +1,129 @@ ++/* ++ * pwr.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== pwr.h ======== ++ * ++ * Public Functions: ++ * ++ * PWR_SleepDSP ++ * PWR_WakeDSP ++ * ++ * Notes: ++ * ++ *! Revision History: ++ *! ================ ++ *! 06-Jun-2002 sg Replaced dspdefs.h with includes of dbdefs.h and errbase.h. ++ *! 13-May-2002 sg Added DSP_SAREADYASLEEP and DSP_SALREADYAWAKE. ++ *! 09-May-2002 sg Updated, added timeouts. ++ *! 02-May-2002 sg Initial. ++ */ ++ ++#ifndef PWR_ ++#define PWR_ ++ ++#include ++#include ++#include ++ ++/* ++ * ======== PWR_SleepDSP ======== ++ * Signal the DSP to go to sleep. ++ * ++ * Parameters: ++ * sleepCode: New sleep state for DSP. (Initially, valid codes ++ * are PWR_DEEPSLEEP or PWR_EMERGENCYDEEPSLEEP; both of ++ * these codes will simply put the DSP in deep sleep.) ++ * ++ * timeout: Maximum time (msec) that PWR should wait for ++ * confirmation that the DSP sleep state has been ++ * reached. If PWR should simply send the command to ++ * the DSP to go to sleep and then return (i.e., ++ * asynchrounous sleep), the timeout should be ++ * specified as zero. ++ * ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_SALREADYASLEEP: Success, but the DSP was already asleep. ++ * DSP_EINVALIDARG: The specified sleepCode is not supported. ++ * DSP_ETIMEOUT: A timeout occured while waiting for DSP sleep ++ * confirmation. ++ * DSP_EFAIL: General failure, unable to send sleep command to ++ * the DSP. ++ */ ++ extern DSP_STATUS PWR_SleepDSP(IN CONST u32 sleepCode, ++ IN CONST u32 timeout); ++ ++/* ++ * ======== PWR_WakeDSP ======== ++ * Signal the DSP to wake from sleep. ++ * ++ * Parameters: ++ * timeout: Maximum time (msec) that PWR should wait for ++ * confirmation that the DSP is awake. If PWR should ++ * simply send a command to the DSP to wake and then ++ * return (i.e., asynchrounous wake), timeout should ++ * be specified as zero. ++ * ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_SALREADYAWAKE: Success, but the DSP was already awake. ++ * DSP_ETIMEOUT: A timeout occured while waiting for wake ++ * confirmation. ++ * DSP_EFAIL: General failure, unable to send wake command to ++ * the DSP. ++ */ ++ extern DSP_STATUS PWR_WakeDSP(IN CONST u32 timeout); ++ ++/* ++ * ======== PWR_PM_PreScale ======== ++ * Prescale notification to DSP. ++ * ++ * Parameters: ++ * voltage_domain: The voltage domain for which notification is sent ++ * level: The level of voltage domain ++ * ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_SALREADYAWAKE: Success, but the DSP was already awake. ++ * DSP_ETIMEOUT: A timeout occured while waiting for wake ++ * confirmation. ++ * DSP_EFAIL: General failure, unable to send wake command to ++ * the DSP. ++ */ ++ extern DSP_STATUS PWR_PM_PreScale(IN u16 voltage_domain, u32 level); ++ ++/* ++ * ======== PWR_PM_PostScale ======== ++ * PostScale notification to DSP. ++ * ++ * Parameters: ++ * voltage_domain: The voltage domain for which notification is sent ++ * level: The level of voltage domain ++ * ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_SALREADYAWAKE: Success, but the DSP was already awake. ++ * DSP_ETIMEOUT: A timeout occured while waiting for wake ++ * confirmation. ++ * DSP_EFAIL: General failure, unable to send wake command to ++ * the DSP. ++ */ ++ extern DSP_STATUS PWR_PM_PostScale(IN u16 voltage_domain, ++ u32 level); ++ ++#endif /* PWR_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/pwr_sh.h b/arch/arm/plat-omap/include/dspbridge/pwr_sh.h +new file mode 100644 +index 0000000..40f1b84 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/pwr_sh.h +@@ -0,0 +1,41 @@ ++/* ++ * pwr_sh.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== pwr_sh.h ======== ++ * ++ * Power Manager shared definitions (used on both GPP and DSP sides). ++ * ++ *! Revision History ++ *! ================ ++ *! 17-Apr-2002 sg: Initial. ++ */ ++ ++#ifndef PWR_SH_ ++#define PWR_SH_ ++ ++#include ++ ++/* valid sleep command codes that can be sent by GPP via mailbox: */ ++#define PWR_DEEPSLEEP MBX_PM_DSPIDLE ++#define PWR_EMERGENCYDEEPSLEEP MBX_PM_EMERGENCYSLEEP ++#define PWR_SLEEPUNTILRESTART MBX_PM_SLEEPUNTILRESTART ++#define PWR_WAKEUP MBX_PM_DSPWAKEUP ++#define PWR_AUTOENABLE MBX_PM_PWRENABLE ++#define PWR_AUTODISABLE MBX_PM_PWRDISABLE ++#define PWR_RETENTION MBX_PM_DSPRETN ++ ++#endif /* PWR_SH_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/reg.h b/arch/arm/plat-omap/include/dspbridge/reg.h +new file mode 100644 +index 0000000..5b34952 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/reg.h +@@ -0,0 +1,257 @@ ++/* ++ * reg.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== reg.h ======== ++ * Purpose: ++ * Provide registry functions. ++ * ++ * Public Functions: ++ * REG_DeleteValue ++ * REG_EnumKey ++ * REG_EnumValue ++ * REG_Exit ++ * REG_GetValue ++ * REG_Init ++ * REG_SetValue ++ * ++ *! Revision History: ++ *! ================= ++ *! 30-Oct-2000 kc: Updated REG_SetValue & REG_GetValue; renamed ++ *! REG_DeleteEntry to REG_DeleteValue. ++ *! 29-Sep-2000 kc: Updated a REG functions for code review. ++ *! 12-Aug-2000 kc: Renamed REG_EnumValue to REG_EnumKey. Re-implemented ++ *! REG_EnumValue. ++ *! 03-Feb-2000 rr: REG_EnumValue Fxn Added ++ *! 13-Dec-1999 rr: windows.h removed ++ *! 02-Dec-1999 rr: windows.h included for retail build ++ *! 22-Nov-1999 kc: Changes from code review. ++ *! 29-Dec-1997 cr: Changes from code review. ++ *! 27-Oct-1997 cr: Added REG_DeleteValue. ++ *! 20-Oct-1997 cr: Added ability to pass bValue = NULL to REG_GetValue ++ *! and return size of reg entry in pdwValueSize. ++ *! 29-Sep-1997 cr: Added REG_SetValue ++ *! 29-Aug-1997 cr: Created. ++ */ ++ ++#ifndef _REG_H ++#define _REG_H ++ ++#include ++ ++/* ------------------------- Defines, Data Structures, Typedefs for Linux */ ++#ifndef UNDER_CE ++ ++#ifndef REG_SZ ++#define REG_SZ 1 ++#endif ++ ++#ifndef REG_BINARY ++#define REG_BINARY 3 ++#endif ++ ++#ifndef REG_DWORD ++#define REG_DWORD 4 ++#endif ++ ++#endif /* UNDER_CE */ ++ ++#define REG_MAXREGPATHLENGTH 255 ++ ++/* ++ * ======== REG_DeleteValue ======== ++ * Purpose: ++ * Deletes a registry entry. NOTE: A registry entry is not the same as ++ * a registry key. ++ * Parameters: ++ * phKey: Currently reserved; must be NULL. ++ * pstrSubkey: Path to key to open. ++ * pstrValue: Name of entry to delete. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: General failure. ++ * Requires: ++ * - REG initialized. ++ * - pstrSubkey & pstrValue are non-NULL values. ++ * - phKey is NULL. ++ * - length of pstrSubkey < REG_MAXREGPATHLENGTH. ++ * - length of pstrValue < REG_MAXREGPATHLENGTH. ++ * Ensures: ++ * Details: ++ */ ++ extern DSP_STATUS REG_DeleteValue(OPTIONAL IN HANDLE *phKey, ++ IN CONST char *pstrSubkey, ++ IN CONST char *pstrValue); ++ ++/* ++ * ======== REG_EnumKey ======== ++ * Purpose: ++ * Enumerates subkeys of the specified path to the registry key ++ * Retrieves the name of the subkey(given the index) and ++ * appends with the orignal path to form the full path. ++ * Parameters: ++ * phKey: Currently reserved; must be NULL. ++ * pstrKey The name of the registry key to be enumerated. ++ * dwIndex Specifies the index of the subkey to retrieve. ++ * pstrSubkey: Pointer to buffer that receives full path name of the ++ * specified key + the sub-key ++ * pdwValueSize: Specifies bytes of memory pstrSubkey points to on input, ++ * on output, specifies actual memory bytes written into. ++ * If there is no sub key,pdwValueSize returns NULL. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: General failure. ++ * Requires: ++ * - REG initialized. ++ * - pstrKey is non-NULL value. ++ * - pdwValueSize is a valid pointer. ++ * - phKey is NULL. ++ * - length of pstrKey < REG_MAXREGPATHLENGTH. ++ * Ensures: ++ * - strlen(pstrSubkey) is > strlen(pstrKey) && ++ * - strlen(pstrSubkey) is < REG_MAXREGPATHLENGTH ++ */ ++ extern DSP_STATUS REG_EnumKey(OPTIONAL IN HANDLE *phKey, ++ IN u32 dwIndex, IN CONST char *pstrKey, ++ IN OUT char *pstrSubkey, ++ IN OUT u32 *pdwValueSize); ++ ++/* ++ * ======== REG_EnumValue ======== ++ * Purpose: ++ * Enumerates values of a specified key. Retrieves each value name and ++ * the data associated with the value. ++ * Parameters: ++ * phKey: Currently reserved; must be NULL. ++ * dwIndex: Specifies the index of the value to retrieve. ++ * pstrKey: The name of the registry key to be enumerated. ++ * pstrValue: Pointer to buffer that receives the name of the value. ++ * pdwValueSize: Specifies bytes of memory pstrValue points to on input, ++ * On output, specifies actual memory bytes written into. ++ * If there is no value, pdwValueSize returns NULL ++ * pstrData: Pointer to buffer that receives the data of a value. ++ * pdwDataSize: Specifies bytes of memory in pstrData on input and ++ * bytes of memory written into pstrData on output. ++ * If there is no data, pdwDataSize returns NULL. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: General failure. ++ * Requires: ++ * REG initialized. ++ * phKey is NULL. ++ * pstrKey is a non-NULL value. ++ * pstrValue, pstrData, pdwValueSize and pdwDataSize are valid pointers. ++ * Length of pstrKey is less than REG_MAXREGPATHLENGTH. ++ * Ensures: ++ */ ++ extern DSP_STATUS REG_EnumValue(IN HANDLE *phKey, ++ IN u32 dwIndex, ++ IN CONST char *pstrKey, ++ IN OUT char *pstrValue, ++ IN OUT u32 *pdwValueSize, ++ IN OUT char *pstrData, ++ IN OUT u32 *pdwDataSize); ++ ++/* ++ * ======== REG_Exit ======== ++ * Purpose: ++ * Discontinue usage of module; free resources when reference count ++ * reaches 0. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * REG initialized. ++ * Ensures: ++ * Resources used by module are freed when cRef reaches zero. ++ */ ++ extern void REG_Exit(void); ++ ++/* ++ * ======== REG_GetValue ======== ++ * Purpose: ++ * Retrieve a value from the registry. ++ * Parameters: ++ * phKey: Currently reserved; must be NULL. ++ * pstrSubkey: Path to key to open. ++ * pstrEntry: Name of entry to retrieve. ++ * pbValue: Upon return, points to retrieved value. ++ * pdwValueSize: Specifies bytes of memory pbValue points to on input, ++ * on output, specifies actual memory bytes written into. ++ * If pbValue is NULL, pdwValueSize reports the size of ++ * the entry in pstrEntry. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: General failure. ++ * Requires: ++ * - REG initialized. ++ * - pstrSubkey & pstrEntry are non-NULL values. ++ * - pbValue is a valid pointer. ++ * - phKey is NULL. ++ * - length of pstrSubkey < REG_MAXREGPATHLENGTH. ++ * - length of pstrEntry < REG_MAXREGPATHLENGTH. ++ * Ensures: ++ */ ++ extern DSP_STATUS REG_GetValue(OPTIONAL IN HANDLE *phKey, ++ IN CONST char *pstrSubkey, ++ IN CONST char *pstrEntry, ++ OUT u8 *pbValue, ++ IN OUT u32 *pdwValueSize); ++ ++/* ++ * ======== REG_Init ======== ++ * Purpose: ++ * Initializes private state of REG module. ++ * Parameters: ++ * Returns: ++ * TRUE if initialized; FALSE if error occured. ++ * Requires: ++ * Ensures: ++ * REG initialized. ++ */ ++ extern bool REG_Init(void); ++ ++/* ++ * ======== REG_SetValue ======== ++ * Purpose: ++ * Set a value in the registry. ++ * Parameters: ++ * phKey: Handle to open reg key, or NULL if pSubkey is full path. ++ * pstrSubkey: Path to key to open, could be based on phKey. ++ * pstrEntry: Name of entry to set. ++ * dwType: Data type of new registry value. ++ * pbValue: Points to buffer containing new data. ++ * dwValueSize: Specifies bytes of memory bValue points to. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: General failure. ++ * Requires: ++ * - REG initialized. ++ * - pstrSubkey & pstrEntry are non-NULL values. ++ * - pbValue is a valid pointer. ++ * - phKey is NULL. ++ * - dwValuSize > 0. ++ * - length of pstrSubkey < REG_MAXREGPATHLENGTH. ++ * - length of pstrEntry < REG_MAXREGPATHLENGTH. ++ * Ensures: ++ */ ++ extern DSP_STATUS REG_SetValue(OPTIONAL IN HANDLE *phKey, ++ IN CONST char *pstrSubKey, ++ IN CONST char *pstrEntry, ++ IN CONST u32 dwType, ++ IN u8 *pbValue, IN u32 dwValueSize); ++ ++#endif /* _REG_H */ +diff --git a/arch/arm/plat-omap/include/dspbridge/resourcecleanup.h b/arch/arm/plat-omap/include/dspbridge/resourcecleanup.h +new file mode 100644 +index 0000000..b43fa16 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/resourcecleanup.h +@@ -0,0 +1,88 @@ ++/* ++ * resourcecleanup.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++#ifndef RES_CLEANUP_DISABLE ++ ++#include ++#include ++ ++ ++extern DSP_STATUS DRV_GetProcCtxtList(struct PROCESS_CONTEXT **pPctxt, ++ struct DRV_OBJECT *hDrvObject); ++ ++extern DSP_STATUS DRV_InsertProcContext(struct DRV_OBJECT *hDrVObject, ++ HANDLE hPCtxt); ++ ++extern DSP_STATUS DRV_RemoveAllDMMResElements(HANDLE pCtxt); ++ ++extern DSP_STATUS DRV_RemoveAllNodeResElements(HANDLE pCtxt); ++ ++extern DSP_STATUS DRV_ProcUpdatestate(HANDLE pCtxt, ++ enum GPP_PROC_RES_STATE resState); ++ ++extern DSP_STATUS DRV_ProcSetPID(HANDLE pCtxt, s32 hProcess); ++ ++extern DSP_STATUS DRV_GetProcContext(u32 phProcess, ++ struct DRV_OBJECT *hDrvObject, ++ HANDLE hPCtxt, DSP_HNODE hNode, ++ u32 pMapAddr); ++ ++extern DSP_STATUS DRV_RemoveAllResources(HANDLE pPctxt); ++ ++extern DSP_STATUS DRV_RemoveProcContext(struct DRV_OBJECT *hDRVObject, ++ HANDLE hPCtxt, HANDLE hProcess); ++ ++extern DSP_STATUS DRV_GetNodeResElement(HANDLE hNode, HANDLE nodeRes, ++ HANDLE pCtxt); ++ ++extern DSP_STATUS DRV_InsertNodeResElement(HANDLE hNode, HANDLE nodeRes, ++ HANDLE pCtxt); ++ ++extern void DRV_ProcNodeUpdateHeapStatus(HANDLE hNodeRes, s32 status); ++ ++extern DSP_STATUS DRV_RemoveNodeResElement(HANDLE nodeRes, HANDLE status); ++ ++extern void DRV_ProcNodeUpdateStatus(HANDLE hNodeRes, s32 status); ++ ++extern DSP_STATUS DRV_UpdateDMMResElement(HANDLE dmmRes, u32 pMpuAddr, ++ u32 ulSize, u32 pReqAddr, ++ u32 ppMapAddr, HANDLE hProcesso); ++ ++extern DSP_STATUS DRV_InsertDMMResElement(HANDLE dmmRes, HANDLE pCtxt); ++ ++extern DSP_STATUS DRV_GetDMMResElement(u32 pMapAddr, HANDLE dmmRes, ++ HANDLE pCtxt); ++ ++extern DSP_STATUS DRV_RemoveDMMResElement(HANDLE dmmRes, HANDLE pCtxt); ++ ++extern DSP_STATUS DRV_ProcUpdateSTRMRes(u32 uNumBufs, HANDLE STRMRes, ++ HANDLE pCtxt); ++ ++extern DSP_STATUS DRV_ProcInsertSTRMResElement(HANDLE hStrm, HANDLE STRMRes, ++ HANDLE pPctxt); ++ ++extern DSP_STATUS DRV_GetSTRMResElement(HANDLE hStrm, HANDLE STRMRes, ++ HANDLE pCtxt); ++ ++extern DSP_STATUS DRV_ProcRemoveSTRMResElement(HANDLE STRMRes, HANDLE pCtxt); ++ ++extern DSP_STATUS DRV_RemoveAllSTRMResElements(HANDLE pCtxt); ++ ++extern DSP_STATUS DRV_ProcDisplayResInfo(u8 *pBuf, u32 *pSize); ++ ++extern enum NODE_STATE NODE_GetState(HANDLE hNode); ++ ++#endif +diff --git a/arch/arm/plat-omap/include/dspbridge/rmm.h b/arch/arm/plat-omap/include/dspbridge/rmm.h +new file mode 100644 +index 0000000..5b14b8f +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/rmm.h +@@ -0,0 +1,199 @@ ++/* ++ * rmm.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== rmm.h ======== ++ * ++ * This memory manager provides general heap management and arbitrary ++ * alignment for any number of memory segments, and management of overlay ++ * memory. ++ * ++ * Public functions: ++ * RMM_alloc ++ * RMM_create ++ * RMM_delete ++ * RMM_exit ++ * RMM_free ++ * RMM_init ++ * ++ *! Revision History ++ *! ================ ++ *! 25-Jun-2002 jeh Added RMM_Addr. Removed RMM_reserve, RMM_stat. ++ *! 15-Oct-2001 jeh Based on rm.h in gen tree. ++ */ ++ ++#ifndef RMM_ ++#define RMM_ ++ ++/* ++ * ======== RMM_Addr ======== ++ * DSP address + segid ++ */ ++struct RMM_Addr { ++ u32 addr; ++ s32 segid; ++} ; ++ ++/* ++ * ======== RMM_Segment ======== ++ * Memory segment on the DSP available for remote allocations. ++ */ ++struct RMM_Segment { ++ u32 base; /* Base of the segment */ ++ u32 length; /* Size of the segment (target MAUs) */ ++ s32 space; /* Code or data */ ++ u32 number; /* Number of Allocated Blocks */ ++} ; ++ ++/* ++ * ======== RMM_Target ======== ++ */ ++struct RMM_TargetObj; ++ ++/* ++ * ======== RMM_alloc ======== ++ * ++ * RMM_alloc is used to remotely allocate or reserve memory on the DSP. ++ * ++ * Parameters: ++ * target - Target returned from RMM_create(). ++ * segid - Memory segment to allocate from. ++ * size - Size (target MAUS) to allocate. ++ * align - alignment. ++ * dspAddr - If reserve is FALSE, the location to store allocated ++ * address on output, otherwise, the DSP address to ++ * reserve. ++ * reserve - If TRUE, reserve the memory specified by dspAddr. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Memory allocation on GPP failed. ++ * DSP_EOVERLAYMEMORY: Cannot "allocate" overlay memory because it's ++ * already in use. ++ * Requires: ++ * RMM initialized. ++ * Valid target. ++ * dspAddr != NULL. ++ * size > 0 ++ * reserve || target->numSegs > 0. ++ * Ensures: ++ */ ++extern DSP_STATUS RMM_alloc(struct RMM_TargetObj *target, u32 segid, u32 size, ++ u32 align, u32 *dspAdr, bool reserve); ++ ++/* ++ * ======== RMM_create ======== ++ * Create a target object with memory segments for remote allocation. If ++ * segTab == NULL or numSegs == 0, memory can only be reserved through ++ * RMM_alloc(). ++ * ++ * Parameters: ++ * pTarget: - Location to store target on output. ++ * segTab: - Table of memory segments. ++ * numSegs: - Number of memory segments. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Memory allocation failed. ++ * Requires: ++ * RMM initialized. ++ * pTarget != NULL. ++ * numSegs == 0 || segTab != NULL. ++ * Ensures: ++ * Success: Valid *pTarget. ++ * Failure: *pTarget == NULL. ++ */ ++extern DSP_STATUS RMM_create(struct RMM_TargetObj **pTarget, ++ struct RMM_Segment segTab[], u32 numSegs); ++ ++/* ++ * ======== RMM_delete ======== ++ * Delete target allocated in RMM_create(). ++ * ++ * Parameters: ++ * target - Target returned from RMM_create(). ++ * Returns: ++ * Requires: ++ * RMM initialized. ++ * Valid target. ++ * Ensures: ++ */ ++extern void RMM_delete(struct RMM_TargetObj *target); ++ ++/* ++ * ======== RMM_exit ======== ++ * Exit the RMM module ++ * ++ * Parameters: ++ * Returns: ++ * Requires: ++ * RMM_init successfully called. ++ * Ensures: ++ */ ++extern void RMM_exit(void); ++ ++/* ++ * ======== RMM_free ======== ++ * Free or unreserve memory allocated through RMM_alloc(). ++ * ++ * Parameters: ++ * target: - Target returned from RMM_create(). ++ * segid: - Segment of memory to free. ++ * dspAddr: - Address to free or unreserve. ++ * size: - Size of memory to free or unreserve. ++ * reserved: - TRUE if memory was reserved only, otherwise FALSE. ++ * Returns: ++ * Requires: ++ * RMM initialized. ++ * Valid target. ++ * reserved || segid < target->numSegs. ++ * reserve || [dspAddr, dspAddr + size] is a valid memory range. ++ * Ensures: ++ */ ++extern bool RMM_free(struct RMM_TargetObj *target, u32 segid, u32 dspAddr, ++ u32 size, bool reserved); ++ ++/* ++ * ======== RMM_init ======== ++ * Initialize the RMM module ++ * ++ * Parameters: ++ * Returns: ++ * TRUE: Success. ++ * FALSE: Failure. ++ * Requires: ++ * Ensures: ++ */ ++extern bool RMM_init(void); ++ ++/* ++ * ======== RMM_stat ======== ++ * Obtain memory segment status ++ * ++ * Parameters: ++ * segid: Segment ID of the dynamic loading segment. ++ * pMemStatBuf: Pointer to allocated buffer into which memory stats are ++ * placed. ++ * Returns: ++ * TRUE: Success. ++ * FALSE: Failure. ++ * Requires: ++ * segid < target->numSegs ++ * Ensures: ++ */ ++extern bool RMM_stat(struct RMM_TargetObj *target, enum DSP_MEMTYPE segid, ++ struct DSP_MEMSTAT *pMemStatBuf); ++ ++#endif /* RMM_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/rms_sh.h b/arch/arm/plat-omap/include/dspbridge/rms_sh.h +new file mode 100644 +index 0000000..5d4b49a +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/rms_sh.h +@@ -0,0 +1,125 @@ ++/* ++ * rms_sh.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== rms_sh.h ======== ++ * ++ * DSP/BIOS Bridge Resource Manager Server shared definitions (used on both ++ * GPP and DSP sides). ++ * ++ *! Revision History ++ *! ================ ++ *! 24-Mar-2003 vp Merged updates required for CCS2.2 transition. ++ *! 24-Feb-2003 kc Rearranged order of node types to temporarily support ++ *! legacy message node code ++ *! 23-Nov-2002 gp Converted tabs -> spaces, to fix formatting. ++ *! 13-Feb-2002 jeh Added sysstacksize element to RMS_MoreTaskArgs. ++ *! 11-Dec-2000 sg Added 'misc' element to RMS_MoreTaskArgs. ++ *! 04-Dec-2000 ag Added RMS_BUFDESC command code. ++ *! C/R code value changed to allow ORing of system/user codes. ++ *! 10-Oct-2000 sg Added 'align' field to RMS_StrmDef. ++ *! 09-Oct-2000 sg Moved pre-defined message codes here from rmsdefs.h. ++ *! 02-Oct-2000 sg Changed ticks to msec. ++ *! 24-Aug-2000 sg Moved definitions that will be exposed to app developers ++ *! to a separate file, rmsdefs.h. ++ *! 10-Aug-2000 sg Added RMS_COMMANDBUFSIZE and RMS_RESPONSEBUFSIZE; added ++ *! pre-defined command/response codes; more comments. ++ *! 09-Aug-2000 sg Added RMS_ETASK. ++ *! 08-Aug-2000 jeh Define RMS_WORD for GPP, rename DSP_MSG to RMS_DSPMSG. ++ *! Added RMS_MsgArgs, RMS_MoreTaskArgs. ++ *! 25-Jul-2000 sg: Changed SIO to STRM. ++ *! 30-Jun-2000 sg: Initial. ++ */ ++ ++#ifndef RMS_SH_ ++#define RMS_SH_ ++ ++#include ++ ++/* Node Types: */ ++#define RMS_TASK 1 /* Task node */ ++#define RMS_DAIS 2 /* xDAIS socket node */ ++#define RMS_MSG 3 /* Message node */ ++ ++/* Memory Types: */ ++#define RMS_CODE 0 /* Program space */ ++#define RMS_DATA 1 /* Data space */ ++#define RMS_IO 2 /* I/O space */ ++ ++/* RM Server Command and Response Buffer Sizes: */ ++#define RMS_COMMANDBUFSIZE 256 /* Size of command buffer */ ++#define RMS_RESPONSEBUFSIZE 16 /* Size of response buffer */ ++ ++/* Pre-Defined Command/Response Codes: */ ++#define RMS_EXIT 0x80000000 /* GPP->Node: shutdown */ ++#define RMS_EXITACK 0x40000000 /* Node->GPP: ack shutdown */ ++#define RMS_BUFDESC 0x20000000 /* Arg1 SM buf, Arg2 is SM size */ ++#define RMS_KILLTASK 0x10000000 /* GPP->Node: Kill Task */ ++#define RMS_USER 0x0 /* Start of user-defined msg codes */ ++#define RMS_MAXUSERCODES 0xfff /* Maximum user defined C/R Codes */ ++ ++ ++/* RM Server RPC Command Structure: */ ++ struct RMS_Command { ++ RMS_WORD fxn; /* Server function address */ ++ RMS_WORD arg1; /* First argument */ ++ RMS_WORD arg2; /* Second argument */ ++ RMS_WORD data; /* Function-specific data array */ ++ } ; ++ ++/* ++ * The RMS_StrmDef structure defines the parameters for both input and output ++ * streams, and is passed to a node's create function. ++ */ ++ struct RMS_StrmDef { ++ RMS_WORD bufsize; /* Buffer size (in DSP words) */ ++ RMS_WORD nbufs; /* Max number of bufs in stream */ ++ RMS_WORD segid; /* Segment to allocate buffers */ ++ RMS_WORD align; /* Alignment for allocated buffers */ ++ RMS_WORD timeout; /* Timeout (msec) for blocking calls */ ++ RMS_CHAR name[1]; /* Device Name (terminated by '\0') */ ++ } ; ++ ++/* Message node create args structure: */ ++ struct RMS_MsgArgs { ++ RMS_WORD maxMessages; /* Max # simultaneous msgs to node */ ++ RMS_WORD segid; /* Mem segment for NODE_allocMsgBuf */ ++ RMS_WORD notifyType; /* Type of message notification */ ++ RMS_WORD argLength; /* Length (in DSP chars) of arg data */ ++ RMS_WORD argData; /* Arg data for node */ ++ } ; ++ ++/* Partial task create args structure */ ++ struct RMS_MoreTaskArgs { ++ RMS_WORD priority; /* Task's runtime priority level */ ++ RMS_WORD stackSize; /* Task's stack size */ ++ RMS_WORD sysstackSize; /* Task's system stack size (55x) */ ++ RMS_WORD stackSeg; /* Memory segment for task's stack */ ++ RMS_WORD heapAddr; /* base address of the node memory heap in ++ * external memory (DSP virtual address) */ ++ RMS_WORD heapSize; /* size in MAUs of the node memory heap in ++ * external memory */ ++ RMS_WORD misc; /* Misc field. Not used for 'normal' ++ * task nodes; for xDAIS socket nodes ++ * specifies the IALG_Fxn pointer. ++ */ ++ /* # input STRM definition structures */ ++ RMS_WORD numInputStreams; ++ } ; ++ ++#endif /* RMS_SH_ */ ++ +diff --git a/arch/arm/plat-omap/include/dspbridge/rmstypes.h b/arch/arm/plat-omap/include/dspbridge/rmstypes.h +new file mode 100644 +index 0000000..13d752e +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/rmstypes.h +@@ -0,0 +1,40 @@ ++/* ++ * rmstypes.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== rmstypes.h ======== ++ * ++ * DSP/BIOS Bridge Resource Manager Server shared data type definitions. ++ * ++ *! Revision History ++ *! ================ ++ *! 06-Oct-2000 sg Added LgFxn type. ++ *! 05-Oct-2000 sg Changed RMS_STATUS to LgUns. ++ *! 31-Aug-2000 sg Added RMS_DSPMSG. ++ *! 25-Aug-2000 sg Initial. ++ */ ++ ++#ifndef RMSTYPES_ ++#define RMSTYPES_ ++#include ++/* ++ * DSP-side definitions. ++ */ ++#include ++typedef u32 RMS_WORD; ++typedef char RMS_CHAR; ++ ++#endif /* RMSTYPES_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/services.h b/arch/arm/plat-omap/include/dspbridge/services.h +new file mode 100644 +index 0000000..35bab0d +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/services.h +@@ -0,0 +1,63 @@ ++/* ++ * services.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== services.h ======== ++ * Purpose: ++ * Provide loading and unloading of SERVICES modules. ++ * ++ * Public Functions: ++ * SERVICES_Exit(void) ++ * SERVICES_Init(void) ++ * ++ *! Revision History: ++ *! ================ ++ *! 01-Feb-2000 kc: Created. ++ */ ++ ++#ifndef SERVICES_ ++#define SERVICES_ ++ ++#include ++/* ++ * ======== SERVICES_Exit ======== ++ * Purpose: ++ * Discontinue usage of module; free resources when reference count ++ * reaches 0. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * SERVICES initialized. ++ * Ensures: ++ * Resources used by module are freed when cRef reaches zero. ++ */ ++ extern void SERVICES_Exit(void); ++ ++/* ++ * ======== SERVICES_Init ======== ++ * Purpose: ++ * Initializes SERVICES modules. ++ * Parameters: ++ * Returns: ++ * TRUE if all modules initialized; otherwise FALSE. ++ * Requires: ++ * Ensures: ++ * SERVICES modules initialized. ++ */ ++ extern bool SERVICES_Init(void); ++ ++#endif /* SERVICES_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/std.h b/arch/arm/plat-omap/include/dspbridge/std.h +new file mode 100644 +index 0000000..ec849f4 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/std.h +@@ -0,0 +1,143 @@ ++/* ++ * std.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== std.h ======== ++ * ++ *! Revision History ++ *! ================ ++ *! 16-Feb-2004 vp GNU compiler 3.x defines inline keyword. Added ++ *! appropriate macros not to redefine inline keyword in ++ *! this file. ++ *! 24-Oct-2002 ashu defined _TI_ and _FIXED_ symbols for 28x. ++ *! 24-Oct-2002 ashu defined _TI_ for 24x. ++ *! 01-Mar-2002 kln changed LARGE_MODEL and Arg definition for 28x ++ *! 01-Feb-2002 kln added definitions for 28x ++ *! 08-Dec-2000 kw: added 'ArgToInt' and 'ArgToPtr' macros ++ *! 30-Nov-2000 mf: Added _64_, _6x_; removed _7d_ ++ *! 30-May-2000 srid: Added __TMS320C55X__ for 55x; Arg is void * for 55 . ++ *! 18-Jun-1999 dr: Added '_TI_', fixed __inline for SUN4, added inline ++ *! 10-Feb-1999 rt: Added '55' support, changed 54's symbol to _TMS320C5XX ++ *! 29-Aug-1998 mf: fixed typo, removed obsolete targets ++ *! 08-Jun-1998 mf: _67_ is synonym for _7d_ ++ *! 10-Oct-1997 rt; added _7d_ for Raytheon C7DSP triggered by _TMS320C6700 ++ *! 04-Aug-1997 cc: added _29_ for _TMS320C2XX ++ *! 11-Jul-1997 dlr: _5t_, and STD_SPOXTASK keyword for Tasking ++ *! 12-Jun-1997 mf: _TMS320C60 -> _TMS320C6200 ++ *! 13-Feb-1997 mf: _62_, with 32-bit LgInt ++ *! 26-Nov-1996 kw: merged bios-c00's and wsx-a27's changes ++ *! *and* revision history ++ *! 12-Sep-1996 kw: added C54x #ifdef's ++ *! 21-Aug-1996 mf: removed #define main smain for _21_ ++ *! 14-May-1996 gp: def'd out INT, FLOAT, and COMPLEX defines for WSX. ++ *! 11-Apr-1996 kw: define _W32_ based on _WIN32 (defined by MS compiler) ++ *! 07-Mar-1996 mg: added Win32 support ++ *! 06-Sep-1995 dh: added _77_ dynamic stack support via fxns77.h ++ *! 27-Jun-1995 dh: added _77_ support ++ *! 16-Mar-1995 mf: for _21_: #define main smain ++ *! 01-Mar-1995 mf: set _20_ and _60_ (as well as _21_ for both) ++ *! 22-Feb-1995 mf: Float is float for _SUN_ and _80_ ++ *! 22-Dec-1994 mf: Added _80_ definition, for PP or MP. ++ *! 09-Dec-1994 mf: Added _53_ definition. ++ *! Added definitions of _30_, etc. ++ *! 23-Aug-1994 dh removed _21_ special case (kw) ++ *! 17-Aug-1994 dh added _51_ support ++ *! 03-Aug-1994 kw updated _80_ support ++ *! 30-Jun-1994 kw added _80_ support ++ *! 05-Apr-1994 kw: Added _SUN_ to _FLOAT_ definition ++ *! 01-Mar-1994 kw: Made Bool an int (was u16) for _56_ (more efficient). ++ *! Added _53_ support. ++ */ ++ ++#ifndef STD_ ++#define STD_ ++ ++#include ++ ++/* ++ * ======== _TI_ ======== ++ * _TI_ is defined for all TI targets ++ */ ++#if defined(_29_) || defined(_30_) || defined(_40_) || defined(_50_) || \ ++ defined(_54_) || defined(_55_) || defined(_6x_) || defined(_80_) || \ ++ defined(_28_) || defined(_24_) ++#define _TI_ 1 ++#endif ++ ++/* ++ * ======== _FLOAT_ ======== ++ * _FLOAT_ is defined for all targets that natively support floating point ++ */ ++#if defined(_SUN_) || defined(_30_) || defined(_40_) || defined(_67_) || \ ++ defined(_80_) ++#define _FLOAT_ 1 ++#endif ++ ++/* ++ * ======== _FIXED_ ======== ++ * _FIXED_ is defined for all fixed point target architectures ++ */ ++#if defined(_29_) || defined(_50_) || defined(_54_) || defined(_55_) || \ ++ defined(_62_) || defined(_64_) || defined(_28_) ++#define _FIXED_ 1 ++#endif ++ ++/* ++ * ======== _TARGET_ ======== ++ * _TARGET_ is defined for all target architectures (as opposed to ++ * host-side software) ++ */ ++#if defined(_FIXED_) || defined(_FLOAT_) ++#define _TARGET_ 1 ++#endif ++ ++/* ++ * 8, 16, 32-bit type definitions ++ * ++ * Sm* - 8-bit type ++ * Md* - 16-bit type ++ * Lg* - 32-bit type ++ * ++ * *s32 - signed type ++ * *u32 - unsigned type ++ * *Bits - unsigned type (bit-maps) ++ */ ++ ++/* ++ * Aliases for standard C types ++ */ ++ ++typedef s32(*Fxn) (void); /* generic function type */ ++ ++#ifndef NULL ++#define NULL 0 ++#endif ++ ++ ++/* ++ * These macros are used to cast 'Arg' types to 's32' or 'Ptr'. ++ * These macros were added for the 55x since Arg is not the same ++ * size as s32 and Ptr in 55x large model. ++ */ ++#if defined(_28l_) || defined(_55l_) ++#define ArgToInt(A) ((s32)((long)(A) & 0xffff)) ++#define ArgToPtr(A) ((Ptr)(A)) ++#else ++#define ArgToInt(A) ((s32)(A)) ++#define ArgToPtr(A) ((Ptr)(A)) ++#endif ++ ++#endif /* STD_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/strm.h b/arch/arm/plat-omap/include/dspbridge/strm.h +new file mode 100644 +index 0000000..5825615 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/strm.h +@@ -0,0 +1,441 @@ ++/* ++ * strm.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== strm.h ======== ++ * Description: ++ * DSPBridge Stream Manager. ++ * ++ * Public Functions: ++ * STRM_AllocateBuffer ++ * STRM_Close ++ * STRM_Create ++ * STRM_Delete ++ * STRM_Exit ++ * STRM_FreeBuffer ++ * STRM_GetEventHandle ++ * STRM_GetInfo ++ * STRM_Idle ++ * STRM_Init ++ * STRM_Issue ++ * STRM_Open ++ * STRM_PrepareBuffer ++ * STRM_Reclaim ++ * STRM_RegisterNotify ++ * STRM_Select ++ * STRM_UnprepareBuffer ++ * ++ * Notes: ++ * ++ *! Revision History: ++ *! ================= ++ *! 15-Nov-2001 ag Changed DSP_STREAMINFO to STRM_INFO in STRM_GetInfo(). ++ *! Added DSP_ESIZE error to STRM_AllocateBuffer(). ++ *! 07-Jun-2001 sg Made DSPStream_AllocateBuffer fxn name plural. ++ *! 10-May-2001 jeh Code review cleanup. ++ *! 13-Feb-2001 kc DSP/BIOS Bridge name updates. ++ *! 06-Feb-2001 kc Updated DBC_Ensure for STRM_Select(). ++ *! 23-Oct-2000 jeh Allow NULL STRM_ATTRS passed to STRM_Open(). ++ *! 25-Sep-2000 jeh Created. ++ */ ++ ++#ifndef STRM_ ++#define STRM_ ++ ++#include ++ ++#include ++ ++/* ++ * ======== STRM_AllocateBuffer ======== ++ * Purpose: ++ * Allocate data buffer(s) for use with a stream. ++ * Parameter: ++ * hStrm: Stream handle returned from STRM_Open(). ++ * uSize: Size (GPP bytes) of the buffer(s). ++ * uNumBufs: Number of buffers to allocate. ++ * apBuffer: Array to hold buffer addresses. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hStrm. ++ * DSP_EMEMORY: Insufficient memory. ++ * DSP_EFAIL: Failure occurred, unable to allocate buffers. ++ * DSP_ESIZE: uSize must be > 0 bytes. ++ * Requires: ++ * STRM_Init(void) called. ++ * apBuffer != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS STRM_AllocateBuffer(struct STRM_OBJECT *hStrm, ++ u32 uSize, ++ OUT u8 **apBuffer, ++ u32 uNumBufs); ++ ++/* ++ * ======== STRM_Close ======== ++ * Purpose: ++ * Close a stream opened with STRM_Open(). ++ * Parameter: ++ * hStrm: Stream handle returned from STRM_Open(). ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hStrm. ++ * DSP_EPENDING: Some data buffers issued to the stream have not ++ * been reclaimed. ++ * DSP_EFAIL: Failure to close stream. ++ * Requires: ++ * STRM_Init(void) called. ++ * Ensures: ++ */ ++ extern DSP_STATUS STRM_Close(struct STRM_OBJECT *hStrm); ++ ++/* ++ * ======== STRM_Create ======== ++ * Purpose: ++ * Create a STRM manager object. This object holds information about the ++ * device needed to open streams. ++ * Parameters: ++ * phStrmMgr: Location to store handle to STRM manager object on ++ * output. ++ * hDev: Device for this processor. ++ * Returns: ++ * DSP_SOK: Success; ++ * DSP_EMEMORY: Insufficient memory for requested resources. ++ * DSP_EFAIL: General failure. ++ * Requires: ++ * STRM_Init(void) called. ++ * phStrmMgr != NULL. ++ * hDev != NULL. ++ * Ensures: ++ * DSP_SOK: Valid *phStrmMgr. ++ * error: *phStrmMgr == NULL. ++ */ ++ extern DSP_STATUS STRM_Create(OUT struct STRM_MGR **phStrmMgr, ++ struct DEV_OBJECT *hDev); ++ ++/* ++ * ======== STRM_Delete ======== ++ * Purpose: ++ * Delete the STRM Object. ++ * Parameters: ++ * hStrmMgr: Handle to STRM manager object from STRM_Create. ++ * Returns: ++ * Requires: ++ * STRM_Init(void) called. ++ * Valid hStrmMgr. ++ * Ensures: ++ * hStrmMgr is not valid. ++ */ ++ extern void STRM_Delete(struct STRM_MGR *hStrmMgr); ++ ++/* ++ * ======== STRM_Exit ======== ++ * Purpose: ++ * Discontinue usage of STRM module. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * STRM_Init(void) successfully called before. ++ * Ensures: ++ */ ++ extern void STRM_Exit(void); ++ ++/* ++ * ======== STRM_FreeBuffer ======== ++ * Purpose: ++ * Free buffer(s) allocated with STRM_AllocateBuffer. ++ * Parameter: ++ * hStrm: Stream handle returned from STRM_Open(). ++ * apBuffer: Array containing buffer addresses. ++ * uNumBufs: Number of buffers to be freed. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid stream handle. ++ * DSP_EFAIL: Failure occurred, unable to free buffers. ++ * Requires: ++ * STRM_Init(void) called. ++ * apBuffer != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS STRM_FreeBuffer(struct STRM_OBJECT *hStrm, ++ u8 **apBuffer, u32 uNumBufs); ++ ++/* ++ * ======== STRM_GetEventHandle ======== ++ * Purpose: ++ * Get stream's user event handle. This function is used when closing ++ * a stream, so the event can be closed. ++ * Parameter: ++ * hStrm: Stream handle returned from STRM_Open(). ++ * phEvent: Location to store event handle on output. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hStrm. ++ * Requires: ++ * STRM_Init(void) called. ++ * phEvent != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS STRM_GetEventHandle(struct STRM_OBJECT *hStrm, ++ OUT HANDLE *phEvent); ++ ++/* ++ * ======== STRM_GetInfo ======== ++ * Purpose: ++ * Get information about a stream. User's DSP_STREAMINFO is contained ++ * in STRM_INFO struct. STRM_INFO also contains Bridge private info. ++ * Parameters: ++ * hStrm: Stream handle returned from STRM_Open(). ++ * pStreamInfo: Location to store stream info on output. ++ * uSteamInfoSize: Size of user's DSP_STREAMINFO structure. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hStrm. ++ * DSP_ESIZE: uStreamInfoSize < sizeof(DSP_STREAMINFO). ++ * DSP_EFAIL: Unable to get stream info. ++ * Requires: ++ * STRM_Init(void) called. ++ * pStreamInfo != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS STRM_GetInfo(struct STRM_OBJECT *hStrm, ++ OUT struct STRM_INFO *pStreamInfo, ++ u32 uStreamInfoSize); ++ ++/* ++ * ======== STRM_Idle ======== ++ * Purpose: ++ * Idle a stream and optionally flush output data buffers. ++ * If this is an output stream and fFlush is TRUE, all data currently ++ * enqueued will be discarded. ++ * If this is an output stream and fFlush is FALSE, this function ++ * will block until all currently buffered data is output, or the timeout ++ * specified has been reached. ++ * After a successful call to STRM_Idle(), all buffers can immediately ++ * be reclaimed. ++ * Parameters: ++ * hStrm: Stream handle returned from STRM_Open(). ++ * fFlush: If TRUE, discard output buffers. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hStrm. ++ * DSP_ETIMEOUT: A timeout occurred before the stream could be idled. ++ * DSP_ERESTART: A critical error occurred, DSP is being restarted. ++ * DSP_EFAIL: Unable to idle stream. ++ * Requires: ++ * STRM_Init(void) called. ++ * Ensures: ++ */ ++ extern DSP_STATUS STRM_Idle(struct STRM_OBJECT *hStrm, bool fFlush); ++ ++/* ++ * ======== STRM_Init ======== ++ * Purpose: ++ * Initialize the STRM module. ++ * Parameters: ++ * Returns: ++ * TRUE if initialization succeeded, FALSE otherwise. ++ * Requires: ++ * Ensures: ++ */ ++ extern bool STRM_Init(void); ++ ++/* ++ * ======== STRM_Issue ======== ++ * Purpose: ++ * Send a buffer of data to a stream. ++ * Parameters: ++ * hStrm: Stream handle returned from STRM_Open(). ++ * pBuf: Pointer to buffer of data to be sent to the stream. ++ * ulBytes: Number of bytes of data in the buffer. ++ * ulBufSize: Actual buffer size in bytes. ++ * dwArg: A user argument that travels with the buffer. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hStrm. ++ * DSP_ESTREAMFULL: The stream is full. ++ * DSP_EFAIL: Failure occurred, unable to issue buffer. ++ * Requires: ++ * STRM_Init(void) called. ++ * pBuf != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS STRM_Issue(struct STRM_OBJECT *hStrm, IN u8 *pBuf, ++ u32 ulBytes, u32 ulBufSize, ++ IN u32 dwArg); ++ ++/* ++ * ======== STRM_Open ======== ++ * Purpose: ++ * Open a stream for sending/receiving data buffers to/from a task of ++ * DAIS socket node on the DSP. ++ * Parameters: ++ * hNode: Node handle returned from NODE_Allocate(). ++ * uDir: DSP_TONODE or DSP_FROMNODE. ++ * uIndex: Stream index. ++ * pAttr: Pointer to structure containing attributes to be ++ * applied to stream. Cannot be NULL. ++ * phStrm: Location to store stream handle on output. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hNode. ++ * DSP_EDIRECTION: Invalid uDir. ++ * DSP_EVALUE: Invalid uIndex. ++ * DSP_ENODETYPE: hNode is not a task or DAIS socket node. ++ * DSP_EFAIL: Unable to open stream. ++ * Requires: ++ * STRM_Init(void) called. ++ * phStrm != NULL. ++ * pAttr != NULL. ++ * Ensures: ++ * DSP_SOK: *phStrm is valid. ++ * error: *phStrm == NULL. ++ */ ++ extern DSP_STATUS STRM_Open(struct NODE_OBJECT *hNode, u32 uDir, ++ u32 uIndex, IN struct STRM_ATTR *pAttr, ++ OUT struct STRM_OBJECT **phStrm); ++ ++/* ++ * ======== STRM_PrepareBuffer ======== ++ * Purpose: ++ * Prepare a data buffer not allocated by DSPStream_AllocateBuffers() ++ * for use with a stream. ++ * Parameter: ++ * hStrm: Stream handle returned from STRM_Open(). ++ * uSize: Size (GPP bytes) of the buffer. ++ * pBuffer: Buffer address. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hStrm. ++ * DSP_EFAIL: Failure occurred, unable to prepare buffer. ++ * Requires: ++ * STRM_Init(void) called. ++ * pBuffer != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS STRM_PrepareBuffer(struct STRM_OBJECT *hStrm, ++ u32 uSize, ++ u8 *pBuffer); ++ ++/* ++ * ======== STRM_Reclaim ======== ++ * Purpose: ++ * Request a buffer back from a stream. ++ * Parameters: ++ * hStrm: Stream handle returned from STRM_Open(). ++ * pBufPtr: Location to store pointer to reclaimed buffer. ++ * pulBytes: Location where number of bytes of data in the ++ * buffer will be written. ++ * pulBufSize: Location where actual buffer size will be written. ++ * pdwArg: Location where user argument that travels with ++ * the buffer will be written. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hStrm. ++ * DSP_ETIMEOUT: A timeout occurred before a buffer could be ++ * retrieved. ++ * DSP_EFAIL: Failure occurred, unable to reclaim buffer. ++ * Requires: ++ * STRM_Init(void) called. ++ * pBufPtr != NULL. ++ * pulBytes != NULL. ++ * pdwArg != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS STRM_Reclaim(struct STRM_OBJECT *hStrm, ++ OUT u8 **pBufPtr, u32 *pulBytes, ++ u32 *pulBufSize, u32 *pdwArg); ++ ++/* ++ * ======== STRM_RegisterNotify ======== ++ * Purpose: ++ * Register to be notified on specific events for this stream. ++ * Parameters: ++ * hStrm: Stream handle returned by STRM_Open(). ++ * uEventMask: Mask of types of events to be notified about. ++ * uNotifyType: Type of notification to be sent. ++ * hNotification: Handle to be used for notification. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hStrm. ++ * DSP_EMEMORY: Insufficient memory on GPP. ++ * DSP_EVALUE: uEventMask is invalid. ++ * DSP_ENOTIMPL: Notification type specified by uNotifyType is not ++ * supported. ++ * Requires: ++ * STRM_Init(void) called. ++ * hNotification != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS STRM_RegisterNotify(struct STRM_OBJECT *hStrm, ++ u32 uEventMask, u32 uNotifyType, ++ struct DSP_NOTIFICATION ++ *hNotification); ++ ++/* ++ * ======== STRM_Select ======== ++ * Purpose: ++ * Select a ready stream. ++ * Parameters: ++ * aStrmTab: Array of stream handles returned from STRM_Open(). ++ * nStrms: Number of stream handles in array. ++ * pMask: Location to store mask of ready streams on output. ++ * uTimeout: Timeout value (milliseconds). ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_ERANGE: nStrms out of range. ++ ++ * DSP_EHANDLE: Invalid stream handle in array. ++ * DSP_ETIMEOUT: A timeout occurred before a stream became ready. ++ * DSP_EFAIL: Failure occurred, unable to select a stream. ++ * Requires: ++ * STRM_Init(void) called. ++ * aStrmTab != NULL. ++ * nStrms > 0. ++ * pMask != NULL. ++ * Ensures: ++ * DSP_SOK: *pMask != 0 || uTimeout == 0. ++ * Error: *pMask == 0. ++ */ ++ extern DSP_STATUS STRM_Select(IN struct STRM_OBJECT **aStrmTab, ++ u32 nStrms, ++ OUT u32 *pMask, u32 uTimeout); ++ ++/* ++ * ======== STRM_UnprepareBuffer ======== ++ * Purpose: ++ * Unprepare a data buffer that was previously prepared for a stream ++ * with DSPStream_PrepareBuffer(), and that will no longer be used with ++ * the stream. ++ * Parameter: ++ * hStrm: Stream handle returned from STRM_Open(). ++ * uSize: Size (GPP bytes) of the buffer. ++ * pBuffer: Buffer address. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hStrm. ++ * DSP_EFAIL: Failure occurred, unable to unprepare buffer. ++ * Requires: ++ * STRM_Init(void) called. ++ * pBuffer != NULL. ++ * Ensures: ++ */ ++ extern DSP_STATUS STRM_UnprepareBuffer(struct STRM_OBJECT *hStrm, ++ u32 uSize, ++ u8 *pBuffer); ++ ++#endif /* STRM_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/strmdefs.h b/arch/arm/plat-omap/include/dspbridge/strmdefs.h +new file mode 100644 +index 0000000..44d217a +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/strmdefs.h +@@ -0,0 +1,57 @@ ++/* ++ * strmdefs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== strmdefs.h ======== ++ * Purpose: ++ * Global STRM constants and types. ++ * ++ *! Revision History ++ *! ================ ++ *! 19-Nov-2001 ag Added STRM_INFO.. ++ *! 25-Sep-2000 jeh Created. ++ */ ++ ++#ifndef STRMDEFS_ ++#define STRMDEFS_ ++ ++#define STRM_MAXEVTNAMELEN 32 ++ ++ struct STRM_MGR; ++ ++ struct STRM_OBJECT; ++ ++ struct STRM_ATTR { ++ HANDLE hUserEvent; ++ char *pstrEventName; ++ void *pVirtBase; /* Process virtual base address of ++ * mapped SM */ ++ u32 ulVirtSize; /* Size of virtual space in bytes */ ++ struct DSP_STREAMATTRIN *pStreamAttrIn; ++ } ; ++ ++ struct STRM_INFO { ++ enum DSP_STRMMODE lMode; /* transport mode of ++ * stream(DMA, ZEROCOPY..) */ ++ u32 uSegment; /* Segment strm allocs from. 0 is local mem */ ++ void *pVirtBase; /* " " Stream'process virt base */ ++ struct DSP_STREAMINFO *pUser; /* User's stream information ++ * returned */ ++ } ; ++ ++#endif /* STRMDEFS_ */ ++ +diff --git a/arch/arm/plat-omap/include/dspbridge/sync.h b/arch/arm/plat-omap/include/dspbridge/sync.h +new file mode 100644 +index 0000000..fa3ff8d +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/sync.h +@@ -0,0 +1,340 @@ ++/* ++ * sync.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== sync.h ======== ++ * Purpose: ++ * Provide synchronization services. ++ * ++ * Public Functions: ++ * SYNC_CloseEvent ++ * SYNC_DeleteCS ++ * SYNC_EnterCS ++ * SYNC_Exit ++ * SYNC_Init ++ * SYNC_InitializeCS ++ * SYNC_LeaveCS ++ * SYNC_OpenEvent ++ * SYNC_PostMessage ++ * SYNC_ResetEvent ++ * SYNC_SetEvent ++ * SYNC_WaitOnEvent ++ * SYNC_WaitOnMultipleEvents ++ * ++ *! Revision History: ++ *! ================ ++ *! 05-Oct-2000 jeh Added SYNC_WaitOnMultipleEvents(). ++ *! 01-Dec-1999 ag: Added #define SYNC_MAXNAMELENGTH. ++ *! 04-Nov-1999 kc: Added critical section functions and objects to SYNC. ++ *! 29-Oct-1999 kc: Cleaned up for code review. ++ *! 24-Sep-1999 kc: Added WinCE notes. ++ *! 20-Oct-1997 gp: Removed unused SYNC_ critical section and must complete fxns ++ *! Added SYNC_HOBJECT, SYNC_ATTRS, and object validation, and ++ *! merged SYNC_DestroyEvent into SYNC_CloseEvent, and merged ++ *! SYNC_CreateEvent into SYNC_OpenEvent. ++ *! 07-Oct-1997 gp: Added SYNC_Create/DestroyEvent (for NT testing). ++ *! 06-Oct-1997 gp: Added SYNC_OpenEvent. ++ *! 03-Jun-1997 gp: Added SYNC_{Begin|End}CritSection() functions. ++ *! 03-Jan-1997 gp: Added SYNC_INFINITE define. ++ *! 05-Aug-1996 gp: Created. ++ */ ++ ++#ifndef _SYNC_H ++#define _SYNC_H ++ ++#define SIGNATURECS 0x53435953 /* "SYCS" (in reverse) */ ++#define SIGNATUREDPCCS 0x53445953 /* "SYDS" (in reverse) */ ++ ++/* Special timeout value indicating an infinite wait: */ ++#define SYNC_INFINITE 0xffffffff ++ ++/* Maximum string length of a named event */ ++#define SYNC_MAXNAMELENGTH 32 ++ ++/* Generic SYNC object: */ ++ struct SYNC_OBJECT; ++ ++/* Generic SYNC CS object: */ ++struct SYNC_CSOBJECT { ++ u32 dwSignature; /* used for object validation */ ++ struct semaphore sem; ++} ; ++ ++/* SYNC object attributes: */ ++ struct SYNC_ATTRS { ++ HANDLE hUserEvent; /* Platform's User Mode synch. object. */ ++ HANDLE hKernelEvent; /* Platform's Kernel Mode sync. object. */ ++ u32 dwReserved1; /* For future expansion. */ ++ u32 dwReserved2; /* For future expansion. */ ++ } ; ++ ++/* ++ * ======== SYNC_CloseEvent ======== ++ * Purpose: ++ * Close this event handle, freeing resources allocated in SYNC_OpenEvent ++ * if necessary. ++ * Parameters: ++ * hEvent: Handle to a synchronization event, created/opened in ++ * SYNC_OpenEvent. ++ * Returns: ++ * DSP_SOK: Success; ++ * DSP_EFAIL: Failed to close event handle. ++ * DSP_EHANDLE: Invalid handle. ++ * Requires: ++ * SYNC initialized. ++ * Ensures: ++ * Any subsequent usage of hEvent would be invalid. ++ */ ++ extern DSP_STATUS SYNC_CloseEvent(IN struct SYNC_OBJECT *hEvent); ++ ++/* ++ * ======== SYNC_DeleteCS ======== ++ * Purpose: ++ * Delete a critical section. ++ * Parameters: ++ * hCSObj: critical section handle. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid handle. ++ * Requires: ++ * Ensures: ++ */ ++ extern DSP_STATUS SYNC_DeleteCS(IN struct SYNC_CSOBJECT *hCSObj); ++ ++/* ++ * ======== SYNC_EnterCS ======== ++ * Purpose: ++ * Enter the critical section. ++ * Parameters: ++ * hCSObj: critical section handle. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid handle. ++ * Requires: ++ * Ensures: ++ */ ++ extern DSP_STATUS SYNC_EnterCS(IN struct SYNC_CSOBJECT *hCSObj); ++ ++/* ++ * ======== SYNC_Exit ======== ++ * Purpose: ++ * Discontinue usage of module; free resources when reference count ++ * reaches 0. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * SYNC initialized. ++ * Ensures: ++ * Resources used by module are freed when cRef reaches zero. ++ */ ++ extern void SYNC_Exit(void); ++ ++/* ++ * ======== SYNC_Init ======== ++ * Purpose: ++ * Initializes private state of SYNC module. ++ * Parameters: ++ * Returns: ++ * TRUE if initialized; FALSE if error occured. ++ * Requires: ++ * Ensures: ++ * SYNC initialized. ++ */ ++ extern bool SYNC_Init(void); ++ ++/* ++ * ======== SYNC_InitializeCS ======== ++ * Purpose: ++ * Initialize the critical section. ++ * Parameters: ++ * hCSObj: critical section handle. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Out of memory. ++ * Requires: ++ * Ensures: ++ */ ++ extern DSP_STATUS SYNC_InitializeCS(OUT struct SYNC_CSOBJECT **phCSObj); ++ ++/* ++ * ======== SYNC_InitializeDPCCS ======== ++ * Purpose: ++ * Initialize the critical section between process context and DPC. ++ * Parameters: ++ * hCSObj: critical section handle. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Out of memory. ++ * Requires: ++ * Ensures: ++ */ ++ extern DSP_STATUS SYNC_InitializeDPCCS(OUT struct SYNC_CSOBJECT ++ **phCSObj); ++ ++/* ++ * ======== SYNC_LeaveCS ======== ++ * Purpose: ++ * Leave the critical section. ++ * Parameters: ++ * hCSObj: critical section handle. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid handle. ++ * Requires: ++ * Ensures: ++ */ ++ extern DSP_STATUS SYNC_LeaveCS(IN struct SYNC_CSOBJECT *hCSObj); ++ ++/* ++ * ======== SYNC_OpenEvent ======== ++ * Purpose: ++ * Create/open and initialize an event object for thread synchronization, ++ * which is initially in the non-signalled state. ++ * Parameters: ++ * phEvent: Pointer to location to receive the event object handle. ++ * pAttrs: Pointer to SYNC_ATTRS object containing initial SYNC ++ * SYNC_OBJECT attributes. If this pointer is NULL, then ++ * SYNC_OpenEvent will create and manage an OS specific ++ * syncronization object. ++ * pAttrs->hUserEvent: Platform's User Mode synchronization object. ++ * ++ * The behaviour of the SYNC methods depend on the value of ++ * the hUserEvent attr: ++ * ++ * 1. (hUserEvent == NULL): ++ * A user mode event is created. ++ * 2. (hUserEvent != NULL): ++ * A user mode event is supplied by the caller of SYNC_OpenEvent(). ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Unable to create user mode event. ++ * DSP_EMEMORY: Insufficient memory. ++ * DSP_EINVALIDARG SYNC_ATTRS values are invalid. ++ * Requires: ++ * - SYNC initialized. ++ * - phEvent != NULL. ++ * Ensures: ++ * If function succeeded, pEvent->hEvent must be a valid event handle. ++ */ ++ extern DSP_STATUS SYNC_OpenEvent(OUT struct SYNC_OBJECT **phEvent, ++ IN OPTIONAL struct SYNC_ATTRS ++ *pAttrs); ++ ++/* ++ * ========= SYNC_PostMessage ======== ++ * Purpose: ++ * To post a windows message ++ * Parameters: ++ * hWindow: Handle to the window ++ * uMsg: Message to be posted ++ * Returns: ++ * DSP_SOK: Success ++ * DSP_EFAIL: Post message failed ++ * DSP_EHANDLE: Invalid Window handle ++ * Requires: ++ * SYNC initialized ++ * Ensures ++ */ ++ extern DSP_STATUS SYNC_PostMessage(IN HANDLE hWindow, IN u32 uMsg); ++ ++/* ++ * ======== SYNC_ResetEvent ======== ++ * Purpose: ++ * Reset a syncronization event object state to non-signalled. ++ * Parameters: ++ * hEvent: Handle to a sync event. ++ * Returns: ++ * DSP_SOK: Success; ++ * DSP_EFAIL: Failed to reset event. ++ * DSP_EHANDLE: Invalid handle. ++ * Requires: ++ * SYNC initialized. ++ * Ensures: ++ */ ++ extern DSP_STATUS SYNC_ResetEvent(IN struct SYNC_OBJECT *hEvent); ++ ++/* ++ * ======== SYNC_SetEvent ======== ++ * Purpose: ++ * Signal the event. Will unblock one waiting thread. ++ * Parameters: ++ * hEvent: Handle to an event object. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Failed to signal event. ++ * DSP_EHANDLE: Invalid handle. ++ * Requires: ++ * SYNC initialized. ++ * Ensures: ++ */ ++ extern DSP_STATUS SYNC_SetEvent(IN struct SYNC_OBJECT *hEvent); ++ ++/* ++ * ======== SYNC_WaitOnEvent ======== ++ * Purpose: ++ * Wait for an event to be signalled, up to the specified timeout. ++ * Parameters: ++ * hEvent: Handle to an event object. ++ * dwTimeOut: The time-out interval, in milliseconds. ++ * The function returns if the interval elapses, even if ++ * the object's state is nonsignaled. ++ * If zero, the function tests the object's state and ++ * returns immediately. ++ * If SYNC_INFINITE, the function's time-out interval ++ * never elapses. ++ * Returns: ++ * DSP_SOK: The object was signalled. ++ * DSP_EHANDLE: Invalid handle. ++ * SYNC_E_FAIL: Wait failed, possibly because the process terminated. ++ * SYNC_E_TIMEOUT: Timeout expired while waiting for event to be signalled. ++ * Requires: ++ * Ensures: ++ */ ++ extern DSP_STATUS SYNC_WaitOnEvent(IN struct SYNC_OBJECT *hEvent, ++ IN u32 dwTimeOut); ++ ++/* ++ * ======== SYNC_WaitOnMultipleEvents ======== ++ * Purpose: ++ * Wait for any of an array of events to be signalled, up to the ++ * specified timeout. ++ * Note: dwTimeOut must be SYNC_INFINITE to signal infinite wait. ++ * Parameters: ++ * hSyncEvents: Array of handles to event objects. ++ * uCount: Number of event handles. ++ * dwTimeOut: The time-out interval, in milliseconds. ++ * The function returns if the interval elapses, even if ++ * no event is signalled. ++ * If zero, the function tests the object's state and ++ * returns immediately. ++ * If SYNC_INFINITE, the function's time-out interval ++ * never elapses. ++ * puIndex: Location to store index of event that was signalled. ++ * Returns: ++ * DSP_SOK: The object was signalled. ++ * SYNC_E_FAIL: Wait failed, possibly because the process terminated. ++ * SYNC_E_TIMEOUT: Timeout expired before event was signalled. ++ * DSP_EMEMORY: Memory allocation failed. ++ * Requires: ++ * Ensures: ++ */ ++ extern DSP_STATUS SYNC_WaitOnMultipleEvents(IN struct SYNC_OBJECT ++ **hSyncEvents, ++ IN u32 uCount, ++ IN u32 dwTimeout, ++ OUT u32 *puIndex); ++ ++#endif /* _SYNC_H */ +diff --git a/arch/arm/plat-omap/include/dspbridge/util.h b/arch/arm/plat-omap/include/dspbridge/util.h +new file mode 100644 +index 0000000..e6815ca +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/util.h +@@ -0,0 +1,122 @@ ++/* ++ * util.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== util.h ======== ++ * Purpose: ++ * Provide general purpose utility functions. ++ * ++ * Public Functions: ++ * UTIL_CDTestDll ++ * UTIL_CmdLineToArgs ++ * UTIL_Exit ++ * UTIL_GetSysInfo ++ * UTIL_Init ++ */ ++ ++#ifndef _UTIL_H ++#define _UTIL_H ++ ++#include ++#include ++ ++#include ++ ++/* ++ * ======== UTIL_CDTestDll ======== ++ * Purpose: ++ * Provides test entry point in class driver context. ++ * Parameters: ++ * cArgc: test module command line input count. ++ * ppArgv: test module command line args. ++ * Returns: ++ * 0 if successful, a negative value otherwise. ++ * Requires: ++ * UTIL initialized. ++ * Ensures: ++ */ ++ extern u32 UTIL_CDTestDll(IN s32 cArgc, IN char **ppArgv); ++ ++/* ++ * ======== UTIL_CmdLineToArgs ======== ++ * Purpose: ++ * This function re-creates C-style cmd line argc & argv from WinMain() ++ * cmd line args. ++ * Parameters: ++ * s8 *pszProgName - The name of the program currently being executed. ++ * s8 *argv[] - The argument vector. ++ * s8 *pCmdLine - The pointer to the command line. ++ * bool fHasProgName - Indicats whether a program name is supplied. ++ * Returns: ++ * Returns the number of arguments found. ++ * Requires: ++ * UTIL initialized. ++ * Ensures: ++ */ ++ extern s32 UTIL_CmdLineToArgs(IN char *pszProgName, ++ IN char *argv[UTIL_MAXARGVS], ++ IN char *pCmdLine, IN bool fHasProgName); ++ ++/* ++ * ======== UTIL_Exit ======== ++ * Purpose: ++ * Discontinue usage of module; free resources when reference count ++ * reaches 0. ++ * Parameters: ++ * Returns: ++ * Requires: ++ * UTIL initialized. ++ * Ensures: ++ * Resources used by module are freed when cRef reaches zero. ++ */ ++ extern inline void UTIL_Exit(void) ++ { ++ } ++/* ++ * ======== UTIL_GetSysInfo ======== ++ * Purpose: ++ * This function return platform specific system information. ++ * ++ * Parameters: ++ * pSysInfo - address to store the system information. ++ * Returns: ++ * DSP_SOK ++ * S_FAIL ++ * Requires: ++ * UTIL initialized. ++ * pSysInfo != NULL ++ * Ensures: ++ */ ++ extern DSP_STATUS UTIL_GetSysInfo(OUT struct UTIL_SYSINFO *pSysInfo); ++ ++/* ++ * ======== UTIL_Init ======== ++ * Purpose: ++ * Initializes private state of UTIL module. ++ * Parameters: ++ * Returns: ++ * TRUE if success, else FALSE. ++ * Requires: ++ * Ensures: ++ * UTIL initialized. ++ */ ++ extern inline bool UTIL_Init(void) ++ { ++ return true; ++ } ++ ++#endif /* _UTIL_H */ +diff --git a/arch/arm/plat-omap/include/dspbridge/utildefs.h b/arch/arm/plat-omap/include/dspbridge/utildefs.h +new file mode 100644 +index 0000000..bd53a5a +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/utildefs.h +@@ -0,0 +1,51 @@ ++/* ++ * utildefs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== utildefs.h ======== ++ * Purpose: ++ * Global UTIL constants and types, shared between WCD and DSPSYS. ++ * ++ *! Revision History: ++ *! ================ ++ *! 24-Feb-2003 kc Removed wIOPort* entries from UTIL_HOSTCONFIG. ++ *! 12-Aug-2000 ag Added UTIL_SYSINFO typedef. ++ *! 08-Oct-1999 rr Adopted for WinCE where test fxns will be added in util.h ++ *! 26-Dec-1996 cr Created. ++ */ ++ ++#ifndef UTILDEFS_ ++#define UTILDEFS_ ++ ++/* constants taken from configmg.h */ ++#define UTIL_MAXMEMREGS 9 ++#define UTIL_MAXIOPORTS 20 ++#define UTIL_MAXIRQS 7 ++#define UTIL_MAXDMACHNLS 7 ++ ++/* misc. constants */ ++#define UTIL_MAXARGVS 10 ++ ++/* Platform specific important info */ ++ struct UTIL_SYSINFO { ++ /* Granularity of page protection; usually 1k or 4k */ ++ u32 dwPageSize; ++ u32 dwAllocationGranularity; /* VM granularity, usually 64K */ ++ u32 dwNumberOfProcessors; /* Used as sanity check */ ++ } ; ++ ++#endif /* UTILDEFS_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/uuidutil.h b/arch/arm/plat-omap/include/dspbridge/uuidutil.h +new file mode 100644 +index 0000000..af4aaec +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/uuidutil.h +@@ -0,0 +1,74 @@ ++/* ++ * uuidutil.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== uuidutil.h ======== ++ * Description: ++ * This file contains the specification of UUID helper functions. ++ * ++ *! Revision History ++ *! ================ ++ *! 09-Nov-2000 kc: Modified description of UUID utility functions. ++ *! 29-Sep-2000 kc: Appended "UUID_" prefix to UUID helper functions. ++ *! 10-Aug-2000 kc: Created. ++ *! ++ */ ++ ++#ifndef UUIDUTIL_ ++#define UUIDUTIL_ ++ ++#define MAXUUIDLEN 37 ++ ++/* ++ * ======== UUID_UuidToString ======== ++ * Purpose: ++ * Converts a DSP_UUID to an ANSI string. ++ * Parameters: ++ * pUuid: Pointer to a DSP_UUID object. ++ * pszUuid: Pointer to a buffer to receive a NULL-terminated UUID ++ * string. ++ * size: Maximum size of the pszUuid string. ++ * Returns: ++ * Requires: ++ * pUuid & pszUuid are non-NULL values. ++ * Ensures: ++ * Lenghth of pszUuid is less than MAXUUIDLEN. ++ * Details: ++ * UUID string limit currently set at MAXUUIDLEN. ++ */ ++ void UUID_UuidToString(IN struct DSP_UUID *pUuid, OUT char *pszUuid, ++ s32 size); ++ ++/* ++ * ======== UUID_UuidFromString ======== ++ * Purpose: ++ * Converts an ANSI string to a DSP_UUID. ++ * Parameters: ++ * pszUuid: Pointer to a string that represents a DSP_UUID object. ++ * pUuid: Pointer to a DSP_UUID object. ++ * Returns: ++ * Requires: ++ * pUuid & pszUuid are non-NULL values. ++ * Ensures: ++ * Details: ++ * We assume the string representation of a UUID has the following format: ++ * "12345678_1234_1234_1234_123456789abc". ++ */ ++ extern void UUID_UuidFromString(IN char *pszUuid, ++ OUT struct DSP_UUID *pUuid); ++ ++#endif /* UUIDUTIL_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/wcd.h b/arch/arm/plat-omap/include/dspbridge/wcd.h +new file mode 100644 +index 0000000..5a7d47a +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/wcd.h +@@ -0,0 +1,61 @@ ++/* ++ * wcd.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== wcd.h ======== ++ * Description: ++ * 'Bridge class driver library functions, object definitions, and ++ * return error/status codes. To be included by 'Bridge mini drivers. ++ * ++ * Public Functions: ++ * See mem.h and dbg.h. ++ * ++ * Notes: ++ * 'Bridge Class Driver services exported to WMD's are initialized by the ++ * WCD on behalf of the WMD. WMD's must not call module Init/Exit ++ * functions. ++ * ++ * To ensure WMD binary compatibility across different platforms, ++ * for the same processor, a WMD must restrict its usage of system ++ * services to those exported by the 'Bridge class library. ++ * ++ *! Revision History: ++ *! ================ ++ *! 07-Jun-2000 jeh Added dev.h ++ *! 01-Nov-1999 ag: #WINCE# WCD_MAJOR_VERSION=8 & WCD_MINOR_VERSION=0 to match ++ *! dll stamps. ++ *! 0.80 - 0.89 Alpha, 0.90 - 0.99 Beta, 1.00 - 1.10 FCS. ++ *! 17-Sep-1997 gp: Changed size of CFG_HOSTRES structure; and ISR_Install API; ++ *! Changed WCD_MINOR_VERSION 3 -> 4. ++ *! 15-Sep-1997 gp: Moved WCD_(Un)registerMinidriver to drv. ++ *! 25-Jul-1997 cr: Added WCD_UnregisterMinidriver. ++ *! 22-Jul-1997 cr: Added WCD_RegisterMinidriver, WCD_MINOR_VERSION 2 -> 3. ++ *! 12-Nov-1996 gp: Defined port io macros. ++ *! 07-Nov-1996 gp: Updated for code review. ++ *! 16-Jul-1996 gp: Added CHNL fxns; updated WCD lib version to 2. ++ *! 10-May-1996 gp: Separated WMD def.s' into wmd.h. ++ *! 03-May-1996 gp: Created. ++ */ ++ ++#ifndef WCD_ ++#define WCD_ ++ ++/* This WCD Library Version: */ ++#define WCD_MAJOR_VERSION (u32)8 /* .8x - Alpha, .9x - Beta, 1.x FCS */ ++#define WCD_MINOR_VERSION (u32)0 ++ ++#endif /* WCD_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/wcdioctl.h b/arch/arm/plat-omap/include/dspbridge/wcdioctl.h +new file mode 100644 +index 0000000..04b13ab +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/wcdioctl.h +@@ -0,0 +1,519 @@ ++/* ++ * wcdioctl.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== wcdioctl.h ======== ++ * Purpose: ++ * Contains structures and commands that are used for interaction ++ * between the DDSP API and class driver. ++ * ++ *! Revision History ++ *! ================ ++ *! 19-Apr-2004 sb Aligned DMM definitions with Symbian ++ *! 08-Mar-2004 sb Added the Dynamic Memory Mapping structs & offsets ++ *! 15-Oct-2002 kc Updated definitions for private PERF module. ++ *! 16-Aug-2002 map Added ARGS_MGR_REGISTEROBJECT & ARGS_MGR_UNREGISTEROBJECT ++ *! Added CMD_MGR_REGISTEROBJECT_OFFSET & ++ *! CMD_MGR_UNREGISTEROBJECT_OFFSET ++ *! 15-Jan-2002 ag Added actaul bufSize to ARGS_STRM_[RECLAIM][ISSUE]. ++ *! 15-Nov-2001 ag change to STRMINFO in ARGS_STRM_GETINFO. ++ *! 11-Sep-2001 ag ARGS_CMM_GETHANDLE defn uses DSP_HPROCESSOR. ++ *! 23-Apr-2001 jeh Added pStatus to NODE_TERMINATE args. ++ *! 13-Feb-2001 kc DSP/BIOS Bridge name updates. ++ *! 22-Nov-2000 kc: Added CMD_MGR_GETPERF_DATA_OFFSET for acquiring PERF stats. ++ *! 27-Oct-2000 jeh Added timeouts to NODE_GETMESSAGE, NODE_PUTMESSAGE args. ++ *! Removed NODE_GETMESSAGESTRM args. ++ *! 11-Oct-2000 ag: Added SM mgr(CMM) args. ++ *! 27-Sep-2000 jeh Removed struct DSP_BUFFERATTR param from ++ *! ARGS_STRM_ALLOCATEBUFFER. ++ *! 25-Sep-2000 rr: Updated to Version 0.9 ++ *! 07-Sep-2000 jeh Changed HANDLE to DSP_HNOTIFICATION in RegisterNotify args. ++ *! Added DSP_STRMATTR to DSPNode_Connect args. ++ *! 04-Aug-2000 rr: MEM and UTIL added to RM. ++ *! 27-Jul-2000 rr: NODE, MGR,STRM and PROC added ++ *! 27-Jun-2000 rr: Modifed to Use either PM or DSP/BIOS Bridge ++ *! IFDEF to build for PM or DSP/BIOS Bridge ++ *! 28-Jan-2000 rr: NT_CMD_FROM_OFFSET moved out to dsptrap.h ++ *! 24-Jan-2000 rr: Merged with Scott's code. ++ *! 21-Jan-2000 sg: In ARGS_CHNL_GETMODE changed mode to be u32 to be ++ *! consistent with chnldefs.h. ++ *! 11-Jan-2000 rr: CMD_CFG_GETCDVERSION_OFFSET added. ++ *! 12-Nov-1999 rr: CMD_BRD_MONITOR_OFFSET added ++ *! 09-Nov-1999 kc: Added MEMRY and enabled CMD_BRD_IOCTL_OFFSET. ++ *! 05-Nov-1999 ag: Added CHNL. ++ *! 02-Nov-1999 kc: Removed field from ARGS_UTIL_TESTDLL. ++ *! 29-Oct-1999 kc: Cleaned up for code review. ++ *! 08-Oct-1999 rr: Util control offsets added. ++ *! 13-Sep-1999 kc: Added ARGS_UTIL_TESTDLL for PM test infrastructure. ++ *! 19-Aug-1999 rr: Created from WSX. Minimal Implementaion of BRD_Start and BRD ++ *! and BRD_Stop. IOCTL Offsets and CTRL Code. ++ */ ++ ++#ifndef WCDIOCTL_ ++#define WCDIOCTL_ ++ ++#include ++#include ++#include ++#include ++ ++union Trapped_Args { ++ ++ /* MGR Module */ ++ struct { ++ u32 uNode; ++ struct DSP_NDBPROPS __user *pNDBProps; ++ u32 uNDBPropsSize; ++ u32 __user *puNumNodes; ++ } ARGS_MGR_ENUMNODE_INFO; ++ ++ struct { ++ u32 uProcessor; ++ struct DSP_PROCESSORINFO __user *pProcessorInfo; ++ u32 uProcessorInfoSize; ++ u32 __user *puNumProcs; ++ } ARGS_MGR_ENUMPROC_INFO; ++ ++ struct { ++ struct DSP_UUID *pUuid; ++ enum DSP_DCDOBJTYPE objType; ++ char *pszPathName; ++ } ARGS_MGR_REGISTEROBJECT; ++ ++ struct { ++ struct DSP_UUID *pUuid; ++ enum DSP_DCDOBJTYPE objType; ++ } ARGS_MGR_UNREGISTEROBJECT; ++ ++ struct { ++ struct DSP_NOTIFICATION __user*__user *aNotifications; ++ u32 uCount; ++ u32 __user *puIndex; ++ u32 uTimeout; ++ } ARGS_MGR_WAIT; ++ ++ /* PROC Module */ ++ struct { ++ u32 uProcessor; ++ struct DSP_PROCESSORATTRIN __user *pAttrIn; ++ DSP_HPROCESSOR __user *phProcessor; ++ } ARGS_PROC_ATTACH; ++ ++ struct { ++ DSP_HPROCESSOR hProcessor; ++ u32 dwCmd; ++ struct DSP_CBDATA __user *pArgs; ++ } ARGS_PROC_CTRL; ++ ++ struct { ++ DSP_HPROCESSOR hProcessor; ++ } ARGS_PROC_DETACH; ++ ++ struct { ++ DSP_HPROCESSOR hProcessor; ++ DSP_HNODE __user *aNodeTab; ++ u32 uNodeTabSize; ++ u32 __user *puNumNodes; ++ u32 __user *puAllocated; ++ } ARGS_PROC_ENUMNODE_INFO; ++ ++ struct { ++ DSP_HPROCESSOR hProcessor; ++ u32 uResourceType; ++ struct DSP_RESOURCEINFO *pResourceInfo; ++ u32 uResourceInfoSize; ++ } ARGS_PROC_ENUMRESOURCES; ++ ++ struct { ++ DSP_HPROCESSOR hProcessor; ++ struct DSP_PROCESSORSTATE __user *pProcStatus; ++ u32 uStateInfoSize; ++ } ARGS_PROC_GETSTATE; ++ ++ struct { ++ DSP_HPROCESSOR hProcessor; ++ u8 __user *pBuf; ++ ++ #ifndef RES_CLEANUP_DISABLE ++ u8 __user *pSize; ++ #endif ++ u32 uMaxSize; ++ } ARGS_PROC_GETTRACE; ++ ++ struct { ++ DSP_HPROCESSOR hProcessor; ++ s32 iArgc; ++ char __user*__user *aArgv; ++ char *__user *aEnvp; ++ } ARGS_PROC_LOAD; ++ ++ struct { ++ DSP_HPROCESSOR hProcessor; ++ u32 uEventMask; ++ u32 uNotifyType; ++ struct DSP_NOTIFICATION __user *hNotification; ++ } ARGS_PROC_REGISTER_NOTIFY; ++ ++ struct { ++ DSP_HPROCESSOR hProcessor; ++ } ARGS_PROC_START; ++ ++ struct { ++ DSP_HPROCESSOR hProcessor; ++ u32 ulSize; ++ void *__user *ppRsvAddr; ++ } ARGS_PROC_RSVMEM; ++ ++ struct { ++ DSP_HPROCESSOR hProcessor; ++ u32 ulSize; ++ void *pRsvAddr; ++ } ARGS_PROC_UNRSVMEM; ++ ++ struct { ++ DSP_HPROCESSOR hProcessor; ++ void *pMpuAddr; ++ u32 ulSize; ++ void *pReqAddr; ++ void *__user *ppMapAddr; ++ u32 ulMapAttr; ++ } ARGS_PROC_MAPMEM; ++ ++ struct { ++ DSP_HPROCESSOR hProcessor; ++ u32 ulSize; ++ void *pMapAddr; ++ } ARGS_PROC_UNMAPMEM; ++ ++ struct { ++ DSP_HPROCESSOR hProcessor; ++ void *pMpuAddr; ++ u32 ulSize; ++ u32 ulFlags; ++ } ARGS_PROC_FLUSHMEMORY; ++ ++ struct { ++ DSP_HPROCESSOR hProcessor; ++ } ARGS_PROC_STOP; ++ ++ struct { ++ DSP_HPROCESSOR hProcessor; ++ void *pMpuAddr; ++ u32 ulSize; ++ } ARGS_PROC_INVALIDATEMEMORY; ++ ++ ++ /* NODE Module */ ++ struct { ++ DSP_HPROCESSOR hProcessor; ++ struct DSP_UUID __user *pNodeID; ++ struct DSP_CBDATA __user *pArgs; ++ struct DSP_NODEATTRIN __user *pAttrIn; ++ DSP_HNODE __user *phNode; ++ } ARGS_NODE_ALLOCATE; ++ ++ struct { ++ DSP_HNODE hNode; ++ u32 uSize; ++ struct DSP_BUFFERATTR __user *pAttr; ++ u8 *__user *pBuffer; ++ } ARGS_NODE_ALLOCMSGBUF; ++ ++ struct { ++ DSP_HNODE hNode; ++ s32 iPriority; ++ } ARGS_NODE_CHANGEPRIORITY; ++ ++ struct { ++ DSP_HNODE hNode; ++ u32 uStream; ++ DSP_HNODE hOtherNode; ++ u32 uOtherStream; ++ struct DSP_STRMATTR __user *pAttrs; ++ struct DSP_CBDATA __user *pConnParam; ++ } ARGS_NODE_CONNECT; ++ ++ struct { ++ DSP_HNODE hNode; ++ } ARGS_NODE_CREATE; ++ ++ struct { ++ DSP_HNODE hNode; ++ } ARGS_NODE_DELETE; ++ ++ struct { ++ DSP_HNODE hNode; ++ struct DSP_BUFFERATTR __user *pAttr; ++ u8 *pBuffer; ++ } ARGS_NODE_FREEMSGBUF; ++ ++ struct { ++ DSP_HNODE hNode; ++ struct DSP_NODEATTR __user *pAttr; ++ u32 uAttrSize; ++ } ARGS_NODE_GETATTR; ++ ++ struct { ++ DSP_HNODE hNode; ++ struct DSP_MSG __user *pMessage; ++ u32 uTimeout; ++ } ARGS_NODE_GETMESSAGE; ++ ++ struct { ++ DSP_HNODE hNode; ++ } ARGS_NODE_PAUSE; ++ ++ struct { ++ DSP_HNODE hNode; ++ struct DSP_MSG __user *pMessage; ++ u32 uTimeout; ++ } ARGS_NODE_PUTMESSAGE; ++ ++ struct { ++ DSP_HNODE hNode; ++ u32 uEventMask; ++ u32 uNotifyType; ++ struct DSP_NOTIFICATION __user *hNotification; ++ } ARGS_NODE_REGISTERNOTIFY; ++ ++ struct { ++ DSP_HNODE hNode; ++ } ARGS_NODE_RUN; ++ ++ struct { ++ DSP_HNODE hNode; ++ DSP_STATUS __user *pStatus; ++ } ARGS_NODE_TERMINATE; ++ ++ struct { ++ DSP_HPROCESSOR hProcessor; ++ struct DSP_UUID __user *pNodeID; ++ struct DSP_NDBPROPS __user *pNodeProps; ++ } ARGS_NODE_GETUUIDPROPS; ++ ++ /* STRM module */ ++ ++ struct { ++ DSP_HSTREAM hStream; ++ u32 uSize; ++ u8 *__user *apBuffer; ++ u32 uNumBufs; ++ } ARGS_STRM_ALLOCATEBUFFER; ++ ++ struct { ++ DSP_HSTREAM hStream; ++ } ARGS_STRM_CLOSE; ++ ++ struct { ++ DSP_HSTREAM hStream; ++ u8 *__user *apBuffer; ++ u32 uNumBufs; ++ } ARGS_STRM_FREEBUFFER; ++ ++ struct { ++ DSP_HSTREAM hStream; ++ HANDLE *phEvent; ++ } ARGS_STRM_GETEVENTHANDLE; ++ ++ struct { ++ DSP_HSTREAM hStream; ++ struct STRM_INFO __user *pStreamInfo; ++ u32 uStreamInfoSize; ++ } ARGS_STRM_GETINFO; ++ ++ struct { ++ DSP_HSTREAM hStream; ++ bool bFlush; ++ } ARGS_STRM_IDLE; ++ ++ struct { ++ DSP_HSTREAM hStream; ++ u8 *pBuffer; ++ u32 dwBytes; ++ u32 dwBufSize; ++ u32 dwArg; ++ } ARGS_STRM_ISSUE; ++ ++ struct { ++ DSP_HNODE hNode; ++ u32 uDirection; ++ u32 uIndex; ++ struct STRM_ATTR __user *pAttrIn; ++ DSP_HSTREAM __user *phStream; ++ } ARGS_STRM_OPEN; ++ ++ struct { ++ DSP_HSTREAM hStream; ++ u8 *__user *pBufPtr; ++ u32 __user *pBytes; ++ u32 __user *pBufSize; ++ u32 __user *pdwArg; ++ } ARGS_STRM_RECLAIM; ++ ++ struct { ++ DSP_HSTREAM hStream; ++ u32 uEventMask; ++ u32 uNotifyType; ++ struct DSP_NOTIFICATION __user *hNotification; ++ } ARGS_STRM_REGISTERNOTIFY; ++ ++ struct { ++ DSP_HSTREAM __user *aStreamTab; ++ u32 nStreams; ++ u32 __user *pMask; ++ u32 uTimeout; ++ } ARGS_STRM_SELECT; ++ ++ /* CMM Module */ ++ struct { ++ struct CMM_OBJECT *hCmmMgr; ++ u32 uSize; ++ struct CMM_ATTRS *pAttrs; ++ OUT void **ppBufVA; ++ } ARGS_CMM_ALLOCBUF; ++ ++ struct { ++ struct CMM_OBJECT *hCmmMgr; ++ void *pBufPA; ++ u32 ulSegId; ++ } ARGS_CMM_FREEBUF; ++ ++ struct { ++ DSP_HPROCESSOR hProcessor; ++ struct CMM_OBJECT *__user *phCmmMgr; ++ } ARGS_CMM_GETHANDLE; ++ ++ struct { ++ struct CMM_OBJECT *hCmmMgr; ++ struct CMM_INFO __user *pCmmInfo; ++ } ARGS_CMM_GETINFO; ++ ++ /* MEM Module */ ++ struct { ++ u32 cBytes; ++ enum MEM_POOLATTRS type; ++ void *pMem; ++ } ARGS_MEM_ALLOC; ++ ++ struct { ++ u32 cBytes; ++ enum MEM_POOLATTRS type; ++ void *pMem; ++ } ARGS_MEM_CALLOC; ++ ++ struct { ++ void *pMem; ++ } ARGS_MEM_FREE; ++ ++ struct { ++ void *pBuffer; ++ u32 cSize; ++ void *pLockedBuffer; ++ } ARGS_MEM_PAGELOCK; ++ ++ struct { ++ void *pBuffer; ++ u32 cSize; ++ } ARGS_MEM_PAGEUNLOCK; ++ ++ /* UTIL module */ ++ struct { ++ s32 cArgc; ++ char **ppArgv; ++ } ARGS_UTIL_TESTDLL; ++} ; ++ ++#define CMD_BASE 1 ++ ++/* MGR module offsets */ ++#define CMD_MGR_BASE_OFFSET CMD_BASE ++#define CMD_MGR_ENUMNODE_INFO_OFFSET (CMD_MGR_BASE_OFFSET + 0) ++#define CMD_MGR_ENUMPROC_INFO_OFFSET (CMD_MGR_BASE_OFFSET + 1) ++#define CMD_MGR_REGISTEROBJECT_OFFSET (CMD_MGR_BASE_OFFSET + 2) ++#define CMD_MGR_UNREGISTEROBJECT_OFFSET (CMD_MGR_BASE_OFFSET + 3) ++#define CMD_MGR_WAIT_OFFSET (CMD_MGR_BASE_OFFSET + 4) ++ ++#ifndef RES_CLEANUP_DISABLE ++#define CMD_MGR_RESOUCES_OFFSET (CMD_MGR_BASE_OFFSET + 5) ++#define CMD_MGR_END_OFFSET CMD_MGR_RESOUCES_OFFSET ++#else ++#define CMD_MGR_END_OFFSET CMD_MGR_WAIT_OFFSET ++#endif ++ ++#define CMD_PROC_BASE_OFFSET (CMD_MGR_END_OFFSET + 1) ++#define CMD_PROC_ATTACH_OFFSET (CMD_PROC_BASE_OFFSET + 0) ++#define CMD_PROC_CTRL_OFFSET (CMD_PROC_BASE_OFFSET + 1) ++#define CMD_PROC_DETACH_OFFSET (CMD_PROC_BASE_OFFSET + 2) ++#define CMD_PROC_ENUMNODE_OFFSET (CMD_PROC_BASE_OFFSET + 3) ++#define CMD_PROC_ENUMRESOURCES_OFFSET (CMD_PROC_BASE_OFFSET + 4) ++#define CMD_PROC_GETSTATE_OFFSET (CMD_PROC_BASE_OFFSET + 5) ++#define CMD_PROC_GETTRACE_OFFSET (CMD_PROC_BASE_OFFSET + 6) ++#define CMD_PROC_LOAD_OFFSET (CMD_PROC_BASE_OFFSET + 7) ++#define CMD_PROC_REGISTERNOTIFY_OFFSET (CMD_PROC_BASE_OFFSET + 8) ++#define CMD_PROC_START_OFFSET (CMD_PROC_BASE_OFFSET + 9) ++#define CMD_PROC_RSVMEM_OFFSET (CMD_PROC_BASE_OFFSET + 10) ++#define CMD_PROC_UNRSVMEM_OFFSET (CMD_PROC_BASE_OFFSET + 11) ++#define CMD_PROC_MAPMEM_OFFSET (CMD_PROC_BASE_OFFSET + 12) ++#define CMD_PROC_UNMAPMEM_OFFSET (CMD_PROC_BASE_OFFSET + 13) ++#define CMD_PROC_FLUSHMEMORY_OFFSET (CMD_PROC_BASE_OFFSET + 14) ++#define CMD_PROC_STOP_OFFSET (CMD_PROC_BASE_OFFSET + 15) ++#define CMD_PROC_INVALIDATEMEMORY_OFFSET (CMD_PROC_BASE_OFFSET + 16) ++#define CMD_PROC_END_OFFSET CMD_PROC_INVALIDATEMEMORY_OFFSET ++ ++ ++#define CMD_NODE_BASE_OFFSET (CMD_PROC_END_OFFSET + 1) ++#define CMD_NODE_ALLOCATE_OFFSET (CMD_NODE_BASE_OFFSET + 0) ++#define CMD_NODE_ALLOCMSGBUF_OFFSET (CMD_NODE_BASE_OFFSET + 1) ++#define CMD_NODE_CHANGEPRIORITY_OFFSET (CMD_NODE_BASE_OFFSET + 2) ++#define CMD_NODE_CONNECT_OFFSET (CMD_NODE_BASE_OFFSET + 3) ++#define CMD_NODE_CREATE_OFFSET (CMD_NODE_BASE_OFFSET + 4) ++#define CMD_NODE_DELETE_OFFSET (CMD_NODE_BASE_OFFSET + 5) ++#define CMD_NODE_FREEMSGBUF_OFFSET (CMD_NODE_BASE_OFFSET + 6) ++#define CMD_NODE_GETATTR_OFFSET (CMD_NODE_BASE_OFFSET + 7) ++#define CMD_NODE_GETMESSAGE_OFFSET (CMD_NODE_BASE_OFFSET + 8) ++#define CMD_NODE_PAUSE_OFFSET (CMD_NODE_BASE_OFFSET + 9) ++#define CMD_NODE_PUTMESSAGE_OFFSET (CMD_NODE_BASE_OFFSET + 10) ++#define CMD_NODE_REGISTERNOTIFY_OFFSET (CMD_NODE_BASE_OFFSET + 11) ++#define CMD_NODE_RUN_OFFSET (CMD_NODE_BASE_OFFSET + 12) ++#define CMD_NODE_TERMINATE_OFFSET (CMD_NODE_BASE_OFFSET + 13) ++#define CMD_NODE_GETUUIDPROPS_OFFSET (CMD_NODE_BASE_OFFSET + 14) ++#define CMD_NODE_END_OFFSET CMD_NODE_GETUUIDPROPS_OFFSET ++ ++#define CMD_STRM_BASE_OFFSET (CMD_NODE_END_OFFSET + 1) ++#define CMD_STRM_ALLOCATEBUFFER_OFFSET (CMD_STRM_BASE_OFFSET + 0) ++#define CMD_STRM_CLOSE_OFFSET (CMD_STRM_BASE_OFFSET + 1) ++#define CMD_STRM_FREEBUFFER_OFFSET (CMD_STRM_BASE_OFFSET + 2) ++#define CMD_STRM_GETEVENTHANDLE_OFFSET (CMD_STRM_BASE_OFFSET + 3) ++#define CMD_STRM_GETINFO_OFFSET (CMD_STRM_BASE_OFFSET + 4) ++#define CMD_STRM_IDLE_OFFSET (CMD_STRM_BASE_OFFSET + 5) ++#define CMD_STRM_ISSUE_OFFSET (CMD_STRM_BASE_OFFSET + 6) ++#define CMD_STRM_OPEN_OFFSET (CMD_STRM_BASE_OFFSET + 7) ++#define CMD_STRM_RECLAIM_OFFSET (CMD_STRM_BASE_OFFSET + 8) ++#define CMD_STRM_REGISTERNOTIFY_OFFSET (CMD_STRM_BASE_OFFSET + 9) ++#define CMD_STRM_SELECT_OFFSET (CMD_STRM_BASE_OFFSET + 10) ++#define CMD_STRM_END_OFFSET CMD_STRM_SELECT_OFFSET ++ ++/* Communication Memory Manager (UCMM) */ ++#define CMD_CMM_BASE_OFFSET (CMD_STRM_END_OFFSET + 1) ++#define CMD_CMM_ALLOCBUF_OFFSET (CMD_CMM_BASE_OFFSET + 0) ++#define CMD_CMM_FREEBUF_OFFSET (CMD_CMM_BASE_OFFSET + 1) ++#define CMD_CMM_GETHANDLE_OFFSET (CMD_CMM_BASE_OFFSET + 2) ++#define CMD_CMM_GETINFO_OFFSET (CMD_CMM_BASE_OFFSET + 3) ++#define CMD_CMM_END_OFFSET CMD_CMM_GETINFO_OFFSET ++ ++#define CMD_BASE_END_OFFSET CMD_CMM_END_OFFSET ++#endif /* WCDIOCTL_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/wmd.h b/arch/arm/plat-omap/include/dspbridge/wmd.h +new file mode 100644 +index 0000000..f584038 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/wmd.h +@@ -0,0 +1,1193 @@ ++/* ++ * wmd.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== wmd.h ======== ++ * Purpose: ++ * 'Bridge mini driver entry point and interface function declarations. ++ * ++ * Public Functions: ++ * WMD_DRV_Entry ++ * ++ * Notes: ++ * The 'Bridge class driver obtains it's function interface to ++ * the 'Bridge mini driver via a call to WMD_DRV_Entry(). ++ * ++ * 'Bridge Class Driver services exported to WMD's are initialized by the ++ * WCD on behalf of the WMD. ++ * ++ * WMD function DBC Requires and Ensures are also made by the WCD on ++ * behalf of the WMD, to simplify the WMD code. ++ * ++ *! Revision History: ++ *! ================ ++ *! 19-Apr-2004 sb Aligned DMM definitions with Symbian ++ *! 08-Mar-2004 sb Added the Dynamic Memory Mapping APIs - WMD_BRD_MemMap/UnMap ++ *! 01-Mar-2004 vp Added filename argument to WMD_DRV_Entry function. ++ *! 29-Aug-2002 map Added WMD_BRD_MemWrite() ++ *! 26-Aug-2002 map Added WMD_BRD_MemCopy() ++ *! 07-Jan-2002 ag Added cBufSize to WMD_CHNL_AddIOReq(). ++ *! 05-Nov-2001 kc: Added error handling DEH functions. ++ *! 06-Dec-2000 jeh Added uEventMask to WMD_MSG_RegisterNotify(). ++ *! 17-Nov-2000 jeh Added WMD_MSG and WMD_IO definitions. ++ *! 01-Nov-2000 jeh Added more error codes to WMD_CHNL_RegisterNotify(). ++ *! 13-Oct-2000 jeh Added dwArg to WMD_CHNL_AddIOReq(), added WMD_CHNL_IDLE ++ *! and WMD_CHNL_RegisterNotify for DSPStream support. ++ *! 17-Jan-2000 rr: WMD_BRD_SETSTATE Added. ++ *! 30-Jul-1997 gp: Split wmd IOCTL space into reserved and private. ++ *! 07-Nov-1996 gp: Updated for code review. ++ *! 18-Oct-1996 gp: Added WMD_E_HARDWARE return code from WMD_BRD_Monitor. ++ *! 09-Sep-1996 gp: Subtly altered the semantics of WMD_CHNL_GetInfo(). ++ *! 02-Aug-1996 gp: Ensured on BRD_Start that interrupts to the PC are enabled. ++ *! 11-Jul-1996 gp: Added CHNL interface. Note stronger DBC_Require conditions. ++ *! 29-May-1996 gp: Removed WCD_ prefix from functions imported from WCD.LIB. ++ *! 29-May-1996 gp: Made OUT param first in WMD_DEV_Create(). ++ *! 09-May-1996 gp: Created. ++ */ ++ ++#ifndef WMD_ ++#define WMD_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * Any IOCTLS at or above this value are reserved for standard WMD ++ * interfaces. ++ */ ++#define WMD_RESERVEDIOCTLBASE 0x8000 ++ ++/* Handle to mini-driver's private device context. */ ++ struct WMD_DEV_CONTEXT; ++ ++/*---------------------------------------------------------------------------*/ ++/* 'Bridge MINI DRIVER FUNCTION TYPES */ ++/*---------------------------------------------------------------------------*/ ++ ++/* ++ * ======== WMD_BRD_Monitor ======== ++ * Purpose: ++ * Bring the board to the BRD_IDLE (monitor) state. ++ * Parameters: ++ * hDevContext: Handle to mini-driver defined device context. ++ * Returns: ++ * DSP_SOK: Success. ++ * WMD_E_HARDWARE: A test of hardware assumptions/integrity failed. ++ * WMD_E_TIMEOUT: Timeout occured waiting for a response from hardware. ++ * DSP_EFAIL: Other, unspecified error. ++ * Requires: ++ * hDevContext != NULL ++ * Ensures: ++ * DSP_SOK: Board is in BRD_IDLE state; ++ * else: Board state is indeterminate. ++ */ ++ typedef DSP_STATUS( ++ *WMD_BRD_MONITOR) (struct WMD_DEV_CONTEXT ++ *hDevContext); ++ ++/* ++ * ======== WMD_BRD_SETSTATE ======== ++ * Purpose: ++ * Sets the Mini driver state ++ * Parameters: ++ * hDevContext: Handle to mini-driver defined device info. ++ * ulBrdState: Board state ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Other, unspecified error. ++ * Requires: ++ * hDevContext != NULL; ++ * ulBrdState <= BRD_LASTSTATE. ++ * Ensures: ++ * ulBrdState <= BRD_LASTSTATE. ++ * Update the Board state to the specified state. ++ */ ++ typedef DSP_STATUS( ++ *WMD_BRD_SETSTATE) (struct WMD_DEV_CONTEXT ++ *hDevContext, u32 ulBrdState); ++ ++/* ++ * ======== WMD_BRD_Start ======== ++ * Purpose: ++ * Bring board to the BRD_RUNNING (start) state. ++ * Parameters: ++ * hDevContext: Handle to mini-driver defined device context. ++ * dwDSPAddr: DSP address at which to start execution. ++ * Returns: ++ * DSP_SOK: Success. ++ * WMD_E_TIMEOUT: Timeout occured waiting for a response from hardware. ++ * DSP_EFAIL: Other, unspecified error. ++ * Requires: ++ * hDevContext != NULL ++ * Board is in monitor (BRD_IDLE) state. ++ * Ensures: ++ * DSP_SOK: Board is in BRD_RUNNING state. ++ * Interrupts to the PC are enabled. ++ * else: Board state is indeterminate. ++ */ ++ typedef DSP_STATUS(*WMD_BRD_START) (struct WMD_DEV_CONTEXT ++ *hDevContext, u32 dwDSPAddr); ++ ++/* ++ * ======== WMD_BRD_MemCopy ======== ++ * Purpose: ++ * Copy memory from one DSP address to another ++ * Parameters: ++ * pDevContext: Pointer to context handle ++ * ulDspDestAddr: DSP address to copy to ++ * ulDspSrcAddr: DSP address to copy from ++ * ulNumBytes: Number of bytes to copy ++ * ulMemType: What section of memory to copy to ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Other, unspecified error. ++ * Requires: ++ * pDevContext != NULL ++ * Ensures: ++ * DSP_SOK: Board is in BRD_RUNNING state. ++ * Interrupts to the PC are enabled. ++ * else: Board state is indeterminate. ++ */ ++ typedef DSP_STATUS(*WMD_BRD_MEMCOPY) (struct WMD_DEV_CONTEXT ++ *hDevContext, ++ u32 ulDspDestAddr, ++ u32 ulDspSrcAddr, ++ u32 ulNumBytes, u32 ulMemType); ++/* ++ * ======== WMD_BRD_MemWrite ======== ++ * Purpose: ++ * Write a block of host memory into a DSP address, into a given memory ++ * space. Unlike WMD_BRD_Write, this API does reset the DSP ++ * Parameters: ++ * hDevContext: Handle to mini-driver defined device info. ++ * dwDSPAddr: Address on DSP board (Destination). ++ * pHostBuf: Pointer to host buffer (Source). ++ * ulNumBytes: Number of bytes to transfer. ++ * ulMemType: Memory space on DSP to which to transfer. ++ * Returns: ++ * DSP_SOK: Success. ++ * WMD_E_TIMEOUT: Timeout occured waiting for a response from hardware. ++ * DSP_EFAIL: Other, unspecified error. ++ * Requires: ++ * hDevContext != NULL; ++ * pHostBuf != NULL. ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*WMD_BRD_MEMWRITE) (struct WMD_DEV_CONTEXT ++ *hDevContext, ++ IN u8 *pHostBuf, ++ u32 dwDSPAddr, u32 ulNumBytes, ++ u32 ulMemType); ++ ++/* ++ * ======== WMD_BRD_MemMap ======== ++ * Purpose: ++ * Map a MPU memory region to a DSP/IVA memory space ++ * Parameters: ++ * hDevContext: Handle to mini-driver defined device info. ++ * ulMpuAddr: MPU memory region start address. ++ * ulVirtAddr: DSP/IVA memory region u8 address. ++ * ulNumBytes: Number of bytes to map. ++ * mapAttrs: Mapping attributes (e.g. endianness). ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Other, unspecified error. ++ * Requires: ++ * hDevContext != NULL; ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*WMD_BRD_MEMMAP) (struct WMD_DEV_CONTEXT ++ *hDevContext, u32 ulMpuAddr, ++ u32 ulVirtAddr, u32 ulNumBytes, ++ u32 ulMapAttrs); ++ ++/* ++ * ======== WMD_BRD_MemUnMap ======== ++ * Purpose: ++ * UnMap an MPU memory region from DSP/IVA memory space ++ * Parameters: ++ * hDevContext: Handle to mini-driver defined device info. ++ * ulVirtAddr: DSP/IVA memory region u8 address. ++ * ulNumBytes: Number of bytes to unmap. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Other, unspecified error. ++ * Requires: ++ * hDevContext != NULL; ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*WMD_BRD_MEMUNMAP) (struct WMD_DEV_CONTEXT ++ *hDevContext, ++ u32 ulVirtAddr, ++ u32 ulNumBytes); ++ ++/* ++ * ======== WMD_BRD_Stop ======== ++ * Purpose: ++ * Bring board to the BRD_STOPPED state. ++ * Parameters: ++ * hDevContext: Handle to mini-driver defined device context. ++ * Returns: ++ * DSP_SOK: Success. ++ * WMD_E_TIMEOUT: Timeout occured waiting for a response from hardware. ++ * DSP_EFAIL: Other, unspecified error. ++ * Requires: ++ * hDevContext != NULL ++ * Ensures: ++ * DSP_SOK: Board is in BRD_STOPPED (stop) state; ++ * Interrupts to the PC are disabled. ++ * else: Board state is indeterminate. ++ */ ++ typedef DSP_STATUS(*WMD_BRD_STOP) (struct WMD_DEV_CONTEXT ++ *hDevContext); ++ ++/* ++ * ======== WMD_BRD_Status ======== ++ * Purpose: ++ * Report the current state of the board. ++ * Parameters: ++ * hDevContext: Handle to mini-driver defined device context. ++ * pdwState: Ptr to BRD status variable. ++ * Returns: ++ * DSP_SOK: ++ * Requires: ++ * pdwState != NULL; ++ * hDevContext != NULL ++ * Ensures: ++ * *pdwState is one of {BRD_STOPPED, BRD_IDLE, BRD_RUNNING, BRD_UNKNOWN}; ++ */ ++ typedef DSP_STATUS(* ++ WMD_BRD_STATUS) (struct WMD_DEV_CONTEXT *hDevContext, ++ OUT BRD_STATUS * pdwState); ++ ++/* ++ * ======== WMD_BRD_Read ======== ++ * Purpose: ++ * Read a block of DSP memory, from a given memory space, into a host ++ * buffer. ++ * Parameters: ++ * hDevContext: Handle to mini-driver defined device info. ++ * pHostBuf: Pointer to host buffer (Destination). ++ * dwDSPAddr: Address on DSP board (Source). ++ * ulNumBytes: Number of bytes to transfer. ++ * ulMemType: Memory space on DSP from which to transfer. ++ * Returns: ++ * DSP_SOK: Success. ++ * WMD_E_TIMEOUT: Timeout occured waiting for a response from hardware. ++ * DSP_EFAIL: Other, unspecified error. ++ * Requires: ++ * hDevContext != NULL; ++ * pHostBuf != NULL. ++ * Ensures: ++ * Will not write more than ulNumBytes bytes into pHostBuf. ++ */ ++typedef DSP_STATUS(*WMD_BRD_READ) (struct WMD_DEV_CONTEXT *hDevContext, ++ OUT u8 *pHostBuf, ++ u32 dwDSPAddr, ++ u32 ulNumBytes, ++ u32 ulMemType); ++ ++/* ++ * ======== WMD_BRD_Write ======== ++ * Purpose: ++ * Write a block of host memory into a DSP address, into a given memory ++ * space. ++ * Parameters: ++ * hDevContext: Handle to mini-driver defined device info. ++ * dwDSPAddr: Address on DSP board (Destination). ++ * pHostBuf: Pointer to host buffer (Source). ++ * ulNumBytes: Number of bytes to transfer. ++ * ulMemType: Memory space on DSP to which to transfer. ++ * Returns: ++ * DSP_SOK: Success. ++ * WMD_E_TIMEOUT: Timeout occured waiting for a response from hardware. ++ * DSP_EFAIL: Other, unspecified error. ++ * Requires: ++ * hDevContext != NULL; ++ * pHostBuf != NULL. ++ * Ensures: ++ */ ++typedef DSP_STATUS(*WMD_BRD_WRITE)(struct WMD_DEV_CONTEXT *hDevContext, ++ IN u8 *pHostBuf, ++ u32 dwDSPAddr, ++ u32 ulNumBytes, ++ u32 ulMemType); ++ ++/* ++ * ======== WMD_CHNL_Create ======== ++ * Purpose: ++ * Create a channel manager object, responsible for opening new channels ++ * and closing old ones for a given 'Bridge board. ++ * Parameters: ++ * phChnlMgr: Location to store a channel manager object on output. ++ * hDevObject: Handle to a device object. ++ * pMgrAttrs: Channel manager attributes. ++ * pMgrAttrs->cChannels: Max channels ++ * pMgrAttrs->bIRQ: Channel's I/O IRQ number. ++ * pMgrAttrs->fShared: TRUE if the IRQ is shareable. ++ * pMgrAttrs->uWordSize: DSP Word size in equivalent PC bytes.. ++ * pMgrAttrs->dwSMBase: Base physical address of shared memory, if any. ++ * pMgrAttrs->uSMLength: Bytes of shared memory block. ++ * Returns: ++ * DSP_SOK: Success; ++ * DSP_EMEMORY: Insufficient memory for requested resources. ++ * CHNL_E_ISR: Unable to plug ISR for given IRQ. ++ * CHNL_E_NOMEMMAP: Couldn't map physical address to a virtual one. ++ * Requires: ++ * phChnlMgr != NULL. ++ * pMgrAttrs != NULL ++ * pMgrAttrs field are all valid: ++ * 0 < cChannels <= CHNL_MAXCHANNELS. ++ * bIRQ <= 15. ++ * uWordSize > 0. ++ * IsValidHandle(hDevObject) ++ * No channel manager exists for this board. ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*WMD_CHNL_CREATE)(OUT struct CHNL_MGR ++ **phChnlMgr, ++ struct DEV_OBJECT ++ *hDevObject, ++ IN CONST struct ++ CHNL_MGRATTRS *pMgrAttrs); ++ ++/* ++ * ======== WMD_CHNL_Destroy ======== ++ * Purpose: ++ * Close all open channels, and destroy the channel manager. ++ * Parameters: ++ * hChnlMgr: Channel manager object. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: hChnlMgr was invalid. ++ * Requires: ++ * Ensures: ++ * DSP_SOK: Cancels I/O on each open channel. Closes each open channel. ++ * CHNL_Create may subsequently be called for the same device. ++ */ ++ typedef DSP_STATUS(*WMD_CHNL_DESTROY) (struct CHNL_MGR ++ *hChnlMgr); ++/* ++ * ======== WMD_DEH_Notify ======== ++ * Purpose: ++ * When notified of DSP error, take appropriate action. ++ * Parameters: ++ * hDehMgr: Handle to DEH manager object. ++ * ulEventMask: Indicate the type of exception ++ * dwErrInfo: Error information ++ * Returns: ++ * ++ * Requires: ++ * hDehMgr != NULL; ++ * ulEventMask with a valid exception ++ * Ensures: ++ */ ++ typedef void (*WMD_DEH_NOTIFY)(struct DEH_MGR *hDehMgr, ++ u32 ulEventMask, u32 dwErrInfo); ++ ++ ++/* ++ * ======== WMD_CHNL_Open ======== ++ * Purpose: ++ * Open a new half-duplex channel to the DSP board. ++ * Parameters: ++ * phChnl: Location to store a channel object handle. ++ * hChnlMgr: Handle to channel manager, as returned by CHNL_GetMgr(). ++ * uMode: One of {CHNL_MODETODSP, CHNL_MODEFROMDSP} specifies ++ * direction of data transfer. ++ * uChnlId: If CHNL_PICKFREE is specified, the channel manager will ++ * select a free channel id (default); ++ * otherwise this field specifies the id of the channel. ++ * pAttrs: Channel attributes. Attribute fields are as follows: ++ * pAttrs->uIOReqs: Specifies the maximum number of I/O requests which can ++ * be pending at any given time. All request packets are ++ * preallocated when the channel is opened. ++ * pAttrs->hEvent: This field allows the user to supply an auto reset ++ * event object for channel I/O completion notifications. ++ * It is the responsibility of the user to destroy this ++ * object AFTER closing the channel. ++ * This channel event object can be retrieved using ++ * CHNL_GetEventHandle(). ++ * pAttrs->hReserved: The kernel mode handle of this event object. ++ * ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: hChnlMgr is invalid. ++ * DSP_EMEMORY: Insufficient memory for requested resources. ++ * DSP_EINVALIDARG: Invalid number of IOReqs. ++ * CHNL_E_OUTOFSTREAMS: No free channels available. ++ * CHNL_E_BADCHANID: Channel ID is out of range. ++ * CHNL_E_CHANBUSY: Channel is in use. ++ * CHNL_E_NOIORPS: No free IO request packets available for ++ * queuing. ++ * Requires: ++ * phChnl != NULL. ++ * pAttrs != NULL. ++ * pAttrs->hEvent is a valid event handle. ++ * pAttrs->hReserved is the kernel mode handle for pAttrs->hEvent. ++ * Ensures: ++ * DSP_SOK: *phChnl is a valid channel. ++ * else: *phChnl is set to NULL if (phChnl != NULL); ++ */ ++ typedef DSP_STATUS(*WMD_CHNL_OPEN) (OUT struct CHNL_OBJECT ++ **phChnl, ++ struct CHNL_MGR *hChnlMgr, ++ CHNL_MODE uMode, ++ u32 uChnlId, ++ CONST IN OPTIONAL struct ++ CHNL_ATTRS *pAttrs); ++ ++/* ++ * ======== WMD_CHNL_Close ======== ++ * Purpose: ++ * Ensures all pending I/O on this channel is cancelled, discards all ++ * queued I/O completion notifications, then frees the resources allocated ++ * for this channel, and makes the corresponding logical channel id ++ * available for subsequent use. ++ * Parameters: ++ * hChnl: Handle to a channel object. ++ * Returns: ++ * DSP_SOK: Success; ++ * DSP_EHANDLE: Invalid hChnl. ++ * Requires: ++ * No thread must be blocked on this channel's I/O completion event. ++ * Ensures: ++ * DSP_SOK: hChnl is no longer valid. ++ */ ++ typedef DSP_STATUS(*WMD_CHNL_CLOSE) (struct CHNL_OBJECT *hChnl); ++ ++/* ++ * ======== WMD_CHNL_AddIOReq ======== ++ * Purpose: ++ * Enqueue an I/O request for data transfer on a channel to the DSP. ++ * The direction (mode) is specified in the channel object. Note the DSP ++ * address is specified for channels opened in direct I/O mode. ++ * Parameters: ++ * hChnl: Channel object handle. ++ * pHostBuf: Host buffer address source. ++ * cBytes: Number of PC bytes to transfer. A zero value indicates ++ * that this buffer is the last in the output channel. ++ * A zero value is invalid for an input channel. ++ *! cBufSize: Actual buffer size in host bytes. ++ * dwDspAddr: DSP address for transfer. (Currently ignored). ++ * dwArg: A user argument that travels with the buffer. ++ * Returns: ++ * DSP_SOK: Success; ++ * DSP_EHANDLE: Invalid hChnl. ++ * DSP_EPOINTER: pHostBuf is invalid. ++ * CHNL_E_NOEOS: User cannot mark EOS on an input channel. ++ * CHNL_E_CANCELLED: I/O has been cancelled on this channel. No further ++ * I/O is allowed. ++ * CHNL_E_EOS: End of stream was already marked on a previous ++ * IORequest on this channel. No further I/O is expected. ++ * CHNL_E_BUFSIZE: Buffer submitted to this output channel is larger than ++ * the size of the physical shared memory output window. ++ * Requires: ++ * Ensures: ++ * DSP_SOK: The buffer will be transferred if the channel is ready; ++ * otherwise, will be queued for transfer when the channel becomes ++ * ready. In any case, notifications of I/O completion are ++ * asynchronous. ++ * If cBytes is 0 for an output channel, subsequent CHNL_AddIOReq's ++ * on this channel will fail with error code CHNL_E_EOS. The ++ * corresponding IOC for this I/O request will have its status flag ++ * set to CHNL_IOCSTATEOS. ++ */ ++ typedef DSP_STATUS(*WMD_CHNL_ADDIOREQ) (struct CHNL_OBJECT ++ *hChnl, ++ void *pHostBuf, ++ u32 cBytes, ++ u32 cBufSize, ++ OPTIONAL u32 dwDspAddr, ++ u32 dwArg); ++ ++/* ++ * ======== WMD_CHNL_GetIOC ======== ++ * Purpose: ++ * Dequeue an I/O completion record, which contains information about the ++ * completed I/O request. ++ * Parameters: ++ * hChnl: Channel object handle. ++ * dwTimeOut: A value of CHNL_IOCNOWAIT will simply dequeue the ++ * first available IOC. ++ * pIOC: On output, contains host buffer address, bytes ++ * transferred, and status of I/O completion. ++ * pIOC->status: See chnldefs.h. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hChnl. ++ * DSP_EPOINTER: pIOC is invalid. ++ * CHNL_E_NOIOC: CHNL_IOCNOWAIT was specified as the dwTimeOut parameter ++ * yet no I/O completions were queued. ++ * Requires: ++ * dwTimeOut == CHNL_IOCNOWAIT. ++ * Ensures: ++ * DSP_SOK: if there are any remaining IOC's queued before this call ++ * returns, the channel event object will be left in a signalled ++ * state. ++ */ ++ typedef DSP_STATUS(*WMD_CHNL_GETIOC) (struct CHNL_OBJECT *hChnl, ++ u32 dwTimeOut, ++ OUT struct CHNL_IOC *pIOC); ++ ++/* ++ * ======== WMD_CHNL_CancelIO ======== ++ * Purpose: ++ * Return all I/O requests to the client which have not yet been ++ * transferred. The channel's I/O completion object is ++ * signalled, and all the I/O requests are queued as IOC's, with the ++ * status field set to CHNL_IOCSTATCANCEL. ++ * This call is typically used in abort situations, and is a prelude to ++ * CHNL_Close(); ++ * Parameters: ++ * hChnl: Channel object handle. ++ * Returns: ++ * DSP_SOK: Success; ++ * DSP_EHANDLE: Invalid hChnl. ++ * Requires: ++ * Ensures: ++ * Subsequent I/O requests to this channel will not be accepted. ++ */ ++ typedef DSP_STATUS(*WMD_CHNL_CANCELIO) (struct CHNL_OBJECT ++ *hChnl); ++ ++/* ++ * ======== WMD_CHNL_FlushIO ======== ++ * Purpose: ++ * For an output stream (to the DSP), indicates if any IO requests are in ++ * the output request queue. For input streams (from the DSP), will ++ * cancel all pending IO requests. ++ * Parameters: ++ * hChnl: Channel object handle. ++ * dwTimeOut: Timeout value for flush operation. ++ * Returns: ++ * DSP_SOK: Success; ++ * S_CHNLIOREQUEST: Returned if any IORequests are in the output queue. ++ * DSP_EHANDLE: Invalid hChnl. ++ * Requires: ++ * Ensures: ++ * DSP_SOK: No I/O requests will be pending on this channel. ++ */ ++ typedef DSP_STATUS(*WMD_CHNL_FLUSHIO) (struct CHNL_OBJECT *hChnl, ++ u32 dwTimeOut); ++ ++/* ++ * ======== WMD_CHNL_GetInfo ======== ++ * Purpose: ++ * Retrieve information related to a channel. ++ * Parameters: ++ * hChnl: Handle to a valid channel object, or NULL. ++ * pInfo: Location to store channel info. ++ * Returns: ++ * DSP_SOK: Success; ++ * DSP_EHANDLE: Invalid hChnl. ++ * DSP_EPOINTER: pInfo == NULL. ++ * Requires: ++ * Ensures: ++ * DSP_SOK: pInfo points to a filled in CHNL_INFO struct, ++ * if (pInfo != NULL). ++ */ ++ typedef DSP_STATUS(*WMD_CHNL_GETINFO) (struct CHNL_OBJECT *hChnl, ++ OUT struct CHNL_INFO ++ *pChnlInfo); ++ ++/* ++ * ======== WMD_CHNL_GetMgrInfo ======== ++ * Purpose: ++ * Retrieve information related to the channel manager. ++ * Parameters: ++ * hChnlMgr: Handle to a valid channel manager, or NULL. ++ * uChnlID: Channel ID. ++ * pMgrInfo: Location to store channel manager info. ++ * Returns: ++ * DSP_SOK: Success; ++ * DSP_EHANDLE: Invalid hChnlMgr. ++ * DSP_EPOINTER: pMgrInfo == NULL. ++ * CHNL_E_BADCHANID: Invalid channel ID. ++ * Requires: ++ * Ensures: ++ * DSP_SOK: pMgrInfo points to a filled in CHNL_MGRINFO ++ * struct, if (pMgrInfo != NULL). ++ */ ++ typedef DSP_STATUS(*WMD_CHNL_GETMGRINFO) (struct CHNL_MGR ++ *hChnlMgr, ++ u32 uChnlID, ++ OUT struct CHNL_MGRINFO ++ *pMgrInfo); ++ ++/* ++ * ======== WMD_CHNL_Idle ======== ++ * Purpose: ++ * Idle a channel. If this is an input channel, or if this is an output ++ * channel and fFlush is TRUE, all currently enqueued buffers will be ++ * dequeued (data discarded for output channel). ++ * If this is an output channel and fFlush is FALSE, this function ++ * will block until all currently buffered data is output, or the timeout ++ * specified has been reached. ++ * ++ * Parameters: ++ * hChnl: Channel object handle. ++ * dwTimeOut: If output channel and fFlush is FALSE, timeout value ++ * to wait for buffers to be output. (Not used for ++ * input channel). ++ * fFlush: If output channel and fFlush is TRUE, discard any ++ * currently buffered data. If FALSE, wait for currently ++ * buffered data to be output, or timeout, whichever ++ * occurs first. fFlush is ignored for input channel. ++ * Returns: ++ * DSP_SOK: Success; ++ * DSP_EHANDLE: Invalid hChnl. ++ * CHNL_E_WAITTIMEOUT: Timeout occured before channel could be idled. ++ * Requires: ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*WMD_CHNL_IDLE) (struct CHNL_OBJECT *hChnl, ++ u32 dwTimeOut, ++ bool fFlush); ++ ++/* ++ * ======== WMD_CHNL_RegisterNotify ======== ++ * Purpose: ++ * Register for notification of events on a channel. ++ * Parameters: ++ * hChnl: Channel object handle. ++ * uEventMask: Type of events to be notified about: IO completion ++ * (DSP_STREAMIOCOMPLETION) or end of stream ++ * (DSP_STREAMDONE). ++ * uNotifyType: DSP_SIGNALEVENT. ++ * hNotification: Handle of a DSP_NOTIFICATION object. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Insufficient memory. ++ * DSP_EVALUE: uEventMask is 0 and hNotification was not ++ * previously registered. ++ * DSP_EHANDLE: NULL hNotification, hNotification event name ++ * too long, or hNotification event name NULL. ++ * Requires: ++ * Valid hChnl. ++ * hNotification != NULL. ++ * (uEventMask & ~(DSP_STREAMIOCOMPLETION | DSP_STREAMDONE)) == 0. ++ * uNotifyType == DSP_SIGNALEVENT. ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*WMD_CHNL_REGISTERNOTIFY) ++ (struct CHNL_OBJECT *hChnl, ++ u32 uEventMask, ++ u32 uNotifyType, ++ struct DSP_NOTIFICATION *hNotification); ++ ++/* ++ * ======== WMD_DEV_Create ======== ++ * Purpose: ++ * Complete creation of the device object for this board. ++ * Parameters: ++ * phDevContext: Ptr to location to store a WMD device context. ++ * hDevObject: Handle to a Device Object, created and managed by WCD. ++ * pConfig: Ptr to configuration parameters provided by the Windows ++ * Configuration Manager during device loading. ++ * pDspConfig: DSP resources, as specified in the registry key for this ++ * device. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Unable to allocate memory for device context. ++ * WMD_E_BADCONFIG: One or more of the host or DSP configuration ++ * parameters did not satisfy hardware assumptions ++ * made by this WMD. ++ * Requires: ++ * phDevContext != NULL; ++ * hDevObject != NULL; ++ * pConfig != NULL; ++ * pDspConfig != NULL; ++ * Fields in pConfig and pDspConfig contain valid values. ++ * Ensures: ++ * DSP_SOK: All mini-driver specific DSP resource and other ++ * board context has been allocated. ++ * DSP_EMEMORY: WMD failed to allocate resources. ++ * Any acquired resources have been freed. The WCD will ++ * not call WMD_DEV_Destroy() if WMD_DEV_Create() fails. ++ * Details: ++ * Called during the CONFIGMG's Device_Init phase. Based on host and ++ * DSP configuration information, create a board context, a handle to ++ * which is passed into other WMD BRD and CHNL functions. The ++ * board context contains state information for the device. Since the ++ * addresses of all IN pointer parameters may be invalid when this ++ * function returns, they must not be stored into the device context ++ * structure. ++ */ ++ typedef DSP_STATUS(*WMD_DEV_CREATE) (OUT struct WMD_DEV_CONTEXT ++ **phDevContext, ++ struct DEV_OBJECT ++ *hDevObject, ++ IN CONST struct CFG_HOSTRES ++ *pConfig, ++ IN CONST struct CFG_DSPRES ++ *pDspConfig); ++ ++/* ++ * ======== WMD_DEV_Ctrl ======== ++ * Purpose: ++ * Mini-driver specific interface. ++ * Parameters: ++ * hDevContext: Handle to mini-driver defined device info. ++ * dwCmd: WMD defined command code. ++ * pArgs: Pointer to an arbitrary argument structure. ++ * Returns: ++ * DSP_SOK or DSP_EFAIL. Actual command error codes should be passed back ++ * in the pArgs structure, and are defined by the WMD implementor. ++ * Requires: ++ * All calls are currently assumed to be synchronous. There are no ++ * IOCTL completion routines provided. ++ * Ensures: ++ */ ++typedef DSP_STATUS(*WMD_DEV_CTRL)(struct WMD_DEV_CONTEXT *hDevContext, ++ u32 dwCmd, ++ IN OUT void *pArgs); ++ ++/* ++ * ======== WMD_DEV_Destroy ======== ++ * Purpose: ++ * Deallocate WMD device extension structures and all other resources ++ * acquired by the mini-driver. ++ * No calls to other mini driver functions may subsequently ++ * occur, except for WMD_DEV_Create(). ++ * Parameters: ++ * hDevContext: Handle to mini-driver defined device information. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Failed to release a resource previously acquired. ++ * Requires: ++ * hDevContext != NULL; ++ * Ensures: ++ * DSP_SOK: Device context is freed. ++ */ ++ typedef DSP_STATUS(*WMD_DEV_DESTROY) (struct WMD_DEV_CONTEXT ++ *hDevContext); ++ ++/* ++ * ======== WMD_DEH_Create ======== ++ * Purpose: ++ * Create an object that manages DSP exceptions from the GPP. ++ * Parameters: ++ * phDehMgr: Location to store DEH manager on output. ++ * hDevObject: Handle to DEV object. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Memory allocation failure. ++ * DSP_EFAIL: Creation failed. ++ * Requires: ++ * hDevObject != NULL; ++ * phDehMgr != NULL; ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*WMD_DEH_CREATE) (OUT struct DEH_MGR ++ **phDehMgr, ++ struct DEV_OBJECT ++ *hDevObject); ++ ++/* ++ * ======== WMD_DEH_Destroy ======== ++ * Purpose: ++ * Destroy the DEH object. ++ * Parameters: ++ * hDehMgr: Handle to DEH manager object. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Destroy failed. ++ * Requires: ++ * hDehMgr != NULL; ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*WMD_DEH_DESTROY) (struct DEH_MGR *hDehMgr); ++ ++/* ++ * ======== WMD_DEH_RegisterNotify ======== ++ * Purpose: ++ * Register for DEH event notification. ++ * Parameters: ++ * hDehMgr: Handle to DEH manager object. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Destroy failed. ++ * Requires: ++ * hDehMgr != NULL; ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*WMD_DEH_REGISTERNOTIFY) ++ (struct DEH_MGR *hDehMgr, ++ u32 uEventMask, u32 uNotifyType, ++ struct DSP_NOTIFICATION *hNotification); ++ ++/* ++ * ======== WMD_DEH_GetInfo ======== ++ * Purpose: ++ * Get DSP exception info. ++ * Parameters: ++ * phDehMgr: Location to store DEH manager on output. ++ * pErrInfo: Ptr to error info structure. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Creation failed. ++ * Requires: ++ * phDehMgr != NULL; ++ * pErrorInfo != NULL; ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*WMD_DEH_GETINFO) (struct DEH_MGR *phDehMgr, ++ struct DSP_ERRORINFO *pErrInfo); ++ ++/* ++ * ======== WMD_IO_Create ======== ++ * Purpose: ++ * Create an object that manages I/O between CHNL and MSG. ++ * Parameters: ++ * phIOMgr: Location to store IO manager on output. ++ * hChnlMgr: Handle to channel manager. ++ * hMsgMgr: Handle to message manager. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Memory allocation failure. ++ * DSP_EFAIL: Creation failed. ++ * Requires: ++ * hDevObject != NULL; ++ * Channel manager already created; ++ * Message manager already created; ++ * pMgrAttrs != NULL; ++ * phIOMgr != NULL; ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*WMD_IO_CREATE) (OUT struct IO_MGR **phIOMgr, ++ struct DEV_OBJECT *hDevObject, ++ IN CONST struct IO_ATTRS *pMgrAttrs); ++ ++/* ++ * ======== WMD_IO_Destroy ======== ++ * Purpose: ++ * Destroy object created in WMD_IO_Create. ++ * Parameters: ++ * hIOMgr: IO Manager. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Memory allocation failure. ++ * DSP_EFAIL: Creation failed. ++ * Requires: ++ * Valid hIOMgr; ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*WMD_IO_DESTROY) (struct IO_MGR *hIOMgr); ++ ++/* ++ * ======== WMD_IO_OnLoaded ======== ++ * Purpose: ++ * Called whenever a program is loaded to update internal data. For ++ * example, if shared memory is used, this function would update the ++ * shared memory location and address. ++ * Parameters: ++ * hIOMgr: IO Manager. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Internal failure occurred. ++ * Requires: ++ * Valid hIOMgr; ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*WMD_IO_ONLOADED) (struct IO_MGR *hIOMgr); ++ ++/* ++ * ======== WMD_IO_GETPROCLOAD ======== ++ * Purpose: ++ * Called to get the Processor's current and predicted load ++ * Parameters: ++ * hIOMgr: IO Manager. ++ * pProcLoadStat Processor Load statistics ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EFAIL: Internal failure occurred. ++ * Requires: ++ * Valid hIOMgr; ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*WMD_IO_GETPROCLOAD)(struct IO_MGR *hIOMgr, ++ struct DSP_PROCLOADSTAT *pProcLoadStat); ++ ++/* ++ * ======== WMD_MSG_Create ======== ++ * Purpose: ++ * Create an object to manage message queues. Only one of these objects ++ * can exist per device object. ++ * Parameters: ++ * phMsgMgr: Location to store MSG manager on output. ++ * hDevObject: Handle to a device object. ++ * msgCallback: Called whenever an RMS_EXIT message is received. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Insufficient memory. ++ * Requires: ++ * phMsgMgr != NULL. ++ * msgCallback != NULL. ++ * hDevObject != NULL. ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*WMD_MSG_CREATE) ++ (OUT struct MSG_MGR **phMsgMgr, ++ struct DEV_OBJECT *hDevObject, ++ MSG_ONEXIT msgCallback); ++ ++/* ++ * ======== WMD_MSG_CreateQueue ======== ++ * Purpose: ++ * Create a MSG queue for sending or receiving messages from a Message ++ * node on the DSP. ++ * Parameters: ++ * hMsgMgr: MSG queue manager handle returned from ++ * WMD_MSG_Create. ++ * phMsgQueue: Location to store MSG queue on output. ++ * dwId: Identifier for messages (node environment pointer). ++ * uMaxMsgs: Max number of simultaneous messages for the node. ++ * h: Handle passed to hMsgMgr->msgCallback(). ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Insufficient memory. ++ * Requires: ++ * phMsgQueue != NULL. ++ * h != NULL. ++ * uMaxMsgs > 0. ++ * Ensures: ++ * phMsgQueue !=NULL <==> DSP_SOK. ++ */ ++ typedef DSP_STATUS(*WMD_MSG_CREATEQUEUE) ++ (struct MSG_MGR *hMsgMgr, ++ OUT struct MSG_QUEUE **phMsgQueue, ++ u32 dwId, u32 uMaxMsgs, HANDLE h); ++ ++/* ++ * ======== WMD_MSG_Delete ======== ++ * Purpose: ++ * Delete a MSG manager allocated in WMD_MSG_Create(). ++ * Parameters: ++ * hMsgMgr: Handle returned from WMD_MSG_Create(). ++ * Returns: ++ * Requires: ++ * Valid hMsgMgr. ++ * Ensures: ++ */ ++ typedef void(*WMD_MSG_DELETE) (struct MSG_MGR *hMsgMgr); ++ ++/* ++ * ======== WMD_MSG_DeleteQueue ======== ++ * Purpose: ++ * Delete a MSG queue allocated in WMD_MSG_CreateQueue. ++ * Parameters: ++ * hMsgQueue: Handle to MSG queue returned from ++ * WMD_MSG_CreateQueue. ++ * Returns: ++ * Requires: ++ * Valid hMsgQueue. ++ * Ensures: ++ */ ++ typedef void(*WMD_MSG_DELETEQUEUE) (struct MSG_QUEUE *hMsgQueue); ++ ++/* ++ * ======== WMD_MSG_Get ======== ++ * Purpose: ++ * Get a message from a MSG queue. ++ * Parameters: ++ * hMsgQueue: Handle to MSG queue returned from ++ * WMD_MSG_CreateQueue. ++ * pMsg: Location to copy message into. ++ * uTimeout: Timeout to wait for a message. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_ETIMEOUT: Timeout occurred. ++ * DSP_EFAIL: No frames available for message (uMaxMessages too ++ * small). ++ * Requires: ++ * Valid hMsgQueue. ++ * pMsg != NULL. ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*WMD_MSG_GET) (struct MSG_QUEUE *hMsgQueue, ++ struct DSP_MSG *pMsg, ++ u32 uTimeout); ++ ++/* ++ * ======== WMD_MSG_Put ======== ++ * Purpose: ++ * Put a message onto a MSG queue. ++ * Parameters: ++ * hMsgQueue: Handle to MSG queue returned from ++ * WMD_MSG_CreateQueue. ++ * pMsg: Pointer to message. ++ * uTimeout: Timeout to wait for a message. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_ETIMEOUT: Timeout occurred. ++ * DSP_EFAIL: No frames available for message (uMaxMessages too ++ * small). ++ * Requires: ++ * Valid hMsgQueue. ++ * pMsg != NULL. ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*WMD_MSG_PUT) (struct MSG_QUEUE *hMsgQueue, ++ IN CONST struct DSP_MSG *pMsg, ++ u32 uTimeout); ++ ++/* ++ * ======== WMD_MSG_RegisterNotify ======== ++ * Purpose: ++ * Register notification for when a message is ready. ++ * Parameters: ++ * hMsgQueue: Handle to MSG queue returned from ++ * WMD_MSG_CreateQueue. ++ * uEventMask: Type of events to be notified about: Must be ++ * DSP_NODEMESSAGEREADY, or 0 to unregister. ++ * uNotifyType: DSP_SIGNALEVENT. ++ * hNotification: Handle of notification object. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Insufficient memory. ++ * Requires: ++ * Valid hMsgQueue. ++ * hNotification != NULL. ++ * uNotifyType == DSP_SIGNALEVENT. ++ * uEventMask == DSP_NODEMESSAGEREADY || uEventMask == 0. ++ * Ensures: ++ */ ++ typedef DSP_STATUS(*WMD_MSG_REGISTERNOTIFY) ++ (struct MSG_QUEUE *hMsgQueue, ++ u32 uEventMask, u32 uNotifyType, ++ struct DSP_NOTIFICATION *hNotification); ++ ++/* ++ * ======== WMD_MSG_SetQueueId ======== ++ * Purpose: ++ * Set message queue id to node environment. Allows WMD_MSG_CreateQueue ++ * to be called in NODE_Allocate, before the node environment is known. ++ * Parameters: ++ * hMsgQueue: Handle to MSG queue returned from ++ * WMD_MSG_CreateQueue. ++ * dwId: Node environment pointer. ++ * Returns: ++ * Requires: ++ * Valid hMsgQueue. ++ * dwId != 0. ++ * Ensures: ++ */ ++ typedef void(*WMD_MSG_SETQUEUEID) (struct MSG_QUEUE *hMsgQueue, ++ u32 dwId); ++ ++/* ++ * 'Bridge Mini Driver (WMD) interface function table. ++ * ++ * The information in this table is filled in by the specific mini-driver, ++ * and copied into the 'Bridge class driver's own space. If any interface ++ * function field is set to a value of NULL, then the class driver will ++ * consider that function not implemented, and return the error code ++ * DSP_ENOTIMPL when a WMD client attempts to call that function. ++ * ++ * This function table contains WCD version numbers, which are used by the ++ * WMD loader to help ensure backwards compatility between older WMD's and a ++ * newer 'Bridge Class Driver. These must be set to WCD_MAJOR_VERSION ++ * and WCD_MINOR_VERSION, respectively. ++ * ++ * A mini-driver need not export a CHNL interface. In this case, *all* of ++ * the WMD_CHNL_* entries must be set to NULL. ++ */ ++ struct WMD_DRV_INTERFACE { ++ u32 dwWCDMajorVersion; /* Set to WCD_MAJOR_VERSION. */ ++ u32 dwWCDMinorVersion; /* Set to WCD_MINOR_VERSION. */ ++ WMD_DEV_CREATE pfnDevCreate; /* Create device context */ ++ WMD_DEV_DESTROY pfnDevDestroy; /* Destroy device context */ ++ WMD_DEV_CTRL pfnDevCntrl; /* Optional vendor interface */ ++ WMD_BRD_MONITOR pfnBrdMonitor; /* Load and/or start monitor */ ++ WMD_BRD_START pfnBrdStart; /* Start DSP program. */ ++ WMD_BRD_STOP pfnBrdStop; /* Stop/reset board. */ ++ WMD_BRD_STATUS pfnBrdStatus; /* Get current board status. */ ++ WMD_BRD_READ pfnBrdRead; /* Read board memory */ ++ WMD_BRD_WRITE pfnBrdWrite; /* Write board memory. */ ++ WMD_BRD_SETSTATE pfnBrdSetState; /* Sets the Board State */ ++ WMD_BRD_MEMCOPY pfnBrdMemCopy; /* Copies DSP Memory */ ++ WMD_BRD_MEMWRITE pfnBrdMemWrite; /* Write DSP Memory w/o halt */ ++ WMD_BRD_MEMMAP pfnBrdMemMap; /* Maps MPU mem to DSP mem */ ++ WMD_BRD_MEMUNMAP pfnBrdMemUnMap; /* Unmaps MPU mem to DSP mem */ ++ WMD_CHNL_CREATE pfnChnlCreate; /* Create channel manager. */ ++ WMD_CHNL_DESTROY pfnChnlDestroy; /* Destroy channel manager. */ ++ WMD_CHNL_OPEN pfnChnlOpen; /* Create a new channel. */ ++ WMD_CHNL_CLOSE pfnChnlClose; /* Close a channel. */ ++ WMD_CHNL_ADDIOREQ pfnChnlAddIOReq; /* Req I/O on a channel. */ ++ WMD_CHNL_GETIOC pfnChnlGetIOC; /* Wait for I/O completion. */ ++ WMD_CHNL_CANCELIO pfnChnlCancelIO; /* Cancl I/O on a channel. */ ++ WMD_CHNL_FLUSHIO pfnChnlFlushIO; /* Flush I/O. */ ++ WMD_CHNL_GETINFO pfnChnlGetInfo; /* Get channel specific info */ ++ /* Get channel manager info. */ ++ WMD_CHNL_GETMGRINFO pfnChnlGetMgrInfo; ++ WMD_CHNL_IDLE pfnChnlIdle; /* Idle the channel */ ++ /* Register for notif. */ ++ WMD_CHNL_REGISTERNOTIFY pfnChnlRegisterNotify; ++ WMD_DEH_CREATE pfnDehCreate; /* Create DEH manager */ ++ WMD_DEH_DESTROY pfnDehDestroy; /* Destroy DEH manager */ ++ WMD_DEH_NOTIFY pfnDehNotify; /* Notify of DSP error */ ++ /* register for deh notif. */ ++ WMD_DEH_REGISTERNOTIFY pfnDehRegisterNotify; ++ WMD_DEH_GETINFO pfnDehGetInfo; /* register for deh notif. */ ++ WMD_IO_CREATE pfnIOCreate; /* Create IO manager */ ++ WMD_IO_DESTROY pfnIODestroy; /* Destroy IO manager */ ++ WMD_IO_ONLOADED pfnIOOnLoaded; /* Notify of program loaded */ ++ /* Get Processor's current and predicted load */ ++ WMD_IO_GETPROCLOAD pfnIOGetProcLoad; ++ WMD_MSG_CREATE pfnMsgCreate; /* Create message manager */ ++ /* Create message queue */ ++ WMD_MSG_CREATEQUEUE pfnMsgCreateQueue; ++ WMD_MSG_DELETE pfnMsgDelete; /* Delete message manager */ ++ /* Delete message queue */ ++ WMD_MSG_DELETEQUEUE pfnMsgDeleteQueue; ++ WMD_MSG_GET pfnMsgGet; /* Get a message */ ++ WMD_MSG_PUT pfnMsgPut; /* Send a message */ ++ /* Register for notif. */ ++ WMD_MSG_REGISTERNOTIFY pfnMsgRegisterNotify; ++ /* Set message queue id */ ++ WMD_MSG_SETQUEUEID pfnMsgSetQueueId; ++ } ; ++ ++/* ++ * ======== WMD_DRV_Entry ======== ++ * Purpose: ++ * Registers WMD functions with the class driver. Called only once ++ * by the WCD. The caller will first check WCD version compatibility, and ++ * then copy the interface functions into its own memory space. ++ * Parameters: ++ * ppDrvInterface Pointer to a location to receive a pointer to the ++ * mini driver interface. ++ * Returns: ++ * Requires: ++ * The code segment this function resides in must expect to be discarded ++ * after completion. ++ * Ensures: ++ * ppDrvInterface pointer initialized to WMD's function interface. ++ * No system resources are acquired by this function. ++ * Details: ++ * Win95: Called during the Device_Init phase. ++ */ ++ void WMD_DRV_Entry(OUT struct WMD_DRV_INTERFACE **ppDrvInterface, ++ IN CONST char *pstrWMDFileName); ++ ++#endif /* WMD_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/wmdchnl.h b/arch/arm/plat-omap/include/dspbridge/wmdchnl.h +new file mode 100644 +index 0000000..2c1f072 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/wmdchnl.h +@@ -0,0 +1,90 @@ ++/* ++ * wmdchnl.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== wmdchnl.h ======== ++ * Description: ++ * Declares the upper edge channel class library functions required by ++ * all WMD / WCD driver interface tables. These functions are implemented ++ * by every class of WMD channel library. ++ * ++ * Public Functions: ++ * ++ * Notes: ++ * The function comment headers reside with the function typedefs in wmd.h. ++ * ++ *! Revision History: ++ *! ================ ++ *! 07-Jan-2002 ag Added cBufSize to WMD_CHNL_AddIOReq(). ++ *! 13-Oct-2000 jeh Added dwArg parameter to WMD_CHNL_AddIOReq(), added ++ *! WMD_CHNL_Idle and WMD_CHNL_RegisterNotify for DSPStream ++ *! support. ++ *! 11-Jul-1996 gp: Created. ++ */ ++ ++#ifndef WMDCHNL_ ++#define WMDCHNL_ ++ ++ extern DSP_STATUS WMD_CHNL_Create(OUT struct CHNL_MGR **phChnlMgr, ++ struct DEV_OBJECT *hDevObject, ++ IN CONST struct CHNL_MGRATTRS ++ *pMgrAttrs); ++ ++ extern DSP_STATUS WMD_CHNL_Destroy(struct CHNL_MGR *hChnlMgr); ++ ++ extern DSP_STATUS WMD_CHNL_Open(OUT struct CHNL_OBJECT **phChnl, ++ struct CHNL_MGR *hChnlMgr, ++ CHNL_MODE uMode, ++ u32 uChnlId, ++ CONST IN OPTIONAL struct CHNL_ATTRS ++ *pAttrs); ++ ++ extern DSP_STATUS WMD_CHNL_Close(struct CHNL_OBJECT *hChnl); ++ ++ extern DSP_STATUS WMD_CHNL_AddIOReq(struct CHNL_OBJECT *hChnl, ++ void *pHostBuf, ++ u32 cBytes, u32 cBufSize, ++ OPTIONAL u32 dwDspAddr, ++ u32 dwArg); ++ ++ extern DSP_STATUS WMD_CHNL_GetIOC(struct CHNL_OBJECT *hChnl, ++ u32 dwTimeOut, ++ OUT struct CHNL_IOC *pIOC); ++ ++ extern DSP_STATUS WMD_CHNL_CancelIO(struct CHNL_OBJECT *hChnl); ++ ++ extern DSP_STATUS WMD_CHNL_FlushIO(struct CHNL_OBJECT *hChnl, ++ u32 dwTimeOut); ++ ++ extern DSP_STATUS WMD_CHNL_GetInfo(struct CHNL_OBJECT *hChnl, ++ OUT struct CHNL_INFO *pInfo); ++ ++ extern DSP_STATUS WMD_CHNL_GetMgrInfo(struct CHNL_MGR *hChnlMgr, ++ u32 uChnlID, ++ OUT struct CHNL_MGRINFO ++ *pMgrInfo); ++ ++ extern DSP_STATUS WMD_CHNL_Idle(struct CHNL_OBJECT *hChnl, ++ u32 dwTimeOut, bool fFlush); ++ ++ extern DSP_STATUS WMD_CHNL_RegisterNotify(struct CHNL_OBJECT *hChnl, ++ u32 uEventMask, ++ u32 uNotifyType, ++ struct DSP_NOTIFICATION ++ *hNotification); ++ ++#endif /* WMDCHNL_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/wmddeh.h b/arch/arm/plat-omap/include/dspbridge/wmddeh.h +new file mode 100644 +index 0000000..dd50a3a +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/wmddeh.h +@@ -0,0 +1,64 @@ ++/* ++ * wmddeh.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== wmddeh.h ======== ++ * Description: ++ * Defines upper edge DEH functions required by all WMD/WCD driver ++ * interface tables. ++ * ++ * Public Functions: ++ * WMD_DEH_Create ++ * IVA_DEH_Create ++ * WMD_DEH_Destroy ++ * WMD_DEH_GetInfo ++ * WMD_DEH_RegisterNotify ++ * WMD_DEH_Notify ++ * ++ * Notes: ++ * Function comment headers reside with the function typedefs in wmd.h. ++ * ++ *! Revision History: ++ *! ================ ++ *! 26-Dec-2004 hn: added IVA_DEH_Create. ++ *! 13-Sep-2001 kc: created. ++ */ ++ ++#ifndef WMDDEH_ ++#define WMDDEH_ ++ ++#include ++ ++#include ++ ++ extern DSP_STATUS WMD_DEH_Create(OUT struct DEH_MGR **phDehMgr, ++ struct DEV_OBJECT *hDevObject); ++ ++ extern DSP_STATUS WMD_DEH_Destroy(struct DEH_MGR *hDehMgr); ++ ++ extern DSP_STATUS WMD_DEH_GetInfo(struct DEH_MGR *hDehMgr, ++ struct DSP_ERRORINFO *pErrInfo); ++ ++ extern DSP_STATUS WMD_DEH_RegisterNotify(struct DEH_MGR *hDehMgr, ++ u32 uEventMask, ++ u32 uNotifyType, ++ struct DSP_NOTIFICATION ++ *hNotification); ++ ++ extern void WMD_DEH_Notify(struct DEH_MGR *hDehMgr, ++ u32 ulEventMask, u32 dwErrInfo); ++#endif /* WMDDEH_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/wmdio.h b/arch/arm/plat-omap/include/dspbridge/wmdio.h +new file mode 100644 +index 0000000..8525474 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/wmdio.h +@@ -0,0 +1,53 @@ ++/* ++ * wmdio.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== wmdio.h ======== ++ * Description: ++ * Declares the upper edge IO functions required by ++ * all WMD / WCD driver interface tables. ++ * ++ * Public Functions: ++ * ++ * Notes: ++ * Function comment headers reside with the function typedefs in wmd.h. ++ * ++ *! Revision History: ++ *! ================ ++ *! 27-Feb-2004 vp Added IVA releated function. ++ *! 06-Nov-2000 jeh Created. ++ */ ++ ++#ifndef WMDIO_ ++#define WMDIO_ ++ ++#include ++#include ++ ++ extern DSP_STATUS WMD_IO_Create(OUT struct IO_MGR **phIOMgr, ++ struct DEV_OBJECT *hDevObject, ++ IN CONST struct IO_ATTRS *pMgrAttrs); ++ ++ extern DSP_STATUS WMD_IO_Destroy(struct IO_MGR *hIOMgr); ++ ++ extern DSP_STATUS WMD_IO_OnLoaded(struct IO_MGR *hIOMgr); ++ ++ extern DSP_STATUS IVA_IO_OnLoaded(struct IO_MGR *hIOMgr); ++ extern DSP_STATUS WMD_IO_GetProcLoad(IN struct IO_MGR *hIOMgr, ++ OUT struct DSP_PROCLOADSTAT *pProcStat); ++ ++#endif /* WMDIO_ */ +diff --git a/arch/arm/plat-omap/include/dspbridge/wmdioctl.h b/arch/arm/plat-omap/include/dspbridge/wmdioctl.h +new file mode 100644 +index 0000000..a41c61a +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/wmdioctl.h +@@ -0,0 +1,91 @@ ++/* ++ * wmdioctl.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== wmdioctl.h ======== ++ * Description: ++ * BRIDGE Minidriver BRD_IOCtl reserved command definitions. ++ * ++ *! Revision History ++ *! ================ ++ *! 19-Apr-2004 sb Updated HW typedefs ++ *! 16-Feb-2004 vp Added MMU endianness attributes to WMDIOCTL_EXTPROC ++ *! 21-Mar-2003 sb Changed WMDIOCTL_NUMOFMMUTLB from 7 to 32 ++ *! 14-May-2001 sg Added codes for PWR. ++ *! 10-Aug-2001 ag Added _SETMMUCONFIG ioctl used for DSP-MMU init. ++ *! 16-Nov-1999 rajesh ? ++ *! 18-Jun-1998 ag Moved EMIF, SDRAM_C, & CE space init to ENBLEXTMEM ioctl. ++ *! Added ENBLEXTMEM, RESETDSP, UNRESETDSP & ASSERTSIG ioctls. ++ *! 07-Jun-1998 ag Added JTAG_SELECT, MAP_TBC, GET_CONFIGURATION ioctls. ++ *! 26-Jan-1998 jeh: Added START, RECV, and SEND ioctls. ++ *! 07-Nov-1997 nn: Added command to interrupt DSP for interrupt test. ++ *! 20-Oct-1997 nn: Added commands for getting and resetting interrupt count. ++ *! 17-Oct-1997 gp: Moved to src/wmd. Standardized prefix. ++ *! 08-Oct-1997 nn: Created. ++ */ ++ ++#ifndef WMDIOCTL_ ++#define WMDIOCTL_ ++ ++/* ------------------------------------ Hardware Abstraction Layer */ ++#include ++#include ++ ++/* Any IOCTLS at or above this value are reserved for standard WMD interfaces.*/ ++#define WMDIOCTL_RESERVEDBASE 0x8000 ++ ++#define WMDIOCTL_CHNLREAD (WMDIOCTL_RESERVEDBASE + 0x10) ++#define WMDIOCTL_CHNLWRITE (WMDIOCTL_RESERVEDBASE + 0x20) ++#define WMDIOCTL_GETINTRCOUNT (WMDIOCTL_RESERVEDBASE + 0x30) ++#define WMDIOCTL_RESETINTRCOUNT (WMDIOCTL_RESERVEDBASE + 0x40) ++#define WMDIOCTL_INTERRUPTDSP (WMDIOCTL_RESERVEDBASE + 0x50) ++#define WMDIOCTL_SETMMUCONFIG (WMDIOCTL_RESERVEDBASE + 0x60) /* DMMU */ ++#define WMDIOCTL_PWRCONTROL (WMDIOCTL_RESERVEDBASE + 0x70) /* PWR */ ++ ++/* attention, modifiers: ++ * Some of these control enumerations are made visible to user for power ++ * control, so any changes to this list, should also be updated in the user ++ * header file 'dbdefs.h' ***/ ++/* These ioctls are reserved for PWR power commands for the DSP */ ++#define WMDIOCTL_DEEPSLEEP (WMDIOCTL_PWRCONTROL + 0x0) ++#define WMDIOCTL_EMERGENCYSLEEP (WMDIOCTL_PWRCONTROL + 0x1) ++#define WMDIOCTL_WAKEUP (WMDIOCTL_PWRCONTROL + 0x2) ++#define WMDIOCTL_PWRENABLE (WMDIOCTL_PWRCONTROL + 0x3) ++#define WMDIOCTL_PWRDISABLE (WMDIOCTL_PWRCONTROL + 0x4) ++#define WMDIOCTL_CLK_CTRL (WMDIOCTL_PWRCONTROL + 0x7) ++#define WMDIOCTL_PWR_HIBERNATE (WMDIOCTL_PWRCONTROL + 0x8) /*DSP Initiated ++ * Hibernate*/ ++#define WMDIOCTL_PRESCALE_NOTIFY (WMDIOCTL_PWRCONTROL + 0x9) ++#define WMDIOCTL_POSTSCALE_NOTIFY (WMDIOCTL_PWRCONTROL + 0xA) ++#define WMDIOCTL_CONSTRAINT_REQUEST (WMDIOCTL_PWRCONTROL + 0xB) ++ ++/* Number of actual DSP-MMU TLB entrries */ ++#define WMDIOCTL_NUMOFMMUTLB 32 ++ ++struct WMDIOCTL_EXTPROC { ++ u32 ulDspVa; /* DSP virtual address */ ++ u32 ulGppPa; /* GPP physical address */ ++ /* GPP virtual address. __va does not work for ioremapped addresses */ ++ u32 ulGppVa; ++ u32 ulSize; /* Size of the mapped memory in bytes */ ++ enum HW_Endianism_t endianism; ++ enum HW_MMUMixedSize_t mixedMode; ++ enum HW_ElementSize_t elemSize; ++}; ++ ++#endif /* WMDIOCTL_ */ ++ +diff --git a/arch/arm/plat-omap/include/dspbridge/wmdmsg.h b/arch/arm/plat-omap/include/dspbridge/wmdmsg.h +new file mode 100644 +index 0000000..81198d4 +--- /dev/null ++++ b/arch/arm/plat-omap/include/dspbridge/wmdmsg.h +@@ -0,0 +1,70 @@ ++/* ++ * wmdmsg.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== wmdmsg.h ======== ++ * Description: ++ * Declares the upper edge message class library functions required by ++ * all WMD / WCD driver interface tables. These functions are ++ * implemented by every class of WMD channel library. ++ * ++ * Public Functions: ++ * ++ * Notes: ++ * Function comment headers reside with the function typedefs in wmd.h. ++ * ++ *! Revision History: ++ *! ================ ++ *! 06-Dec-2000 jeh Added uEventMask to WMD_MSG_RegisterNotify(). Added ++ *! WMD_MSG_SetQueueId(). ++ *! 17-Nov-2000 jeh Created. ++ */ ++ ++#ifndef WMDMSG_ ++#define WMDMSG_ ++ ++#include ++ ++ extern DSP_STATUS WMD_MSG_Create(OUT struct MSG_MGR **phMsgMgr, ++ struct DEV_OBJECT *hDevObject, ++ MSG_ONEXIT msgCallback); ++ ++ extern DSP_STATUS WMD_MSG_CreateQueue(struct MSG_MGR *hMsgMgr, ++ OUT struct MSG_QUEUE **phMsgQueue, ++ u32 dwId, u32 uMaxMsgs, ++ HANDLE h); ++ ++ extern void WMD_MSG_Delete(struct MSG_MGR *hMsgMgr); ++ ++ extern void WMD_MSG_DeleteQueue(struct MSG_QUEUE *hMsgQueue); ++ ++ extern DSP_STATUS WMD_MSG_Get(struct MSG_QUEUE *hMsgQueue, ++ struct DSP_MSG *pMsg, u32 uTimeout); ++ ++ extern DSP_STATUS WMD_MSG_Put(struct MSG_QUEUE *hMsgQueue, ++ IN CONST struct DSP_MSG *pMsg, ++ u32 uTimeout); ++ ++ extern DSP_STATUS WMD_MSG_RegisterNotify(struct MSG_QUEUE *hMsgQueue, ++ u32 uEventMask, ++ u32 uNotifyType, ++ struct DSP_NOTIFICATION ++ *hNotification); ++ ++ extern void WMD_MSG_SetQueueId(struct MSG_QUEUE *hMsgQueue, u32 dwId); ++ ++#endif /* WMDMSG_ */ +diff --git a/drivers/Makefile b/drivers/Makefile +index fec4d8e..6fcee09 100644 +--- a/drivers/Makefile ++++ b/drivers/Makefile +@@ -42,6 +42,7 @@ obj-$(CONFIG_PARPORT) += parport/ + obj-y += base/ block/ misc/ mfd/ net/ media/ + obj-y += i2c/ + obj-y += cbus/ ++obj-$(CONFIG_MPU_BRIDGE) += dsp/bridge/ + obj-$(CONFIG_NUBUS) += nubus/ + obj-$(CONFIG_ATM) += atm/ + obj-y += macintosh/ +diff --git a/drivers/dsp/bridge/Kbuild b/drivers/dsp/bridge/Kbuild +new file mode 100644 +index 0000000..3432ff2 +--- /dev/null ++++ b/drivers/dsp/bridge/Kbuild +@@ -0,0 +1,39 @@ ++obj-$(CONFIG_MPU_BRIDGE) += bridgedriver.o ++ ++libgen = gen/gb.o gen/gt.o gen/gs.o gen/gh.o gen/_gt_para.o gen/uuidutil.o ++libservices = services/csl.o services/mem.o services/list.o services/dpc.o \ ++ services/kfile.o services/sync.o \ ++ services/clk.o services/cfg.o services/reg.o \ ++ services/regsup.o services/ntfy.o \ ++ services/dbg.o services/services.o ++libwmd = wmd/chnl_sm.o wmd/msg_sm.o wmd/io_sm.o wmd/tiomap3430.o \ ++ wmd/tiomap3430_pwr.o wmd/tiomap_sm.o wmd/tiomap_io.o \ ++ wmd/mmu_fault.o wmd/ue_deh.o ++libpmgr = pmgr/chnl.o pmgr/io.o pmgr/msg.o pmgr/cod.o pmgr/dev.o pmgr/wcd.o \ ++ pmgr/dmm.o pmgr/cmm.o pmgr/dbll.o ++librmgr = rmgr/dbdcd.o rmgr/disp.o rmgr/drv.o rmgr/mgr.o rmgr/node.o \ ++ rmgr/proc.o rmgr/pwr.o rmgr/rmm.o rmgr/strm.o rmgr/dspdrv.o \ ++ rmgr/nldr.o rmgr/drv_interface.o ++libdload = dynload/cload.o dynload/getsection.o dynload/reloc.o ++libhw = hw/hw_prcm.o hw/hw_dspssC64P.o hw/hw_mmu.o hw/hw_mbox.o ++ ++bridgedriver-objs = $(libgen) $(libservices) $(libwmd) $(libpmgr) $(librmgr) \ ++ $(libdload) $(libhw) ++ ++# Debug ++ifeq ($(CONFIG_BRIDGE_DEBUG),y) ++ccflags-y += -DGT_TRACE -DDEBUG ++endif ++ ++#Machine dependent ++ccflags-y += -D_TI_ -D_DB_TIOMAP -DTMS32060 \ ++ -DTICFG_PROC_VER -DTICFG_EVM_TYPE -DCHNL_SMCLASS \ ++ -DCHNL_MESSAGES -DUSE_LEVEL_1_MACROS ++ ++#Header files ++ccflags-y += -Idrivers/dsp/bridge/services ++ccflags-y += -Idrivers/dsp/bridge/wmd ++ccflags-y += -Idrivers/dsp/bridge/pmgr ++ccflags-y += -Idrivers/dsp/bridge/rmgr ++ccflags-y += -Idrivers/dsp/bridge/hw ++ccflags-y += -Iarch/arm +diff --git a/drivers/dsp/bridge/Kconfig b/drivers/dsp/bridge/Kconfig +new file mode 100644 +index 0000000..2fed82c +--- /dev/null ++++ b/drivers/dsp/bridge/Kconfig +@@ -0,0 +1,36 @@ ++# ++# DSP Bridge Driver Support ++# ++ ++menuconfig MPU_BRIDGE ++ tristate "DSP Bridge driver" ++ default n ++ help ++ DSP/BIOS Bridge is designed for platforms that contain a GPP and ++ one or more attached DSPs. The GPP is considered the master or ++ "host" processor, and the attached DSPs are processing resources ++ that can be utilized by applications and drivers running on the GPP. ++ ++config BRIDGE_DVFS ++ bool "Enable Bridge Dynamic Voltage and Frequency Scaling (DVFS)" ++ depends on MPU_BRIDGE && OMAP_PM_SRF ++ default n ++ help ++ DVFS allows DSP Bridge to initiate the operating point change to ++ scale the chip voltage and frequency in order to match the ++ performance and power consumption to the current processing ++ requirements. ++ ++config BRIDGE_MEMPOOL_SIZE ++ hex "Physical memory pool size (Byte)" ++ depends on MPU_BRIDGE ++ default 0x600000 ++ help ++ Allocate specified size of memory at booting time to avoid allocation ++ failure under heavy memory fragmentation after some use time. ++ ++config BRIDGE_DEBUG ++ bool "DSP Bridge Debug Support" ++ depends on MPU_BRIDGE ++ help ++ Say Y to enable Bridge debugging capabilities +diff --git a/drivers/dsp/bridge/dynload/cload.c b/drivers/dsp/bridge/dynload/cload.c +new file mode 100644 +index 0000000..271ab81 +--- /dev/null ++++ b/drivers/dsp/bridge/dynload/cload.c +@@ -0,0 +1,1854 @@ ++/* ++ * cload.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++#include "header.h" ++ ++#include "module_list.h" ++#define LINKER_MODULES_HEADER ("_" MODULES_HEADER) ++ ++/* ++ * we use the fact that DOFF section records are shaped just like ++ * LDR_SECTION_INFO to reduce our section storage usage. This macro marks ++ * the places where that assumption is made ++ */ ++#define DOFFSEC_IS_LDRSEC(pdoffsec) ((struct LDR_SECTION_INFO *)(pdoffsec)) ++ ++/* ++ * forward references ++ */ ++static void dload_symbols(struct dload_state *dlthis); ++static void dload_data(struct dload_state *dlthis); ++static void allocate_sections(struct dload_state *dlthis); ++static void string_table_free(struct dload_state *dlthis); ++static void symbol_table_free(struct dload_state *dlthis); ++static void section_table_free(struct dload_state *dlthis); ++static void init_module_handle(struct dload_state *dlthis); ++#if BITS_PER_AU > BITS_PER_BYTE ++static char *unpack_name(struct dload_state *dlthis, u32 soffset); ++#endif ++ ++static const char CINITNAME[] = { ".cinit" }; ++static const char LOADER_DLLVIEW_ROOT[] = { "?DLModules?" }; ++ ++/* ++ * Error strings ++ */ ++static const char E_READSTRM[] = { "Error reading %s from input stream" }; ++static const char E_ALLOC[] = { "Syms->Allocate( %d ) failed" }; ++static const char E_TGTALLOC[] = ++ { "Target memory allocate failed, section %s size " FMT_UI32 }; ++static const char E_INITFAIL[] = { "%s to target address " FMT_UI32 " failed" }; ++static const char E_DLVWRITE[] = { "Write to DLLview list failed" }; ++static const char E_ICONNECT[] = { "Connect call to init interface failed" }; ++static const char E_CHECKSUM[] = { "Checksum failed on %s" }; ++ ++/************************************************************************* ++ * Procedure dload_error ++ * ++ * Parameters: ++ * errtxt description of the error, printf style ++ * ... additional information ++ * ++ * Effect: ++ * Reports or records the error as appropriate. ++ ************************************************************************/ ++void dload_error(struct dload_state *dlthis, const char *errtxt, ...) ++{ ++ va_list args; ++ ++ va_start(args, errtxt); ++ dlthis->mysym->Error_Report(dlthis->mysym, errtxt, args); ++ va_end(args); ++ dlthis->dload_errcount += 1; ++ ++} /* dload_error */ ++ ++#define DL_ERROR(zza, zzb) dload_error(dlthis, zza, zzb) ++ ++/************************************************************************* ++ * Procedure dload_syms_error ++ * ++ * Parameters: ++ * errtxt description of the error, printf style ++ * ... additional information ++ * ++ * Effect: ++ * Reports or records the error as appropriate. ++ ************************************************************************/ ++void dload_syms_error(struct Dynamic_Loader_Sym *syms, const char *errtxt, ...) ++{ ++ va_list args; ++ ++ va_start(args, errtxt); ++ syms->Error_Report(syms, errtxt, args); ++ va_end(args); ++} ++ ++/************************************************************************* ++ * Procedure Dynamic_Load_Module ++ * ++ * Parameters: ++ * module The input stream that supplies the module image ++ * syms Host-side symbol table and malloc/free functions ++ * alloc Target-side memory allocation ++ * init Target-side memory initialization ++ * options Option flags DLOAD_* ++ * mhandle A module handle for use with Dynamic_Unload ++ * ++ * Effect: ++ * The module image is read using *module. Target storage for the new ++ * image is ++ * obtained from *alloc. Symbols defined and referenced by the module are ++ * managed using *syms. The image is then relocated and references ++ * resolved as necessary, and the resulting executable bits are placed ++ * into target memory using *init. ++ * ++ * Returns: ++ * On a successful load, a module handle is placed in *mhandle, ++ * and zero is returned. On error, the number of errors detected is ++ * returned. Individual errors are reported during the load process ++ * using syms->Error_Report(). ++ ***********************************************************************/ ++int Dynamic_Load_Module(struct Dynamic_Loader_Stream *module, ++ struct Dynamic_Loader_Sym *syms , ++ struct Dynamic_Loader_Allocate *alloc, ++ struct Dynamic_Loader_Initialize *init, ++ unsigned options, DLOAD_mhandle *mhandle) ++{ ++ register unsigned *dp, sz; ++ struct dload_state dl_state; /* internal state for this call */ ++ ++ /* blast our internal state */ ++ dp = (unsigned *)&dl_state; ++ for (sz = sizeof(dl_state) / sizeof(unsigned); sz > 0; sz -= 1) ++ *dp++ = 0; ++ ++ /* Enable _only_ BSS initialization if enabled by user */ ++ if ((options & DLOAD_INITBSS) == DLOAD_INITBSS) ++ dl_state.myoptions = DLOAD_INITBSS; ++ ++ /* Check that mandatory arguments are present */ ++ if (!module || !syms) { ++ dload_error(&dl_state, "Required parameter is NULL"); ++ } else { ++ dl_state.strm = module; ++ dl_state.mysym = syms; ++ dload_headers(&dl_state); ++ if (!dl_state.dload_errcount) ++ dload_strings(&dl_state, false); ++ if (!dl_state.dload_errcount) ++ dload_sections(&dl_state); ++ ++ if (init && !dl_state.dload_errcount) { ++ if (init->connect(init)) { ++ dl_state.myio = init; ++ dl_state.myalloc = alloc; ++ /* do now, before reducing symbols */ ++ allocate_sections(&dl_state); ++ } else ++ dload_error(&dl_state, E_ICONNECT); ++ } ++ ++ if (!dl_state.dload_errcount) { ++ /* fix up entry point address */ ++ unsigned sref = dl_state.dfile_hdr.df_entry_secn - 1; ++ if (sref < dl_state.allocated_secn_count) ++ dl_state.dfile_hdr.df_entrypt += ++ dl_state.ldr_sections[sref].run_addr; ++ ++ dload_symbols(&dl_state); ++ } ++ ++ if (init && !dl_state.dload_errcount) ++ dload_data(&dl_state); ++ ++ init_module_handle(&dl_state); ++ ++ if (dl_state.myio) { ++ if ((!dl_state.dload_errcount) && ++ (dl_state.dfile_hdr.df_entry_secn != DN_UNDEF)) { ++ if (init != NULL) { ++ if (!init->execute(init, ++ dl_state.dfile_hdr.df_entrypt)) ++ dload_error(&dl_state, ++ "Init->Execute Failed"); ++ } else { ++ dload_error(&dl_state, "init is NULL"); ++ } ++ } ++ init->release(init); ++ } ++ ++ symbol_table_free(&dl_state); ++ section_table_free(&dl_state); ++ string_table_free(&dl_state); ++ ++ if (dl_state.dload_errcount) { ++ Dynamic_Unload_Module(dl_state.myhandle, syms, alloc, ++ init); ++ dl_state.myhandle = NULL; ++ } ++ } ++ ++ if (mhandle) ++ *mhandle = dl_state.myhandle; /* give back the handle */ ++ ++ return dl_state.dload_errcount; ++} /* DLOAD_File */ ++ ++/************************************************************************* ++ * Procedure Dynamic_Open_Module ++ * ++ * Parameters: ++ * module The input stream that supplies the module image ++ * syms Host-side symbol table and malloc/free functions ++ * alloc Target-side memory allocation ++ * init Target-side memory initialization ++ * options Option flags DLOAD_* ++ * mhandle A module handle for use with Dynamic_Unload ++ * ++ * Effect: ++ * The module image is read using *module. Target storage for the new ++ * image is ++ * obtained from *alloc. Symbols defined and referenced by the module are ++ * managed using *syms. The image is then relocated and references ++ * resolved as necessary, and the resulting executable bits are placed ++ * into target memory using *init. ++ * ++ * Returns: ++ * On a successful load, a module handle is placed in *mhandle, ++ * and zero is returned. On error, the number of errors detected is ++ * returned. Individual errors are reported during the load process ++ * using syms->Error_Report(). ++ ***********************************************************************/ ++int ++Dynamic_Open_Module(struct Dynamic_Loader_Stream *module, ++ struct Dynamic_Loader_Sym *syms, ++ struct Dynamic_Loader_Allocate *alloc, ++ struct Dynamic_Loader_Initialize *init, ++ unsigned options, DLOAD_mhandle *mhandle) ++{ ++ register unsigned *dp, sz; ++ struct dload_state dl_state; /* internal state for this call */ ++ ++ /* blast our internal state */ ++ dp = (unsigned *)&dl_state; ++ for (sz = sizeof(dl_state) / sizeof(unsigned); sz > 0; sz -= 1) ++ *dp++ = 0; ++ ++ /* Enable _only_ BSS initialization if enabled by user */ ++ if ((options & DLOAD_INITBSS) == DLOAD_INITBSS) ++ dl_state.myoptions = DLOAD_INITBSS; ++ ++ /* Check that mandatory arguments are present */ ++ if (!module || !syms) { ++ dload_error(&dl_state, "Required parameter is NULL"); ++ } else { ++ dl_state.strm = module; ++ dl_state.mysym = syms; ++ dload_headers(&dl_state); ++ if (!dl_state.dload_errcount) ++ dload_strings(&dl_state, false); ++ if (!dl_state.dload_errcount) ++ dload_sections(&dl_state); ++ ++ if (init && !dl_state.dload_errcount) { ++ if (init->connect(init)) { ++ dl_state.myio = init; ++ dl_state.myalloc = alloc; ++ /* do now, before reducing symbols */ ++ allocate_sections(&dl_state); ++ } else ++ dload_error(&dl_state, E_ICONNECT); ++ } ++ ++ if (!dl_state.dload_errcount) { ++ /* fix up entry point address */ ++ unsigned sref = dl_state.dfile_hdr.df_entry_secn - 1; ++ if (sref < dl_state.allocated_secn_count) ++ dl_state.dfile_hdr.df_entrypt += ++ dl_state.ldr_sections[sref].run_addr; ++ ++ dload_symbols(&dl_state); ++ } ++ ++ init_module_handle(&dl_state); ++ ++ if (dl_state.myio) { ++ if ((!dl_state.dload_errcount) ++ && (dl_state.dfile_hdr.df_entry_secn != DN_UNDEF)) ++ if (!init->execute(init, ++ dl_state.dfile_hdr.df_entrypt)) ++ dload_error(&dl_state, ++ "Init->Execute Failed"); ++ init->release(init); ++ } ++ ++ symbol_table_free(&dl_state); ++ section_table_free(&dl_state); ++ string_table_free(&dl_state); ++ ++ if (dl_state.dload_errcount) { ++ Dynamic_Unload_Module(dl_state.myhandle, syms, alloc, ++ init); ++ dl_state.myhandle = NULL; ++ } ++ } ++ ++ if (mhandle) ++ *mhandle = dl_state.myhandle; /* give back the handle */ ++ ++ return dl_state.dload_errcount; ++} /* DLOAD_File */ ++ ++/************************************************************************* ++ * Procedure dload_headers ++ * ++ * Parameters: ++ * none ++ * ++ * Effect: ++ * Loads the DOFF header and verify record. Deals with any byte-order ++ * issues and checks them for validity. ++ ************************************************************************/ ++#define COMBINED_HEADER_SIZE (sizeof(struct doff_filehdr_t)+ \ ++ sizeof(struct doff_verify_rec_t)) ++ ++void dload_headers(struct dload_state *dlthis) ++{ ++ u32 map; ++ ++ /* Read the header and the verify record as one. If we don't get it ++ all, we're done */ ++ if (dlthis->strm->read_buffer(dlthis->strm, &dlthis->dfile_hdr, ++ COMBINED_HEADER_SIZE) != COMBINED_HEADER_SIZE) { ++ DL_ERROR(E_READSTRM, "File Headers"); ++ return; ++ } ++ /* ++ * Verify that we have the byte order of the file correct. ++ * If not, must fix it before we can continue ++ */ ++ map = REORDER_MAP(dlthis->dfile_hdr.df_byte_reshuffle); ++ if (map != REORDER_MAP(BYTE_RESHUFFLE_VALUE)) { ++ /* input is either byte-shuffled or bad */ ++ if ((map & 0xFCFCFCFC) == 0) { /* no obviously bogus bits */ ++ dload_reorder(&dlthis->dfile_hdr, COMBINED_HEADER_SIZE, ++ map); ++ } ++ if (dlthis->dfile_hdr.df_byte_reshuffle != ++ BYTE_RESHUFFLE_VALUE) { ++ /* didn't fix the problem, the byte swap map is bad */ ++ dload_error(dlthis, ++ "Bad byte swap map " FMT_UI32 " in header", ++ dlthis->dfile_hdr.df_byte_reshuffle); ++ return; ++ } ++ dlthis->reorder_map = map; /* keep map for future use */ ++ } ++ ++ /* ++ * Verify checksum of header and verify record ++ */ ++ if (~dload_checksum(&dlthis->dfile_hdr, ++ sizeof(struct doff_filehdr_t)) || ++ ~dload_checksum(&dlthis->verify, ++ sizeof(struct doff_verify_rec_t))) { ++ DL_ERROR(E_CHECKSUM, "header or verify record"); ++ return; ++ } ++#if HOST_ENDIANNESS ++ dlthis->dfile_hdr.df_byte_reshuffle = map; /* put back for later */ ++#endif ++ ++ /* Check for valid target ID */ ++ if ((dlthis->dfile_hdr.df_target_id != TARGET_ID) && ++ -(dlthis->dfile_hdr.df_target_id != TMS470_ID)) { ++ dload_error(dlthis, "Bad target ID 0x%x and TARGET_ID 0x%x", ++ dlthis->dfile_hdr.df_target_id, TARGET_ID); ++ return; ++ } ++ /* Check for valid file format */ ++ if ((dlthis->dfile_hdr.df_doff_version != DOFF0)) { ++ dload_error(dlthis, "Bad DOFF version 0x%x", ++ dlthis->dfile_hdr.df_doff_version); ++ return; ++ } ++ ++ /* ++ * Apply reasonableness checks to count fields ++ */ ++ if (dlthis->dfile_hdr.df_strtab_size > MAX_REASONABLE_STRINGTAB) { ++ dload_error(dlthis, "Excessive string table size " FMT_UI32, ++ dlthis->dfile_hdr.df_strtab_size); ++ return; ++ } ++ if (dlthis->dfile_hdr.df_no_scns > MAX_REASONABLE_SECTIONS) { ++ dload_error(dlthis, "Excessive section count 0x%x", ++ dlthis->dfile_hdr.df_no_scns); ++ return; ++ } ++#ifndef TARGET_ENDIANNESS ++ /* ++ * Check that endianness does not disagree with explicit specification ++ */ ++ if ((dlthis->dfile_hdr.df_flags >> ALIGN_COFF_ENDIANNESS) & ++ dlthis->myoptions & ENDIANNESS_MASK) { ++ dload_error(dlthis, ++ "Input endianness disagrees with specified option"); ++ return; ++ } ++ dlthis->big_e_target = dlthis->dfile_hdr.df_flags & DF_BIG; ++#endif ++ ++} /* dload_headers */ ++ ++/* COFF Section Processing ++ * ++ * COFF sections are read in and retained intact. Each record is embedded ++ * in a new structure that records the updated load and ++ * run addresses of the section */ ++ ++static const char SECN_ERRID[] = { "section" }; ++ ++/************************************************************************* ++ * Procedure dload_sections ++ * ++ * Parameters: ++ * none ++ * ++ * Effect: ++ * Loads the section records into an internal table. ++ ************************************************************************/ ++void ++dload_sections(struct dload_state *dlthis) ++{ ++ s16 siz; ++ struct doff_scnhdr_t *shp; ++ unsigned nsecs = dlthis->dfile_hdr.df_no_scns; ++ ++ /* allocate space for the DOFF section records */ ++ siz = nsecs * sizeof(struct doff_scnhdr_t); ++ shp = (struct doff_scnhdr_t *)dlthis->mysym->Allocate(dlthis->mysym, ++ siz); ++ if (!shp) { /* not enough storage */ ++ DL_ERROR(E_ALLOC, siz); ++ return; ++ } ++ dlthis->sect_hdrs = shp; ++ ++ /* read in the section records */ ++ if (dlthis->strm->read_buffer(dlthis->strm, shp, siz) != siz) { ++ DL_ERROR(E_READSTRM, SECN_ERRID); ++ return; ++ } ++ ++ /* if we need to fix up byte order, do it now */ ++ if (dlthis->reorder_map) ++ dload_reorder(shp, siz, dlthis->reorder_map); ++ ++ /* check for validity */ ++ if (~dload_checksum(dlthis->sect_hdrs, siz) != ++ dlthis->verify.dv_scn_rec_checksum) { ++ DL_ERROR(E_CHECKSUM, SECN_ERRID); ++ return; ++ } ++ ++} /* dload_sections */ ++ ++/***************************************************************************** ++ * Procedure allocate_sections ++ * ++ * Parameters: ++ * alloc target memory allocator class ++ * ++ * Effect: ++ * Assigns new (target) addresses for sections ++ *****************************************************************************/ ++static void allocate_sections(struct dload_state *dlthis) ++{ ++ u16 curr_sect, nsecs, siz; ++ struct doff_scnhdr_t *shp; ++ struct LDR_SECTION_INFO *asecs; ++ struct my_handle *hndl; ++ nsecs = dlthis->dfile_hdr.df_no_scns; ++ if (!nsecs) ++ return; ++ if ((dlthis->myalloc == NULL) && ++ (dlthis->dfile_hdr.df_target_scns > 0)) { ++ DL_ERROR("Arg 3 (alloc) required but NULL", 0); ++ return; ++ } ++ /* allocate space for the module handle, which we will ++ * keep for unload purposes */ ++ siz = dlthis->dfile_hdr.df_target_scns * ++ sizeof(struct LDR_SECTION_INFO) + MY_HANDLE_SIZE; ++ hndl = (struct my_handle *)dlthis->mysym->Allocate(dlthis->mysym, siz); ++ if (!hndl) { /* not enough storage */ ++ DL_ERROR(E_ALLOC, siz); ++ return; ++ } ++ /* initialize the handle header */ ++ hndl->dm.hnext = hndl->dm.hprev = hndl; /* circular list */ ++ hndl->dm.hroot = NULL; ++ hndl->dm.dbthis = 0; ++ dlthis->myhandle = hndl; /* save away for return */ ++ /* pointer to the section list of allocated sections */ ++ dlthis->ldr_sections = asecs = hndl->secns; ++ /* * Insert names into all sections, make copies of ++ the sections we allocate */ ++ shp = dlthis->sect_hdrs; ++ for (curr_sect = 0; curr_sect < nsecs; curr_sect++) { ++ u32 soffset = shp->ds_offset; ++#if BITS_PER_AU <= BITS_PER_BYTE ++ /* attempt to insert the name of this section */ ++ if (soffset < dlthis->dfile_hdr.df_strtab_size) ++ DOFFSEC_IS_LDRSEC(shp)->name = dlthis->str_head + ++ soffset; ++ else { ++ dload_error(dlthis, "Bad name offset in section %d", ++ curr_sect); ++ DOFFSEC_IS_LDRSEC(shp)->name = NULL; ++ } ++#endif ++ /* allocate target storage for sections that require it */ ++ if (DS_NEEDS_ALLOCATION(shp)) { ++ *asecs = *DOFFSEC_IS_LDRSEC(shp); ++ asecs->context = 0; /* zero the context field */ ++#if BITS_PER_AU > BITS_PER_BYTE ++ asecs->name = unpack_name(dlthis, soffset); ++ dlthis->debug_string_size = soffset + dlthis->temp_len; ++#else ++ dlthis->debug_string_size = soffset; ++#endif ++ if (dlthis->myalloc != NULL) { ++ if (!dlthis->myalloc->Allocate(dlthis->myalloc, asecs, ++ DS_ALIGNMENT(asecs->type))) { ++ dload_error(dlthis, E_TGTALLOC, asecs->name, ++ asecs->size); ++ return; ++ } ++ } ++ /* keep address deltas in original section table */ ++ shp->ds_vaddr = asecs->load_addr - shp->ds_vaddr; ++ shp->ds_paddr = asecs->run_addr - shp->ds_paddr; ++ dlthis->allocated_secn_count += 1; ++ } /* allocate target storage */ ++ shp += 1; ++ asecs += 1; ++ } ++#if BITS_PER_AU <= BITS_PER_BYTE ++ dlthis->debug_string_size += ++ strlen(dlthis->str_head + dlthis->debug_string_size) + 1; ++#endif ++} /* allocate sections */ ++ ++/************************************************************************* ++ * Procedure section_table_free ++ * ++ * Parameters: ++ * none ++ * ++ * Effect: ++ * Frees any state used by the symbol table. ++ * ++ * WARNING: ++ * This routine is not allowed to declare errors! ++ ************************************************************************/ ++static void section_table_free(struct dload_state *dlthis) ++{ ++ struct doff_scnhdr_t *shp; ++ ++ shp = dlthis->sect_hdrs; ++ if (shp) ++ dlthis->mysym->Deallocate(dlthis->mysym, shp); ++ ++} /* section_table_free */ ++ ++/************************************************************************* ++ * Procedure dload_strings ++ * ++ * Parameters: ++ * sec_names_only If true only read in the "section names" ++ * portion of the string table ++ * ++ * Effect: ++ * Loads the DOFF string table into memory. DOFF keeps all strings in a ++ * big unsorted array. We just read that array into memory in bulk. ++ ************************************************************************/ ++static const char S_STRINGTBL[] = { "string table" }; ++void dload_strings(struct dload_state *dlthis, boolean sec_names_only) ++{ ++ u32 ssiz; ++ char *strbuf; ++ ++ if (sec_names_only) { ++ ssiz = BYTE_TO_HOST(DOFF_ALIGN ++ (dlthis->dfile_hdr.df_scn_name_size)); ++ } else { ++ ssiz = BYTE_TO_HOST(DOFF_ALIGN ++ (dlthis->dfile_hdr.df_strtab_size)); ++ } ++ if (ssiz == 0) ++ return; ++ ++ /* get some memory for the string table */ ++#if BITS_PER_AU > BITS_PER_BYTE ++ strbuf = (char *)dlthis->mysym->Allocate(dlthis->mysym, ssiz + ++ dlthis->dfile_hdr.df_max_str_len); ++#else ++ strbuf = (char *)dlthis->mysym->Allocate(dlthis->mysym, ssiz); ++#endif ++ if (strbuf == NULL) { ++ DL_ERROR(E_ALLOC, ssiz); ++ return; ++ } ++ dlthis->str_head = strbuf; ++#if BITS_PER_AU > BITS_PER_BYTE ++ dlthis->str_temp = strbuf + ssiz; ++#endif ++ /* read in the strings and verify them */ ++ if ((unsigned)(dlthis->strm->read_buffer(dlthis->strm, strbuf, ++ ssiz)) != ssiz) { ++ DL_ERROR(E_READSTRM, S_STRINGTBL); ++ } ++ /* if we need to fix up byte order, do it now */ ++#ifndef _BIG_ENDIAN ++ if (dlthis->reorder_map) ++ dload_reorder(strbuf, ssiz, dlthis->reorder_map); ++ ++ if ((!sec_names_only) && (~dload_checksum(strbuf, ssiz) != ++ dlthis->verify.dv_str_tab_checksum)) { ++ DL_ERROR(E_CHECKSUM, S_STRINGTBL); ++ } ++#else ++ if (dlthis->dfile_hdr.df_byte_reshuffle != ++ HOST_BYTE_ORDER(REORDER_MAP(BYTE_RESHUFFLE_VALUE))) { ++ /* put strings in big-endian order, not in PC order */ ++ dload_reorder(strbuf, ssiz, HOST_BYTE_ORDER(dlthis->dfile_hdr. ++ df_byte_reshuffle)); ++ } ++ if ((!sec_names_only) && (~dload_reverse_checksum(strbuf, ssiz) != ++ dlthis->verify.dv_str_tab_checksum)) { ++ DL_ERROR(E_CHECKSUM, S_STRINGTBL); ++ } ++#endif ++} /* dload_strings */ ++ ++/************************************************************************* ++ * Procedure string_table_free ++ * ++ * Parameters: ++ * none ++ * ++ * Effect: ++ * Frees any state used by the string table. ++ * ++ * WARNING: ++ * This routine is not allowed to declare errors! ++ *************************************************************************/ ++static void string_table_free(struct dload_state *dlthis) ++{ ++ if (dlthis->str_head) ++ dlthis->mysym->Deallocate(dlthis->mysym, dlthis->str_head); ++ ++} /* string_table_free */ ++ ++/* ++ * Symbol Table Maintenance Functions ++ * ++ * COFF symbols are read by dload_symbols(), which is called after ++ * sections have been allocated. Symbols which might be used in ++ * relocation (ie, not debug info) are retained in an internal temporary ++ * compressed table (type Local_Symbol). A particular symbol is recovered ++ * by index by calling dload_find_symbol(). dload_find_symbol ++ * reconstructs a more explicit representation (type SLOTVEC) which is ++ * used by reloc.c ++ */ ++/* real size of debug header */ ++#define DBG_HDR_SIZE (sizeof(struct dll_module) - sizeof(struct dll_sect)) ++ ++static const char SYM_ERRID[] = { "symbol" }; ++ ++/************************************************************************** ++ * Procedure dload_symbols ++ * ++ * Parameters: ++ * none ++ * ++ * Effect: ++ * Reads in symbols and retains ones that might be needed for relocation ++ * purposes. ++ ************************************************************************/ ++/* size of symbol buffer no bigger than target data buffer, to limit stack ++ * usage*/ ++#define MY_SYM_BUF_SIZ (BYTE_TO_HOST(IMAGE_PACKET_SIZE)/\ ++ sizeof(struct doff_syment_t)) ++ ++static void dload_symbols(struct dload_state *dlthis) ++{ ++ u32 s_count, siz, dsiz, symbols_left; ++ u32 checks; ++ struct Local_Symbol *sp; ++ struct dynload_symbol *symp; ++ struct dynload_symbol *newsym; ++ ++ s_count = dlthis->dfile_hdr.df_no_syms; ++ if (s_count == 0) ++ return; ++ ++ /* We keep a local symbol table for all of the symbols in the input. ++ * This table contains only section & value info, as we do not have ++ * to do any name processing for locals. We reuse this storage ++ * as a temporary for .dllview record construction. ++ * Allocate storage for the whole table.*/ ++ siz = s_count * sizeof(struct Local_Symbol); ++ dsiz = DBG_HDR_SIZE + ++ (sizeof(struct dll_sect) * dlthis->allocated_secn_count) + ++ BYTE_TO_HOST_ROUND(dlthis->debug_string_size + 1); ++ if (dsiz > siz) ++ siz = dsiz; /* larger of symbols and .dllview temp */ ++ sp = (struct Local_Symbol *)dlthis->mysym->Allocate(dlthis->mysym, siz); ++ if (!sp) { ++ DL_ERROR(E_ALLOC, siz); ++ return; ++ } ++ dlthis->local_symtab = sp; ++ /* Read the symbols in the input, store them in the table, and post any ++ * globals to the global symbol table. In the process, externals ++ become defined from the global symbol table */ ++ checks = dlthis->verify.dv_sym_tab_checksum; ++ symbols_left = s_count; ++ do { /* read all symbols */ ++ char *sname; ++ u32 val; ++ s32 delta; ++ struct doff_syment_t *input_sym; ++ unsigned syms_in_buf; ++ struct doff_syment_t my_sym_buf[MY_SYM_BUF_SIZ]; ++ input_sym = my_sym_buf; ++ syms_in_buf = symbols_left > MY_SYM_BUF_SIZ ? ++ MY_SYM_BUF_SIZ : symbols_left; ++ siz = syms_in_buf * sizeof(struct doff_syment_t); ++ if (dlthis->strm->read_buffer(dlthis->strm, input_sym, siz) != ++ siz) { ++ DL_ERROR(E_READSTRM, SYM_ERRID); ++ return; ++ } ++ if (dlthis->reorder_map) ++ dload_reorder(input_sym, siz, dlthis->reorder_map); ++ ++ checks += dload_checksum(input_sym, siz); ++ do { /* process symbols in buffer */ ++ symbols_left -= 1; ++ /* attempt to derive the name of this symbol */ ++ sname = NULL; ++ if (input_sym->dn_offset > 0) { ++#if BITS_PER_AU <= BITS_PER_BYTE ++ if ((u32) input_sym->dn_offset < ++ dlthis->dfile_hdr.df_strtab_size) ++ sname = dlthis->str_head + ++ BYTE_TO_HOST(input_sym->dn_offset); ++ else ++ dload_error(dlthis, ++ "Bad name offset in symbol %d", ++ symbols_left); ++#else ++ sname = unpack_name(dlthis, ++ input_sym->dn_offset); ++#endif ++ } ++ val = input_sym->dn_value; ++ delta = 0; ++ sp->sclass = input_sym->dn_sclass; ++ sp->secnn = input_sym->dn_scnum; ++ /* if this is an undefined symbol, ++ * define it (or fail) now */ ++ if (sp->secnn == DN_UNDEF) { ++ /* pointless for static undefined */ ++ if (input_sym->dn_sclass != DN_EXT) ++ goto loop_cont; ++ ++ /* try to define symbol from previously ++ * loaded images */ ++ symp = dlthis->mysym->Find_Matching_Symbol ++ (dlthis->mysym, sname); ++ if (!symp) { ++ DL_ERROR ++ ("Undefined external symbol %s", ++ sname); ++ goto loop_cont; ++ } ++ val = delta = symp->value; ++ goto loop_cont; ++ } ++ /* symbol defined by this module */ ++ if (sp->secnn > 0) { /* symbol references a section */ ++ if ((unsigned)sp->secnn <= ++ dlthis->allocated_secn_count) { ++ /* section was allocated */ ++ struct doff_scnhdr_t *srefp = ++ &dlthis->sect_hdrs ++ [sp->secnn - 1]; ++ ++ if (input_sym->dn_sclass == ++ DN_STATLAB || ++ input_sym->dn_sclass == DN_EXTLAB){ ++ /* load */ ++ delta = srefp->ds_vaddr; ++ } else { ++ /* run */ ++ delta = srefp->ds_paddr; ++ } ++ val += delta; ++ } ++ goto loop_itr; ++ } ++ /* This symbol is an absolute symbol */ ++ if (sp->secnn == DN_ABS && ((sp->sclass == DN_EXT) || ++ (sp->sclass == DN_EXTLAB))) { ++ symp = dlthis->mysym->Find_Matching_Symbol ++ (dlthis->mysym, sname); ++ if (!symp) ++ goto loop_itr; ++ /* This absolute symbol is already defined. */ ++ if (symp->value == input_sym->dn_value) { ++ /* If symbol values are equal, continue ++ * but don't add to the global symbol ++ * table */ ++ sp->value = val; ++ sp->delta = delta; ++ sp += 1; ++ input_sym += 1; ++ continue; ++ } else { ++ /* If symbol values are not equal, ++ * return with redefinition error */ ++ DL_ERROR("Absolute symbol %s is " ++ "defined multiple times with " ++ "different values", sname); ++ return; ++ } ++ } ++loop_itr: ++ /* if this is a global symbol, post it to the ++ * global table */ ++ if (input_sym->dn_sclass == DN_EXT || ++ input_sym->dn_sclass == DN_EXTLAB) { ++ /* Keep this global symbol for subsequent ++ * modules. Don't complain on error, to allow ++ * symbol API to suppress global symbols */ ++ if (!sname) ++ goto loop_cont; ++ ++ newsym = dlthis->mysym->Add_To_Symbol_Table ++ (dlthis->mysym, sname, ++ (unsigned)dlthis->myhandle); ++ if (newsym) ++ newsym->value = val; ++ ++ } /* global */ ++loop_cont: ++ sp->value = val; ++ sp->delta = delta; ++ sp += 1; ++ input_sym += 1; ++ } while ((syms_in_buf -= 1) > 0); /* process sym in buffer */ ++ } while (symbols_left > 0); /* read all symbols */ ++ if (~checks) ++ dload_error(dlthis, "Checksum of symbols failed"); ++ ++} /* dload_symbols */ ++ ++/***************************************************************************** ++ * Procedure symbol_table_free ++ * ++ * Parameters: ++ * none ++ * ++ * Effect: ++ * Frees any state used by the symbol table. ++ * ++ * WARNING: ++ * This routine is not allowed to declare errors! ++ *****************************************************************************/ ++static void symbol_table_free(struct dload_state *dlthis) ++{ ++ if (dlthis->local_symtab) { ++ if (dlthis->dload_errcount) { /* blow off our symbols */ ++ dlthis->mysym->Purge_Symbol_Table(dlthis->mysym, ++ (unsigned)dlthis->myhandle); ++ } ++ dlthis->mysym->Deallocate(dlthis->mysym, dlthis->local_symtab); ++ } ++} /* symbol_table_free */ ++ ++/* .cinit Processing ++ * ++ * The dynamic loader does .cinit interpretation. cload_cinit() ++ * acts as a special write-to-target function, in that it takes relocated ++ * data from the normal data flow, and interprets it as .cinit actions. ++ * Because the normal data flow does not necessarily process the whole ++ * .cinit section in one buffer, cload_cinit() must be prepared to ++ * interpret the data piecemeal. A state machine is used for this ++ * purpose. ++ */ ++ ++/* The following are only for use by reloc.c and things it calls */ ++static const struct LDR_SECTION_INFO CINIT_INFO_INIT = { CINITNAME, 0, 0, ++ (LDR_ADDR) -1, 0, DLOAD_BSS, 0 }; ++ ++/************************************************************************* ++ * Procedure cload_cinit ++ * ++ * Parameters: ++ * ipacket Pointer to data packet to be loaded ++ * ++ * Effect: ++ * Interprets the data in the buffer as .cinit data, and performs the ++ * appropriate initializations. ++ ************************************************************************/ ++static void cload_cinit(struct dload_state *dlthis, ++ struct image_packet_t *ipacket) ++{ ++#if TDATA_TO_HOST(CINIT_COUNT)*BITS_PER_AU > 16 ++ s32 init_count, left; ++#else ++ s16 init_count, left; ++#endif ++ unsigned char *pktp = ipacket->i_bits; ++ unsigned char *pktend = pktp + ++ BYTE_TO_HOST_ROUND(ipacket->i_packet_size); ++ int temp; ++ LDR_ADDR atmp; ++ struct LDR_SECTION_INFO cinit_info; ++ ++ /* PROCESS ALL THE INITIALIZATION RECORDS IN THE BUFFER. */ ++ while (true) { ++ left = pktend - pktp; ++ switch (dlthis->cinit_state) { ++ case CI_count: /* count field */ ++ if (left < TDATA_TO_HOST(CINIT_COUNT)) ++ goto loopexit; ++ temp = dload_unpack(dlthis, (TgtAU_t *)pktp, ++ CINIT_COUNT * TDATA_AU_BITS, 0, ++ ROP_SGN); ++ pktp += TDATA_TO_HOST(CINIT_COUNT); ++ /* negative signifies BSS table, zero means done */ ++ if (temp <= 0) { ++ dlthis->cinit_state = CI_done; ++ break; ++ } ++ dlthis->cinit_count = temp; ++ dlthis->cinit_state = CI_address; ++ break; ++#if CINIT_ALIGN < CINIT_ADDRESS ++ case CI_partaddress: ++ pktp -= TDATA_TO_HOST(CINIT_ALIGN); ++ /* back up pointer into space courtesy of caller */ ++ *(uint16_t *)pktp = dlthis->cinit_addr; ++ /* stuff in saved bits !! FALL THRU !! */ ++#endif ++ case CI_address: /* Address field for a copy packet */ ++ if (left < TDATA_TO_HOST(CINIT_ADDRESS)) { ++#if CINIT_ALIGN < CINIT_ADDRESS ++ if (left == TDATA_TO_HOST(CINIT_ALIGN)) { ++ /* address broken into halves */ ++ dlthis->cinit_addr = *(uint16_t *)pktp; ++ /* remember 1st half */ ++ dlthis->cinit_state = CI_partaddress; ++ left = 0; ++ } ++#endif ++ goto loopexit; ++ } ++ atmp = dload_unpack(dlthis, (TgtAU_t *)pktp, ++ CINIT_ADDRESS * TDATA_AU_BITS, 0, ++ ROP_UNS); ++ pktp += TDATA_TO_HOST(CINIT_ADDRESS); ++#if CINIT_PAGE_BITS > 0 ++ dlthis->cinit_page = atmp & ++ ((1 << CINIT_PAGE_BITS) - 1); ++ atmp >>= CINIT_PAGE_BITS; ++#else ++ dlthis->cinit_page = CINIT_DEFAULT_PAGE; ++#endif ++ dlthis->cinit_addr = atmp; ++ dlthis->cinit_state = CI_copy; ++ break; ++ case CI_copy: /* copy bits to the target */ ++ init_count = HOST_TO_TDATA(left); ++ if (init_count > dlthis->cinit_count) ++ init_count = dlthis->cinit_count; ++ if (init_count == 0) ++ goto loopexit; /* get more bits */ ++ cinit_info = CINIT_INFO_INIT; ++ cinit_info.page = dlthis->cinit_page; ++ if (!dlthis->myio->writemem(dlthis->myio, pktp, ++ TDATA_TO_TADDR(dlthis->cinit_addr), ++ &cinit_info, ++ TDATA_TO_HOST(init_count))) { ++ dload_error(dlthis, E_INITFAIL, "write", ++ dlthis->cinit_addr); ++ } ++ dlthis->cinit_count -= init_count; ++ if (dlthis->cinit_count <= 0) { ++ dlthis->cinit_state = CI_count; ++ init_count = (init_count + CINIT_ALIGN - 1) & ++ -CINIT_ALIGN; ++ /* align to next init */ ++ } ++ pktp += TDATA_TO_HOST(init_count); ++ dlthis->cinit_addr += init_count; ++ break; ++ case CI_done: /* no more .cinit to do */ ++ return; ++ } /* switch (cinit_state) */ ++ } /* while */ ++ ++loopexit: ++ if (left > 0) { ++ dload_error(dlthis, "%d bytes left over in cinit packet", left); ++ dlthis->cinit_state = CI_done; /* left over bytes are bad */ ++ } ++} /* cload_cinit */ ++ ++/* Functions to interface to reloc.c ++ * ++ * reloc.c is the relocation module borrowed from the linker, with ++ * minimal (we hope) changes for our purposes. cload_sect_data() invokes ++ * this module on a section to relocate and load the image data for that ++ * section. The actual read and write actions are supplied by the global ++ * routines below. ++ */ ++ ++/************************************************************************ ++ * Procedure relocate_packet ++ * ++ * Parameters: ++ * ipacket Pointer to an image packet to relocate ++ * ++ * Effect: ++ * Performs the required relocations on the packet. Returns a checksum ++ * of the relocation operations. ++ ************************************************************************/ ++#define MY_RELOC_BUF_SIZ 8 ++/* careful! exists at the same time as the image buffer*/ ++static int relocate_packet(struct dload_state *dlthis, ++ struct image_packet_t *ipacket, u32 *checks) ++{ ++ u32 rnum; ++ ++ rnum = ipacket->i_num_relocs; ++ do { /* all relocs */ ++ unsigned rinbuf; ++ int siz; ++ struct reloc_record_t *rp, rrec[MY_RELOC_BUF_SIZ]; ++ rp = rrec; ++ rinbuf = rnum > MY_RELOC_BUF_SIZ ? MY_RELOC_BUF_SIZ : rnum; ++ siz = rinbuf * sizeof(struct reloc_record_t); ++ if (dlthis->strm->read_buffer(dlthis->strm, rp, siz) != siz) { ++ DL_ERROR(E_READSTRM, "relocation"); ++ return 0; ++ } ++ /* reorder the bytes if need be */ ++ if (dlthis->reorder_map) ++ dload_reorder(rp, siz, dlthis->reorder_map); ++ ++ *checks += dload_checksum(rp, siz); ++ do { ++ /* perform the relocation operation */ ++ dload_relocate(dlthis, (TgtAU_t *) ipacket->i_bits, rp); ++ rp += 1; ++ rnum -= 1; ++ } while ((rinbuf -= 1) > 0); ++ } while (rnum > 0); /* all relocs */ ++ return 1; ++} /* dload_read_reloc */ ++ ++#define IPH_SIZE (sizeof(struct image_packet_t) - sizeof(u32)) ++ ++/* VERY dangerous */ ++static const char IMAGEPAK[] = { "image packet" }; ++ ++/************************************************************************* ++ * Procedure dload_data ++ * ++ * Parameters: ++ * none ++ * ++ * Effect: ++ * Read image data from input file, relocate it, and download it to the ++ * target. ++ ************************************************************************/ ++static void dload_data(struct dload_state *dlthis) ++{ ++ u16 curr_sect; ++ struct doff_scnhdr_t *sptr = dlthis->sect_hdrs; ++ struct LDR_SECTION_INFO *lptr = dlthis->ldr_sections; ++#ifdef OPT_ZERO_COPY_LOADER ++ boolean bZeroCopy = false; ++#endif ++ u8 *pDest; ++ ++ struct { ++ struct image_packet_t ipacket; ++ u8 bufr[BYTE_TO_HOST(IMAGE_PACKET_SIZE)]; ++ } ibuf; ++ ++ /* Indicates whether CINIT processing has occurred */ ++ boolean cinit_processed = false; ++ ++ /* Loop through the sections and load them one at a time. ++ */ ++ for (curr_sect = 0; curr_sect < dlthis->dfile_hdr.df_no_scns; ++ curr_sect += 1) { ++ if (DS_NEEDS_DOWNLOAD(sptr)) { ++ s32 nip; ++ LDR_ADDR image_offset = 0; ++ /* set relocation info for this section */ ++ if (curr_sect < dlthis->allocated_secn_count) ++ dlthis->delta_runaddr = sptr->ds_paddr; ++ else { ++ lptr = DOFFSEC_IS_LDRSEC(sptr); ++ dlthis->delta_runaddr = 0; ++ } ++ dlthis->image_secn = lptr; ++#if BITS_PER_AU > BITS_PER_BYTE ++ lptr->name = unpack_name(dlthis, sptr->ds_offset); ++#endif ++ nip = sptr->ds_nipacks; ++ while ((nip -= 1) >= 0) { /* process packets */ ++ ++ s32 ipsize; ++ u32 checks; ++ /* get the fixed header bits */ ++ if (dlthis->strm->read_buffer(dlthis->strm, ++ &ibuf.ipacket, IPH_SIZE) != IPH_SIZE) { ++ DL_ERROR(E_READSTRM, IMAGEPAK); ++ return; ++ } ++ /* reorder the header if need be */ ++ if (dlthis->reorder_map) { ++ dload_reorder(&ibuf.ipacket, IPH_SIZE, ++ dlthis->reorder_map); ++ } ++ /* now read the rest of the packet */ ++ ipsize = ++ BYTE_TO_HOST(DOFF_ALIGN ++ (ibuf.ipacket.i_packet_size)); ++ if (ipsize > BYTE_TO_HOST(IMAGE_PACKET_SIZE)) { ++ DL_ERROR("Bad image packet size %d", ++ ipsize); ++ return; ++ } ++ pDest = ibuf.bufr; ++#ifdef OPT_ZERO_COPY_LOADER ++ bZeroCopy = false; ++ if (DLOAD_SECT_TYPE(sptr) != DLOAD_CINIT) { ++ dlthis->myio->writemem(dlthis->myio, ++ &pDest, lptr->load_addr + ++ image_offset, lptr, 0); ++ bZeroCopy = (pDest != ibuf.bufr); ++ } ++#endif ++ /* End of determination */ ++ ++ if (dlthis->strm->read_buffer(dlthis->strm, ++ ibuf.bufr, ipsize) != ipsize) { ++ DL_ERROR(E_READSTRM, IMAGEPAK); ++ return; ++ } ++ ibuf.ipacket.i_bits = pDest; ++ ++ /* reorder the bytes if need be */ ++#if !defined(_BIG_ENDIAN) || (TARGET_AU_BITS > 16) ++ if (dlthis->reorder_map) { ++ dload_reorder(pDest, ipsize, ++ dlthis->reorder_map); ++ } ++ checks = dload_checksum(pDest, ipsize); ++#else ++ if (dlthis->dfile_hdr.df_byte_reshuffle != ++ TARGET_ORDER(REORDER_MAP ++ (BYTE_RESHUFFLE_VALUE))) { ++ /* put image bytes in big-endian order, ++ * not PC order */ ++ dload_reorder(pDest, ipsize, ++ TARGET_ORDER ++ (dlthis->dfile_hdr.df_byte_reshuffle)); ++ } ++#if TARGET_AU_BITS > 8 ++ checks = dload_reverse_checksum_16(pDest, ++ ipsize); ++#else ++ checks = dload_reverse_checksum(pDest, ++ ipsize); ++#endif ++#endif ++ ++ checks += dload_checksum(&ibuf.ipacket, ++ IPH_SIZE); ++ /* relocate the image bits as needed */ ++ if (ibuf.ipacket.i_num_relocs) { ++ dlthis->image_offset = image_offset; ++ if (!relocate_packet(dlthis, ++ &ibuf.ipacket, &checks)) ++ return; /* serious error */ ++ } ++ if (~checks) ++ DL_ERROR(E_CHECKSUM, IMAGEPAK); ++ /* stuff the result into target memory */ ++ if (DLOAD_SECT_TYPE(sptr) == DLOAD_CINIT) { ++ cload_cinit(dlthis, &ibuf.ipacket); ++ cinit_processed = true; ++ } else { ++#ifdef OPT_ZERO_COPY_LOADER ++ if (!bZeroCopy) { ++#endif ++ ++ if (!dlthis->myio->writemem ++ (dlthis->myio, ibuf.bufr, ++ lptr->load_addr + image_offset, lptr, ++ BYTE_TO_HOST ++ (ibuf.ipacket.i_packet_size))) { ++ DL_ERROR( ++ "Write to " FMT_UI32 " failed", ++ lptr->load_addr + image_offset); ++ } ++#ifdef OPT_ZERO_COPY_LOADER ++ } ++#endif ++ ++ } ++ image_offset += ++ BYTE_TO_TADDR(ibuf.ipacket.i_packet_size); ++ } /* process packets */ ++ /* if this is a BSS section, we may want to fill it */ ++ if (DLOAD_SECT_TYPE(sptr) != DLOAD_BSS) ++ goto loop_cont; ++ ++ if (!(dlthis->myoptions & DLOAD_INITBSS)) ++ goto loop_cont; ++ ++ if (cinit_processed) { ++ /* Don't clear BSS after load-time ++ * initialization */ ++ DL_ERROR ++ ("Zero-initialization at " FMT_UI32 " after " ++ "load-time initialization!", lptr->load_addr); ++ goto loop_cont; ++ } ++ /* fill the .bss area */ ++ dlthis->myio->fillmem(dlthis->myio, ++ TADDR_TO_HOST(lptr->load_addr), ++ lptr, TADDR_TO_HOST(lptr->size), ++ dload_fill_bss); ++ goto loop_cont; ++ } /* if DS_DOWNLOAD_MASK */ ++ /* If not loading, but BSS, zero initialize */ ++ if (DLOAD_SECT_TYPE(sptr) != DLOAD_BSS) ++ goto loop_cont; ++ ++ if (!(dlthis->myoptions & DLOAD_INITBSS)) ++ goto loop_cont; ++ ++ if (curr_sect >= dlthis->allocated_secn_count) ++ lptr = DOFFSEC_IS_LDRSEC(sptr); ++ ++ if (cinit_processed) { ++ /*Don't clear BSS after load-time initialization */ ++ DL_ERROR( ++ "Zero-initialization at " FMT_UI32 " attempted after " ++ "load-time initialization!", lptr->load_addr); ++ goto loop_cont; ++ } ++ /* fill the .bss area */ ++ dlthis->myio->fillmem(dlthis->myio, ++ TADDR_TO_HOST(lptr->load_addr), lptr, ++ TADDR_TO_HOST(lptr->size), dload_fill_bss); ++loop_cont: ++ sptr += 1; ++ lptr += 1; ++ } /* load sections */ ++} /* dload_data */ ++ ++/************************************************************************* ++ * Procedure dload_reorder ++ * ++ * Parameters: ++ * data 32-bit aligned pointer to data to be byte-swapped ++ * dsiz size of the data to be reordered in sizeof() units. ++ * map 32-bit map defining how to reorder the data. Value ++ * must be REORDER_MAP() of some permutation ++ * of 0x00 01 02 03 ++ * ++ * Effect: ++ * Re-arranges the bytes in each word according to the map specified. ++ * ++ ************************************************************************/ ++/* mask for byte shift count */ ++#define SHIFT_COUNT_MASK (3 << LOG_BITS_PER_BYTE) ++ ++void dload_reorder(void *data, int dsiz, unsigned int map) ++{ ++ register u32 tmp, tmap, datv; ++ u32 *dp = (u32 *)data; ++ ++ map <<= LOG_BITS_PER_BYTE; /* align map with SHIFT_COUNT_MASK */ ++ do { ++ tmp = 0; ++ datv = *dp; ++ tmap = map; ++ do { ++ tmp |= (datv & BYTE_MASK) << (tmap & SHIFT_COUNT_MASK); ++ tmap >>= BITS_PER_BYTE; ++ } while (datv >>= BITS_PER_BYTE); ++ *dp++ = tmp; ++ } while ((dsiz -= sizeof(u32)) > 0); ++} /* dload_reorder */ ++ ++/************************************************************************* ++ * Procedure dload_checksum ++ * ++ * Parameters: ++ * data 32-bit aligned pointer to data to be checksummed ++ * siz size of the data to be checksummed in sizeof() units. ++ * ++ * Effect: ++ * Returns a checksum of the specified block ++ * ++ ************************************************************************/ ++u32 dload_checksum(void *data, unsigned siz) ++{ ++ u32 sum; ++ u32 *dp; ++ int left; ++ ++ sum = 0; ++ dp = (u32 *)data; ++ for (left = siz; left > 0; left -= sizeof(u32)) ++ sum += *dp++; ++ return sum; ++} /* dload_checksum */ ++ ++#if HOST_ENDIANNESS ++/************************************************************************* ++ * Procedure dload_reverse_checksum ++ * ++ * Parameters: ++ * data 32-bit aligned pointer to data to be checksummed ++ * siz size of the data to be checksummed in sizeof() units. ++ * ++ * Effect: ++ * Returns a checksum of the specified block, which is assumed to be bytes ++ * in big-endian order. ++ * ++ * Notes: ++ * In a big-endian host, things like the string table are stored as bytes ++ * in host order. But dllcreate always checksums in little-endian order. ++ * It is most efficient to just handle the difference a word at a time. ++ * ++ ***********************************************************************/ ++u32 dload_reverse_checksum(void *data, unsigned siz) ++{ ++ u32 sum, temp; ++ u32 *dp; ++ int left; ++ ++ sum = 0; ++ dp = (u32 *)data; ++ ++ for (left = siz; left > 0; left -= sizeof(u32)) { ++ temp = *dp++; ++ sum += temp << BITS_PER_BYTE * 3; ++ sum += temp >> BITS_PER_BYTE * 3; ++ sum += (temp >> BITS_PER_BYTE) & (BYTE_MASK << BITS_PER_BYTE); ++ sum += (temp & (BYTE_MASK << BITS_PER_BYTE)) << BITS_PER_BYTE; ++ } ++ ++ return sum; ++} /* dload_reverse_checksum */ ++ ++#if (TARGET_AU_BITS > 8) && (TARGET_AU_BITS < 32) ++u32 dload_reverse_checksum_16(void *data, unsigned siz) ++{ ++ uint_fast32_t sum, temp; ++ u32 *dp; ++ int left; ++ ++ sum = 0; ++ dp = (u32 *)data; ++ ++ for (left = siz; left > 0; left -= sizeof(u32)) { ++ temp = *dp++; ++ sum += temp << BITS_PER_BYTE * 2; ++ sum += temp >> BITS_PER_BYTE * 2; ++ } ++ ++ return sum; ++} /* dload_reverse_checksum_16 */ ++#endif ++#endif ++ ++/************************************************************************* ++ * Procedure swap_words ++ * ++ * Parameters: ++ * data 32-bit aligned pointer to data to be swapped ++ * siz size of the data to be swapped. ++ * bitmap Bit map of how to swap each 32-bit word; 1 => 2 shorts, ++ * 0 => 1 long ++ * ++ * Effect: ++ * Swaps the specified data according to the specified map ++ * ++ ************************************************************************/ ++static void swap_words(void *data, unsigned siz, unsigned bitmap) ++{ ++ register int i; ++#if TARGET_AU_BITS < 16 ++ register u16 *sp; ++#endif ++ register u32 *lp; ++ ++ siz /= sizeof(u16); ++ ++#if TARGET_AU_BITS < 16 ++ /* pass 1: do all the bytes */ ++ i = siz; ++ sp = (u16 *) data; ++ do { ++ register u16 tmp; ++ tmp = *sp; ++ *sp++ = SWAP16BY8(tmp); ++ } while ((i -= 1) > 0); ++#endif ++ ++#if TARGET_AU_BITS < 32 ++ /* pass 2: fixup the 32-bit words */ ++ i = siz >> 1; ++ lp = (u32 *) data; ++ do { ++ if ((bitmap & 1) == 0) { ++ register u32 tmp; ++ tmp = *lp; ++ *lp = SWAP32BY16(tmp); ++ } ++ lp += 1; ++ bitmap >>= 1; ++ } while ((i -= 1) > 0); ++#endif ++} /* swap_words */ ++ ++/************************************************************************* ++ * Procedure copy_tgt_strings ++ * ++ * Parameters: ++ * dstp Destination address. Assumed to be 32-bit aligned ++ * srcp Source address. Assumed to be 32-bit aligned ++ * charcount Number of characters to copy. ++ * ++ * Effect: ++ * Copies strings from the source (which is in usual .dof file order on ++ * the loading processor) to the destination buffer (which should be in proper ++ * target addressable unit order). Makes sure the last string in the ++ * buffer is NULL terminated (for safety). ++ * Returns the first unused destination address. ++ ************************************************************************/ ++static char *copy_tgt_strings(void *dstp, void *srcp, unsigned charcount) ++{ ++ register TgtAU_t *src = (TgtAU_t *)srcp; ++ register TgtAU_t *dst = (TgtAU_t *)dstp; ++ register int cnt = charcount; ++ do { ++#if TARGET_AU_BITS <= BITS_PER_AU ++ /* byte-swapping issues may exist for strings on target */ ++ *dst++ = *src++; ++#elif TARGET_ENDIANNESS_DIFFERS(TARGET_BIG_ENDIAN) ++ register TgtAU_t tmp; ++ tmp = *src++; ++ *dst++ = SWAP16BY8(tmp); /* right for TARGET_AU_BITS == 16 */ ++#else ++ *dst++ = *src++; ++#endif ++ } while ((cnt -= (sizeof(TgtAU_t) * BITS_PER_AU / BITS_PER_BYTE)) > 0); ++ /*apply force to make sure that the string table has null terminator */ ++#if (BITS_PER_AU == BITS_PER_BYTE) && (TARGET_AU_BITS == BITS_PER_BYTE) ++ dst[-1] = 0; ++#elif TARGET_BIG_ENDIAN ++ dst[-1] &= ~BYTE_MASK; /* big-endian */ ++#else ++ dst[-1] &= (1 << (BITS_PER_AU - BITS_PER_BYTE)) - 1; /* little endian */ ++#endif ++ return (char *)dst; ++} /* copy_tgt_strings */ ++ ++/************************************************************************* ++ * Procedure init_module_handle ++ * ++ * Parameters: ++ * none ++ * ++ * Effect: ++ * Initializes the module handle we use to enable unloading, and installs ++ * the debug information required by the target. ++ * ++ * Notes: ++ * The handle returned from Dynamic_Load_Module needs to encapsulate all the ++ * allocations done for the module, and enable them plus the modules symbols to ++ * be deallocated. ++ * ++ ************************************************************************/ ++#ifndef _BIG_ENDIAN ++static const struct LDR_SECTION_INFO DLLVIEW_INFO_INIT = { ".dllview", 0, 0, ++ (LDR_ADDR) -1, DBG_LIST_PAGE, DLOAD_DATA, 0 }; ++#else ++static const struct LDR_SECTION_INFO DLLVIEW_INFO_INIT = { ".dllview", 0, 0, ++ (LDR_ADDR) -1, DLOAD_DATA, DBG_LIST_PAGE, 0 }; ++#endif ++static void init_module_handle(struct dload_state *dlthis) ++{ ++ struct my_handle *hndl; ++ u16 curr_sect; ++ struct LDR_SECTION_INFO *asecs; ++ struct dll_module *dbmod; ++ struct dll_sect *dbsec; ++ struct dbg_mirror_root *mlist; ++ register char *cp; ++ struct modules_header mhdr; ++ struct LDR_SECTION_INFO dllview_info; ++ struct dynload_symbol *debug_mirror_sym; ++ hndl = dlthis->myhandle; ++ if (!hndl) ++ return; /* must be errors detected, so forget it */ ++ hndl->secn_count = dlthis->allocated_secn_count << 1; ++#ifndef TARGET_ENDIANNESS ++ if (dlthis->big_e_target) ++ hndl->secn_count += 1; /* flag for big-endian */ ++#endif ++ if (dlthis->dload_errcount) ++ return; /* abandon if errors detected */ ++ /* Locate the symbol that names the header for the CCS debug list ++ of modules. If not found, we just don't generate the debug record. ++ If found, we create our modules list. We make sure to create the ++ LOADER_DLLVIEW_ROOT even if there is no relocation info to record, ++ just to try to put both symbols in the same symbol table and ++ module.*/ ++ debug_mirror_sym = dlthis->mysym->Find_Matching_Symbol(dlthis->mysym, ++ LOADER_DLLVIEW_ROOT); ++ if (!debug_mirror_sym) { ++ struct dynload_symbol *dlmodsym; ++ struct dbg_mirror_root *mlst; ++ ++ /* our root symbol is not yet present; ++ check if we have DLModules defined */ ++ dlmodsym = dlthis->mysym->Find_Matching_Symbol(dlthis->mysym, ++ LINKER_MODULES_HEADER); ++ if (!dlmodsym) ++ return; /* no DLModules list so no debug info */ ++ /* if we have DLModules defined, construct our header */ ++ mlst = (struct dbg_mirror_root *) ++ dlthis->mysym->Allocate(dlthis->mysym, ++ sizeof(struct dbg_mirror_root)); ++ if (!mlst) { ++ DL_ERROR(E_ALLOC, sizeof(struct dbg_mirror_root)); ++ return; ++ } ++ mlst->hnext = NULL; ++ mlst->changes = 0; ++ mlst->refcount = 0; ++ mlst->dbthis = TDATA_TO_TADDR(dlmodsym->value); ++ /* add our root symbol */ ++ debug_mirror_sym = dlthis->mysym->Add_To_Symbol_Table ++ (dlthis->mysym, LOADER_DLLVIEW_ROOT, ++ (unsigned)dlthis->myhandle); ++ if (!debug_mirror_sym) { ++ /* failed, recover memory */ ++ dlthis->mysym->Deallocate(dlthis->mysym, mlst); ++ return; ++ } ++ debug_mirror_sym->value = (u32)mlst; ++ } ++ /* First create the DLLview record and stuff it into the buffer. ++ Then write it to the DSP. Record pertinent locations in our hndl, ++ and add it to the per-processor list of handles with debug info.*/ ++#ifndef DEBUG_HEADER_IN_LOADER ++ mlist = (struct dbg_mirror_root *)debug_mirror_sym->value; ++ if (!mlist) ++ return; ++#else ++ mlist = (struct dbg_mirror_root *)&debug_list_header; ++#endif ++ hndl->dm.hroot = mlist; /* set pointer to root into our handle */ ++ if (!dlthis->allocated_secn_count) ++ return; /* no load addresses to be recorded */ ++ /* reuse temporary symbol storage */ ++ dbmod = (struct dll_module *) dlthis->local_symtab; ++ /* Create the DLLview record in the memory we retain for our handle*/ ++ dbmod->num_sects = dlthis->allocated_secn_count; ++ dbmod->timestamp = dlthis->verify.dv_timdat; ++ dbmod->version = INIT_VERSION; ++ dbmod->verification = VERIFICATION; ++ asecs = dlthis->ldr_sections; ++ dbsec = dbmod->sects; ++ for (curr_sect = dlthis->allocated_secn_count; ++ curr_sect > 0; curr_sect -= 1) { ++ dbsec->sect_load_adr = asecs->load_addr; ++ dbsec->sect_run_adr = asecs->run_addr; ++ dbsec += 1; ++ asecs += 1; ++ } ++ /* now cram in the names */ ++ cp = copy_tgt_strings(dbsec, dlthis->str_head, ++ dlthis->debug_string_size); ++ ++ /* round off the size of the debug record, and remember same */ ++ hndl->dm.dbsiz = HOST_TO_TDATA_ROUND(cp - (char *)dbmod); ++ *cp = 0; /* strictly to make our test harness happy */ ++ dllview_info = DLLVIEW_INFO_INIT; ++ dllview_info.size = TDATA_TO_TADDR(hndl->dm.dbsiz); ++ /* Initialize memory context to default heap */ ++ dllview_info.context = 0; ++ hndl->dm.context = 0; ++ /* fill in next pointer and size */ ++ if (mlist->hnext) { ++ dbmod->next_module = TADDR_TO_TDATA(mlist->hnext->dm.dbthis); ++ dbmod->next_module_size = mlist->hnext->dm.dbsiz; ++ } else { ++ dbmod->next_module_size = 0; ++ dbmod->next_module = 0; ++ } ++ /* allocate memory for on-DSP DLLview debug record */ ++ if (!dlthis->myalloc) ++ return; ++ if (!dlthis->myalloc->Allocate(dlthis->myalloc, &dllview_info, ++ HOST_TO_TADDR(sizeof(u32)))) { ++ return; ++ } ++ /* Store load address of .dllview section */ ++ hndl->dm.dbthis = dllview_info.load_addr; ++ /* Store memory context (segid) in which .dllview section ++ * was allocated */ ++ hndl->dm.context = dllview_info.context; ++ mlist->refcount += 1; ++ /* swap bytes in the entire debug record, but not the string table */ ++ if (TARGET_ENDIANNESS_DIFFERS(TARGET_BIG_ENDIAN)) { ++ swap_words(dbmod, (char *)dbsec - (char *)dbmod, ++ DLL_MODULE_BITMAP); ++ } ++ /* Update the DLLview list on the DSP write new record */ ++ if (!dlthis->myio->writemem(dlthis->myio, dbmod, ++ dllview_info.load_addr, &dllview_info, ++ TADDR_TO_HOST(dllview_info.size))) { ++ return; ++ } ++ /* write new header */ ++ mhdr.first_module_size = hndl->dm.dbsiz; ++ mhdr.first_module = TADDR_TO_TDATA(dllview_info.load_addr); ++ /* swap bytes in the module header, if needed */ ++ if (TARGET_ENDIANNESS_DIFFERS(TARGET_BIG_ENDIAN)) { ++ swap_words(&mhdr, sizeof(struct modules_header) - sizeof(u16), ++ MODULES_HEADER_BITMAP); ++ } ++ dllview_info = DLLVIEW_INFO_INIT; ++ if (!dlthis->myio->writemem(dlthis->myio, &mhdr, mlist->dbthis, ++ &dllview_info, sizeof(struct modules_header) - ++ sizeof(u16))) { ++ return; ++ } ++ /* Add the module handle to this processor's list ++ of handles with debug info */ ++ hndl->dm.hnext = mlist->hnext; ++ if (hndl->dm.hnext) ++ hndl->dm.hnext->dm.hprev = hndl; ++ hndl->dm.hprev = (struct my_handle *) mlist; ++ mlist->hnext = hndl; /* insert after root*/ ++} /* init_module_handle */ ++ ++/************************************************************************* ++ * Procedure Dynamic_Unload_Module ++ * ++ * Parameters: ++ * mhandle A module handle from Dynamic_Load_Module ++ * syms Host-side symbol table and malloc/free functions ++ * alloc Target-side memory allocation ++ * ++ * Effect: ++ * The module specified by mhandle is unloaded. Unloading causes all ++ * target memory to be deallocated, all symbols defined by the module to ++ * be purged, and any host-side storage used by the dynamic loader for ++ * this module to be released. ++ * ++ * Returns: ++ * Zero for success. On error, the number of errors detected is returned. ++ * Individual errors are reported using syms->Error_Report(). ++ ************************************************************************/ ++int Dynamic_Unload_Module(DLOAD_mhandle mhandle, ++ struct Dynamic_Loader_Sym *syms, ++ struct Dynamic_Loader_Allocate *alloc, ++ struct Dynamic_Loader_Initialize *init) ++{ ++ s16 curr_sect; ++ struct LDR_SECTION_INFO *asecs; ++ struct my_handle *hndl; ++ struct dbg_mirror_root *root; ++ unsigned errcount = 0; ++ struct LDR_SECTION_INFO dllview_info = DLLVIEW_INFO_INIT; ++ struct modules_header mhdr; ++ ++ hndl = (struct my_handle *)mhandle; ++ if (!hndl) ++ return 0; /* if handle is null, nothing to do */ ++ /* Clear out the module symbols ++ * Note that if this is the module that defined MODULES_HEADER ++ (the head of the target debug list) ++ * then this operation will blow away that symbol. ++ It will therefore be impossible for subsequent ++ * operations to add entries to this un-referenceable list.*/ ++ if (!syms) ++ return 1; ++ syms->Purge_Symbol_Table(syms, (unsigned) hndl); ++ /* Deallocate target memory for sections */ ++ asecs = hndl->secns; ++ if (alloc) ++ for (curr_sect = (hndl->secn_count >> 1); curr_sect > 0; ++ curr_sect -= 1) { ++ asecs->name = NULL; ++ alloc->Deallocate(alloc, asecs++); ++ } ++ root = hndl->dm.hroot; ++ if (!root) { ++ /* there is a debug list containing this module */ ++ goto func_end; ++ } ++ if (!hndl->dm.dbthis) { /* target-side dllview record exists */ ++ goto loop_end; ++ } ++ /* Retrieve memory context in which .dllview was allocated */ ++ dllview_info.context = hndl->dm.context; ++ if (hndl->dm.hprev == hndl) ++ goto exitunltgt; ++ ++ /* target-side dllview record is in list */ ++ /* dequeue this record from our GPP-side mirror list */ ++ hndl->dm.hprev->dm.hnext = hndl->dm.hnext; ++ if (hndl->dm.hnext) ++ hndl->dm.hnext->dm.hprev = hndl->dm.hprev; ++ /* Update next_module of previous entry in target list ++ * We are using mhdr here as a surrogate for either a ++ struct modules_header or a dll_module */ ++ if (hndl->dm.hnext) { ++ mhdr.first_module = TADDR_TO_TDATA(hndl->dm.hnext->dm.dbthis); ++ mhdr.first_module_size = hndl->dm.hnext->dm.dbsiz; ++ } else { ++ mhdr.first_module = 0; ++ mhdr.first_module_size = 0; ++ } ++ if (!init) ++ goto exitunltgt; ++ ++ if (!init->connect(init)) { ++ dload_syms_error(syms, E_ICONNECT); ++ errcount += 1; ++ goto exitunltgt; ++ } ++ /* swap bytes in the module header, if needed */ ++ if (TARGET_ENDIANNESS_DIFFERS(hndl->secn_count & 0x1)) { ++ swap_words(&mhdr, sizeof(struct modules_header) - sizeof(u16), ++ MODULES_HEADER_BITMAP); ++ } ++ if (!init->writemem(init, &mhdr, hndl->dm.hprev->dm.dbthis, ++ &dllview_info, sizeof(struct modules_header) - ++ sizeof(mhdr.update_flag))) { ++ dload_syms_error(syms, E_DLVWRITE); ++ errcount += 1; ++ } ++ /* update change counter */ ++ root->changes += 1; ++ if (!init->writemem(init, &(root->changes), ++ root->dbthis + HOST_TO_TADDR ++ (sizeof(mhdr.first_module) + ++ sizeof(mhdr.first_module_size)), ++ &dllview_info, ++ sizeof(mhdr.update_flag))) { ++ dload_syms_error(syms, E_DLVWRITE); ++ errcount += 1; ++ } ++ init->release(init); ++exitunltgt: ++ /* release target storage */ ++ dllview_info.size = TDATA_TO_TADDR(hndl->dm.dbsiz); ++ dllview_info.load_addr = hndl->dm.dbthis; ++ if (alloc) ++ alloc->Deallocate(alloc, &dllview_info); ++ root->refcount -= 1; ++ /* target-side dllview record exists */ ++loop_end: ++#ifndef DEBUG_HEADER_IN_LOADER ++ if (root->refcount <= 0) { ++ /* if all references gone, blow off the header */ ++ /* our root symbol may be gone due to the Purge above, ++ but if not, do not destroy the root */ ++ if (syms->Find_Matching_Symbol ++ (syms, LOADER_DLLVIEW_ROOT) == NULL) ++ syms->Deallocate(syms, root); ++ } ++#endif ++func_end: ++ /* there is a debug list containing this module */ ++ syms->Deallocate(syms, mhandle); /* release our storage */ ++ return errcount; ++} /* Dynamic_Unload_Module */ ++ ++#if BITS_PER_AU > BITS_PER_BYTE ++/************************************************************************* ++ * Procedure unpack_name ++ * ++ * Parameters: ++ * soffset Byte offset into the string table ++ * ++ * Effect: ++ * Returns a pointer to the string specified by the offset supplied, or ++ * NULL for error. ++ * ++ ************************************************************************/ ++static char *unpack_name(struct dload_state *dlthis, u32 soffset) ++{ ++ u8 tmp, *src; ++ char *dst; ++ ++ if (soffset >= dlthis->dfile_hdr.df_strtab_size) { ++ dload_error(dlthis, "Bad string table offset " FMT_UI32, ++ soffset); ++ return NULL; ++ } ++ src = (uint_least8_t *)dlthis->str_head + ++ (soffset >> (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE)); ++ dst = dlthis->str_temp; ++ if (soffset & 1) ++ *dst++ = *src++; /* only 1 character in first word */ ++ do { ++ tmp = *src++; ++ *dst = (tmp >> BITS_PER_BYTE); ++ if (!(*dst++)) ++ break; ++ } while ((*dst++ = tmp & BYTE_MASK)); ++ dlthis->temp_len = dst - dlthis->str_temp; ++ /* squirrel away length including terminating null */ ++ return dlthis->str_temp; ++} /* unpack_name */ ++#endif +diff --git a/drivers/dsp/bridge/dynload/dlclasses_hdr.h b/drivers/dsp/bridge/dynload/dlclasses_hdr.h +new file mode 100644 +index 0000000..04f136e +--- /dev/null ++++ b/drivers/dsp/bridge/dynload/dlclasses_hdr.h +@@ -0,0 +1,41 @@ ++/* ++ * dlclasses_hdr.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++ ++#ifndef _DLCLASSES_HDR_H ++#define _DLCLASSES_HDR_H ++ ++/***************************************************************************** ++ ***************************************************************************** ++ * ++ * DLCLASSES_HDR.H ++ * ++ * Sample classes in support of the dynamic loader ++ * ++ * These are just concrete derivations of the virtual ones in dynamic_loader.h ++ * with a few additional interfaces for init, etc. ++ ***************************************************************************** ++ *****************************************************************************/ ++ ++#include ++ ++#include "DLstream.h" ++#include "DLsymtab.h" ++#include "DLalloc.h" ++#include "DLinit.h" ++ ++#endif /* _DLCLASSES_HDR_H */ +diff --git a/drivers/dsp/bridge/dynload/dload_internal.h b/drivers/dsp/bridge/dynload/dload_internal.h +new file mode 100644 +index 0000000..78f5058 +--- /dev/null ++++ b/drivers/dsp/bridge/dynload/dload_internal.h +@@ -0,0 +1,237 @@ ++/* ++ * dload_internal.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++ ++#ifndef __DLOAD_INTERNAL__ ++#define __DLOAD_INTERNAL__ ++ ++#include ++ ++/* ++ * Internal state definitions for the dynamic loader ++ */ ++ ++#define TRUE 1 ++#define FALSE 0 ++typedef int boolean; ++ ++ ++/* type used for relocation intermediate results */ ++typedef s32 RVALUE; ++ ++/* unsigned version of same; must have at least as many bits */ ++typedef u32 URVALUE; ++ ++/* ++ * Dynamic loader configuration constants ++ */ ++/* error issued if input has more sections than this limit */ ++#define REASONABLE_SECTION_LIMIT 100 ++ ++/* (Addressable unit) value used to clear BSS section */ ++#define dload_fill_bss 0 ++ ++/* ++ * Reorder maps explained (?) ++ * ++ * The doff file format defines a 32-bit pattern used to determine the ++ * byte order of an image being read. That value is ++ * BYTE_RESHUFFLE_VALUE == 0x00010203 ++ * For purposes of the reorder routine, we would rather have the all-is-OK ++ * for 32-bits pattern be 0x03020100. This first macro makes the ++ * translation from doff file header value to MAP value: */ ++#define REORDER_MAP(rawmap) ((rawmap) ^ 0x3030303) ++/* This translation is made in dload_headers. Thereafter, the all-is-OK ++ * value for the maps stored in dlthis is REORDER_MAP(BYTE_RESHUFFLE_VALUE). ++ * But sadly, not all bits of the doff file are 32-bit integers. ++ * The notable exceptions are strings and image bits. ++ * Strings obey host byte order: */ ++#if defined(_BIG_ENDIAN) ++#define HOST_BYTE_ORDER(cookedmap) ((cookedmap) ^ 0x3030303) ++#else ++#define HOST_BYTE_ORDER(cookedmap) (cookedmap) ++#endif ++/* Target bits consist of target AUs (could be bytes, or 16-bits, ++ * or 32-bits) stored as an array in host order. A target order ++ * map is defined by: */ ++#if !defined(_BIG_ENDIAN) || TARGET_AU_BITS > 16 ++#define TARGET_ORDER(cookedmap) (cookedmap) ++#elif TARGET_AU_BITS > 8 ++#define TARGET_ORDER(cookedmap) ((cookedmap) ^ 0x2020202) ++#else ++#define TARGET_ORDER(cookedmap) ((cookedmap) ^ 0x3030303) ++#endif ++ ++/* forward declaration for handle returned by dynamic loader */ ++struct my_handle; ++ ++/* ++ * a list of module handles, which mirrors the debug list on the target ++ */ ++struct dbg_mirror_root { ++ /* must be same as dbg_mirror_list; __DLModules address on target */ ++ u32 dbthis; ++ struct my_handle *hnext; /* must be same as dbg_mirror_list */ ++ u16 changes; /* change counter */ ++ u16 refcount; /* number of modules referencing this root */ ++} ; ++ ++struct dbg_mirror_list { ++ u32 dbthis; ++ struct my_handle *hnext, *hprev; ++ struct dbg_mirror_root *hroot; ++ u16 dbsiz; ++ u32 context; /* Save context for .dllview memory allocation */ ++} ; ++ ++#define VARIABLE_SIZE 1 ++/* ++ * the structure we actually return as an opaque module handle ++ */ ++struct my_handle { ++ struct dbg_mirror_list dm; /* !!! must be first !!! */ ++ /* sections following << 1, LSB is set for big-endian target */ ++ u16 secn_count; ++ struct LDR_SECTION_INFO secns[VARIABLE_SIZE]; ++} ; ++#define MY_HANDLE_SIZE (sizeof(struct my_handle) -\ ++ sizeof(struct LDR_SECTION_INFO)) ++/* real size of my_handle */ ++ ++/* ++ * reduced symbol structure used for symbols during relocation ++ */ ++struct Local_Symbol { ++ s32 value; /* Relocated symbol value */ ++ s32 delta; /* Original value in input file */ ++ s16 secnn; /* section number */ ++ s16 sclass; /* symbol class */ ++} ; ++ ++/* ++ * States of the .cinit state machine ++ */ ++enum cinit_mode { ++ CI_count = 0, /* expecting a count */ ++ CI_address, /* expecting an address */ ++#if CINIT_ALIGN < CINIT_ADDRESS /* handle case of partial address field */ ++ CI_partaddress, /* have only part of the address */ ++#endif ++ CI_copy, /* in the middle of copying data */ ++ CI_done /* end of .cinit table */ ++}; ++ ++/* ++ * The internal state of the dynamic loader, which is passed around as ++ * an object ++ */ ++struct dload_state { ++ struct Dynamic_Loader_Stream *strm; /* The module input stream */ ++ struct Dynamic_Loader_Sym *mysym; /* Symbols for this session */ ++ struct Dynamic_Loader_Allocate *myalloc; /* target memory allocator */ ++ struct Dynamic_Loader_Initialize *myio; /* target memory initializer */ ++ unsigned myoptions; /* Options parameter Dynamic_Load_Module */ ++ ++ char *str_head; /* Pointer to string table */ ++#if BITS_PER_AU > BITS_PER_BYTE ++ char *str_temp; /* Pointer to temporary buffer for strings */ ++ /* big enough to hold longest string */ ++ unsigned temp_len; /* length of last temporary string */ ++ char *xstrings; /* Pointer to buffer for expanded */ ++ /* strings for sec names */ ++#endif ++ /* Total size of strings for DLLView section names */ ++ unsigned debug_string_size; ++ /* Pointer to parallel section info for allocated sections only */ ++ struct doff_scnhdr_t *sect_hdrs; /* Pointer to section table */ ++ struct LDR_SECTION_INFO *ldr_sections; ++#if TMS32060 ++ /* The address of the start of the .bss section */ ++ LDR_ADDR bss_run_base; ++#endif ++ struct Local_Symbol *local_symtab; /* Relocation symbol table */ ++ ++ /* pointer to DL section info for the section being relocated */ ++ struct LDR_SECTION_INFO *image_secn; ++ /* change in run address for current section during relocation */ ++ LDR_ADDR delta_runaddr; ++ LDR_ADDR image_offset; /* offset of current packet in section */ ++ enum cinit_mode cinit_state; /* current state of cload_cinit() */ ++ int cinit_count; /* the current count */ ++ LDR_ADDR cinit_addr; /* the current address */ ++ s16 cinit_page; /* the current page */ ++ /* Handle to be returned by Dynamic_Load_Module */ ++ struct my_handle *myhandle; ++ unsigned dload_errcount; /* Total # of errors reported so far */ ++ /* Number of target sections that require allocation and relocation */ ++ unsigned allocated_secn_count; ++#ifndef TARGET_ENDIANNESS ++ boolean big_e_target; /* Target data in big-endian format */ ++#endif ++ /* map for reordering bytes, 0 if not needed */ ++ u32 reorder_map; ++ struct doff_filehdr_t dfile_hdr; /* DOFF file header structure */ ++ struct doff_verify_rec_t verify; /* Verify record */ ++ ++ int relstkidx; /* index into relocation value stack */ ++ /* relocation value stack used in relexp.c */ ++ RVALUE relstk[STATIC_EXPR_STK_SIZE]; ++ ++} ; ++ ++#ifdef TARGET_ENDIANNESS ++#define TARGET_BIG_ENDIAN TARGET_ENDIANNESS ++#else ++#define TARGET_BIG_ENDIAN (dlthis->big_e_target) ++#endif ++ ++/* ++ * Exports from cload.c to rest of the world ++ */ ++extern void dload_error(struct dload_state *dlthis, const char *errtxt, ...); ++extern void dload_syms_error(struct Dynamic_Loader_Sym *syms, ++ const char *errtxt, ...); ++extern void dload_headers(struct dload_state *dlthis); ++extern void dload_strings(struct dload_state *dlthis, boolean sec_names_only); ++extern void dload_sections(struct dload_state *dlthis); ++extern void dload_reorder(void *data, int dsiz, u32 map); ++extern u32 dload_checksum(void *data, unsigned siz); ++ ++#if HOST_ENDIANNESS ++extern uint32_t dload_reverse_checksum(void *data, unsigned siz); ++#if (TARGET_AU_BITS > 8) && (TARGET_AU_BITS < 32) ++extern uint32_t dload_reverse_checksum_16(void *data, unsigned siz); ++#endif ++#endif ++ ++#define is_data_scn(zzz) (DLOAD_SECTION_TYPE((zzz)->type) != DLOAD_TEXT) ++#define is_data_scn_num(zzz) \ ++ (DLOAD_SECT_TYPE(&dlthis->sect_hdrs[(zzz)-1]) != DLOAD_TEXT) ++ ++/* ++ * exported by reloc.c ++ */ ++extern void dload_relocate(struct dload_state *dlthis, TgtAU_t *data, ++ struct reloc_record_t *rp); ++ ++extern RVALUE dload_unpack(struct dload_state *dlthis, TgtAU_t *data, ++ int fieldsz, int offset, unsigned sgn); ++ ++extern int dload_repack(struct dload_state *dlthis, RVALUE val, TgtAU_t *data, ++ int fieldsz, int offset, unsigned sgn); ++ ++#endif /* __DLOAD_INTERNAL__ */ +diff --git a/drivers/dsp/bridge/dynload/doff.h b/drivers/dsp/bridge/dynload/doff.h +new file mode 100644 +index 0000000..2b8fc37 +--- /dev/null ++++ b/drivers/dsp/bridge/dynload/doff.h +@@ -0,0 +1,347 @@ ++/* ++ * doff.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/*****************************************************************************/ ++/* DOFF.H - Structures & definitions used for dynamically */ ++/* loaded modules file format. This format is a reformatted */ ++/* version of COFF.(see coff.h for details) It optimizes the */ ++/* layout for the dynamic loader. */ ++/* */ ++/* .dof files, when viewed as a sequence of 32-bit integers, look the same */ ++/* on big-endian and little-endian machines. */ ++/*****************************************************************************/ ++#ifndef _DOFF_H ++#define _DOFF_H ++ ++#ifndef UINT32_C ++#define UINT32_C(zzz) ((u32)zzz) ++#endif ++ ++#define BYTE_RESHUFFLE_VALUE UINT32_C(0x00010203) ++ ++/* DOFF file header containing fields categorizing the remainder of the file */ ++struct doff_filehdr_t { ++ ++ /* string table size, including filename, in bytes */ ++ u32 df_strtab_size; ++ ++ /* entry point if one exists */ ++ u32 df_entrypt; ++ ++ /* identifies byte ordering of file; ++ * always set to BYTE_RESHUFFLE_VALUE */ ++ u32 df_byte_reshuffle; ++ ++ /* Size of the string table up to and including the last section name */ ++ /* Size includes the name of the COFF file also */ ++ u32 df_scn_name_size; ++ ++#ifndef _BIG_ENDIAN ++ /* number of symbols */ ++ u16 df_no_syms; ++ ++ /* length in bytes of the longest string, including terminating NULL */ ++ /* excludes the name of the file */ ++ u16 df_max_str_len; ++ ++ /* total number of sections including no-load ones */ ++ u16 df_no_scns; ++ ++ /* number of sections containing target code allocated or downloaded */ ++ u16 df_target_scns; ++ ++ /* unique id for dll file format & version */ ++ u16 df_doff_version; ++ ++ /* identifies ISA */ ++ u16 df_target_id; ++ ++ /* useful file flags */ ++ u16 df_flags; ++ ++ /* section reference for entry point, N_UNDEF for none, */ ++ /* N_ABS for absolute address */ ++ s16 df_entry_secn; ++#else ++ /* length of the longest string, including terminating NULL */ ++ u16 df_max_str_len; ++ ++ /* number of symbols */ ++ u16 df_no_syms; ++ ++ /* number of sections containing target code allocated or downloaded */ ++ u16 df_target_scns; ++ ++ /* total number of sections including no-load ones */ ++ u16 df_no_scns; ++ ++ /* identifies ISA */ ++ u16 df_target_id; ++ ++ /* unique id for dll file format & version */ ++ u16 df_doff_version; ++ ++ /* section reference for entry point, N_UNDEF for none, */ ++ /* N_ABS for absolute address */ ++ s16 df_entry_secn; ++ ++ /* useful file flags */ ++ u16 df_flags; ++#endif ++ /* checksum for file header record */ ++ u32 df_checksum; ++ ++} ; ++ ++/* flags in the df_flags field */ ++#define DF_LITTLE 0x100 ++#define DF_BIG 0x200 ++#define DF_BYTE_ORDER (DF_LITTLE | DF_BIG) ++ ++/* Supported processors */ ++#define TMS470_ID 0x97 ++#define LEAD_ID 0x98 ++#define TMS32060_ID 0x99 ++#define LEAD3_ID 0x9c ++ ++/* Primary processor for loading */ ++#if TMS32060 ++#define TARGET_ID TMS32060_ID ++#endif ++ ++/* Verification record containing values used to test integrity of the bits */ ++struct doff_verify_rec_t { ++ ++ /* time and date stamp */ ++ u32 dv_timdat; ++ ++ /* checksum for all section records */ ++ u32 dv_scn_rec_checksum; ++ ++ /* checksum for string table */ ++ u32 dv_str_tab_checksum; ++ ++ /* checksum for symbol table */ ++ u32 dv_sym_tab_checksum; ++ ++ /* checksum for verification record */ ++ u32 dv_verify_rec_checksum; ++ ++} ; ++ ++/* String table is an array of null-terminated strings. The first entry is ++ * the filename, which is added by DLLcreate. No new structure definitions ++ * are required. ++ */ ++ ++/* Section Records including information on the corresponding image packets */ ++/* ++ * !!WARNING!! ++ * ++ * This structure is expected to match in form LDR_SECTION_INFO in ++ * dynamic_loader.h ++ */ ++ ++struct doff_scnhdr_t { ++ ++ s32 ds_offset; /* offset into string table of name */ ++ s32 ds_paddr; /* RUN address, in target AU */ ++ s32 ds_vaddr; /* LOAD address, in target AU */ ++ s32 ds_size; /* section size, in target AU */ ++#ifndef _BIG_ENDIAN ++ u16 ds_page; /* memory page id */ ++ u16 ds_flags; /* section flags */ ++#else ++ u16 ds_flags; /* section flags */ ++ u16 ds_page; /* memory page id */ ++#endif ++ u32 ds_first_pkt_offset; ++ /* Absolute byte offset into the file */ ++ /* where the first image record resides */ ++ ++ s32 ds_nipacks; /* number of image packets */ ++ ++}; ++ ++/* Symbol table entry */ ++struct doff_syment_t { ++ ++ s32 dn_offset; /* offset into string table of name */ ++ s32 dn_value; /* value of symbol */ ++#ifndef _BIG_ENDIAN ++ s16 dn_scnum; /* section number */ ++ s16 dn_sclass; /* storage class */ ++#else ++ s16 dn_sclass; /* storage class */ ++ s16 dn_scnum; /* section number, 1-based */ ++#endif ++ ++} ; ++ ++/* special values for dn_scnum */ ++#define DN_UNDEF 0 /* undefined symbol */ ++#define DN_ABS (-1) /* value of symbol is absolute */ ++/* special values for dn_sclass */ ++#define DN_EXT 2 ++#define DN_STATLAB 20 ++#define DN_EXTLAB 21 ++ ++/* Default value of image bits in packet */ ++/* Configurable by user on the command line */ ++#define IMAGE_PACKET_SIZE 1024 ++ ++/* An image packet contains a chunk of data from a section along with */ ++/* information necessary for its processing. */ ++struct image_packet_t { ++ ++ s32 i_num_relocs; /* number of relocations for */ ++ /* this packet */ ++ ++ s32 i_packet_size; /* number of bytes in array */ ++ /* "bits" occupied by */ ++ /* valid data. Could be */ ++ /* < IMAGE_PACKET_SIZE to */ ++ /* prevent splitting a */ ++ /* relocation across packets. */ ++ /* Last packet of a section */ ++ /* will most likely contain */ ++ /* < IMAGE_PACKET_SIZE bytes */ ++ /* of valid data */ ++ ++ s32 i_checksum; /* Checksum for image packet */ ++ /* and the corresponding */ ++ /* relocation records */ ++ ++ u8 *i_bits; /* Actual data in section */ ++ ++}; ++ ++/* The relocation structure definition matches the COFF version. Offsets */ ++/* however are relative to the image packet base not the section base. */ ++struct reloc_record_t { ++ ++ s32 r_vaddr; ++ ++ /* expressed in target AUs */ ++ ++ union { ++ struct { ++#ifndef _BIG_ENDIAN ++ u8 _offset; /* bit offset of rel fld */ ++ u8 _fieldsz; /* size of rel fld */ ++ u8 _wordsz; /* # bytes containing rel fld */ ++ u8 _dum1; ++ u16 _dum2; ++ u16 _type; ++#else ++ unsigned _dum1:8; ++ unsigned _wordsz:8; /* # bytes containing rel fld */ ++ unsigned _fieldsz:8; /* size of rel fld */ ++ unsigned _offset:8; /* bit offset of rel fld */ ++ u16 _type; ++ u16 _dum2; ++#endif ++ } _r_field; ++ ++ struct { ++ u32 _spc; /* image packet relative PC */ ++#ifndef _BIG_ENDIAN ++ u16 _dum; ++ u16 _type; /* relocation type */ ++#else ++ u16 _type; /* relocation type */ ++ u16 _dum; ++#endif ++ } _r_spc; ++ ++ struct { ++ u32 _uval; /* constant value */ ++#ifndef _BIG_ENDIAN ++ u16 _dum; ++ u16 _type; /* relocation type */ ++#else ++ u16 _type; /* relocation type */ ++ u16 _dum; ++#endif ++ } _r_uval; ++ ++ struct { ++ s32 _symndx; /* 32-bit sym tbl index */ ++#ifndef _BIG_ENDIAN ++ u16 _disp; /* extra addr encode data */ ++ u16 _type; /* relocation type */ ++#else ++ u16 _type; /* relocation type */ ++ u16 _disp; /* extra addr encode data */ ++#endif ++ } _r_sym; ++ } _u_reloc; ++ ++} ; ++ ++/* abbreviations for convenience */ ++#ifndef r_type ++#define r_type _u_reloc._r_sym._type ++#define r_uval _u_reloc._r_uval._uval ++#define r_symndx _u_reloc._r_sym._symndx ++#define r_offset _u_reloc._r_field._offset ++#define r_fieldsz _u_reloc._r_field._fieldsz ++#define r_wordsz _u_reloc._r_field._wordsz ++#define r_disp _u_reloc._r_sym._disp ++#endif ++ ++/*****************************************************************************/ ++/* */ ++/* Important DOFF macros used for file processing */ ++/* */ ++/*****************************************************************************/ ++ ++/* DOFF Versions */ ++#define DOFF0 0 ++ ++/* Return the address/size >= to addr that is at a 32-bit boundary */ ++/* This assumes that a byte is 8 bits */ ++#define DOFF_ALIGN(addr) (((addr) + 3) & ~UINT32_C(3)) ++ ++/*****************************************************************************/ ++/* */ ++/* The DOFF section header flags field is laid out as follows: */ ++/* */ ++/* Bits 0-3 : Section Type */ ++/* Bit 4 : Set when section requires target memory to be allocated by DL */ ++/* Bit 5 : Set when section requires downloading */ ++/* Bits 8-11: Alignment, same as COFF */ ++/* */ ++/*****************************************************************************/ ++ ++/* Enum for DOFF section types (bits 0-3 of flag): See dynamic_loader.h */ ++ ++/* Macros to help processing of sections */ ++#define DLOAD_SECT_TYPE(s_hdr) ((s_hdr)->ds_flags & 0xF) ++ ++/* DS_ALLOCATE indicates whether a section needs space on the target */ ++#define DS_ALLOCATE_MASK 0x10 ++#define DS_NEEDS_ALLOCATION(s_hdr) ((s_hdr)->ds_flags & DS_ALLOCATE_MASK) ++ ++/* DS_DOWNLOAD indicates that the loader needs to copy bits */ ++#define DS_DOWNLOAD_MASK 0x20 ++#define DS_NEEDS_DOWNLOAD(s_hdr) ((s_hdr)->ds_flags & DS_DOWNLOAD_MASK) ++ ++/* Section alignment requirement in AUs */ ++#define DS_ALIGNMENT(ds_flags) (1 << (((ds_flags) >> 8) & 0xF)) ++ ++#endif /* _DOFF_H */ +diff --git a/drivers/dsp/bridge/dynload/getsection.c b/drivers/dsp/bridge/dynload/getsection.c +new file mode 100644 +index 0000000..78a301a +--- /dev/null ++++ b/drivers/dsp/bridge/dynload/getsection.c +@@ -0,0 +1,412 @@ ++/* ++ * getsection.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++ ++#include ++#include "header.h" ++ ++/* ++ * Error strings ++ */ ++static const char E_READSTRM[] = { "Error reading %s from input stream" }; ++static const char E_SEEK[] = { "Set file position to %d failed" }; ++static const char E_ISIZ[] = { "Bad image packet size %d" }; ++static const char E_CHECKSUM[] = { "Checksum failed on %s" }; ++static const char E_RELOC[] = { "DLOAD_GetSection unable to read" ++ "sections containing relocation entries"}; ++#if BITS_PER_AU > BITS_PER_BYTE ++static const char E_ALLOC[] = { "Syms->Allocate( %d ) failed" }; ++static const char E_STBL[] = { "Bad string table offset " FMT_UI32 }; ++#endif ++ ++/* ++ * we use the fact that DOFF section records are shaped just like ++ * LDR_SECTION_INFO to reduce our section storage usage. These macros ++ * marks the places where that assumption is made ++ */ ++#define DOFFSEC_IS_LDRSEC(pdoffsec) ((struct LDR_SECTION_INFO *)(pdoffsec)) ++#define LDRSEC_IS_DOFFSEC(ldrsec) ((struct doff_scnhdr_t *)(ldrsec)) ++ ++/***************************************************************/ ++/********************* SUPPORT FUNCTIONS ***********************/ ++/***************************************************************/ ++ ++#if BITS_PER_AU > BITS_PER_BYTE ++/************************************************************************** ++ * Procedure unpack_sec_name ++ * ++ * Parameters: ++ * dlthis Handle from DLOAD_module_open for this module ++ * soffset Byte offset into the string table ++ * dst Place to store the expanded string ++ * ++ * Effect: ++ * Stores a string from the string table into the destination, expanding ++ * it in the process. Returns a pointer just past the end of the stored ++ * string on success, or NULL on failure. ++ * ++ *************************************************************************/ ++static char *unpack_sec_name(struct dload_state *dlthis, ++ u32 soffset, char *dst) ++{ ++ u8 tmp, *src; ++ ++ if (soffset >= dlthis->dfile_hdr.df_scn_name_size) { ++ dload_error(dlthis, E_STBL, soffset); ++ return NULL; ++ } ++ src = (u8 *)dlthis->str_head + ++ (soffset >> (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE)); ++ if (soffset & 1) ++ *dst++ = *src++; /* only 1 character in first word */ ++ do { ++ tmp = *src++; ++ *dst = (tmp >> BITS_PER_BYTE) ++ if (!(*dst++)) ++ break; ++ } while ((*dst++ = tmp & BYTE_MASK)); ++ ++ return dst; ++} ++ ++/************************************************************************** ++ * Procedure expand_sec_names ++ * ++ * Parameters: ++ * dlthis Handle from DLOAD_module_open for this module ++ * ++ * Effect: ++ * Allocates a buffer, unpacks and copies strings from string table into it. ++ * Stores a pointer to the buffer into a state variable. ++ **************************************************************************/ ++static void expand_sec_names(struct dload_state *dlthis) ++{ ++ char *xstrings, *curr, *next; ++ u32 xsize; ++ u16 sec; ++ struct LDR_SECTION_INFO *shp; ++ /* assume worst-case size requirement */ ++ xsize = dlthis->dfile_hdr.df_max_str_len * dlthis->dfile_hdr.df_no_scns; ++ xstrings = (char *)dlthis->mysym->Allocate(dlthis->mysym, xsize); ++ if (xstrings == NULL) { ++ dload_error(dlthis, E_ALLOC, xsize); ++ return; ++ } ++ dlthis->xstrings = xstrings; ++ /* For each sec, copy and expand its name */ ++ curr = xstrings; ++ for (sec = 0; sec < dlthis->dfile_hdr.df_no_scns; sec++) { ++ shp = DOFFSEC_IS_LDRSEC(&dlthis->sect_hdrs[sec]); ++ next = unpack_sec_name(dlthis, *(u32 *) &shp->name, curr); ++ if (next == NULL) ++ break; /* error */ ++ shp->name = curr; ++ curr = next; ++ } ++} ++ ++#endif ++ ++/***************************************************************/ ++/********************* EXPORTED FUNCTIONS **********************/ ++/***************************************************************/ ++ ++/************************************************************************** ++ * Procedure DLOAD_module_open ++ * ++ * Parameters: ++ * module The input stream that supplies the module image ++ * syms Host-side malloc/free and error reporting functions. ++ * Other methods are unused. ++ * ++ * Effect: ++ * Reads header information from a dynamic loader module using the ++ specified ++ * stream object, and returns a handle for the module information. This ++ * handle may be used in subsequent query calls to obtain information ++ * contained in the module. ++ * ++ * Returns: ++ * NULL if an error is encountered, otherwise a module handle for use ++ * in subsequent operations. ++ **************************************************************************/ ++DLOAD_module_info DLOAD_module_open(struct Dynamic_Loader_Stream *module, ++ struct Dynamic_Loader_Sym *syms) ++{ ++ struct dload_state *dlthis; /* internal state for this call */ ++ unsigned *dp, sz; ++ u32 sec_start; ++#if BITS_PER_AU <= BITS_PER_BYTE ++ u16 sec; ++#endif ++ ++ /* Check that mandatory arguments are present */ ++ if (!module || !syms) { ++ if (syms != NULL) ++ dload_syms_error(syms, "Required parameter is NULL"); ++ ++ return NULL; ++ } ++ ++ dlthis = (struct dload_state *) ++ syms->Allocate(syms, sizeof(struct dload_state)); ++ if (!dlthis) { ++ /* not enough storage */ ++ dload_syms_error(syms, "Can't allocate module info"); ++ return NULL; ++ } ++ ++ /* clear our internal state */ ++ dp = (unsigned *)dlthis; ++ for (sz = sizeof(struct dload_state) / sizeof(unsigned); ++ sz > 0; sz -= 1) ++ *dp++ = 0; ++ ++ dlthis->strm = module; ++ dlthis->mysym = syms; ++ ++ /* read in the doff image and store in our state variable */ ++ dload_headers(dlthis); ++ ++ if (!dlthis->dload_errcount) ++ dload_strings(dlthis, true); ++ ++ /* skip ahead past the unread portion of the string table */ ++ sec_start = sizeof(struct doff_filehdr_t) + ++ sizeof(struct doff_verify_rec_t) + ++ BYTE_TO_HOST(DOFF_ALIGN(dlthis->dfile_hdr.df_strtab_size)); ++ ++ if (dlthis->strm->set_file_posn(dlthis->strm, sec_start) != 0) { ++ dload_error(dlthis, E_SEEK, sec_start); ++ return NULL; ++ } ++ ++ if (!dlthis->dload_errcount) ++ dload_sections(dlthis); ++ ++ if (dlthis->dload_errcount) { ++ DLOAD_module_close(dlthis); /* errors, blow off our state */ ++ dlthis = NULL; ++ return NULL; ++ } ++#if BITS_PER_AU > BITS_PER_BYTE ++ /* Expand all section names from the string table into the */ ++ /* state variable, and convert section names from a relative */ ++ /* string table offset to a pointers to the expanded string. */ ++ expand_sec_names(dlthis); ++#else ++ /* Convert section names from a relative string table offset */ ++ /* to a pointer into the string table. */ ++ for (sec = 0; sec < dlthis->dfile_hdr.df_no_scns; sec++) { ++ struct LDR_SECTION_INFO *shp = ++ DOFFSEC_IS_LDRSEC(&dlthis->sect_hdrs[sec]); ++ shp->name = dlthis->str_head + *(u32 *)&shp->name; ++ } ++#endif ++ ++ return dlthis; ++} ++ ++/*************************************************************************** ++ * Procedure DLOAD_GetSectionInfo ++ * ++ * Parameters: ++ * minfo Handle from DLOAD_module_open for this module ++ * sectionName Pointer to the string name of the section desired ++ * sectionInfo Address of a section info structure pointer to be ++ * initialized ++ * ++ * Effect: ++ * Finds the specified section in the module information, and initializes ++ * the provided struct LDR_SECTION_INFO pointer. ++ * ++ * Returns: ++ * true for success, false for section not found ++ **************************************************************************/ ++int DLOAD_GetSectionInfo(DLOAD_module_info minfo, const char *sectionName, ++ const struct LDR_SECTION_INFO **const sectionInfo) ++{ ++ struct dload_state *dlthis; ++ struct LDR_SECTION_INFO *shp; ++ u16 sec; ++ ++ dlthis = (struct dload_state *)minfo; ++ if (!dlthis) ++ return false; ++ ++ for (sec = 0; sec < dlthis->dfile_hdr.df_no_scns; sec++) { ++ shp = DOFFSEC_IS_LDRSEC(&dlthis->sect_hdrs[sec]); ++ if (strcmp(sectionName, shp->name) == 0) { ++ *sectionInfo = shp; ++ return true; ++ } ++ } ++ ++ return false; ++} ++ ++#define IPH_SIZE (sizeof(struct image_packet_t) - sizeof(u32)) ++#define REVERSE_REORDER_MAP(rawmap) ((rawmap) ^ 0x3030303) ++ ++/************************************************************************** ++ * Procedure DLOAD_GetSection ++ * ++ * Parameters: ++ * minfo Handle from DLOAD_module_open for this module ++ * sectionInfo Pointer to a section info structure for the desired ++ * section ++ * sectionData Buffer to contain the section initialized data ++ * ++ * Effect: ++ * Copies the initialized data for the specified section into the ++ * supplied buffer. ++ * ++ * Returns: ++ * true for success, false for section not found ++ **************************************************************************/ ++int DLOAD_GetSection(DLOAD_module_info minfo, ++ const struct LDR_SECTION_INFO *sectionInfo, void *sectionData) ++{ ++ struct dload_state *dlthis; ++ u32 pos; ++ struct doff_scnhdr_t *sptr = NULL; ++ s32 nip; ++ struct image_packet_t ipacket; ++ s32 ipsize; ++ u32 checks; ++ s8 *dest = (s8 *)sectionData; ++ ++ dlthis = (struct dload_state *)minfo; ++ if (!dlthis) ++ return false; ++ sptr = LDRSEC_IS_DOFFSEC(sectionInfo); ++ if (sptr == NULL) ++ return false; ++ ++ /* skip ahead to the start of the first packet */ ++ pos = BYTE_TO_HOST(DOFF_ALIGN((u32) sptr->ds_first_pkt_offset)); ++ if (dlthis->strm->set_file_posn(dlthis->strm, pos) != 0) { ++ dload_error(dlthis, E_SEEK, pos); ++ return false; ++ } ++ ++ nip = sptr->ds_nipacks; ++ while ((nip -= 1) >= 0) { /* for each packet */ ++ /* get the fixed header bits */ ++ if (dlthis->strm-> ++ read_buffer(dlthis->strm, &ipacket, IPH_SIZE) != IPH_SIZE) { ++ dload_error(dlthis, E_READSTRM, "image packet"); ++ return false; ++ } ++ /* reorder the header if need be */ ++ if (dlthis->reorder_map) ++ dload_reorder(&ipacket, IPH_SIZE, dlthis->reorder_map); ++ ++ /* Now read the packet image bits. Note: round the size up to ++ * the next multiple of 4 bytes; this is what checksum ++ * routines want. */ ++ ipsize = BYTE_TO_HOST(DOFF_ALIGN(ipacket.i_packet_size)); ++ if (ipsize > BYTE_TO_HOST(IMAGE_PACKET_SIZE)) { ++ dload_error(dlthis, E_ISIZ, ipsize); ++ return false; ++ } ++ if (dlthis->strm->read_buffer ++ (dlthis->strm, dest, ipsize) != ipsize) { ++ dload_error(dlthis, E_READSTRM, "image packet"); ++ return false; ++ } ++ /* reorder the bytes if need be */ ++#if !defined(_BIG_ENDIAN) || (TARGET_AU_BITS > 16) ++ if (dlthis->reorder_map) ++ dload_reorder(dest, ipsize, dlthis->reorder_map); ++ ++ checks = dload_checksum(dest, ipsize); ++#else ++ if (dlthis->dfile_hdr.df_byte_reshuffle != ++ TARGET_ORDER(REORDER_MAP(BYTE_RESHUFFLE_VALUE))) { ++ /* put image bytes in big-endian order, not PC order */ ++ dload_reorder(dest, ipsize, ++ TARGET_ORDER(dlthis->dfile_hdr. ++ df_byte_reshuffle)); ++ } ++#if TARGET_AU_BITS > 8 ++ checks = dload_reverse_checksum_16(dest, ipsize); ++#else ++ checks = dload_reverse_checksum(dest, ipsize); ++#endif ++#endif ++ checks += dload_checksum(&ipacket, IPH_SIZE); ++ ++ /* NYI: unable to handle relocation entries here. Reloc ++ * entries referring to fields that span the packet boundaries ++ * may result in packets of sizes that are not multiple of ++ * 4 bytes. Our checksum implementation works on 32-bit words ++ * only. */ ++ if (ipacket.i_num_relocs != 0) { ++ dload_error(dlthis, E_RELOC, ipsize); ++ return false; ++ } ++ ++ if (~checks) { ++ dload_error(dlthis, E_CHECKSUM, "image packet"); ++ return false; ++ } ++ ++ /*Advance destination ptr by the size of the just-read packet*/ ++ dest += ipsize; ++ } ++ ++ return true; ++} ++ ++/*************************************************************************** ++ * Procedure DLOAD_module_close ++ * ++ * Parameters: ++ * minfo Handle from DLOAD_module_open for this module ++ * ++ * Effect: ++ * Releases any storage associated with the module handle. On return, ++ * the module handle is invalid. ++ * ++ * Returns: ++ * Zero for success. On error, the number of errors detected is returned. ++ * Individual errors are reported using syms->Error_Report(), where syms was ++ * an argument to DLOAD_module_open ++ **************************************************************************/ ++void DLOAD_module_close(DLOAD_module_info minfo) ++{ ++ struct dload_state *dlthis; ++ ++ dlthis = (struct dload_state *)minfo; ++ if (!dlthis) ++ return; ++ ++ if (dlthis->str_head) ++ dlthis->mysym->Deallocate(dlthis->mysym, dlthis->str_head); ++ ++ if (dlthis->sect_hdrs) ++ dlthis->mysym->Deallocate(dlthis->mysym, dlthis->sect_hdrs); ++ ++#if BITS_PER_AU > BITS_PER_BYTE ++ if (dlthis->xstrings) ++ dlthis->mysym->Deallocate(dlthis->mysym, dlthis->xstrings); ++ ++#endif ++ ++ dlthis->mysym->Deallocate(dlthis->mysym, dlthis); ++} +diff --git a/drivers/dsp/bridge/dynload/header.h b/drivers/dsp/bridge/dynload/header.h +new file mode 100644 +index 0000000..0de744b +--- /dev/null ++++ b/drivers/dsp/bridge/dynload/header.h +@@ -0,0 +1,59 @@ ++/* ++ * header.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++ ++#define TRUE 1 ++#define FALSE 0 ++#ifndef NULL ++#define NULL 0 ++#endif ++ ++#include ++#define DL_STRCMP strcmp ++ ++/* maximum parenthesis nesting in relocation stack expressions */ ++#define STATIC_EXPR_STK_SIZE 10 ++ ++#include ++typedef unsigned int uint_least32_t; ++typedef unsigned short int uint_least16_t; ++ ++#include "doff.h" ++#include ++#include "params.h" ++#include "dload_internal.h" ++#include "reloc_table.h" ++ ++/* ++ * Plausibility limits ++ * ++ * These limits are imposed upon the input DOFF file as a check for validity. ++ * They are hard limits, in that the load will fail if they are exceeded. ++ * The numbers selected are arbitrary, in that the loader implementation does ++ * not require these limits. ++ */ ++ ++/* maximum number of bytes in string table */ ++#define MAX_REASONABLE_STRINGTAB (0x100000) ++/* maximum number of code,data,etc. sections */ ++#define MAX_REASONABLE_SECTIONS (200) ++/* maximum number of linker symbols */ ++#define MAX_REASONABLE_SYMBOLS (100000) ++ ++/* shift count to align F_BIG with DLOAD_LITTLE */ ++#define ALIGN_COFF_ENDIANNESS 7 ++#define ENDIANNESS_MASK (DF_BYTE_ORDER >> ALIGN_COFF_ENDIANNESS) +diff --git a/drivers/dsp/bridge/dynload/module_list.h b/drivers/dsp/bridge/dynload/module_list.h +new file mode 100644 +index 0000000..9c4876a +--- /dev/null ++++ b/drivers/dsp/bridge/dynload/module_list.h +@@ -0,0 +1,161 @@ ++/* ++ * dspbridge/mpu_driver/src/dynload/module_list.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/*============================================================================ ++ Filename: module_list.h ++ ++ Copyright (C) 2002 Texas Instruments Incorporated ++ ++ ++ This C header file gives the layout of the data structure created by the ++ dynamic loader to describe the set of modules loaded into the DSP. ++ ++ Linked List Structure: ++ ---------------------- ++ The data structure defined here is a singly-linked list. The list ++ represents the set of modules which are currently loaded in the DSP memory. ++ The first entry in the list is a header record which contains a flag ++ representing the state of the list. The rest of the entries in the list ++ are module records. ++ ++ Global symbol _DLModules designates the first record in the list (i.e. the ++ header record). This symbol must be defined in any program that wishes to ++ use DLLview plug-in. ++ ++ String Representation: ++ ---------------------- ++ The string names of the module and its sections are stored in a block of ++ memory which follows the module record itself. The strings are ordered: ++ module name first, followed by section names in order from the first ++ section to the last. String names are tightly packed arrays of 8-bit ++ characters (two characters per 16-bit word on the C55x). Strings are ++ zero-byte-terminated. ++ ++ Creating and updating the list: ++------------------------------- ++ Upon loading a new module into the DSP memory the dynamic loader inserts a ++new module record as the first module record in the list. The fields of ++ this module record are initialized to reflect the properties of the module. ++ The dynamic loader does NOT increment the flag/counter in the list's header ++ record. ++ ++ Upon unloading a module from the DSP memory the dynamic loader removes the ++module's record from this list. The dynamic loader also increments the ++ flag/counter in the list's header record to indicate that the list has been ++ changed. ++ ++============================================================================*/ ++ ++#ifndef _MODULE_LIST_H_ ++#define _MODULE_LIST_H_ ++ ++#include ++ ++/* Global pointer to the modules_header structure*/ ++#define MODULES_HEADER "_DLModules" ++#define MODULES_HEADER_NO_UNDERSCORE "DLModules" ++ ++/* Initial version number*/ ++#define INIT_VERSION 1 ++ ++/* Verification number -- to be recorded in each module record */ ++#define VERIFICATION 0x79 ++ ++/* forward declarations */ ++struct dll_module; ++struct dll_sect; ++ ++/* the first entry in the list is the modules_header record; ++ * its address is contained in the global _DLModules pointer */ ++struct modules_header { ++ ++ /* Address of the first dll_module record in the list or NULL. ++ Note: for C55x this is a word address (C55x data is word-addressable)*/ ++ u32 first_module; ++ ++ /* Combined storage size (in target addressable units) of the ++ * dll_module record which follows this header record, or zero ++ * if the list is empty. This size includes the module's string table. ++ * Note: for C55x the unit is a 16-bit word */ ++ u16 first_module_size; ++ ++ /* Counter is incremented whenever a module record is removed from ++ * the list */ ++ u16 update_flag; ++ ++} ; ++ ++/* for each 32-bits in above structure, a bitmap, LSB first, whose bits are: ++ * 0 => a 32-bit value, 1 => 2 16-bit values */ ++#define MODULES_HEADER_BITMAP 0x2 /* swapping bitmap for type modules_header */ ++ ++/* information recorded about each section in a module */ ++struct dll_sect { ++ ++ /* Load-time address of the section. ++ * Note: for C55x this is a byte address for program sections, and ++ * a word address for data sections. C55x program memory is ++ * byte-addressable, while data memory is word-addressable. */ ++ u32 sect_load_adr; ++ ++ /* Run-time address of the section. ++ * Note 1: for C55x this is a byte address for program sections, and ++ * a word address for data sections. ++ * Note 2: for C55x two most significant bits of this field indicate ++ * the section type: '00' for a code section, '11' for a data section ++ * (C55 addresses are really only 24-bits wide). */ ++ u32 sect_run_adr; ++ ++} ; ++ ++/* the rest of the entries in the list are module records */ ++struct dll_module { ++ ++ /* Address of the next dll_module record in the list, or 0 if this is ++ * the last record in the list. ++ * Note: for C55x this is a word address (C55x data is ++ * word-addressable) */ ++ u32 next_module; ++ ++ /* Combined storage size (in target addressable units) of the ++ * dll_module record which follows this one, or zero if this is the ++ * last record in the list. This size includes the module's string ++ * table. ++ * Note: for C55x the unit is a 16-bit word. */ ++ u16 next_module_size; ++ ++ /* version number of the tooling; set to INIT_VERSION for Phase 1 */ ++ u16 version; ++ ++ /* the verification word; set to VERIFICATION */ ++ u16 verification; ++ ++ /* Number of sections in the sects array */ ++ u16 num_sects; ++ ++ /* Module's "unique" id; copy of the timestamp from the host ++ * COFF file */ ++ u32 timestamp; ++ ++ /* Array of num_sects elements of the module's section records */ ++ struct dll_sect sects[1]; ++} ; ++ ++/* for each 32 bits in above structure, a bitmap, LSB first, whose bits are: ++ * 0 => a 32-bit value, 1 => 2 16-bit values */ ++#define DLL_MODULE_BITMAP 0x6 /* swapping bitmap for type dll_module */ ++ ++#endif /* _MODULE_LIST_H_ */ +diff --git a/drivers/dsp/bridge/dynload/params.h b/drivers/dsp/bridge/dynload/params.h +new file mode 100644 +index 0000000..ade430d +--- /dev/null ++++ b/drivers/dsp/bridge/dynload/params.h +@@ -0,0 +1,231 @@ ++/* ++ * params.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++ ++/****************************************************************************** ++ * ++ * This file defines host and target properties for all machines ++ * supported by the dynamic loader. To be tedious... ++ * ++ * host == the machine on which the dynamic loader runs ++ * target == the machine that the dynamic loader is loading ++ * ++ * Host and target may or may not be the same, depending upon the particular ++ * use. ++ *****************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * Host Properties ++ * ++ *****************************************************************************/ ++ ++#define BITS_PER_BYTE 8 /* bits in the standard PC/SUN byte */ ++#define LOG_BITS_PER_BYTE 3 /* log base 2 of same */ ++#define BYTE_MASK ((1U<> 16)) ++#define SWAP16BY8(zz) (((zz) << 8) | ((zz) >> 8)) ++ ++/* !! don't be tempted to insert type definitions here; use !! */ ++ ++/****************************************************************************** ++ * ++ * Target Properties ++ * ++ *****************************************************************************/ ++ ++ ++/*--------------------------------------------------------------------------*/ ++/* TMS320C6x Target Specific Parameters (byte-addressable) */ ++/*--------------------------------------------------------------------------*/ ++#if TMS32060 ++#define MEMORG 0x0L /* Size of configured memory */ ++#define MEMSIZE 0x0L /* (full address space) */ ++ ++#define CINIT_ALIGN 8 /* alignment of cinit record in TDATA AUs */ ++#define CINIT_COUNT 4 /* width of count field in TDATA AUs */ ++#define CINIT_ADDRESS 4 /* width of address field in TDATA AUs */ ++#define CINIT_PAGE_BITS 0 /* Number of LSBs of address that ++ * are page number */ ++ ++#define LENIENT_SIGNED_RELEXPS 0 /* DOES SIGNED ALLOW MAX UNSIGNED */ ++ ++#undef TARGET_ENDIANNESS /* may be big or little endian */ ++ ++/* align a target address to a word boundary */ ++#define TARGET_WORD_ALIGN(zz) (((zz) + 0x3) & -0x4) ++#endif ++ ++ ++/*-------------------------------------------------------------------------- ++ * ++ * DEFAULT SETTINGS and DERIVED PROPERTIES ++ * ++ * This section establishes defaults for values not specified above ++ *--------------------------------------------------------------------------*/ ++#ifndef TARGET_AU_BITS ++#define TARGET_AU_BITS 8 /* width of the target addressable unit */ ++#define LOG_TARGET_AU_BITS 3 /* log2 of same */ ++#endif ++ ++#ifndef CINIT_DEFAULT_PAGE ++#define CINIT_DEFAULT_PAGE 0 /* default .cinit page number */ ++#endif ++ ++#ifndef DATA_RUN2LOAD ++#define DATA_RUN2LOAD(zz) (zz) /* translate data run address to load address */ ++#endif ++ ++#ifndef DBG_LIST_PAGE ++#define DBG_LIST_PAGE 0 /* page number for .dllview section */ ++#endif ++ ++#ifndef TARGET_WORD_ALIGN ++/* align a target address to a word boundary */ ++#define TARGET_WORD_ALIGN(zz) (zz) ++#endif ++ ++#ifndef TDATA_TO_TADDR ++#define TDATA_TO_TADDR(zz) (zz) /* target data address to target AU address */ ++#define TADDR_TO_TDATA(zz) (zz) /* target AU address to target data address */ ++#define TDATA_AU_BITS TARGET_AU_BITS /* bits per data AU */ ++#define LOG_TDATA_AU_BITS LOG_TARGET_AU_BITS ++#endif ++ ++/* ++ * ++ * Useful properties and conversions derived from the above ++ * ++ */ ++ ++/* ++ * Conversions between host and target addresses ++ */ ++#if LOG_BITS_PER_AU == LOG_TARGET_AU_BITS ++/* translate target addressable unit to host address */ ++#define TADDR_TO_HOST(x) (x) ++/* translate host address to target addressable unit */ ++#define HOST_TO_TADDR(x) (x) ++#elif LOG_BITS_PER_AU > LOG_TARGET_AU_BITS ++#define TADDR_TO_HOST(x) ((x) >> (LOG_BITS_PER_AU-LOG_TARGET_AU_BITS)) ++#define HOST_TO_TADDR(x) ((x) << (LOG_BITS_PER_AU-LOG_TARGET_AU_BITS)) ++#else ++#define TADDR_TO_HOST(x) ((x) << (LOG_TARGET_AU_BITS-LOG_BITS_PER_AU)) ++#define HOST_TO_TADDR(x) ((x) >> (LOG_TARGET_AU_BITS-LOG_BITS_PER_AU)) ++#endif ++ ++#if LOG_BITS_PER_AU == LOG_TDATA_AU_BITS ++/* translate target addressable unit to host address */ ++#define TDATA_TO_HOST(x) (x) ++/* translate host address to target addressable unit */ ++#define HOST_TO_TDATA(x) (x) ++/* translate host address to target addressable unit, round up */ ++#define HOST_TO_TDATA_ROUND(x) (x) ++/* byte offset to host offset, rounded up for TDATA size */ ++#define BYTE_TO_HOST_TDATA_ROUND(x) BYTE_TO_HOST_ROUND(x) ++#elif LOG_BITS_PER_AU > LOG_TDATA_AU_BITS ++#define TDATA_TO_HOST(x) ((x) >> (LOG_BITS_PER_AU-LOG_TDATA_AU_BITS)) ++#define HOST_TO_TDATA(x) ((x) << (LOG_BITS_PER_AU-LOG_TDATA_AU_BITS)) ++#define HOST_TO_TDATA_ROUND(x) ((x) << (LOG_BITS_PER_AU-LOG_TDATA_AU_BITS)) ++#define BYTE_TO_HOST_TDATA_ROUND(x) BYTE_TO_HOST_ROUND(x) ++#else ++#define TDATA_TO_HOST(x) ((x) << (LOG_TDATA_AU_BITS-LOG_BITS_PER_AU)) ++#define HOST_TO_TDATA(x) ((x) >> (LOG_TDATA_AU_BITS-LOG_BITS_PER_AU)) ++#define HOST_TO_TDATA_ROUND(x) (((x) +\ ++ (1<<(LOG_TDATA_AU_BITS-LOG_BITS_PER_AU))-1) >>\ ++ (LOG_TDATA_AU_BITS-LOG_BITS_PER_AU)) ++#define BYTE_TO_HOST_TDATA_ROUND(x) (BYTE_TO_HOST((x) +\ ++ (1<<(LOG_TDATA_AU_BITS-LOG_BITS_PER_BYTE))-1) &\ ++ -(TDATA_AU_BITS/BITS_PER_AU)) ++#endif ++ ++/* ++ * Input in DOFF format is always expresed in bytes, regardless of loading host ++ * so we wind up converting from bytes to target and host units even when the ++ * host is not a byte machine. ++ */ ++#if LOG_BITS_PER_AU == LOG_BITS_PER_BYTE ++#define BYTE_TO_HOST(x) (x) ++#define BYTE_TO_HOST_ROUND(x) (x) ++#define HOST_TO_BYTE(x) (x) ++#elif LOG_BITS_PER_AU >= LOG_BITS_PER_BYTE ++#define BYTE_TO_HOST(x) ((x) >> (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE)) ++#define BYTE_TO_HOST_ROUND(x) ((x + (BITS_PER_AU/BITS_PER_BYTE-1)) >>\ ++ (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE)) ++#define HOST_TO_BYTE(x) ((x) << (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE)) ++#else ++/* lets not try to deal with sub-8-bit byte machines */ ++#endif ++ ++#if LOG_TARGET_AU_BITS == LOG_BITS_PER_BYTE ++/* translate target addressable unit to byte address */ ++#define TADDR_TO_BYTE(x) (x) ++/* translate byte address to target addressable unit */ ++#define BYTE_TO_TADDR(x) (x) ++#elif LOG_TARGET_AU_BITS > LOG_BITS_PER_BYTE ++#define TADDR_TO_BYTE(x) ((x) << (LOG_TARGET_AU_BITS-LOG_BITS_PER_BYTE)) ++#define BYTE_TO_TADDR(x) ((x) >> (LOG_TARGET_AU_BITS-LOG_BITS_PER_BYTE)) ++#else ++/* lets not try to deal with sub-8-bit byte machines */ ++#endif ++ ++#ifdef _BIG_ENDIAN ++#define HOST_ENDIANNESS 1 ++#else ++#define HOST_ENDIANNESS 0 ++#endif ++ ++#ifdef TARGET_ENDIANNESS ++#define TARGET_ENDIANNESS_DIFFERS(rtend) (HOST_ENDIANNESS^TARGET_ENDIANNESS) ++#elif HOST_ENDIANNESS ++#define TARGET_ENDIANNESS_DIFFERS(rtend) (!(rtend)) ++#else ++#define TARGET_ENDIANNESS_DIFFERS(rtend) (rtend) ++#endif ++ ++/* the unit in which we process target image data */ ++#if TARGET_AU_BITS <= 8 ++typedef u8 TgtAU_t; ++#elif TARGET_AU_BITS <= 16 ++typedef u16 TgtAU_t; ++#else ++typedef u32 TgtAU_t; ++#endif ++ ++/* size of that unit */ ++#if TARGET_AU_BITS < BITS_PER_AU ++#define TGTAU_BITS BITS_PER_AU ++#define LOG_TGTAU_BITS LOG_BITS_PER_AU ++#else ++#define TGTAU_BITS TARGET_AU_BITS ++#define LOG_TGTAU_BITS LOG_TARGET_AU_BITS ++#endif +diff --git a/drivers/dsp/bridge/dynload/reloc.c b/drivers/dsp/bridge/dynload/reloc.c +new file mode 100644 +index 0000000..54e460e +--- /dev/null ++++ b/drivers/dsp/bridge/dynload/reloc.c +@@ -0,0 +1,425 @@ ++/* ++ * reloc.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++#include "header.h" ++ ++#if TMS32060 ++/* the magic symbol for the start of BSS */ ++static const char BSSSYMBOL[] = {".bss"}; ++#endif ++ ++#if TMS32060 ++#include "reloc_table_c6000.c" ++#endif ++ ++#if TMS32060 ++/* From coff.h - ignore these relocation operations */ ++#define R_C60ALIGN 0x76 /* C60: Alignment info for compressor */ ++#define R_C60FPHEAD 0x77 /* C60: Explicit assembly directive */ ++#define R_C60NOCMP 0x100 /* C60: Don't compress this code scn */ ++#endif ++ ++/************************************************************************** ++ * Procedure dload_unpack ++ * ++ * Parameters: ++ * data pointer to storage unit containing lowest host address of ++ * image data ++ * fieldsz Size of bit field, 0 < fieldsz <= sizeof(RVALUE)*BITS_PER_AU ++ * offset Offset from LSB, 0 <= offset < BITS_PER_AU ++ * sgn Signedness of the field (ROP_SGN, ROP_UNS, ROP_MAX, ROP_ANY) ++ * ++ * Effect: ++ * Extracts the specified field and returns it. ++ **************************************************************************/ ++RVALUE dload_unpack(struct dload_state *dlthis, TgtAU_t *data, int fieldsz, ++ int offset, unsigned sgn) ++{ ++ register RVALUE objval; ++ register int shift, direction; ++ register TgtAU_t *dp = data; ++ ++ fieldsz -= 1; /* avoid nastiness with 32-bit shift of 32-bit value*/ ++ /* * collect up enough bits to contain the desired field */ ++ if (TARGET_BIG_ENDIAN) { ++ dp += (fieldsz + offset) >> LOG_TGTAU_BITS; ++ direction = -1; ++ } else ++ direction = 1; ++ objval = *dp >> offset; ++ shift = TGTAU_BITS - offset; ++ while (shift <= fieldsz) { ++ dp += direction; ++ objval += (RVALUE)*dp << shift; ++ shift += TGTAU_BITS; ++ } ++ ++ /* * sign or zero extend the value appropriately */ ++ if (sgn == ROP_UNS) ++ objval &= (2 << fieldsz) - 1; ++ else { ++ shift = sizeof(RVALUE) * BITS_PER_AU-1 - fieldsz; ++ objval = (objval << shift) >> shift; ++ } ++ ++ return objval; ++ ++} /* dload_unpack */ ++ ++ ++/************************************************************************** ++ * Procedure dload_repack ++ * ++ * Parameters: ++ * val Value to insert ++ * data Pointer to storage unit containing lowest host address of ++ * image data ++ * fieldsz Size of bit field, 0 < fieldsz <= sizeof(RVALUE)*BITS_PER_AU ++ * offset Offset from LSB, 0 <= offset < BITS_PER_AU ++ * sgn Signedness of the field (ROP_SGN, ROP_UNS, ROP_MAX, ROP_ANY) ++ * ++ * Effect: ++ * Stuffs the specified value in the specified field. Returns 0 for ++ * success ++ * or 1 if the value will not fit in the specified field according to the ++ * specified signedness rule. ++ **************************************************************************/ ++static const unsigned char ovf_limit[] = {1, 2, 2}; ++int dload_repack(struct dload_state *dlthis, RVALUE val, TgtAU_t *data, ++ int fieldsz, int offset, unsigned sgn) ++{ ++ register URVALUE objval, mask; ++ register int shift, direction; ++ register TgtAU_t *dp = data; ++ ++ ++ fieldsz -= 1; /* avoid nastiness with 32-bit shift of 32-bit value */ ++ /* clip the bits */ ++ mask = ((UINT32_C(2) << fieldsz) - 1); ++ objval = (val & mask); ++ /* * store the bits through the specified mask */ ++ if (TARGET_BIG_ENDIAN) { ++ dp += (fieldsz + offset) >> LOG_TGTAU_BITS; ++ direction = -1; ++ } else ++ direction = 1; ++ ++ /* insert LSBs */ ++ *dp = (*dp & ~(mask << offset)) + (objval << offset); ++ shift = TGTAU_BITS-offset; ++ /* align mask and objval with AU boundary */ ++ objval >>= shift; ++ mask >>= shift; ++ ++ while (mask) { ++ dp += direction; ++ *dp = (*dp & ~mask) + objval; ++ objval >>= TGTAU_BITS; ++ mask >>= TGTAU_BITS; ++ } ++ ++ /* ++ * check for overflow ++ */ ++ if (sgn) { ++ unsigned tmp = (val >> fieldsz) + (sgn & 0x1); ++ if (tmp > ovf_limit[sgn-1]) ++ return 1; ++ } ++ return 0; ++ ++} /* dload_repack */ ++ ++/* lookup table for the scaling amount in a C6x instruction */ ++#if TMS32060 ++#define SCALE_BITS 4 /* there are 4 bits in the scale field */ ++#define SCALE_MASK 0x7 /* we really only use the bottom 3 bits */ ++static const u8 C60_Scale[SCALE_MASK+1] = { ++ 1, 0, 0, 0, 1, 1, 2, 2 ++}; ++#endif ++ ++/************************************************************************** ++ * Procedure dload_relocate ++ * ++ * Parameters: ++ * data Pointer to base of image data ++ * rp Pointer to relocation operation ++ * ++ * Effect: ++ * Performs the specified relocation operation ++ **************************************************************************/ ++void dload_relocate(struct dload_state *dlthis, TgtAU_t *data, ++ struct reloc_record_t *rp) ++{ ++ RVALUE val = 0; ++ RVALUE reloc_amt = 0; ++ unsigned int fieldsz = 0; ++ unsigned int offset = 0; ++ unsigned int reloc_info = 0; ++ unsigned int reloc_action = 0; ++ register int rx = 0; ++ RVALUE *stackp = NULL; ++ int top; ++ struct Local_Symbol *svp = NULL; ++#ifdef RFV_SCALE ++ unsigned int scale = 0; ++#endif ++ ++ rx = HASH_FUNC(rp->r_type); ++ while (rop_map1[rx] != rp->r_type) { ++ rx = HASH_L(rop_map2[rx]); ++ if (rx < 0) { ++#if TMS32060 ++ switch (rp->r_type) { ++ case R_C60ALIGN: ++ case R_C60NOCMP: ++ case R_C60FPHEAD: ++ /* Ignore these reloc types and return */ ++ break; ++ default: ++ /* Unknown reloc type, print error and return */ ++ dload_error(dlthis, "Bad coff operator 0x%x", rp->r_type); ++ } ++#else ++ dload_error(dlthis, "Bad coff operator 0x%x", rp->r_type); ++#endif ++ return; ++ } ++ } ++ rx = HASH_I(rop_map2[rx]); ++ if ((rx < (sizeof(rop_action)/sizeof(uint_least16_t))) ++ && (rx < (sizeof(rop_info)/sizeof(uint_least16_t))) && (rx > 0)) { ++ reloc_action = rop_action[rx]; reloc_info = rop_info[rx]; ++ } else { ++ dload_error(dlthis, "Buffer Overflow - Array Index Out of Bounds"); ++ } ++ ++ /* Compute the relocation amount for the referenced symbol, if any */ ++ reloc_amt = rp->r_uval; ++ if (RFV_SYM(reloc_info)) { /* relocation uses a symbol reference */ ++ if ((u32)rp->r_symndx < dlthis->dfile_hdr.df_no_syms) { ++ /* real symbol reference */ ++ svp = &dlthis->local_symtab[rp->r_symndx]; ++ reloc_amt = (RFV_SYM(reloc_info) == ROP_SYMD) ? ++ svp->delta : svp->value; ++ } ++ /* reloc references current section */ ++ else if (rp->r_symndx == -1) ++ reloc_amt = (RFV_SYM(reloc_info) == ROP_SYMD) ? ++ dlthis->delta_runaddr : dlthis->image_secn->run_addr; ++ } /* relocation uses a symbol reference */ ++ /* Handle stack adjustment */ ++ val = 0; ++ top = RFV_STK(reloc_info); ++ if (top) { ++ top += dlthis->relstkidx - RSTK_UOP; ++ if (top >= STATIC_EXPR_STK_SIZE) { ++ dload_error(dlthis, ++ "Expression stack overflow in %s at offset " ++ FMT_UI32, dlthis->image_secn->name, ++ rp->r_vaddr + dlthis->image_offset); ++ return; ++ } ++ val = dlthis->relstk[dlthis->relstkidx]; ++ dlthis->relstkidx = top; ++ stackp = &dlthis->relstk[top]; ++ } ++ /* Derive field position and size, if we need them */ ++ if (reloc_info & ROP_RW) { /* read or write action in our future */ ++ fieldsz = RFV_WIDTH(reloc_action); ++ if (fieldsz) { /* field info from table */ ++ offset = RFV_POSN(reloc_action); ++ if (TARGET_BIG_ENDIAN) ++ /* make sure r_vaddr is the lowest target ++ * address containing bits */ ++ rp->r_vaddr += RFV_BIGOFF(reloc_info); ++ } else { /* field info from relocation op */ ++ fieldsz = rp->r_fieldsz; offset = rp->r_offset; ++ if (TARGET_BIG_ENDIAN) ++ /* make sure r_vaddr is the lowest target ++ address containing bits */ ++ rp->r_vaddr += (rp->r_wordsz - offset - fieldsz) ++ >> LOG_TARGET_AU_BITS; ++ } ++ data = (TgtAU_t *)((char *)data + TADDR_TO_HOST(rp->r_vaddr)); ++ /* compute lowest host location of referenced data */ ++#if BITS_PER_AU > TARGET_AU_BITS ++ /* conversion from target address to host address may lose ++ address bits; add loss to offset */ ++ if (TARGET_BIG_ENDIAN) { ++ offset += -((rp->r_vaddr << LOG_TARGET_AU_BITS) + ++ offset + fieldsz) & ++ (BITS_PER_AU-TARGET_AU_BITS); ++ } else { ++ offset += (rp->r_vaddr << LOG_TARGET_AU_BITS) & ++ (BITS_PER_AU-1); ++ } ++#endif ++#ifdef RFV_SCALE ++ scale = RFV_SCALE(reloc_info); ++#endif ++ } ++ /* read the object value from the current image, if so ordered */ ++ if (reloc_info & ROP_R) { /* relocation reads current image value */ ++ val = dload_unpack(dlthis, data, fieldsz, offset, ++ RFV_SIGN(reloc_info)); ++#ifdef RFV_SCALE ++ val <<= scale; ++#endif ++ } ++ /* perform the necessary arithmetic */ ++ switch (RFV_ACTION(reloc_action)) { /* relocation actions */ ++ case RACT_VAL: ++ break; ++ case RACT_ASGN: ++ val = reloc_amt; ++ break; ++ case RACT_ADD: ++ val += reloc_amt; ++ break; ++ case RACT_PCR: ++ /*----------------------------------------------------------- ++ * Handle special cases of jumping from absolute sections ++ * (special reloc type) or to absolute destination ++ * (symndx == -1). In either case, set the appropriate ++ * relocation amount to 0. ++ *-----------------------------------------------------------*/ ++ if (rp->r_symndx == -1) ++ reloc_amt = 0; ++ val += reloc_amt - dlthis->delta_runaddr; ++ break; ++ case RACT_ADDISP: ++ val += rp->r_disp + reloc_amt; ++ break; ++ case RACT_ASGPC: ++ val = dlthis->image_secn->run_addr + reloc_amt; ++ break; ++ case RACT_PLUS: ++ if (stackp != NULL) ++ val += *stackp; ++ break; ++ case RACT_SUB: ++ if (stackp != NULL) ++ val = *stackp - val; ++ break; ++ case RACT_NEG: ++ val = -val; ++ break; ++ case RACT_MPY: ++ if (stackp != NULL) ++ val *= *stackp; ++ break; ++ case RACT_DIV: ++ if (stackp != NULL) ++ val = *stackp / val; ++ break; ++ case RACT_MOD: ++ if (stackp != NULL) ++ val = *stackp % val; ++ break; ++ case RACT_SR: ++ if (val >= sizeof(RVALUE) * BITS_PER_AU) ++ val = 0; ++ else if (stackp != NULL) ++ val = (URVALUE)*stackp >> val; ++ break; ++ case RACT_ASR: ++ if (val >= sizeof(RVALUE)*BITS_PER_AU) ++ val = sizeof(RVALUE)*BITS_PER_AU - 1; ++ else if (stackp != NULL) ++ val = *stackp >> val; ++ break; ++ case RACT_SL: ++ if (val >= sizeof(RVALUE)*BITS_PER_AU) ++ val = 0; ++ else if (stackp != NULL) ++ val = *stackp << val; ++ break; ++ case RACT_AND: ++ if (stackp != NULL) ++ val &= *stackp; ++ break; ++ case RACT_OR: ++ if (stackp != NULL) ++ val |= *stackp; ++ break; ++ case RACT_XOR: ++ if (stackp != NULL) ++ val ^= *stackp; ++ break; ++ case RACT_NOT: ++ val = ~val; ++ break; ++#if TMS32060 ++ case RACT_C6SECT: ++ /* actually needed address of secn containing symbol */ ++ if (svp != NULL) { ++ if (rp->r_symndx >= 0) ++ if (svp->secnn > 0) ++ reloc_amt = dlthis->ldr_sections ++ [svp->secnn-1].run_addr; ++ } ++ /* !!! FALL THRU !!! */ ++ case RACT_C6BASE: ++ if (dlthis->bss_run_base == 0) { ++ struct dynload_symbol *symp; ++ symp = dlthis->mysym->Find_Matching_Symbol ++ (dlthis->mysym, BSSSYMBOL); ++ /* lookup value of global BSS base */ ++ if (symp) ++ dlthis->bss_run_base = symp->value; ++ else ++ dload_error(dlthis, ++ "Global BSS base referenced in %s offset"\ ++ FMT_UI32 " but not defined", ++ dlthis->image_secn->name, ++ rp->r_vaddr + dlthis->image_offset); ++ } ++ reloc_amt -= dlthis->bss_run_base; ++ /* !!! FALL THRU !!! */ ++ case RACT_C6DSPL: ++ /* scale factor determined by 3 LSBs of field */ ++ scale = C60_Scale[val & SCALE_MASK]; ++ offset += SCALE_BITS; ++ fieldsz -= SCALE_BITS; ++ val >>= SCALE_BITS; /* ignore the scale field hereafter */ ++ val <<= scale; ++ val += reloc_amt; /* do the usual relocation */ ++ if (((1 << scale)-1) & val) ++ dload_error(dlthis, ++ "Unaligned reference in %s offset " FMT_UI32, ++ dlthis->image_secn->name, ++ rp->r_vaddr + dlthis->image_offset); ++ break; ++#endif ++ } /* relocation actions */ ++ /* * Put back result as required */ ++ if (reloc_info & ROP_W) { /* relocation writes image value */ ++#ifdef RFV_SCALE ++ val >>= scale; ++#endif ++ if (dload_repack(dlthis, val, data, fieldsz, offset, ++ RFV_SIGN(reloc_info))) { ++ dload_error(dlthis, "Relocation value " FMT_UI32 ++ " overflows %d bits in %s offset " FMT_UI32, val, ++ fieldsz, dlthis->image_secn->name, ++ dlthis->image_offset + rp->r_vaddr); ++ } ++ } else if (top) ++ *stackp = val; ++} /* reloc_value */ ++ +diff --git a/drivers/dsp/bridge/dynload/reloc_table.h b/drivers/dsp/bridge/dynload/reloc_table.h +new file mode 100644 +index 0000000..6326146 +--- /dev/null ++++ b/drivers/dsp/bridge/dynload/reloc_table.h +@@ -0,0 +1,102 @@ ++/* ++ * reloc_table.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++ ++#ifndef __RELOC_TABLE_H__ ++#define __RELOC_TABLE_H__ ++/* ++ * Table of relocation operator properties ++ */ ++#include ++ ++/* How does this relocation operation access the program image? */ ++#define ROP_N 0 /* does not access image */ ++#define ROP_R 1 /* read from image */ ++#define ROP_W 2 /* write to image */ ++#define ROP_RW 3 /* read from and write to image */ ++ ++/* For program image access, what are the overflow rules for the bit field? */ ++/* Beware! Procedure repack depends on this encoding */ ++#define ROP_ANY 0 /* no overflow ever, just truncate the value */ ++#define ROP_SGN 1 /* signed field */ ++#define ROP_UNS 2 /* unsigned field */ ++#define ROP_MAX 3 /* allow maximum range of either signed or unsigned */ ++ ++/* How does the relocation operation use the symbol reference */ ++#define ROP_IGN 0 /* no symbol is referenced */ ++#define ROP_LIT 0 /* use rp->r_uval literal field */ ++#define ROP_SYM 1 /* symbol value is used in relocation */ ++#define ROP_SYMD 2 /* delta value vs last link is used */ ++ ++/* How does the reloc op use the stack? */ ++#define RSTK_N 0 /* Does not use */ ++#define RSTK_POP 1 /* Does a POP */ ++#define RSTK_UOP 2 /* Unary op, stack position unaffected */ ++#define RSTK_PSH 3 /* Does a push */ ++ ++/* ++ * Computational actions performed by the dynamic loader ++ */ ++enum Dload_Actions { ++ RACT_VAL, /* don't alter the current val (from stack or mem fetch) */ ++ RACT_ASGN, /* set value to reference amount (from symbol reference) */ ++ RACT_ADD, /* add reference to value */ ++ RACT_PCR, /* add reference minus PC delta to value */ ++ RACT_ADDISP, /* add reference plus r_disp */ ++ RACT_ASGPC, /* set value to section address plus reference */ ++ ++ RACT_PLUS, /* stack + */ ++ RACT_SUB, /* stack - */ ++ RACT_NEG, /* stack unary - */ ++ ++ RACT_MPY, /* stack * */ ++ RACT_DIV, /* stack / */ ++ RACT_MOD, /* stack % */ ++ ++ RACT_SR, /* stack unsigned >> */ ++ RACT_ASR, /* stack signed >> */ ++ RACT_SL, /* stack << */ ++ RACT_AND, /* stack & */ ++ RACT_OR, /* stack | */ ++ RACT_XOR, /* stack ^ */ ++ RACT_NOT, /* stack ~ */ ++ RACT_C6SECT, /* for C60 R_SECT op */ ++ RACT_C6BASE, /* for C60 R_BASE op */ ++ RACT_C6DSPL, /* for C60 scaled 15-bit displacement */ ++ RACT_PCR23T /* for ARM Thumb long branch */ ++}; ++ ++/* ++ * macros used to extract values ++ */ ++#define RFV_POSN(aaa) ((aaa) & 0xF) ++#define RFV_WIDTH(aaa) (((aaa) >> 4) & 0x3F) ++#define RFV_ACTION(aaa) ((aaa) >> 10) ++ ++#define RFV_SIGN(iii) (((iii) >> 2) & 0x3) ++#define RFV_SYM(iii) (((iii) >> 4) & 0x3) ++#define RFV_STK(iii) (((iii) >> 6) & 0x3) ++#define RFV_ACCS(iii) ((iii) & 0x3) ++ ++#if (TMS32060) ++#define RFV_SCALE(iii) ((iii) >> 11) ++#define RFV_BIGOFF(iii) (((iii) >> 8) & 0x7) ++#else ++#define RFV_BIGOFF(iii) ((iii) >> 8) ++#endif ++ ++#endif /* __RELOC_TABLE_H__ */ +diff --git a/drivers/dsp/bridge/dynload/reloc_table_c6000.c b/drivers/dsp/bridge/dynload/reloc_table_c6000.c +new file mode 100644 +index 0000000..978834c +--- /dev/null ++++ b/drivers/dsp/bridge/dynload/reloc_table_c6000.c +@@ -0,0 +1,258 @@ ++/* ++ * reloc_table_c6000.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* Tables generated for c6000 */ ++ ++#define HASH_FUNC(zz) (((((zz) + 1) * UINT32_C(1845)) >> 11) & 63) ++#define HASH_L(zz) ((zz) >> 8) ++#define HASH_I(zz) ((zz) & 0xFF) ++ ++static const u16 rop_map1[] = { ++ 0, ++ 1, ++ 2, ++ 20, ++ 4, ++ 5, ++ 6, ++ 15, ++ 80, ++ 81, ++ 82, ++ 83, ++ 84, ++ 85, ++ 86, ++ 87, ++ 17, ++ 18, ++ 19, ++ 21, ++ 16, ++ 16394, ++ 16404, ++ 65535, ++ 65535, ++ 65535, ++ 65535, ++ 65535, ++ 65535, ++ 32, ++ 65535, ++ 65535, ++ 65535, ++ 65535, ++ 65535, ++ 65535, ++ 40, ++ 112, ++ 113, ++ 65535, ++ 16384, ++ 16385, ++ 16386, ++ 16387, ++ 16388, ++ 16389, ++ 16390, ++ 16391, ++ 16392, ++ 16393, ++ 16395, ++ 16396, ++ 16397, ++ 16398, ++ 16399, ++ 16400, ++ 16401, ++ 16402, ++ 16403, ++ 16405, ++ 16406, ++ 65535, ++ 65535, ++ 65535 ++}; ++ ++static const s16 rop_map2[] = { ++ -256, ++ -255, ++ -254, ++ -245, ++ -253, ++ -252, ++ -251, ++ -250, ++ -241, ++ -240, ++ -239, ++ -238, ++ -237, ++ -236, ++ 1813, ++ 5142, ++ -248, ++ -247, ++ 778, ++ -244, ++ -249, ++ -221, ++ -211, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -243, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -1, ++ -242, ++ -233, ++ -232, ++ -1, ++ -231, ++ -230, ++ -229, ++ -228, ++ -227, ++ -226, ++ -225, ++ -224, ++ -223, ++ 5410, ++ -220, ++ -219, ++ -218, ++ -217, ++ -216, ++ -215, ++ -214, ++ -213, ++ 5676, ++ -210, ++ -209, ++ -1, ++ -1, ++ -1 ++}; ++ ++static const u16 rop_action[] = { ++ 2560, ++ 2304, ++ 2304, ++ 2432, ++ 2432, ++ 2560, ++ 2176, ++ 2304, ++ 2560, ++ 3200, ++ 3328, ++ 3584, ++ 3456, ++ 2304, ++ 4208, ++ 20788, ++ 21812, ++ 3415, ++ 3245, ++ 2311, ++ 4359, ++ 19764, ++ 2311, ++ 3191, ++ 3280, ++ 6656, ++ 7680, ++ 8704, ++ 9728, ++ 10752, ++ 11776, ++ 12800, ++ 13824, ++ 14848, ++ 15872, ++ 16896, ++ 17920, ++ 18944, ++ 0, ++ 0, ++ 0, ++ 0, ++ 1536, ++ 1536, ++ 1536, ++ 5632, ++ 512, ++ 0 ++}; ++ ++static const u16 rop_info[] = { ++ 0, ++ 35, ++ 35, ++ 35, ++ 35, ++ 35, ++ 35, ++ 35, ++ 35, ++ 39, ++ 39, ++ 39, ++ 39, ++ 35, ++ 34, ++ 283, ++ 299, ++ 4135, ++ 4391, ++ 291, ++ 33059, ++ 283, ++ 295, ++ 4647, ++ 4135, ++ 64, ++ 64, ++ 128, ++ 64, ++ 64, ++ 64, ++ 64, ++ 64, ++ 64, ++ 64, ++ 64, ++ 64, ++ 128, ++ 201, ++ 197, ++ 74, ++ 70, ++ 208, ++ 196, ++ 200, ++ 192, ++ 192, ++ 66 ++}; +diff --git a/drivers/dsp/bridge/gen/_gt_para.c b/drivers/dsp/bridge/gen/_gt_para.c +new file mode 100644 +index 0000000..181fe41 +--- /dev/null ++++ b/drivers/dsp/bridge/gen/_gt_para.c +@@ -0,0 +1,107 @@ ++/* ++ * _gt_para.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== _gt_para.c ======== ++ * Description: ++ * Configuration parameters for GT. This file is separated from ++ * gt.c so that GT_assert() can reference the error function without ++ * forcing the linker to include all the code for GT_set(), GT_init(), ++ * etc. into a fully bound image. Thus, GT_assert() can be retained in ++ * a program for which GT_?trace() has been compiled out. ++ * ++ *! Revision History: ++ *! ================ ++ *! 24-Feb-2003 vp: Code Review Updates. ++ *! 18-Oct-2002 sb: Ported to Linux platform. ++ *! 03-Jul-2001 rr: Removed kfuncs.h because of build errors. ++ *! 07-Dec-1999 ag: Fxn error now causes a WinCE DebugBreak; ++ *! 30-Aug-1999 ag: Now uses GP_printf for printf and error. ++ *! ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++ ++/* ----------------------------------- Function Prototypes */ ++static void error(char *msg, ...); ++static s32 GT_nop(void); ++ ++/* ----------------------------------- Defines, Data Structures, Typedefs */ ++ ++struct GT_Config _GT_params = { ++ (Fxn) printk, /* printf */ ++ (Fxn) NULL, /* procid */ ++ (Fxn) GT_nop, /* taskid */ ++ (Fxn) error, /* error */ ++}; ++ ++/* ----------------------------------- Globals */ ++struct GT_Config *GT = &_GT_params; ++ ++/* ++ * ======== GT_nop ======== ++ */ ++static s32 GT_nop(void) ++{ ++ return 0; ++} ++ ++/* ++ * ======== error ======== ++ * purpose: ++ * Prints error onto the standard output. ++ */ ++static void error(char *fmt, ...) ++{ ++ s32 arg1, arg2, arg3, arg4, arg5, arg6; ++ ++ va_list va; ++ ++ va_start(va, fmt); ++ ++ arg1 = va_arg(va, s32); ++ arg2 = va_arg(va, s32); ++ arg3 = va_arg(va, s32); ++ arg4 = va_arg(va, s32); ++ arg5 = va_arg(va, s32); ++ arg6 = va_arg(va, s32); ++ ++ va_end(va); ++ ++ printk("ERROR: "); ++ printk(fmt, arg1, arg2, arg3, arg4, arg5, arg6); ++ ++#if defined(DEBUG) || defined(DDSP_DEBUG_PRODUCT) ++ if (in_interrupt()) { ++ printk(KERN_INFO "Not stopping after error since ISR/DPC " ++ "are disabled\n"); ++ } else { ++ set_current_state(TASK_INTERRUPTIBLE); ++ flush_signals(current); ++ schedule(); ++ flush_signals(current); ++ printk(KERN_INFO "Signaled in error function\n"); ++ } ++#endif ++} +diff --git a/drivers/dsp/bridge/gen/gb.c b/drivers/dsp/bridge/gen/gb.c +new file mode 100644 +index 0000000..1d21e97 +--- /dev/null ++++ b/drivers/dsp/bridge/gen/gb.c +@@ -0,0 +1,182 @@ ++/* ++ * gb.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== gb.c ======== ++ * Description: Generic bitmap operations. ++ * ++ *! Revision History ++ *! ================ ++ *! 24-Feb-2003 vp Code review updates. ++ *! 17-Dec-2002 map Fixed GB_minset(), GB_empty(), and GB_full(), ++ *! to ensure only 'len' bits are considered in the map ++ *! 18-Oct-2002 sb Ported to Linux platform. ++ *! 06-Dec-2001 jeh Fixed bug in GB_minclear(). ++ *! ++ */ ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++/* ----------------------------------- This */ ++#include ++#include ++ ++typedef GB_BitNum GB_WordNum; ++ ++struct GB_TMap { ++ GB_BitNum len; ++ GB_WordNum wcnt; ++ u32 *words; ++}; ++ ++/* ++ * ======== GB_clear ======== ++ * purpose: ++ * Clears a bit in the bit map. ++ */ ++ ++void GB_clear(struct GB_TMap *map, GB_BitNum bitn) ++{ ++ u32 mask; ++ ++ mask = 1L << (bitn % BITS_PER_LONG); ++ map->words[bitn / BITS_PER_LONG] &= ~mask; ++} ++ ++/* ++ * ======== GB_create ======== ++ * purpose: ++ * Creates a bit map. ++ */ ++ ++struct GB_TMap *GB_create(GB_BitNum len) ++{ ++ struct GB_TMap *map; ++ GB_WordNum i; ++ map = (struct GB_TMap *)GS_alloc(sizeof(struct GB_TMap)); ++ if (map != NULL) { ++ map->len = len; ++ map->wcnt = len / BITS_PER_LONG + 1; ++ map->words = (u32 *)GS_alloc(map->wcnt * sizeof(u32)); ++ if (map->words != NULL) { ++ for (i = 0; i < map->wcnt; i++) ++ map->words[i] = 0L; ++ ++ } else { ++ GS_frees(map, sizeof(struct GB_TMap)); ++ map = NULL; ++ } ++ } ++ ++ return map; ++} ++ ++/* ++ * ======== GB_delete ======== ++ * purpose: ++ * Frees a bit map. ++ */ ++ ++void GB_delete(struct GB_TMap *map) ++{ ++ GS_frees(map->words, map->wcnt * sizeof(u32)); ++ GS_frees(map, sizeof(struct GB_TMap)); ++} ++ ++/* ++ * ======== GB_findandset ======== ++ * purpose: ++ * Finds a free bit and sets it. ++ */ ++GB_BitNum GB_findandset(struct GB_TMap *map) ++{ ++ GB_BitNum bitn; ++ ++ bitn = GB_minclear(map); ++ ++ if (bitn != GB_NOBITS) ++ GB_set(map, bitn); ++ ++ return bitn; ++} ++ ++/* ++ * ======== GB_minclear ======== ++ * purpose: ++ * returns the location of the first unset bit in the bit map. ++ */ ++GB_BitNum GB_minclear(struct GB_TMap *map) ++{ ++ GB_BitNum bit_location = 0; ++ GB_BitNum bitAcc = 0; ++ GB_WordNum i; ++ GB_BitNum bit; ++ u32 *word; ++ ++ for (word = map->words, i = 0; i < map->wcnt; word++, i++) { ++ if (~*word) { ++ for (bit = 0; bit < BITS_PER_LONG; bit++, bitAcc++) { ++ if (bitAcc == map->len) ++ return GB_NOBITS; ++ ++ if (~*word & (1L << bit)) { ++ bit_location = i * BITS_PER_LONG + bit; ++ return bit_location; ++ } ++ ++ } ++ } else { ++ bitAcc += BITS_PER_LONG; ++ } ++ } ++ ++ return GB_NOBITS; ++} ++ ++/* ++ * ======== GB_set ======== ++ * purpose: ++ * Sets a bit in the bit map. ++ */ ++ ++void GB_set(struct GB_TMap *map, GB_BitNum bitn) ++{ ++ u32 mask; ++ ++ mask = 1L << (bitn % BITS_PER_LONG); ++ map->words[bitn / BITS_PER_LONG] |= mask; ++} ++ ++/* ++ * ======== GB_test ======== ++ * purpose: ++ * Returns true if the bit is set in the specified location. ++ */ ++ ++bool GB_test(struct GB_TMap *map, GB_BitNum bitn) ++{ ++ bool state; ++ u32 mask; ++ u32 word; ++ ++ mask = 1L << (bitn % BITS_PER_LONG); ++ word = map->words[bitn / BITS_PER_LONG]; ++ state = word & mask ? TRUE : FALSE; ++ ++ return state; ++} +diff --git a/drivers/dsp/bridge/gen/gh.c b/drivers/dsp/bridge/gen/gh.c +new file mode 100644 +index 0000000..a20ae16 +--- /dev/null ++++ b/drivers/dsp/bridge/gen/gh.c +@@ -0,0 +1,191 @@ ++/* ++ * gh.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== gh.c ======== ++ */ ++ ++#include ++ ++#include ++ ++#include ++ ++#include ++ ++struct Elem { ++ struct Elem *next; ++ u8 data[1]; ++}; ++ ++struct GH_THashTab { ++ u16 maxBucket; ++ u16 valSize; ++ struct Elem **buckets; ++ u16(*hash) (void *, u16); ++ bool(*match) (void *, void *); ++ void(*delete) (void *); ++}; ++ ++static void Nop(void *p); ++static s32 curInit; ++static void myfree(void *ptr, s32 size); ++ ++/* ++ * ======== GH_create ======== ++ */ ++ ++struct GH_THashTab *GH_create(u16 maxBucket, u16 valSize, ++ u16(*hash)(void *, u16), bool(*match)(void *, void *), ++ void(*delete)(void *)) ++{ ++ struct GH_THashTab *hashTab; ++ u16 i; ++ hashTab = (struct GH_THashTab *)GS_alloc(sizeof(struct GH_THashTab)); ++ if (hashTab == NULL) ++ return NULL; ++ hashTab->maxBucket = maxBucket; ++ hashTab->valSize = valSize; ++ hashTab->hash = hash; ++ hashTab->match = match; ++ hashTab->delete = delete == NULL ? Nop : delete; ++ ++ hashTab->buckets = (struct Elem **) ++ GS_alloc(sizeof(struct Elem *) * maxBucket); ++ if (hashTab->buckets == NULL) { ++ GH_delete(hashTab); ++ return NULL; ++ } ++ ++ for (i = 0; i < maxBucket; i++) ++ hashTab->buckets[i] = NULL; ++ ++ return hashTab; ++} ++ ++/* ++ * ======== GH_delete ======== ++ */ ++void GH_delete(struct GH_THashTab *hashTab) ++{ ++ struct Elem *elem, *next; ++ u16 i; ++ ++ if (hashTab != NULL) { ++ if (hashTab->buckets != NULL) { ++ for (i = 0; i < hashTab->maxBucket; i++) { ++ for (elem = hashTab->buckets[i]; elem != NULL; ++ elem = next) { ++ next = elem->next; ++ (*hashTab->delete) (elem->data); ++ myfree(elem, sizeof(struct Elem) - 1 + ++ hashTab->valSize); ++ } ++ } ++ ++ myfree(hashTab->buckets, sizeof(struct Elem *) ++ * hashTab->maxBucket); ++ } ++ ++ myfree(hashTab, sizeof(struct GH_THashTab)); ++ } ++} ++ ++/* ++ * ======== GH_exit ======== ++ */ ++ ++void GH_exit(void) ++{ ++ if (curInit-- == 1) ++ GS_exit(); ++ ++} ++ ++/* ++ * ======== GH_find ======== ++ */ ++ ++void *GH_find(struct GH_THashTab *hashTab, void *key) ++{ ++ struct Elem *elem; ++ ++ elem = hashTab->buckets[(*hashTab->hash)(key, hashTab->maxBucket)]; ++ ++ for (; elem; elem = elem->next) { ++ if ((*hashTab->match)(key, elem->data)) ++ return elem->data; ++ } ++ ++ return NULL; ++} ++ ++/* ++ * ======== GH_init ======== ++ */ ++ ++void GH_init(void) ++{ ++ if (curInit++ == 0) ++ GS_init(); ++} ++ ++/* ++ * ======== GH_insert ======== ++ */ ++ ++void *GH_insert(struct GH_THashTab *hashTab, void *key, void *value) ++{ ++ struct Elem *elem; ++ u16 i; ++ char *src, *dst; ++ ++ elem = (struct Elem *)GS_alloc(sizeof(struct Elem) - 1 + ++ hashTab->valSize); ++ if (elem != NULL) { ++ ++ dst = (char *)elem->data; ++ src = (char *)value; ++ for (i = 0; i < hashTab->valSize; i++) ++ *dst++ = *src++; ++ ++ i = (*hashTab->hash)(key, hashTab->maxBucket); ++ elem->next = hashTab->buckets[i]; ++ hashTab->buckets[i] = elem; ++ ++ return elem->data; ++ } ++ ++ return NULL; ++} ++ ++/* ++ * ======== Nop ======== ++ */ ++/* ARGSUSED */ ++static void Nop(void *p) ++{ ++ p = p; /* stifle compiler warning */ ++} ++ ++/* ++ * ======== myfree ======== ++ */ ++static void myfree(void *ptr, s32 size) ++{ ++ GS_free(ptr); ++} +diff --git a/drivers/dsp/bridge/gen/gs.c b/drivers/dsp/bridge/gen/gs.c +new file mode 100644 +index 0000000..ef5f923 +--- /dev/null ++++ b/drivers/dsp/bridge/gen/gs.c +@@ -0,0 +1,108 @@ ++/* ++ * gs.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== gs.c ======== ++ * Description: ++ * General storage memory allocator services. ++ * ++ *! Revision History ++ *! ================ ++ *! 29-Sep-1999 ag: Un-commented MEM_Init in GS_init(). ++ *! 14-May-1997 mg: Modified to use new GS API for GS_free() and GS_frees(). ++ *! 06-Nov-1996 gp: Re-commented MEM_Init in GS_init(). GS needs GS_Exit(). ++ *! 21-Oct-1996 db: Un-commented MEM_Init in GS_init(). ++ *! 21-May-1996 mg: Created from original stdlib implementation. ++ */ ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++/* ----------------------------------- Globals */ ++static u32 cumsize; ++ ++/* ++ * ======== GS_alloc ======== ++ * purpose: ++ * Allocates memory of the specified size. ++ */ ++void *GS_alloc(u32 size) ++{ ++ void *p; ++ ++ p = MEM_Calloc(size, MEM_PAGED); ++ if (p == NULL) ++ return NULL; ++ cumsize += size; ++ return p; ++} ++ ++/* ++ * ======== GS_exit ======== ++ * purpose: ++ * Discontinue the usage of the GS module. ++ */ ++void GS_exit(void) ++{ ++ MEM_Exit(); ++} ++ ++/* ++ * ======== GS_free ======== ++ * purpose: ++ * Frees the memory. ++ */ ++void GS_free(void *ptr) ++{ ++ MEM_Free(ptr); ++ /* ack! no size info */ ++ /* cumsize -= size; */ ++} ++ ++/* ++ * ======== GS_frees ======== ++ * purpose: ++ * Frees the memory. ++ */ ++void GS_frees(void *ptr, u32 size) ++{ ++ MEM_Free(ptr); ++ cumsize -= size; ++} ++ ++/* ++ * ======== GS_init ======== ++ * purpose: ++ * Initializes the GS module. ++ */ ++void GS_init(void) ++{ ++ static bool curInit; ++ ++ if (curInit == false) { ++ curInit = true; ++ ++ MEM_Init(); ++ } ++} +diff --git a/drivers/dsp/bridge/gen/gt.c b/drivers/dsp/bridge/gen/gt.c +new file mode 100644 +index 0000000..452d6e6 +--- /dev/null ++++ b/drivers/dsp/bridge/gen/gt.c +@@ -0,0 +1,348 @@ ++/* ++ * gt.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== gt.c ======== ++ * Description: This module implements the trace mechanism for bridge. ++ * ++ *! Revision History ++ *! ================ ++ *! 16-May-1997 dr Changed GT_Config member names to conform to coding ++ *! standards. ++ *! 23-Apr-1997 ge Check for GT->TIDFXN for NULL before calling it. ++ *! 03-Jan-1997 ge Changed GT_Config structure member names to eliminate ++ *! preprocessor confusion with other macros. ++ */ ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++#define GT_WILD '*' ++ ++#define GT_CLEAR '=' ++#define GT_ON '+' ++#define GT_OFF '-' ++ ++enum GT_State { ++ GT_SEP, ++ GT_FIRST, ++ GT_SECOND, ++ GT_OP, ++ GT_DIGITS ++} ; ++ ++#ifdef CONFIG_BRIDGE_DEBUG ++static char *GT_1format = "%s - %d: "; ++static char *GT_2format = "%s - %d(%d): "; ++#endif /* CONFIG_BRIDGE_DEBUG */ ++ ++static unsigned char *GT_tMask[GT_BOUND]; ++ ++static bool curInit; ++static char *separator; ++static unsigned char tabMem[GT_BOUND][sizeof(unsigned char) * GT_BOUND]; ++ ++static void error(char *string); ++static void setMask(s16 index1, s16 index2, char op, unsigned char mask); ++ ++/* ++ * ======== _GT_create ======== ++ * purpose: ++ * Creates GT mask. ++ */ ++void _GT_create(struct GT_Mask *mask, char *modName) ++{ ++ mask->modName = modName; ++ mask->flags = &(GT_tMask[modName[0] - 'A'][modName[1] - 'A']); ++} ++ ++/* ++ * ======== GT_init ======== ++ * purpose: ++ * Initializes GT module. ++ */ ++#ifdef GT_init ++#undef GT_init ++#endif ++void GT_init(void) ++{ ++ register unsigned char index1; ++ register unsigned char index2; ++ ++ if (!curInit) { ++ curInit = true; ++ ++ separator = " ,;/"; ++ ++ for (index1 = 0; index1 < GT_BOUND; index1++) { ++ GT_tMask[index1] = tabMem[index1]; ++ for (index2 = 0; index2 < GT_BOUND; index2++) { ++ /* no tracing */ ++ GT_tMask[index1][index2] = 0x00; ++ } ++ } ++ } ++} ++ ++/* ++ * ======== _GT_set ======== ++ * purpose: ++ * Sets the trace string format. ++ */ ++ ++void _GT_set(char *str) ++{ ++ enum GT_State state; ++ char *sep; ++ s16 index1 = GT_BOUND; /* indicates all values */ ++ s16 index2 = GT_BOUND; /* indicates all values */ ++ char op = GT_CLEAR; ++ bool maskValid; ++ s16 digit; ++ register unsigned char mask = 0x0; /* no tracing */ ++ ++ if (str == NULL) ++ return; ++ ++ maskValid = false; ++ state = GT_SEP; ++ while (*str != '\0') { ++ switch ((s32) state) { ++ case (s32) GT_SEP: ++ maskValid = false; ++ sep = separator; ++ while (*sep != '\0') { ++ if (*str == *sep) { ++ str++; ++ break; ++ } else { ++ sep++; ++ } ++ } ++ if (*sep == '\0') ++ state = GT_FIRST; ++ ++ break; ++ case (s32) GT_FIRST: ++ if (*str == GT_WILD) { ++ /* indicates all values */ ++ index1 = GT_BOUND; ++ /* indicates all values */ ++ index2 = GT_BOUND; ++ state = GT_OP; ++ } else { ++ if (*str >= 'a') ++ index1 = (s16) (*str - 'a'); ++ else ++ index1 = (s16) (*str - 'A'); ++ if ((index1 >= 0) && (index1 < GT_BOUND)) ++ state = GT_SECOND; ++ else ++ state = GT_SEP; ++ } ++ str++; ++ break; ++ case (s32) GT_SECOND: ++ if (*str == GT_WILD) { ++ index2 = GT_BOUND; /* indicates all values */ ++ state = GT_OP; ++ str++; ++ } else { ++ if (*str >= 'a') ++ index2 = (s16) (*str - 'a'); ++ else ++ index2 = (s16) (*str - 'A'); ++ if ((index2 >= 0) && (index2 < GT_BOUND)) { ++ state = GT_OP; ++ str++; ++ } else { ++ state = GT_SEP; ++ } ++ } ++ break; ++ case (s32) GT_OP: ++ op = *str; ++ mask = 0x0; /* no tracing */ ++ switch (op) { ++ case (s32) GT_CLEAR: ++ maskValid = true; ++ case (s32) GT_ON: ++ case (s32) GT_OFF: ++ state = GT_DIGITS; ++ str++; ++ break; ++ default: ++ state = GT_SEP; ++ break; ++ } ++ break; ++ case (s32) GT_DIGITS: ++ digit = (s16) (*str - '0'); ++ if ((digit >= 0) && (digit <= 7)) { ++ mask |= (0x01 << digit); ++ maskValid = true; ++ str++; ++ } else { ++ if (maskValid == true) { ++ setMask(index1, index2, op, mask); ++ maskValid = false; ++ } ++ state = GT_SEP; ++ } ++ break; ++ default: ++ error("illegal trace mask"); ++ break; ++ } ++ } ++ ++ if (maskValid) ++ setMask(index1, index2, op, mask); ++} ++ ++/* ++ * ======== _GT_trace ======== ++ * purpose: ++ * Prints the input string onto standard output ++ */ ++ ++s32 _GT_trace(struct GT_Mask *mask, char *format, ...) ++{ ++ s32 arg1, arg2, arg3, arg4, arg5, arg6; ++ va_list va; ++ ++ va_start(va, format); ++ ++ arg1 = va_arg(va, s32); ++ arg2 = va_arg(va, s32); ++ arg3 = va_arg(va, s32); ++ arg4 = va_arg(va, s32); ++ arg5 = va_arg(va, s32); ++ arg6 = va_arg(va, s32); ++ ++ va_end(va); ++#ifdef DEBUG ++ if (GT->PIDFXN == NULL) { ++ printk(GT_1format, mask->modName, GT->TIDFXN ? ++ (*GT->TIDFXN)() : 0); ++ } else { ++ printk(GT_2format, mask->modName, (*GT->PIDFXN)(), ++ GT->TIDFXN ? (*GT->TIDFXN)() : 0); ++ } ++#endif ++ printk(format, arg1, arg2, arg3, arg4, arg5, arg6); ++ ++ return 0; ++} ++ ++/* ++ * ======== error ======== ++ * purpose: ++ * Prints errors onto the standard output. ++ */ ++static void error(char *string) ++{ ++ printk("GT: %s", string); ++} ++ ++/* ++ * ======== setmask ======== ++ * purpose: ++ * Sets mask for the GT module. ++ */ ++ ++static void setMask(s16 index1, s16 index2, char op, u8 mask) ++{ ++ register s16 index; ++ ++ if (index1 < GT_BOUND) { ++ if (index2 < GT_BOUND) { ++ switch (op) { ++ case (s32) GT_CLEAR: ++ GT_tMask[index1][index2] = mask; ++ break; ++ case (s32) GT_ON: ++ GT_tMask[index1][index2] |= mask; ++ break; ++ case (s32) GT_OFF: ++ GT_tMask[index1][index2] &= ~mask; ++ break; ++ default: ++ error("illegal trace mask"); ++ break; ++ } ++ } else { ++ for (index2--; index2 >= 0; index2--) { ++ switch (op) { ++ case (s32) GT_CLEAR: ++ GT_tMask[index1][index2] = mask; ++ break; ++ case (s32) GT_ON: ++ GT_tMask[index1][index2] |= mask; ++ break; ++ case (s32) GT_OFF: ++ GT_tMask[index1][index2] &= ~mask; ++ break; ++ default: ++ error("illegal trace mask"); ++ break; ++ } ++ } ++ } ++ } else { ++ for (index1--; index1 >= 0; index1--) { ++ if (index2 < GT_BOUND) { ++ switch (op) { ++ case (s32) GT_CLEAR: ++ GT_tMask[index1][index2] = mask; ++ break; ++ case (s32) GT_ON: ++ GT_tMask[index1][index2] |= mask; ++ break; ++ case (s32) GT_OFF: ++ GT_tMask[index1][index2] &= ~mask; ++ break; ++ default: ++ error("illegal trace mask"); ++ break; ++ } ++ } else { ++ index = GT_BOUND; ++ for (index--; index >= 0; index--) { ++ switch (op) { ++ case (s32) GT_CLEAR: ++ GT_tMask[index1][index] = mask; ++ break; ++ case (s32) GT_ON: ++ GT_tMask[index1][index] |= mask; ++ break; ++ case (s32) GT_OFF: ++ GT_tMask[index1][index] &= ++ ~mask; ++ break; ++ default: ++ error("illegal trace mask"); ++ break; ++ } ++ } ++ } ++ } ++ } ++} +diff --git a/drivers/dsp/bridge/gen/uuidutil.c b/drivers/dsp/bridge/gen/uuidutil.c +new file mode 100644 +index 0000000..a45f448 +--- /dev/null ++++ b/drivers/dsp/bridge/gen/uuidutil.c +@@ -0,0 +1,238 @@ ++/* ++ * uuidutil.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== uuidutil.c ======== ++ * Description: ++ * This file contains the implementation of UUID helper functions. ++ * ++ *! Revision History ++ *! ================ ++ *! 23-Feb-2003 vp: Code review updates. ++ *! 18-Oct-2003 vp: Ported to Linux platform. ++ *! 31-Aug-2000 rr: UUID_UuidFromString bug fixed. ++ *! 29-Aug-2000 rr: Modified UUID_UuidFromString. ++ *! 09-Nov-2000 kc: Modified UUID_UuidFromString to simplify implementation. ++ *! 30-Oct-2000 kc: Modified UUID utility module function prefix. ++ *! 10-Aug-2000 kc: Created. ++ *! ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++/* ++ * ======== UUID_UuidToString ======== ++ * Purpose: ++ * Converts a struct DSP_UUID to a string. ++ * Note: snprintf format specifier is: ++ * %[flags] [width] [.precision] [{h | l | I64 | L}]type ++ */ ++void UUID_UuidToString(IN struct DSP_UUID *pUuid, OUT char *pszUuid, ++ IN s32 size) ++{ ++ s32 i; /* return result from snprintf. */ ++ ++ DBC_Require(pUuid && pszUuid); ++ ++ i = snprintf(pszUuid, size, ++ "%.8X_%.4X_%.4X_%.2X%.2X_%.2X%.2X%.2X%.2X%.2X%.2X", ++ pUuid->ulData1, pUuid->usData2, pUuid->usData3, ++ pUuid->ucData4, pUuid->ucData5, pUuid->ucData6[0], ++ pUuid->ucData6[1], pUuid->ucData6[2], pUuid->ucData6[3], ++ pUuid->ucData6[4], pUuid->ucData6[5]); ++ ++ DBC_Ensure(i != -1); ++} ++ ++/* ++ * ======== htoi ======== ++ * Purpose: ++ * Converts a hex value to a decimal integer. ++ */ ++ ++static int htoi(char c) ++{ ++ switch (c) { ++ case '0': ++ return 0; ++ case '1': ++ return 1; ++ case '2': ++ return 2; ++ case '3': ++ return 3; ++ case '4': ++ return 4; ++ case '5': ++ return 5; ++ case '6': ++ return 6; ++ case '7': ++ return 7; ++ case '8': ++ return 8; ++ case '9': ++ return 9; ++ case 'A': ++ return 10; ++ case 'B': ++ return 11; ++ case 'C': ++ return 12; ++ case 'D': ++ return 13; ++ case 'E': ++ return 14; ++ case 'F': ++ return 15; ++ case 'a': ++ return 10; ++ case 'b': ++ return 11; ++ case 'c': ++ return 12; ++ case 'd': ++ return 13; ++ case 'e': ++ return 14; ++ case 'f': ++ return 15; ++ } ++ return 0; ++} ++ ++/* ++ * ======== UUID_UuidFromString ======== ++ * Purpose: ++ * Converts a string to a struct DSP_UUID. ++ */ ++void UUID_UuidFromString(IN char *pszUuid, OUT struct DSP_UUID *pUuid) ++{ ++ char c; ++ s32 i, j; ++ s32 result; ++ char *temp = pszUuid; ++ ++ result = 0; ++ for (i = 0; i < 8; i++) { ++ /* Get first character in string */ ++ c = *temp; ++ ++ /* Increase the results by new value */ ++ result *= 16; ++ result += htoi(c); ++ ++ /* Go to next character in string */ ++ temp++; ++ } ++ pUuid->ulData1 = result; ++ ++ /* Step over underscore */ ++ temp++; ++ ++ result = 0; ++ for (i = 0; i < 4; i++) { ++ /* Get first character in string */ ++ c = *temp; ++ ++ /* Increase the results by new value */ ++ result *= 16; ++ result += htoi(c); ++ ++ /* Go to next character in string */ ++ temp++; ++ } ++ pUuid->usData2 = (u16)result; ++ ++ /* Step over underscore */ ++ temp++; ++ ++ result = 0; ++ for (i = 0; i < 4; i++) { ++ /* Get first character in string */ ++ c = *temp; ++ ++ /* Increase the results by new value */ ++ result *= 16; ++ result += htoi(c); ++ ++ /* Go to next character in string */ ++ temp++; ++ } ++ pUuid->usData3 = (u16)result; ++ ++ /* Step over underscore */ ++ temp++; ++ ++ result = 0; ++ for (i = 0; i < 2; i++) { ++ /* Get first character in string */ ++ c = *temp; ++ ++ /* Increase the results by new value */ ++ result *= 16; ++ result += htoi(c); ++ ++ /* Go to next character in string */ ++ temp++; ++ } ++ pUuid->ucData4 = (u8)result; ++ ++ result = 0; ++ for (i = 0; i < 2; i++) { ++ /* Get first character in string */ ++ c = *temp; ++ ++ /* Increase the results by new value */ ++ result *= 16; ++ result += htoi(c); ++ ++ /* Go to next character in string */ ++ temp++; ++ } ++ pUuid->ucData5 = (u8)result; ++ ++ /* Step over underscore */ ++ temp++; ++ ++ for (j = 0; j < 6; j++) { ++ result = 0; ++ for (i = 0; i < 2; i++) { ++ /* Get first character in string */ ++ c = *temp; ++ ++ /* Increase the results by new value */ ++ result *= 16; ++ result += htoi(c); ++ ++ /* Go to next character in string */ ++ temp++; ++ } ++ pUuid->ucData6[j] = (u8)result; ++ } ++} +diff --git a/drivers/dsp/bridge/hw/EasiGlobal.h b/drivers/dsp/bridge/hw/EasiGlobal.h +new file mode 100644 +index 0000000..b023826 +--- /dev/null ++++ b/drivers/dsp/bridge/hw/EasiGlobal.h +@@ -0,0 +1,42 @@ ++/* ++ * EasiGlobal.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2007 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++#ifndef __EASIGLOBAL_H ++#define __EASIGLOBAL_H ++#include ++ ++/* ++ * DEFINE: READ_ONLY, WRITE_ONLY & READ_WRITE ++ * ++ * DESCRIPTION: Defines used to describe register types for EASI-checker tests. ++ */ ++ ++#define READ_ONLY 1 ++#define WRITE_ONLY 2 ++#define READ_WRITE 3 ++ ++/* ++ * MACRO: _DEBUG_LEVEL_1_EASI ++ * ++ * DESCRIPTION: A MACRO which can be used to indicate that a particular beach ++ * register access function was called. ++ * ++ * NOTE: We currently dont use this functionality. ++ */ ++#define _DEBUG_LEVEL_1_EASI(easiNum) ((void)0) ++ ++#endif /* __EASIGLOBAL_H */ ++ +diff --git a/drivers/dsp/bridge/hw/GlobalTypes.h b/drivers/dsp/bridge/hw/GlobalTypes.h +new file mode 100644 +index 0000000..9004a37 +--- /dev/null ++++ b/drivers/dsp/bridge/hw/GlobalTypes.h +@@ -0,0 +1,325 @@ ++/* ++ * GlobalTypes.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2007 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== GlobalTypes.h ======== ++ * Description: ++ * Global HW definitions ++ * ++ *! Revision History: ++ *! ================ ++ *! 16 Feb 2003 sb: Initial version ++ */ ++#ifndef __GLOBALTYPES_H ++#define __GLOBALTYPES_H ++ ++/* ++ * Definition: TRUE, FALSE ++ * ++ * DESCRIPTION: Boolean Definitions ++ */ ++#ifndef TRUE ++#define FALSE 0 ++#define TRUE (!(FALSE)) ++#endif ++ ++/* ++ * Definition: NULL ++ * ++ * DESCRIPTION: Invalid pointer ++ */ ++#ifndef NULL ++#define NULL (void *)0 ++#endif ++ ++/* ++ * Definition: RET_CODE_BASE ++ * ++ * DESCRIPTION: Base value for return code offsets ++ */ ++#define RET_CODE_BASE 0 ++ ++/* ++ * Definition: *BIT_OFFSET ++ * ++ * DESCRIPTION: offset in bytes from start of 32-bit word. ++ */ ++#define LOWER_16BIT_OFFSET 0 ++#define UPPER_16BIT_OFFSET 2 ++ ++#define LOWER_8BIT_OFFSET 0 ++#define LOWER_MIDDLE_8BIT_OFFSET 1 ++#define UPPER_MIDDLE_8BIT_OFFSET 2 ++#define UPPER_8BIT_OFFSET 3 ++ ++#define LOWER_8BIT_OF16_OFFSET 0 ++#define UPPER_8BIT_OF16_OFFSET 1 ++ ++/* ++ * Definition: *BIT_SHIFT ++ * ++ * DESCRIPTION: offset in bits from start of 32-bit word. ++ */ ++#define LOWER_16BIT_SHIFT 0 ++#define UPPER_16BIT_SHIFT 16 ++ ++#define LOWER_8BIT_SHIFT 0 ++#define LOWER_MIDDLE_8BIT_SHIFT 8 ++#define UPPER_MIDDLE_8BIT_SHIFT 16 ++#define UPPER_8BIT_SHIFT 24 ++ ++#define LOWER_8BIT_OF16_SHIFT 0 ++#define UPPER_8BIT_OF16_SHIFT 8 ++ ++ ++/* ++ * Definition: LOWER_16BIT_MASK ++ * ++ * DESCRIPTION: 16 bit mask used for inclusion of lower 16 bits i.e. mask out ++ * the upper 16 bits ++ */ ++#define LOWER_16BIT_MASK 0x0000FFFF ++ ++ ++/* ++ * Definition: LOWER_8BIT_MASK ++ * ++ * DESCRIPTION: 8 bit masks used for inclusion of 8 bits i.e. mask out ++ * the upper 16 bits ++ */ ++#define LOWER_8BIT_MASK 0x000000FF ++ ++/* ++ * Definition: RETURN_32BITS_FROM_16LOWER_AND_16UPPER(lower16Bits, upper16Bits) ++ * ++ * DESCRIPTION: Returns a 32 bit value given a 16 bit lower value and a 16 ++ * bit upper value ++ */ ++#define RETURN_32BITS_FROM_16LOWER_AND_16UPPER(lower16Bits,upper16Bits)\ ++ (((((u32)lower16Bits) & LOWER_16BIT_MASK)) | \ ++ (((((u32)upper16Bits) & LOWER_16BIT_MASK) << UPPER_16BIT_SHIFT))) ++ ++/* ++ * Definition: RETURN_16BITS_FROM_8LOWER_AND_8UPPER(lower16Bits, upper16Bits) ++ * ++ * DESCRIPTION: Returns a 16 bit value given a 8 bit lower value and a 8 ++ * bit upper value ++ */ ++#define RETURN_16BITS_FROM_8LOWER_AND_8UPPER(lower8Bits,upper8Bits)\ ++ (((((u32)lower8Bits) & LOWER_8BIT_MASK)) | \ ++ (((((u32)upper8Bits) & LOWER_8BIT_MASK) << UPPER_8BIT_OF16_SHIFT))) ++ ++/* ++ * Definition: RETURN_32BITS_FROM_4_8BIT_VALUES(lower8Bits, lowerMiddle8Bits, ++ * lowerUpper8Bits, upper8Bits) ++ * ++ * DESCRIPTION: Returns a 32 bit value given four 8 bit values ++ */ ++#define RETURN_32BITS_FROM_4_8BIT_VALUES(lower8Bits, lowerMiddle8Bits,\ ++ lowerUpper8Bits, upper8Bits)\ ++ (((((u32)lower8Bits) & LOWER_8BIT_MASK)) | \ ++ (((((u32)lowerMiddle8Bits) & LOWER_8BIT_MASK) <<\ ++ LOWER_MIDDLE_8BIT_SHIFT)) | \ ++ (((((u32)lowerUpper8Bits) & LOWER_8BIT_MASK) <<\ ++ UPPER_MIDDLE_8BIT_SHIFT)) | \ ++ (((((u32)upper8Bits) & LOWER_8BIT_MASK) <<\ ++ UPPER_8BIT_SHIFT))) ++ ++/* ++ * Definition: READ_LOWER_16BITS_OF_32(value32bits) ++ * ++ * DESCRIPTION: Returns a 16 lower bits of 32bit value ++ */ ++#define READ_LOWER_16BITS_OF_32(value32bits)\ ++ ((u16)((u32)(value32bits) & LOWER_16BIT_MASK)) ++ ++/* ++ * Definition: READ_UPPER_16BITS_OF_32(value32bits) ++ * ++ * DESCRIPTION: Returns a 16 lower bits of 32bit value ++ */ ++#define READ_UPPER_16BITS_OF_32(value32bits)\ ++ (((u16)((u32)(value32bits) >> UPPER_16BIT_SHIFT)) &\ ++ LOWER_16BIT_MASK) ++ ++ ++/* ++ * Definition: READ_LOWER_8BITS_OF_32(value32bits) ++ * ++ * DESCRIPTION: Returns a 8 lower bits of 32bit value ++ */ ++#define READ_LOWER_8BITS_OF_32(value32bits)\ ++ ((u8)((u32)(value32bits) & LOWER_8BIT_MASK)) ++ ++/* ++ * Definition: READ_LOWER_MIDDLE_8BITS_OF_32(value32bits) ++ * ++ * DESCRIPTION: Returns a 8 lower middle bits of 32bit value ++ */ ++#define READ_LOWER_MIDDLE_8BITS_OF_32(value32bits)\ ++ (((u8)((u32)(value32bits) >> LOWER_MIDDLE_8BIT_SHIFT)) &\ ++ LOWER_8BIT_MASK) ++ ++/* ++ * Definition: READ_LOWER_MIDDLE_8BITS_OF_32(value32bits) ++ * ++ * DESCRIPTION: Returns a 8 lower middle bits of 32bit value ++ */ ++#define READ_UPPER_MIDDLE_8BITS_OF_32(value32bits)\ ++ (((u8)((u32)(value32bits) >> LOWER_MIDDLE_8BIT_SHIFT)) &\ ++ LOWER_8BIT_MASK) ++ ++/* ++ * Definition: READ_UPPER_8BITS_OF_32(value32bits) ++ * ++ * DESCRIPTION: Returns a 8 upper bits of 32bit value ++ */ ++#define READ_UPPER_8BITS_OF_32(value32bits)\ ++ (((u8)((u32)(value32bits) >> UPPER_8BIT_SHIFT)) & LOWER_8BIT_MASK) ++ ++ ++/* ++ * Definition: READ_LOWER_8BITS_OF_16(value16bits) ++ * ++ * DESCRIPTION: Returns a 8 lower bits of 16bit value ++ */ ++#define READ_LOWER_8BITS_OF_16(value16bits)\ ++ ((u8)((u16)(value16bits) & LOWER_8BIT_MASK)) ++ ++/* ++ * Definition: READ_UPPER_8BITS_OF_16(value32bits) ++ * ++ * DESCRIPTION: Returns a 8 upper bits of 16bit value ++ */ ++#define READ_UPPER_8BITS_OF_16(value16bits)\ ++ (((u8)((u32)(value16bits) >> UPPER_8BIT_SHIFT)) & LOWER_8BIT_MASK) ++ ++ ++ ++/* UWORD16: 16 bit tpyes */ ++ ++ ++/* REG_UWORD8, REG_WORD8: 8 bit register types */ ++typedef volatile unsigned char REG_UWORD8; ++typedef volatile signed char REG_WORD8; ++ ++/* REG_UWORD16, REG_WORD16: 16 bit register types */ ++#ifndef OMAPBRIDGE_TYPES ++typedef volatile unsigned short REG_UWORD16; ++#endif ++typedef volatile short REG_WORD16; ++ ++/* REG_UWORD32, REG_WORD32: 32 bit register types */ ++typedef volatile unsigned long REG_UWORD32; ++ ++/* FLOAT ++ * ++ * Type to be used for floating point calculation. Note that floating point ++ * calculation is very CPU expensive, and you should only use if you ++ * absolutely need this. */ ++ ++ ++/* boolean_t: Boolean Type True, False */ ++/* ReturnCode_t: Return codes to be returned by all library functions */ ++typedef enum ReturnCode_label { ++ RET_OK = 0, ++ RET_FAIL = -1, ++ RET_BAD_NULL_PARAM = -2, ++ RET_PARAM_OUT_OF_RANGE = -3, ++ RET_INVALID_ID = -4, ++ RET_EMPTY = -5, ++ RET_FULL = -6, ++ RET_TIMEOUT = -7, ++ RET_INVALID_OPERATION = -8, ++ ++ /* Add new error codes at end of above list */ ++ ++ RET_NUM_RET_CODES /* this should ALWAYS be LAST entry */ ++} ReturnCode_t, *pReturnCode_t; ++ ++/* MACRO: RD_MEM_8, WR_MEM_8 ++ * ++ * DESCRIPTION: 32 bit memory access macros ++ */ ++#define RD_MEM_8(addr) ((u8)(*((u8 *)(addr)))) ++#define WR_MEM_8(addr, data) (*((u8 *)(addr)) = (u8)(data)) ++ ++/* MACRO: RD_MEM_8_VOLATILE, WR_MEM_8_VOLATILE ++ * ++ * DESCRIPTION: 8 bit register access macros ++ */ ++#define RD_MEM_8_VOLATILE(addr) ((u8)(*((REG_UWORD8 *)(addr)))) ++#define WR_MEM_8_VOLATILE(addr, data) (*((REG_UWORD8 *)(addr)) = (u8)(data)) ++ ++ ++/* ++ * MACRO: RD_MEM_16, WR_MEM_16 ++ * ++ * DESCRIPTION: 16 bit memory access macros ++ */ ++#define RD_MEM_16(addr) ((u16)(*((u16 *)(addr)))) ++#define WR_MEM_16(addr, data) (*((u16 *)(addr)) = (u16)(data)) ++ ++/* ++ * MACRO: RD_MEM_16_VOLATILE, WR_MEM_16_VOLATILE ++ * ++ * DESCRIPTION: 16 bit register access macros ++ */ ++#define RD_MEM_16_VOLATILE(addr) ((u16)(*((REG_UWORD16 *)(addr)))) ++#define WR_MEM_16_VOLATILE(addr, data) (*((REG_UWORD16 *)(addr)) =\ ++ (u16)(data)) ++ ++/* ++ * MACRO: RD_MEM_32, WR_MEM_32 ++ * ++ * DESCRIPTION: 32 bit memory access macros ++ */ ++#define RD_MEM_32(addr) ((u32)(*((u32 *)(addr)))) ++#define WR_MEM_32(addr, data) (*((u32 *)(addr)) = (u32)(data)) ++ ++/* ++ * MACRO: RD_MEM_32_VOLATILE, WR_MEM_32_VOLATILE ++ * ++ * DESCRIPTION: 32 bit register access macros ++ */ ++#define RD_MEM_32_VOLATILE(addr) ((u32)(*((REG_UWORD32 *)(addr)))) ++#define WR_MEM_32_VOLATILE(addr, data) (*((REG_UWORD32 *)(addr)) =\ ++ (u32)(data)) ++ ++/* Not sure if this all belongs here */ ++ ++#define CHECK_RETURN_VALUE(actualValue, expectedValue, returnCodeIfMismatch,\ ++ spyCodeIfMisMatch) ++#define CHECK_RETURN_VALUE_RET(actualValue, expectedValue, returnCodeIfMismatch) ++#define CHECK_RETURN_VALUE_RES(actualValue, expectedValue, spyCodeIfMisMatch) ++#define CHECK_RETURN_VALUE_RET_VOID(actualValue, expectedValue,\ ++ spyCodeIfMisMatch) ++ ++#define CHECK_INPUT_PARAM(actualValue, invalidValue, returnCodeIfMismatch,\ ++ spyCodeIfMisMatch) ++#define CHECK_INPUT_PARAM_NO_SPY(actualValue, invalidValue,\ ++ returnCodeIfMismatch) ++#define CHECK_INPUT_RANGE(actualValue, minValidValue, maxValidValue,\ ++ returnCodeIfMismatch, spyCodeIfMisMatch) ++#define CHECK_INPUT_RANGE_NO_SPY(actualValue, minValidValue, maxValidValue,\ ++ returnCodeIfMismatch) ++#define CHECK_INPUT_RANGE_MIN0(actualValue, maxValidValue,\ ++ returnCodeIfMismatch, spyCodeIfMisMatch) ++#define CHECK_INPUT_RANGE_NO_SPY_MIN0(actualValue, maxValidValue,\ ++ returnCodeIfMismatch) ++ ++#endif /* __GLOBALTYPES_H */ +diff --git a/drivers/dsp/bridge/hw/IPIAccInt.h b/drivers/dsp/bridge/hw/IPIAccInt.h +new file mode 100644 +index 0000000..b88a58c +--- /dev/null ++++ b/drivers/dsp/bridge/hw/IPIAccInt.h +@@ -0,0 +1,41 @@ ++/* ++ * IPIAccInt.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++#ifndef _IPI_ACC_INT_H ++#define _IPI_ACC_INT_H ++ ++/* Bitfield mask and offset declarations */ ++#define SYSC_IVA2BOOTMOD_OFFSET 0x404 ++#define SYSC_IVA2BOOTADDR_OFFSET 0x400 ++#define SYSC_IVA2BOOTADDR_MASK 0xfffffc00 ++ ++ ++/* The following represent the enumerated values for each bitfield */ ++ ++enum IPIIPI_SYSCONFIGAutoIdleE { ++ IPIIPI_SYSCONFIGAutoIdleclkfree = 0x0000, ++ IPIIPI_SYSCONFIGAutoIdleautoclkgate = 0x0001 ++} ; ++ ++enum IPIIPI_ENTRYElemSizeValueE { ++ IPIIPI_ENTRYElemSizeValueElemSz8b = 0x0000, ++ IPIIPI_ENTRYElemSizeValueElemSz16b = 0x0001, ++ IPIIPI_ENTRYElemSizeValueElemSz32b = 0x0002, ++ IPIIPI_ENTRYElemSizeValueReserved = 0x0003 ++} ; ++ ++#endif /* _IPI_ACC_INT_H */ ++/* EOF */ +diff --git a/drivers/dsp/bridge/hw/IVA2RegAcM.h b/drivers/dsp/bridge/hw/IVA2RegAcM.h +new file mode 100644 +index 0000000..6c1e300 +--- /dev/null ++++ b/drivers/dsp/bridge/hw/IVA2RegAcM.h +@@ -0,0 +1,28 @@ ++/* ++ * IVA1RegAcM.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++ ++#ifndef _IVA2_REG_ACM_H ++#define _IVA2_REG_ACM_H ++ ++#include ++#include ++ ++#define SYSC_IVA2BOOTMOD_OFFSET 0x404 ++#define SYSC_IVA2BOOTADDR_OFFSET 0x400 ++ ++#endif +diff --git a/drivers/dsp/bridge/hw/MLBAccInt.h b/drivers/dsp/bridge/hw/MLBAccInt.h +new file mode 100644 +index 0000000..7a03c6a +--- /dev/null ++++ b/drivers/dsp/bridge/hw/MLBAccInt.h +@@ -0,0 +1,132 @@ ++/* ++ * MLBAccInt.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2007 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++#ifndef _MLB_ACC_INT_H ++#define _MLB_ACC_INT_H ++ ++/* Mappings of level 1 EASI function numbers to function names */ ++ ++#define EASIL1_MLBMAILBOX_SYSCONFIGReadRegister32 (MLB_BASE_EASIL1 + 3) ++#define EASIL1_MLBMAILBOX_SYSCONFIGWriteRegister32 (MLB_BASE_EASIL1 + 4) ++#define EASIL1_MLBMAILBOX_SYSCONFIGSIdleModeRead32 (MLB_BASE_EASIL1 + 7) ++#define EASIL1_MLBMAILBOX_SYSCONFIGSIdleModeWrite32 (MLB_BASE_EASIL1 + 17) ++#define EASIL1_MLBMAILBOX_SYSCONFIGSoftResetWrite32 (MLB_BASE_EASIL1 + 29) ++#define EASIL1_MLBMAILBOX_SYSCONFIGAutoIdleRead32 \ ++ (MLB_BASE_EASIL1 + 33) ++#define EASIL1_MLBMAILBOX_SYSCONFIGAutoIdleWrite32 (MLB_BASE_EASIL1 + 39) ++#define EASIL1_MLBMAILBOX_SYSSTATUSResetDoneRead32 (MLB_BASE_EASIL1 + 44) ++#define EASIL1_MLBMAILBOX_MESSAGE___0_15ReadRegister32 \ ++ (MLB_BASE_EASIL1 + 50) ++#define EASIL1_MLBMAILBOX_MESSAGE___0_15WriteRegister32 \ ++ (MLB_BASE_EASIL1 + 51) ++#define EASIL1_MLBMAILBOX_FIFOSTATUS___0_15ReadRegister32 \ ++ (MLB_BASE_EASIL1 + 56) ++#define EASIL1_MLBMAILBOX_FIFOSTATUS___0_15FifoFullMBmRead32 \ ++ (MLB_BASE_EASIL1 + 57) ++#define EASIL1_MLBMAILBOX_MSGSTATUS___0_15NbOfMsgMBmRead32 \ ++ (MLB_BASE_EASIL1 + 60) ++#define EASIL1_MLBMAILBOX_IRQSTATUS___0_3ReadRegister32 \ ++ (MLB_BASE_EASIL1 + 62) ++#define EASIL1_MLBMAILBOX_IRQSTATUS___0_3WriteRegister32 \ ++ (MLB_BASE_EASIL1 + 63) ++#define EASIL1_MLBMAILBOX_IRQENABLE___0_3ReadRegister32 \ ++ (MLB_BASE_EASIL1 + 192) ++#define EASIL1_MLBMAILBOX_IRQENABLE___0_3WriteRegister32 \ ++ (MLB_BASE_EASIL1 + 193) ++ ++/* Register set MAILBOX_MESSAGE___REGSET_0_15 address offset, bank address ++ * increment and number of banks */ ++ ++#define MLB_MAILBOX_MESSAGE___REGSET_0_15_OFFSET (u32)(0x0040) ++#define MLB_MAILBOX_MESSAGE___REGSET_0_15_STEP (u32)(0x0004) ++ ++/* Register offset address definitions relative to register set ++ * MAILBOX_MESSAGE___REGSET_0_15 */ ++ ++#define MLB_MAILBOX_MESSAGE___0_15_OFFSET (u32)(0x0) ++ ++ ++/* Register set MAILBOX_FIFOSTATUS___REGSET_0_15 address offset, bank address ++ * increment and number of banks */ ++ ++#define MLB_MAILBOX_FIFOSTATUS___REGSET_0_15_OFFSET (u32)(0x0080) ++#define MLB_MAILBOX_FIFOSTATUS___REGSET_0_15_STEP (u32)(0x0004) ++ ++/* Register offset address definitions relative to register set ++ * MAILBOX_FIFOSTATUS___REGSET_0_15 */ ++ ++#define MLB_MAILBOX_FIFOSTATUS___0_15_OFFSET (u32)(0x0) ++ ++ ++/* Register set MAILBOX_MSGSTATUS___REGSET_0_15 address offset, bank address ++ * increment and number of banks */ ++ ++#define MLB_MAILBOX_MSGSTATUS___REGSET_0_15_OFFSET (u32)(0x00c0) ++#define MLB_MAILBOX_MSGSTATUS___REGSET_0_15_STEP (u32)(0x0004) ++ ++/* Register offset address definitions relative to register set ++ * MAILBOX_MSGSTATUS___REGSET_0_15 */ ++ ++#define MLB_MAILBOX_MSGSTATUS___0_15_OFFSET (u32)(0x0) ++ ++ ++/* Register set MAILBOX_IRQSTATUS___REGSET_0_3 address offset, bank address ++ * increment and number of banks */ ++ ++#define MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET (u32)(0x0100) ++#define MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP (u32)(0x0008) ++ ++/* Register offset address definitions relative to register set ++ * MAILBOX_IRQSTATUS___REGSET_0_3 */ ++ ++#define MLB_MAILBOX_IRQSTATUS___0_3_OFFSET (u32)(0x0) ++ ++ ++/* Register set MAILBOX_IRQENABLE___REGSET_0_3 address offset, bank address ++ * increment and number of banks */ ++ ++#define MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET (u32)(0x0104) ++#define MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP (u32)(0x0008) ++ ++/* Register offset address definitions relative to register set ++ * MAILBOX_IRQENABLE___REGSET_0_3 */ ++ ++#define MLB_MAILBOX_IRQENABLE___0_3_OFFSET (u32)(0x0) ++ ++ ++/* Register offset address definitions */ ++ ++#define MLB_MAILBOX_SYSCONFIG_OFFSET (u32)(0x10) ++#define MLB_MAILBOX_SYSSTATUS_OFFSET (u32)(0x14) ++ ++ ++/* Bitfield mask and offset declarations */ ++ ++#define MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK (u32)(0x18) ++#define MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET (u32)(3) ++#define MLB_MAILBOX_SYSCONFIG_SoftReset_MASK (u32)(0x2) ++#define MLB_MAILBOX_SYSCONFIG_SoftReset_OFFSET (u32)(1) ++#define MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK (u32)(0x1) ++#define MLB_MAILBOX_SYSCONFIG_AutoIdle_OFFSET (u32)(0) ++#define MLB_MAILBOX_SYSSTATUS_ResetDone_MASK (u32)(0x1) ++#define MLB_MAILBOX_SYSSTATUS_ResetDone_OFFSET (u32)(0) ++#define MLB_MAILBOX_FIFOSTATUS___0_15_FifoFullMBm_MASK (u32)(0x1) ++#define MLB_MAILBOX_FIFOSTATUS___0_15_FifoFullMBm_OFFSET (u32)(0) ++#define MLB_MAILBOX_MSGSTATUS___0_15_NbOfMsgMBm_MASK (u32)(0x7f) ++#define MLB_MAILBOX_MSGSTATUS___0_15_NbOfMsgMBm_OFFSET (u32)(0) ++ ++#endif /* _MLB_ACC_INT_H */ +diff --git a/drivers/dsp/bridge/hw/MLBRegAcM.h b/drivers/dsp/bridge/hw/MLBRegAcM.h +new file mode 100644 +index 0000000..747a2e1 +--- /dev/null ++++ b/drivers/dsp/bridge/hw/MLBRegAcM.h +@@ -0,0 +1,200 @@ ++/* ++ * MLBRegAcM.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2007 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++#ifndef _MLB_REG_ACM_H ++#define _MLB_REG_ACM_H ++ ++#include ++#include ++#include "MLBAccInt.h" ++ ++#if defined(USE_LEVEL_1_MACROS) ++ ++#define MLBMAILBOX_SYSCONFIGReadRegister32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGReadRegister32),\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+ \ ++ MLB_MAILBOX_SYSCONFIG_OFFSET)) ++ ++ ++#define MLBMAILBOX_SYSCONFIGWriteRegister32(baseAddress, value)\ ++{\ ++ const u32 offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGWriteRegister32);\ ++ WR_MEM_32_VOLATILE(((u32)(baseAddress))+offset, newValue);\ ++} ++ ++ ++#define MLBMAILBOX_SYSCONFIGSIdleModeRead32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGSIdleModeRead32),\ ++ (((RD_MEM_32_VOLATILE((((u32)(baseAddress))+\ ++ (MLB_MAILBOX_SYSCONFIG_OFFSET)))) &\ ++ MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK) >>\ ++ MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET)) ++ ++ ++#define MLBMAILBOX_SYSCONFIGSIdleModeWrite32(baseAddress, value)\ ++{\ ++ const u32 offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE(((u32)(baseAddress)) +\ ++ offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGSIdleModeWrite32);\ ++ data &= ~(MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK);\ ++ newValue <<= MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET;\ ++ newValue &= MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define MLBMAILBOX_SYSCONFIGSoftResetWrite32(baseAddress, value)\ ++{\ ++ const u32 offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ ++ register u32 data =\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGSoftResetWrite32);\ ++ data &= ~(MLB_MAILBOX_SYSCONFIG_SoftReset_MASK);\ ++ newValue <<= MLB_MAILBOX_SYSCONFIG_SoftReset_OFFSET;\ ++ newValue &= MLB_MAILBOX_SYSCONFIG_SoftReset_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define MLBMAILBOX_SYSCONFIGAutoIdleRead32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGAutoIdleRead32),\ ++ (((RD_MEM_32_VOLATILE((((u32)(baseAddress))+\ ++ (MLB_MAILBOX_SYSCONFIG_OFFSET)))) &\ ++ MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK) >>\ ++ MLB_MAILBOX_SYSCONFIG_AutoIdle_OFFSET)) ++ ++ ++#define MLBMAILBOX_SYSCONFIGAutoIdleWrite32(baseAddress, value)\ ++{\ ++ const u32 offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ ++ register u32 data =\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGAutoIdleWrite32);\ ++ data &= ~(MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK);\ ++ newValue <<= MLB_MAILBOX_SYSCONFIG_AutoIdle_OFFSET;\ ++ newValue &= MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define MLBMAILBOX_SYSSTATUSResetDoneRead32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSSTATUSResetDoneRead32),\ ++ (((RD_MEM_32_VOLATILE((((u32)(baseAddress))+\ ++ (MLB_MAILBOX_SYSSTATUS_OFFSET)))) &\ ++ MLB_MAILBOX_SYSSTATUS_ResetDone_MASK) >>\ ++ MLB_MAILBOX_SYSSTATUS_ResetDone_OFFSET)) ++ ++ ++#define MLBMAILBOX_MESSAGE___0_15ReadRegister32(baseAddress, bank)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_MESSAGE___0_15ReadRegister32),\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+\ ++ (MLB_MAILBOX_MESSAGE___REGSET_0_15_OFFSET +\ ++ MLB_MAILBOX_MESSAGE___0_15_OFFSET+(\ ++ (bank)*MLB_MAILBOX_MESSAGE___REGSET_0_15_STEP)))) ++ ++ ++#define MLBMAILBOX_MESSAGE___0_15WriteRegister32(baseAddress, bank, value)\ ++{\ ++ const u32 offset = MLB_MAILBOX_MESSAGE___REGSET_0_15_OFFSET +\ ++ MLB_MAILBOX_MESSAGE___0_15_OFFSET +\ ++ ((bank)*MLB_MAILBOX_MESSAGE___REGSET_0_15_STEP);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_MESSAGE___0_15WriteRegister32);\ ++ WR_MEM_32_VOLATILE(((u32)(baseAddress))+offset, newValue);\ ++} ++ ++ ++#define MLBMAILBOX_FIFOSTATUS___0_15ReadRegister32(baseAddress, bank)\ ++ (_DEBUG_LEVEL_1_EASI(\ ++ EASIL1_MLBMAILBOX_FIFOSTATUS___0_15ReadRegister32),\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+\ ++ (MLB_MAILBOX_FIFOSTATUS___REGSET_0_15_OFFSET +\ ++ MLB_MAILBOX_FIFOSTATUS___0_15_OFFSET+\ ++ ((bank)*MLB_MAILBOX_FIFOSTATUS___REGSET_0_15_STEP)))) ++ ++ ++#define MLBMAILBOX_FIFOSTATUS___0_15FifoFullMBmRead32(baseAddress, bank)\ ++ (_DEBUG_LEVEL_1_EASI(\ ++ EASIL1_MLBMAILBOX_FIFOSTATUS___0_15FifoFullMBmRead32),\ ++ (((RD_MEM_32_VOLATILE(((u32)(baseAddress))+\ ++ (MLB_MAILBOX_FIFOSTATUS___REGSET_0_15_OFFSET +\ ++ MLB_MAILBOX_FIFOSTATUS___0_15_OFFSET+\ ++ ((bank)*MLB_MAILBOX_FIFOSTATUS___REGSET_0_15_STEP)))) &\ ++ MLB_MAILBOX_FIFOSTATUS___0_15_FifoFullMBm_MASK) >>\ ++ MLB_MAILBOX_FIFOSTATUS___0_15_FifoFullMBm_OFFSET)) ++ ++ ++#define MLBMAILBOX_MSGSTATUS___0_15NbOfMsgMBmRead32(baseAddress, bank)\ ++ (_DEBUG_LEVEL_1_EASI(\ ++ EASIL1_MLBMAILBOX_MSGSTATUS___0_15NbOfMsgMBmRead32),\ ++ (((RD_MEM_32_VOLATILE(((u32)(baseAddress))+\ ++ (MLB_MAILBOX_MSGSTATUS___REGSET_0_15_OFFSET +\ ++ MLB_MAILBOX_MSGSTATUS___0_15_OFFSET+\ ++ ((bank)*MLB_MAILBOX_MSGSTATUS___REGSET_0_15_STEP)))) &\ ++ MLB_MAILBOX_MSGSTATUS___0_15_NbOfMsgMBm_MASK) >>\ ++ MLB_MAILBOX_MSGSTATUS___0_15_NbOfMsgMBm_OFFSET)) ++ ++ ++#define MLBMAILBOX_IRQSTATUS___0_3ReadRegister32(baseAddress, bank)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_IRQSTATUS___0_3ReadRegister32),\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+\ ++ (MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ ++ MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+\ ++ ((bank)*MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) ++ ++ ++#define MLBMAILBOX_IRQSTATUS___0_3WriteRegister32(baseAddress, bank, value)\ ++{\ ++ const u32 offset = MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ ++ MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ ++ ((bank)*MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_IRQSTATUS___0_3WriteRegister32);\ ++ WR_MEM_32_VOLATILE(((u32)(baseAddress))+offset, newValue);\ ++} ++ ++ ++#define MLBMAILBOX_IRQENABLE___0_3ReadRegister32(baseAddress, bank)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_IRQENABLE___0_3ReadRegister32),\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+\ ++ (MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ ++ MLB_MAILBOX_IRQENABLE___0_3_OFFSET+\ ++ ((bank)*MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) ++ ++ ++#define MLBMAILBOX_IRQENABLE___0_3WriteRegister32(baseAddress, bank, value)\ ++{\ ++ const u32 offset = MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ ++ MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ ++ ((bank)*MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_IRQENABLE___0_3WriteRegister32);\ ++ WR_MEM_32_VOLATILE(((u32)(baseAddress))+offset, newValue);\ ++} ++ ++ ++#endif /* USE_LEVEL_1_MACROS */ ++ ++#endif /* _MLB_REG_ACM_H */ +diff --git a/drivers/dsp/bridge/hw/MMUAccInt.h b/drivers/dsp/bridge/hw/MMUAccInt.h +new file mode 100644 +index 0000000..6ca1573 +--- /dev/null ++++ b/drivers/dsp/bridge/hw/MMUAccInt.h +@@ -0,0 +1,76 @@ ++/* ++ * MMUAccInt.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2007 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++#ifndef _MMU_ACC_INT_H ++#define _MMU_ACC_INT_H ++ ++/* Mappings of level 1 EASI function numbers to function names */ ++ ++#define EASIL1_MMUMMU_SYSCONFIGReadRegister32 (MMU_BASE_EASIL1 + 3) ++#define EASIL1_MMUMMU_SYSCONFIGIdleModeWrite32 (MMU_BASE_EASIL1 + 17) ++#define EASIL1_MMUMMU_SYSCONFIGAutoIdleWrite32 (MMU_BASE_EASIL1 + 39) ++#define EASIL1_MMUMMU_IRQSTATUSWriteRegister32 (MMU_BASE_EASIL1 + 51) ++#define EASIL1_MMUMMU_IRQENABLEReadRegister32 (MMU_BASE_EASIL1 + 102) ++#define EASIL1_MMUMMU_IRQENABLEWriteRegister32 (MMU_BASE_EASIL1 + 103) ++#define EASIL1_MMUMMU_WALKING_STTWLRunningRead32 (MMU_BASE_EASIL1 + 156) ++#define EASIL1_MMUMMU_CNTLTWLEnableRead32 (MMU_BASE_EASIL1 + 174) ++#define EASIL1_MMUMMU_CNTLTWLEnableWrite32 (MMU_BASE_EASIL1 + 180) ++#define EASIL1_MMUMMU_CNTLMMUEnableWrite32 (MMU_BASE_EASIL1 + 190) ++#define EASIL1_MMUMMU_FAULT_ADReadRegister32 (MMU_BASE_EASIL1 + 194) ++#define EASIL1_MMUMMU_TTBWriteRegister32 (MMU_BASE_EASIL1 + 198) ++#define EASIL1_MMUMMU_LOCKReadRegister32 (MMU_BASE_EASIL1 + 203) ++#define EASIL1_MMUMMU_LOCKWriteRegister32 (MMU_BASE_EASIL1 + 204) ++#define EASIL1_MMUMMU_LOCKBaseValueRead32 (MMU_BASE_EASIL1 + 205) ++#define EASIL1_MMUMMU_LOCKCurrentVictimRead32 (MMU_BASE_EASIL1 + 209) ++#define EASIL1_MMUMMU_LOCKCurrentVictimWrite32 (MMU_BASE_EASIL1 + 211) ++#define EASIL1_MMUMMU_LOCKCurrentVictimSet32 (MMU_BASE_EASIL1 + 212) ++#define EASIL1_MMUMMU_LD_TLBReadRegister32 (MMU_BASE_EASIL1 + 213) ++#define EASIL1_MMUMMU_LD_TLBWriteRegister32 (MMU_BASE_EASIL1 + 214) ++#define EASIL1_MMUMMU_CAMWriteRegister32 (MMU_BASE_EASIL1 + 226) ++#define EASIL1_MMUMMU_RAMWriteRegister32 (MMU_BASE_EASIL1 + 268) ++#define EASIL1_MMUMMU_FLUSH_ENTRYWriteRegister32 (MMU_BASE_EASIL1 + 322) ++ ++/* Register offset address definitions */ ++#define MMU_MMU_SYSCONFIG_OFFSET 0x10 ++#define MMU_MMU_IRQSTATUS_OFFSET 0x18 ++#define MMU_MMU_IRQENABLE_OFFSET 0x1c ++#define MMU_MMU_WALKING_ST_OFFSET 0x40 ++#define MMU_MMU_CNTL_OFFSET 0x44 ++#define MMU_MMU_FAULT_AD_OFFSET 0x48 ++#define MMU_MMU_TTB_OFFSET 0x4c ++#define MMU_MMU_LOCK_OFFSET 0x50 ++#define MMU_MMU_LD_TLB_OFFSET 0x54 ++#define MMU_MMU_CAM_OFFSET 0x58 ++#define MMU_MMU_RAM_OFFSET 0x5c ++#define MMU_MMU_GFLUSH_OFFSET 0x60 ++#define MMU_MMU_FLUSH_ENTRY_OFFSET 0x64 ++/* Bitfield mask and offset declarations */ ++#define MMU_MMU_SYSCONFIG_IdleMode_MASK 0x18 ++#define MMU_MMU_SYSCONFIG_IdleMode_OFFSET 3 ++#define MMU_MMU_SYSCONFIG_AutoIdle_MASK 0x1 ++#define MMU_MMU_SYSCONFIG_AutoIdle_OFFSET 0 ++#define MMU_MMU_WALKING_ST_TWLRunning_MASK 0x1 ++#define MMU_MMU_WALKING_ST_TWLRunning_OFFSET 0 ++#define MMU_MMU_CNTL_TWLEnable_MASK 0x4 ++#define MMU_MMU_CNTL_TWLEnable_OFFSET 2 ++#define MMU_MMU_CNTL_MMUEnable_MASK 0x2 ++#define MMU_MMU_CNTL_MMUEnable_OFFSET 1 ++#define MMU_MMU_LOCK_BaseValue_MASK 0xfc00 ++#define MMU_MMU_LOCK_BaseValue_OFFSET 10 ++#define MMU_MMU_LOCK_CurrentVictim_MASK 0x3f0 ++#define MMU_MMU_LOCK_CurrentVictim_OFFSET 4 ++ ++#endif /* _MMU_ACC_INT_H */ +diff --git a/drivers/dsp/bridge/hw/MMURegAcM.h b/drivers/dsp/bridge/hw/MMURegAcM.h +new file mode 100644 +index 0000000..e46fdcb +--- /dev/null ++++ b/drivers/dsp/bridge/hw/MMURegAcM.h +@@ -0,0 +1,253 @@ ++/* ++ * MMURegAcM.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2007 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++#ifndef _MMU_REG_ACM_H ++#define _MMU_REG_ACM_H ++ ++#include ++ ++#include ++ ++#include "MMUAccInt.h" ++ ++#if defined(USE_LEVEL_1_MACROS) ++ ++ ++#define MMUMMU_SYSCONFIGReadRegister32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_SYSCONFIGReadRegister32),\ ++ RD_MEM_32_VOLATILE((baseAddress)+MMU_MMU_SYSCONFIG_OFFSET)) ++ ++ ++#define MMUMMU_SYSCONFIGIdleModeWrite32(baseAddress, value)\ ++{\ ++ const u32 offset = MMU_MMU_SYSCONFIG_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((baseAddress)+offset);\ ++ register u32 newValue = (value);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_SYSCONFIGIdleModeWrite32);\ ++ data &= ~(MMU_MMU_SYSCONFIG_IdleMode_MASK);\ ++ newValue <<= MMU_MMU_SYSCONFIG_IdleMode_OFFSET;\ ++ newValue &= MMU_MMU_SYSCONFIG_IdleMode_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE(baseAddress+offset, newValue);\ ++} ++ ++ ++#define MMUMMU_SYSCONFIGAutoIdleWrite32(baseAddress, value)\ ++{\ ++ const u32 offset = MMU_MMU_SYSCONFIG_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((baseAddress)+offset);\ ++ register u32 newValue = (value);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_SYSCONFIGAutoIdleWrite32);\ ++ data &= ~(MMU_MMU_SYSCONFIG_AutoIdle_MASK);\ ++ newValue <<= MMU_MMU_SYSCONFIG_AutoIdle_OFFSET;\ ++ newValue &= MMU_MMU_SYSCONFIG_AutoIdle_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE(baseAddress+offset, newValue);\ ++} ++ ++ ++#define MMUMMU_IRQSTATUSReadRegister32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_IRQSTATUSReadRegister32),\ ++ RD_MEM_32_VOLATILE((baseAddress)+MMU_MMU_IRQSTATUS_OFFSET)) ++ ++ ++#define MMUMMU_IRQSTATUSWriteRegister32(baseAddress, value)\ ++{\ ++ const u32 offset = MMU_MMU_IRQSTATUS_OFFSET;\ ++ register u32 newValue = (value);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_IRQSTATUSWriteRegister32);\ ++ WR_MEM_32_VOLATILE((baseAddress)+offset, newValue);\ ++} ++ ++ ++#define MMUMMU_IRQENABLEReadRegister32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_IRQENABLEReadRegister32),\ ++ RD_MEM_32_VOLATILE((baseAddress)+MMU_MMU_IRQENABLE_OFFSET)) ++ ++ ++#define MMUMMU_IRQENABLEWriteRegister32(baseAddress, value)\ ++{\ ++ const u32 offset = MMU_MMU_IRQENABLE_OFFSET;\ ++ register u32 newValue = (value);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_IRQENABLEWriteRegister32);\ ++ WR_MEM_32_VOLATILE((baseAddress)+offset, newValue);\ ++} ++ ++ ++#define MMUMMU_WALKING_STTWLRunningRead32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_WALKING_STTWLRunningRead32),\ ++ (((RD_MEM_32_VOLATILE(((baseAddress)+(MMU_MMU_WALKING_ST_OFFSET))))\ ++ & MMU_MMU_WALKING_ST_TWLRunning_MASK) >>\ ++ MMU_MMU_WALKING_ST_TWLRunning_OFFSET)) ++ ++ ++#define MMUMMU_CNTLTWLEnableRead32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_CNTLTWLEnableRead32),\ ++ (((RD_MEM_32_VOLATILE(((baseAddress)+(MMU_MMU_CNTL_OFFSET)))) &\ ++ MMU_MMU_CNTL_TWLEnable_MASK) >>\ ++ MMU_MMU_CNTL_TWLEnable_OFFSET)) ++ ++ ++#define MMUMMU_CNTLTWLEnableWrite32(baseAddress, value)\ ++{\ ++ const u32 offset = MMU_MMU_CNTL_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((baseAddress)+offset);\ ++ register u32 newValue = (value);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_CNTLTWLEnableWrite32);\ ++ data &= ~(MMU_MMU_CNTL_TWLEnable_MASK);\ ++ newValue <<= MMU_MMU_CNTL_TWLEnable_OFFSET;\ ++ newValue &= MMU_MMU_CNTL_TWLEnable_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE(baseAddress+offset, newValue);\ ++} ++ ++ ++#define MMUMMU_CNTLMMUEnableWrite32(baseAddress, value)\ ++{\ ++ const u32 offset = MMU_MMU_CNTL_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((baseAddress)+offset);\ ++ register u32 newValue = (value);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_CNTLMMUEnableWrite32);\ ++ data &= ~(MMU_MMU_CNTL_MMUEnable_MASK);\ ++ newValue <<= MMU_MMU_CNTL_MMUEnable_OFFSET;\ ++ newValue &= MMU_MMU_CNTL_MMUEnable_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE(baseAddress+offset, newValue);\ ++} ++ ++ ++#define MMUMMU_FAULT_ADReadRegister32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_FAULT_ADReadRegister32),\ ++ RD_MEM_32_VOLATILE((baseAddress)+MMU_MMU_FAULT_AD_OFFSET)) ++ ++ ++#define MMUMMU_TTBWriteRegister32(baseAddress, value)\ ++{\ ++ const u32 offset = MMU_MMU_TTB_OFFSET;\ ++ register u32 newValue = (value);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_TTBWriteRegister32);\ ++ WR_MEM_32_VOLATILE((baseAddress)+offset, newValue);\ ++} ++ ++ ++#define MMUMMU_LOCKReadRegister32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_LOCKReadRegister32),\ ++ RD_MEM_32_VOLATILE((baseAddress)+MMU_MMU_LOCK_OFFSET)) ++ ++ ++#define MMUMMU_LOCKWriteRegister32(baseAddress, value)\ ++{\ ++ const u32 offset = MMU_MMU_LOCK_OFFSET;\ ++ register u32 newValue = (value);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_LOCKWriteRegister32);\ ++ WR_MEM_32_VOLATILE((baseAddress)+offset, newValue);\ ++} ++ ++ ++#define MMUMMU_LOCKBaseValueRead32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_LOCKBaseValueRead32),\ ++ (((RD_MEM_32_VOLATILE(((baseAddress)+(MMU_MMU_LOCK_OFFSET)))) &\ ++ MMU_MMU_LOCK_BaseValue_MASK) >>\ ++ MMU_MMU_LOCK_BaseValue_OFFSET)) ++ ++ ++#define MMUMMU_LOCKBaseValueWrite32(baseAddress, value)\ ++{\ ++ const u32 offset = MMU_MMU_LOCK_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((baseAddress)+offset);\ ++ register u32 newValue = (value);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_LOCKBaseValueWrite32);\ ++ data &= ~(MMU_MMU_LOCK_BaseValue_MASK);\ ++ newValue <<= MMU_MMU_LOCK_BaseValue_OFFSET;\ ++ newValue &= MMU_MMU_LOCK_BaseValue_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE(baseAddress+offset, newValue);\ ++} ++ ++ ++#define MMUMMU_LOCKCurrentVictimRead32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_LOCKCurrentVictimRead32),\ ++ (((RD_MEM_32_VOLATILE(((baseAddress)+(MMU_MMU_LOCK_OFFSET)))) &\ ++ MMU_MMU_LOCK_CurrentVictim_MASK) >>\ ++ MMU_MMU_LOCK_CurrentVictim_OFFSET)) ++ ++ ++#define MMUMMU_LOCKCurrentVictimWrite32(baseAddress, value)\ ++{\ ++ const u32 offset = MMU_MMU_LOCK_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((baseAddress)+offset);\ ++ register u32 newValue = (value);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_LOCKCurrentVictimWrite32);\ ++ data &= ~(MMU_MMU_LOCK_CurrentVictim_MASK);\ ++ newValue <<= MMU_MMU_LOCK_CurrentVictim_OFFSET;\ ++ newValue &= MMU_MMU_LOCK_CurrentVictim_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE(baseAddress+offset, newValue);\ ++} ++ ++ ++#define MMUMMU_LOCKCurrentVictimSet32(var, value)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_LOCKCurrentVictimSet32),\ ++ (((var) & ~(MMU_MMU_LOCK_CurrentVictim_MASK)) |\ ++ (((value) << MMU_MMU_LOCK_CurrentVictim_OFFSET) &\ ++ MMU_MMU_LOCK_CurrentVictim_MASK))) ++ ++ ++#define MMUMMU_LD_TLBReadRegister32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_LD_TLBReadRegister32),\ ++ RD_MEM_32_VOLATILE((baseAddress)+MMU_MMU_LD_TLB_OFFSET)) ++ ++ ++#define MMUMMU_LD_TLBWriteRegister32(baseAddress, value)\ ++{\ ++ const u32 offset = MMU_MMU_LD_TLB_OFFSET;\ ++ register u32 newValue = (value);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_LD_TLBWriteRegister32);\ ++ WR_MEM_32_VOLATILE((baseAddress)+offset, newValue);\ ++} ++ ++ ++#define MMUMMU_CAMWriteRegister32(baseAddress, value)\ ++{\ ++ const u32 offset = MMU_MMU_CAM_OFFSET;\ ++ register u32 newValue = (value);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_CAMWriteRegister32);\ ++ WR_MEM_32_VOLATILE((baseAddress)+offset, newValue);\ ++} ++ ++ ++#define MMUMMU_RAMWriteRegister32(baseAddress, value)\ ++{\ ++ const u32 offset = MMU_MMU_RAM_OFFSET;\ ++ register u32 newValue = (value);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_RAMWriteRegister32);\ ++ WR_MEM_32_VOLATILE((baseAddress)+offset, newValue);\ ++} ++ ++ ++#define MMUMMU_FLUSH_ENTRYWriteRegister32(baseAddress, value)\ ++{\ ++ const u32 offset = MMU_MMU_FLUSH_ENTRY_OFFSET;\ ++ register u32 newValue = (value);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_MMUMMU_FLUSH_ENTRYWriteRegister32);\ ++ WR_MEM_32_VOLATILE((baseAddress)+offset, newValue);\ ++} ++ ++ ++#endif /* USE_LEVEL_1_MACROS */ ++ ++#endif /* _MMU_REG_ACM_H */ +diff --git a/drivers/dsp/bridge/hw/PRCMAccInt.h b/drivers/dsp/bridge/hw/PRCMAccInt.h +new file mode 100644 +index 0000000..42baa68 +--- /dev/null ++++ b/drivers/dsp/bridge/hw/PRCMAccInt.h +@@ -0,0 +1,300 @@ ++/* ++ * PRCMAccInt.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2007 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++#ifndef _PRCM_ACC_INT_H ++#define _PRCM_ACC_INT_H ++ ++/* Mappings of level 1 EASI function numbers to function names */ ++ ++#define EASIL1_PRCMPRCM_CLKCFG_CTRLValid_configWriteClk_valid32 \ ++ (PRCM_BASE_EASIL1 + 349) ++#define EASIL1_PRCMCM_FCLKEN1_COREReadRegister32 (PRCM_BASE_EASIL1 + 743) ++#define EASIL1_PRCMCM_FCLKEN1_COREEN_GPT8Write32 (PRCM_BASE_EASIL1 + 951) ++#define EASIL1_PRCMCM_FCLKEN1_COREEN_GPT7Write32 (PRCM_BASE_EASIL1 + 961) ++#define EASIL1_PRCMCM_ICLKEN1_COREReadRegister32 \ ++ (PRCM_BASE_EASIL1 + 1087) ++#define EASIL1_PRCMCM_ICLKEN1_COREEN_MAILBOXESWrite32 \ ++ (PRCM_BASE_EASIL1 + 1105) ++#define EASIL1_PRCMCM_ICLKEN1_COREEN_GPT8Write32 \ ++ (PRCM_BASE_EASIL1 + 1305) ++#define EASIL1_PRCMCM_ICLKEN1_COREEN_GPT7Write32 \ ++ (PRCM_BASE_EASIL1 + 1315) ++#define EASIL1_PRCMCM_CLKSEL1_CORECLKSEL_L3ReadIssel132 \ ++ (PRCM_BASE_EASIL1 + 2261) ++#define EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT8Write32k32 \ ++ (PRCM_BASE_EASIL1 + 2364) ++#define EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT8WriteSys32 \ ++ (PRCM_BASE_EASIL1 + 2365) ++#define EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT8WriteExt32 \ ++ (PRCM_BASE_EASIL1 + 2366) ++#define EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT7Write32k32 \ ++ (PRCM_BASE_EASIL1 + 2380) ++#define EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT7WriteSys32 \ ++ (PRCM_BASE_EASIL1 + 2381) ++#define EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT7WriteExt32 \ ++ (PRCM_BASE_EASIL1 + 2382) ++#define EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT6WriteSys32 \ ++ (PRCM_BASE_EASIL1 + 2397) ++#define EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT6WriteExt32 \ ++ (PRCM_BASE_EASIL1 + 2398) ++#define EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT5WriteSys32 \ ++ (PRCM_BASE_EASIL1 + 2413) ++#define EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT5WriteExt32 \ ++ (PRCM_BASE_EASIL1 + 2414) ++#define EASIL1_PRCMCM_CLKSEL1_PLLAPLLs_ClkinRead32 \ ++ (PRCM_BASE_EASIL1 + 3747) ++#define EASIL1_PRCMCM_FCLKEN_DSPEN_DSPWrite32 (PRCM_BASE_EASIL1 + 3834) ++#define EASIL1_PRCMCM_ICLKEN_DSPEN_DSP_IPIWrite32 \ ++ (PRCM_BASE_EASIL1 + 3846) ++#define EASIL1_PRCMCM_IDLEST_DSPReadRegister32 (PRCM_BASE_EASIL1 + 3850) ++#define EASIL1_PRCMCM_IDLEST_DSPST_IPIRead32 (PRCM_BASE_EASIL1 + 3857) ++#define EASIL1_PRCMCM_IDLEST_DSPST_DSPRead32 (PRCM_BASE_EASIL1 + 3863) ++#define EASIL1_PRCMCM_AUTOIDLE_DSPAUTO_DSP_IPIWrite32 \ ++ (PRCM_BASE_EASIL1 + 3877) ++#define EASIL1_PRCMCM_CLKSEL_DSPSYNC_DSPWrite32 (PRCM_BASE_EASIL1 + 3927) ++#define EASIL1_PRCMCM_CLKSEL_DSPCLKSEL_DSP_IFWrite32 \ ++ (PRCM_BASE_EASIL1 + 3941) ++#define EASIL1_PRCMCM_CLKSEL_DSPCLKSEL_DSPWrite32 \ ++ (PRCM_BASE_EASIL1 + 3965) ++#define EASIL1_PRCMCM_CLKSTCTRL_DSPAutostate_DSPRead32 \ ++ (PRCM_BASE_EASIL1 + 3987) ++#define EASIL1_PRCMCM_CLKSTCTRL_DSPAutostate_DSPWrite32 \ ++ (PRCM_BASE_EASIL1 + 3993) ++#define EASIL1_PRCMRM_RSTCTRL_DSPReadRegister32 (PRCM_BASE_EASIL1 + 3997) ++#define EASIL1_PRCMRM_RSTCTRL_DSPRST1_DSPWrite32 \ ++ (PRCM_BASE_EASIL1 + 4025) ++#define EASIL1_PRCMRM_RSTST_DSPReadRegister32 (PRCM_BASE_EASIL1 + 4029) ++#define EASIL1_PRCMRM_RSTST_DSPWriteRegister32 (PRCM_BASE_EASIL1 + 4030) ++#define EASIL1_PRCMPM_PWSTCTRL_DSPForceStateWrite32 \ ++ (PRCM_BASE_EASIL1 + 4165) ++#define EASIL1_PRCMPM_PWSTCTRL_DSPPowerStateWriteRET32 \ ++ (PRCM_BASE_EASIL1 + 4193) ++#define EASIL1_PRCMPM_PWSTST_DSPReadRegister32 (PRCM_BASE_EASIL1 + 4197) ++#define EASIL1_PRCMPM_PWSTST_DSPInTransitionRead32 \ ++ (PRCM_BASE_EASIL1 + 4198) ++#define EASIL1_PRCMPM_PWSTST_DSPPowerStateStGet32 \ ++ (PRCM_BASE_EASIL1 + 4235) ++#define EASIL1_CM_FCLKEN_PER_GPT5WriteRegister32 \ ++ (PRCM_BASE_EASIL1 + 4368) ++#define EASIL1_CM_ICLKEN_PER_GPT5WriteRegister32 \ ++ (PRCM_BASE_EASIL1 + 4370) ++#define EASIL1_CM_CLKSEL_PER_GPT5Write32k32 (PRCM_BASE_EASIL1 + 4372) ++#define EASIL1_CM_CLKSEL_PER_GPT6Write32k32 (PRCM_BASE_EASIL1 + 4373) ++#define EASIL1_PRCMCM_CLKSTCTRL_IVA2WriteRegister32 \ ++ (PRCM_BASE_EASIL1 + 4374) ++#define EASIL1_PRCMPM_PWSTCTRL_IVA2PowerStateWriteON32 \ ++ (PRCM_BASE_EASIL1 + 4375) ++#define EASIL1_PRCMPM_PWSTCTRL_IVA2PowerStateWriteOFF32 \ ++ (PRCM_BASE_EASIL1 + 4376) ++#define EASIL1_PRCMPM_PWSTST_IVA2InTransitionRead32 \ ++ (PRCM_BASE_EASIL1 + 4377) ++#define EASIL1_PRCMPM_PWSTST_IVA2PowerStateStGet32 \ ++ (PRCM_BASE_EASIL1 + 4378) ++#define EASIL1_PRCMPM_PWSTST_IVA2ReadRegister32 (PRCM_BASE_EASIL1 + 4379) ++ ++/* Register offset address definitions */ ++ ++#define PRCM_PRCM_CLKCFG_CTRL_OFFSET (u32)(0x80) ++#define PRCM_CM_FCLKEN1_CORE_OFFSET (u32)(0x200) ++#define PRCM_CM_ICLKEN1_CORE_OFFSET (u32)(0x210) ++#define PRCM_CM_CLKSEL2_CORE_OFFSET (u32)(0x244) ++#define PRCM_CM_CLKSEL1_PLL_OFFSET (u32)(0x540) ++#define PRCM_CM_ICLKEN_DSP_OFFSET (u32)(0x810) ++#define PRCM_CM_IDLEST_DSP_OFFSET (u32)(0x820) ++#define PRCM_CM_AUTOIDLE_DSP_OFFSET (u32)(0x830) ++#define PRCM_CM_CLKSEL_DSP_OFFSET (u32)(0x840) ++#define PRCM_CM_CLKSTCTRL_DSP_OFFSET (u32)(0x848) ++#define PRCM_RM_RSTCTRL_DSP_OFFSET (u32)(0x850) ++#define PRCM_RM_RSTST_DSP_OFFSET (u32)(0x858) ++#define PRCM_PM_PWSTCTRL_DSP_OFFSET (u32)(0x8e0) ++#define PRCM_PM_PWSTST_DSP_OFFSET (u32)(0x8e4) ++#define PRCM_PM_PWSTST_IVA2_OFFSET (u32)(0xE4) ++#define PRCM_PM_PWSTCTRL_IVA2_OFFSET (u32)(0xE0) ++#define PRCM_CM_CLKSTCTRL_IVA2_OFFSET (u32)(0x48) ++#define CM_CLKSEL_PER_OFFSET (u32)(0x40) ++ ++/* Bitfield mask and offset declarations */ ++ ++#define PRCM_PRCM_CLKCFG_CTRL_Valid_config_MASK (u32)(0x1) ++#define PRCM_PRCM_CLKCFG_CTRL_Valid_config_OFFSET (u32)(0) ++ ++#define PRCM_CM_FCLKEN1_CORE_EN_GPT8_MASK (u32)(0x400) ++#define PRCM_CM_FCLKEN1_CORE_EN_GPT8_OFFSET (u32)(10) ++ ++#define PRCM_CM_FCLKEN1_CORE_EN_GPT7_MASK (u32)(0x200) ++#define PRCM_CM_FCLKEN1_CORE_EN_GPT7_OFFSET (u32)(9) ++ ++#define PRCM_CM_ICLKEN1_CORE_EN_GPT8_MASK (u32)(0x400) ++#define PRCM_CM_ICLKEN1_CORE_EN_GPT8_OFFSET (u32)(10) ++ ++#define PRCM_CM_ICLKEN1_CORE_EN_GPT7_MASK (u32)(0x200) ++#define PRCM_CM_ICLKEN1_CORE_EN_GPT7_OFFSET (u32)(9) ++ ++#define PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT8_MASK (u32)(0xc000) ++#define PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT8_OFFSET (u32)(14) ++ ++#define PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT7_MASK (u32)(0x3000) ++#define PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT7_OFFSET (u32)(12) ++ ++#define PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT6_MASK (u32)(0xc00) ++#define PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT6_OFFSET (u32)(10) ++ ++#define PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT5_MASK (u32)(0x300) ++#define PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT5_OFFSET (u32)(8) ++ ++#define PRCM_CM_CLKSEL1_PLL_APLLs_Clkin_MASK (u32)(0x3800000) ++#define PRCM_CM_CLKSEL1_PLL_APLLs_Clkin_OFFSET (u32)(23) ++ ++#define PRCM_CM_ICLKEN_DSP_EN_DSP_IPI_MASK (u32)(0x2) ++#define PRCM_CM_ICLKEN_DSP_EN_DSP_IPI_OFFSET (u32)(1) ++ ++#define PRCM_CM_IDLEST_DSP_ST_IPI_MASK (u32)(0x2) ++#define PRCM_CM_IDLEST_DSP_ST_IPI_OFFSET (u32)(1) ++ ++#define PRCM_CM_AUTOIDLE_DSP_AUTO_DSP_IPI_MASK (u32)(0x2) ++#define PRCM_CM_AUTOIDLE_DSP_AUTO_DSP_IPI_OFFSET (u32)(1) ++ ++#define PRCM_CM_CLKSEL_DSP_SYNC_DSP_MASK (u32)(0x80) ++#define PRCM_CM_CLKSEL_DSP_SYNC_DSP_OFFSET (u32)(7) ++ ++#define PRCM_CM_CLKSEL_DSP_CLKSEL_DSP_IF_MASK (u32)(0x60) ++#define PRCM_CM_CLKSEL_DSP_CLKSEL_DSP_IF_OFFSET (u32)(5) ++ ++#define PRCM_CM_CLKSEL_DSP_CLKSEL_DSP_MASK (u32)(0x1f) ++#define PRCM_CM_CLKSEL_DSP_CLKSEL_DSP_OFFSET (u32)(0) ++ ++#define PRCM_CM_CLKSTCTRL_DSP_Autostate_DSP_MASK (u32)(0x1) ++#define PRCM_CM_CLKSTCTRL_DSP_Autostate_DSP_OFFSET (u32)(0) ++ ++#define PRCM_PM_PWSTCTRL_DSP_ForceState_MASK (u32)(0x40000) ++#define PRCM_PM_PWSTCTRL_DSP_ForceState_OFFSET (u32)(18) ++ ++#define PRCM_PM_PWSTCTRL_DSP_PowerState_MASK (u32)(0x3) ++#define PRCM_PM_PWSTCTRL_DSP_PowerState_OFFSET (u32)(0) ++ ++#define PRCM_PM_PWSTCTRL_IVA2_PowerState_MASK (u32)(0x3) ++#define PRCM_PM_PWSTCTRL_IVA2_PowerState_OFFSET (u32)(0) ++ ++#define PRCM_PM_PWSTST_DSP_InTransition_MASK (u32)(0x100000) ++#define PRCM_PM_PWSTST_DSP_InTransition_OFFSET (u32)(20) ++ ++#define PRCM_PM_PWSTST_IVA2_InTransition_MASK (u32)(0x100000) ++#define PRCM_PM_PWSTST_IVA2_InTransition_OFFSET (u32)(20) ++ ++#define PRCM_PM_PWSTST_DSP_PowerStateSt_MASK (u32)(0x3) ++#define PRCM_PM_PWSTST_DSP_PowerStateSt_OFFSET (u32)(0) ++ ++#define PRCM_PM_PWSTST_IVA2_PowerStateSt_MASK (u32)(0x3) ++#define PRCM_PM_PWSTST_IVA2_PowerStateSt_OFFSET (u32)(0) ++ ++#define CM_FCLKEN_PER_OFFSET (u32)(0x0) ++#define CM_FCLKEN_PER_GPT5_OFFSET (u32)(6) ++#define CM_FCLKEN_PER_GPT5_MASK (u32)(0x40) ++ ++#define CM_FCLKEN_PER_GPT6_OFFSET (u32)(7) ++#define CM_FCLKEN_PER_GPT6_MASK (u32)(0x80) ++ ++#define CM_ICLKEN_PER_OFFSET (u32)(0x10) ++#define CM_ICLKEN_PER_GPT5_OFFSET (u32)(6) ++#define CM_ICLKEN_PER_GPT5_MASK (u32)(0x40) ++ ++#define CM_ICLKEN_PER_GPT6_OFFSET (u32)(7) ++#define CM_ICLKEN_PER_GPT6_MASK (u32)(0x80) ++ ++#define CM_CLKSEL_PER_GPT5_OFFSET (u32)(3) ++#define CM_CLKSEL_PER_GPT5_MASK (u32)(0x8) ++ ++#define CM_CLKSEL_PER_GPT6_OFFSET (u32)(4) ++#define CM_CLKSEL_PER_GPT6_MASK (u32)(0x10) ++ ++ ++#define CM_FCLKEN_IVA2_OFFSET (u32)(0x0) ++#define CM_FCLKEN_IVA2_EN_MASK (u32)(0x1) ++#define CM_FCLKEN_IVA2_EN_OFFSET (u32)(0x0) ++ ++#define CM_IDLEST_IVA2_OFFSET (u32)(0x20) ++#define CM_IDLEST_IVA2_ST_IVA2_MASK (u32) (0x01) ++#define CM_IDLEST_IVA2_ST_IVA2_OFFSET (u32) (0x00) ++ ++#define CM_FCLKEN1_CORE_OFFSET (u32)(0xA00) ++ ++#define CM_ICLKEN1_CORE_OFFSET (u32)(0xA10) ++#define CM_ICLKEN1_CORE_EN_MAILBOXES_MASK (u32)(0x00000080) /* bit 7 */ ++#define CM_ICLKEN1_CORE_EN_MAILBOXES_OFFSET (u32)(7) ++ ++#define CM_CLKSTCTRL_IVA2_OFFSET (u32)(0x0) ++#define CM_CLKSTCTRL_IVA2_MASK (u32)(0x3) ++ ++ ++#define PRM_RSTCTRL_IVA2_OFFSET (u32)(0x50) ++#define PRM_RSTCTRL_IVA2_RST1_MASK (u32)(0x1) ++#define PRM_RSTCTRL_IVA2_RST1_OFFSET (u32)(0x0) ++#define PRM_RSTCTRL_IVA2_RST2_MASK (u32)(0x2) ++#define PRM_RSTCTRL_IVA2_RST2_OFFSET (u32)(0x1) ++#define PRM_RSTCTRL_IVA2_RST3_MASK (u32)(0x4) ++#define PRM_RSTCTRL_IVA2_RST3_OFFSET (u32)(0x2) ++ ++ ++/* The following represent the enumerated values for each bitfield */ ++ ++enum PRCMPRCM_CLKCFG_CTRLValid_configE { ++ PRCMPRCM_CLKCFG_CTRLValid_configUpdated = 0x0000, ++ PRCMPRCM_CLKCFG_CTRLValid_configClk_valid = 0x0001 ++} ; ++ ++enum PRCMCM_CLKSEL2_CORECLKSEL_GPT8E { ++ PRCMCM_CLKSEL2_CORECLKSEL_GPT832k = 0x0000, ++ PRCMCM_CLKSEL2_CORECLKSEL_GPT8Sys = 0x0001, ++ PRCMCM_CLKSEL2_CORECLKSEL_GPT8Ext = 0x0002, ++ PRCMCM_CLKSEL2_CORECLKSEL_GPT8Reserved = 0x0003 ++} ; ++ ++enum PRCMCM_CLKSEL2_CORECLKSEL_GPT7E { ++ PRCMCM_CLKSEL2_CORECLKSEL_GPT732k = 0x0000, ++ PRCMCM_CLKSEL2_CORECLKSEL_GPT7Sys = 0x0001, ++ PRCMCM_CLKSEL2_CORECLKSEL_GPT7Ext = 0x0002, ++ PRCMCM_CLKSEL2_CORECLKSEL_GPT7Reserved = 0x0003 ++} ; ++ ++enum PRCMCM_CLKSEL2_CORECLKSEL_GPT6E { ++ PRCMCM_CLKSEL2_CORECLKSEL_GPT632k = 0x0000, ++ PRCMCM_CLKSEL2_CORECLKSEL_GPT6Sys = 0x0001, ++ PRCMCM_CLKSEL2_CORECLKSEL_GPT6Ext = 0x0002, ++ PRCMCM_CLKSEL2_CORECLKSEL_GPT6Reserved = 0x0003 ++} ; ++ ++enum PRCMCM_CLKSEL2_CORECLKSEL_GPT5E { ++ PRCMCM_CLKSEL2_CORECLKSEL_GPT532k = 0x0000, ++ PRCMCM_CLKSEL2_CORECLKSEL_GPT5Sys = 0x0001, ++ PRCMCM_CLKSEL2_CORECLKSEL_GPT5Ext = 0x0002, ++ PRCMCM_CLKSEL2_CORECLKSEL_GPT5Reserved = 0x0003 ++} ; ++ ++enum PRCMPM_PWSTCTRL_DSPPowerStateE { ++ PRCMPM_PWSTCTRL_DSPPowerStateON = 0x0000, ++ PRCMPM_PWSTCTRL_DSPPowerStateRET = 0x0001, ++ PRCMPM_PWSTCTRL_DSPPowerStateReserved = 0x0002, ++ PRCMPM_PWSTCTRL_DSPPowerStateOFF = 0x0003 ++} ; ++ ++enum PRCMPM_PWSTCTRL_IVA2PowerStateE { ++ PRCMPM_PWSTCTRL_IVA2PowerStateON = 0x0003, ++ PRCMPM_PWSTCTRL_IVA2PowerStateRET = 0x0001, ++ PRCMPM_PWSTCTRL_IVA2PowerStateReserved = 0x0002, ++ PRCMPM_PWSTCTRL_IVA2PowerStateOFF = 0x0000 ++} ; ++ ++#endif /* _PRCM_ACC_INT_H */ +diff --git a/drivers/dsp/bridge/hw/PRCMRegAcM.h b/drivers/dsp/bridge/hw/PRCMRegAcM.h +new file mode 100644 +index 0000000..91cb33c +--- /dev/null ++++ b/drivers/dsp/bridge/hw/PRCMRegAcM.h +@@ -0,0 +1,669 @@ ++/* ++ * PRCMRegAcM.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2007 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++#ifndef _PRCM_REG_ACM_H ++#define _PRCM_REG_ACM_H ++ ++#include ++ ++#include ++ ++#include "PRCMAccInt.h" ++ ++#if defined(USE_LEVEL_1_MACROS) ++ ++#define PRCMPRCM_CLKCFG_CTRLValid_configWriteClk_valid32(baseAddress)\ ++{\ ++ const u32 offset = PRCM_PRCM_CLKCFG_CTRL_OFFSET;\ ++ const u32 newValue = \ ++ (u32)PRCMPRCM_CLKCFG_CTRLValid_configClk_valid <<\ ++ PRCM_PRCM_CLKCFG_CTRL_Valid_config_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((u32)(baseAddress)+offset);\ ++ _DEBUG_LEVEL_1_EASI(\ ++ EASIL1_PRCMPRCM_CLKCFG_CTRLValid_configWriteClk_valid32);\ ++ data &= ~(PRCM_PRCM_CLKCFG_CTRL_Valid_config_MASK);\ ++ data |= newValue;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, data);\ ++} ++ ++ ++#define CM_FCLKEN_PERReadRegister32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_FCLKEN1_COREReadRegister32),\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+CM_FCLKEN_PER_OFFSET)) ++ ++ ++#define CM_ICLKEN_PERReadRegister32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_FCLKEN1_COREReadRegister32),\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+CM_ICLKEN_PER_OFFSET)) ++ ++ ++#define CM_FCLKEN_PER_GPT5WriteRegister32(baseAddress,value)\ ++{\ ++ const u32 offset = CM_FCLKEN_PER_OFFSET;\ ++ register u32 data = \ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_CM_FCLKEN_PER_GPT5WriteRegister32);\ ++ data &= ~(CM_FCLKEN_PER_GPT5_MASK);\ ++ newValue <<= CM_FCLKEN_PER_GPT5_OFFSET;\ ++ newValue &= CM_FCLKEN_PER_GPT5_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE(((u32)(baseAddress))+offset, newValue);\ ++} ++ ++ ++#define CM_FCLKEN_PER_GPT6WriteRegister32(baseAddress,value)\ ++{\ ++ const u32 offset = CM_FCLKEN_PER_OFFSET;\ ++ register u32 data =\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_CM_FCLKEN_PER_GPT5WriteRegister32);\ ++ data &= ~(CM_FCLKEN_PER_GPT6_MASK);\ ++ newValue <<= CM_FCLKEN_PER_GPT6_OFFSET;\ ++ newValue &= CM_FCLKEN_PER_GPT6_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE(((u32)(baseAddress))+offset, newValue);\ ++} ++ ++ ++#define CM_ICLKEN_PER_GPT5WriteRegister32(baseAddress,value)\ ++{\ ++ const u32 offset = CM_ICLKEN_PER_OFFSET;\ ++ register u32 data = \ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_CM_ICLKEN_PER_GPT5WriteRegister32);\ ++ data &= ~(CM_ICLKEN_PER_GPT5_MASK);\ ++ newValue <<= CM_ICLKEN_PER_GPT5_OFFSET;\ ++ newValue &= CM_ICLKEN_PER_GPT5_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE(((u32)(baseAddress))+offset, newValue);\ ++} ++ ++ ++#define CM_ICLKEN_PER_GPT6WriteRegister32(baseAddress,value)\ ++{\ ++ const u32 offset = CM_ICLKEN_PER_OFFSET;\ ++ register u32 data = \ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_CM_ICLKEN_PER_GPT5WriteRegister32);\ ++ data &= ~(CM_ICLKEN_PER_GPT6_MASK);\ ++ newValue <<= CM_ICLKEN_PER_GPT6_OFFSET;\ ++ newValue &= CM_ICLKEN_PER_GPT6_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE(((u32)(baseAddress))+offset, newValue);\ ++} ++ ++ ++#define CM_FCLKEN1_COREReadRegister32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_FCLKEN1_COREReadRegister32),\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+CM_FCLKEN1_CORE_OFFSET)) ++ ++ ++#define PRCMCM_FCLKEN1_COREEN_GPT8Write32(baseAddress,value)\ ++{\ ++ const u32 offset = PRCM_CM_FCLKEN1_CORE_OFFSET;\ ++ register u32 data = \ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_FCLKEN1_COREEN_GPT8Write32);\ ++ data &= ~(PRCM_CM_FCLKEN1_CORE_EN_GPT8_MASK);\ ++ newValue <<= PRCM_CM_FCLKEN1_CORE_EN_GPT8_OFFSET;\ ++ newValue &= PRCM_CM_FCLKEN1_CORE_EN_GPT8_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define PRCMCM_FCLKEN1_COREEN_GPT7Write32(baseAddress,value)\ ++{\ ++ const u32 offset = PRCM_CM_FCLKEN1_CORE_OFFSET;\ ++ register u32 data = \ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_FCLKEN1_COREEN_GPT7Write32);\ ++ data &= ~(PRCM_CM_FCLKEN1_CORE_EN_GPT7_MASK);\ ++ newValue <<= PRCM_CM_FCLKEN1_CORE_EN_GPT7_OFFSET;\ ++ newValue &= PRCM_CM_FCLKEN1_CORE_EN_GPT7_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define CM_ICLKEN1_COREReadRegister32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_ICLKEN1_COREReadRegister32),\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+CM_ICLKEN1_CORE_OFFSET)) ++ ++ ++#define CM_ICLKEN1_COREEN_MAILBOXESWrite32(baseAddress, value)\ ++{\ ++ const u32 offset = CM_ICLKEN1_CORE_OFFSET;\ ++ register u32 data = \ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_ICLKEN1_COREEN_MAILBOXESWrite32);\ ++ data &= ~(CM_ICLKEN1_CORE_EN_MAILBOXES_MASK);\ ++ newValue <<= CM_ICLKEN1_CORE_EN_MAILBOXES_OFFSET;\ ++ newValue &= CM_ICLKEN1_CORE_EN_MAILBOXES_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define PRCMCM_ICLKEN1_COREEN_GPT8Write32(baseAddress, value)\ ++{\ ++ const u32 offset = PRCM_CM_ICLKEN1_CORE_OFFSET;\ ++ register u32 data = \ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_ICLKEN1_COREEN_GPT8Write32);\ ++ data &= ~(PRCM_CM_ICLKEN1_CORE_EN_GPT8_MASK);\ ++ newValue <<= PRCM_CM_ICLKEN1_CORE_EN_GPT8_OFFSET;\ ++ newValue &= PRCM_CM_ICLKEN1_CORE_EN_GPT8_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define PRCMCM_ICLKEN1_COREEN_GPT7Write32(baseAddress, value)\ ++{\ ++ const u32 offset = PRCM_CM_ICLKEN1_CORE_OFFSET;\ ++ register u32 data =\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_ICLKEN1_COREEN_GPT7Write32);\ ++ data &= ~(PRCM_CM_ICLKEN1_CORE_EN_GPT7_MASK);\ ++ newValue <<= PRCM_CM_ICLKEN1_CORE_EN_GPT7_OFFSET;\ ++ newValue &= PRCM_CM_ICLKEN1_CORE_EN_GPT7_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define PRCMCM_CLKSEL2_CORECLKSEL_GPT8Write32k32(baseAddress)\ ++{\ ++ const u32 offset = PRCM_CM_CLKSEL2_CORE_OFFSET;\ ++ const u32 newValue = (u32)PRCMCM_CLKSEL2_CORECLKSEL_GPT832k <<\ ++ PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT8_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((u32)(baseAddress)+offset);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT8Write32k32);\ ++ data &= ~(PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT8_MASK);\ ++ data |= newValue;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, data);\ ++} ++ ++ ++#define PRCMCM_CLKSEL2_CORECLKSEL_GPT8WriteSys32(baseAddress)\ ++{\ ++ const u32 offset = PRCM_CM_CLKSEL2_CORE_OFFSET;\ ++ const u32 newValue = (u32)PRCMCM_CLKSEL2_CORECLKSEL_GPT8Sys <<\ ++ PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT8_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((u32)(baseAddress)+offset);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT8WriteSys32);\ ++ data &= ~(PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT8_MASK);\ ++ data |= newValue;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, data);\ ++} ++ ++ ++#define PRCMCM_CLKSEL2_CORECLKSEL_GPT8WriteExt32(baseAddress)\ ++{\ ++ const u32 offset = PRCM_CM_CLKSEL2_CORE_OFFSET;\ ++ const u32 newValue = (u32)PRCMCM_CLKSEL2_CORECLKSEL_GPT8Ext <<\ ++ PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT8_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((u32)(baseAddress)+offset);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT8WriteExt32);\ ++ data &= ~(PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT8_MASK);\ ++ data |= newValue;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, data);\ ++} ++ ++ ++#define PRCMCM_CLKSEL2_CORECLKSEL_GPT7Write32k32(baseAddress)\ ++{\ ++ const u32 offset = PRCM_CM_CLKSEL2_CORE_OFFSET;\ ++ const u32 newValue = (u32)PRCMCM_CLKSEL2_CORECLKSEL_GPT732k <<\ ++ PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT7_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((u32)(baseAddress)+offset);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT7Write32k32);\ ++ data &= ~(PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT7_MASK);\ ++ data |= newValue;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, data);\ ++} ++ ++ ++#define PRCMCM_CLKSEL2_CORECLKSEL_GPT7WriteSys32(baseAddress)\ ++{\ ++ const u32 offset = PRCM_CM_CLKSEL2_CORE_OFFSET;\ ++ const u32 newValue = (u32)PRCMCM_CLKSEL2_CORECLKSEL_GPT7Sys <<\ ++ PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT7_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((u32)(baseAddress)+offset);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT7WriteSys32);\ ++ data &= ~(PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT7_MASK);\ ++ data |= newValue;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, data);\ ++} ++ ++ ++#define PRCMCM_CLKSEL2_CORECLKSEL_GPT7WriteExt32(baseAddress)\ ++{\ ++ const u32 offset = PRCM_CM_CLKSEL2_CORE_OFFSET;\ ++ const u32 newValue = (u32)PRCMCM_CLKSEL2_CORECLKSEL_GPT7Ext <<\ ++ PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT7_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((u32)(baseAddress)+offset);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT7WriteExt32);\ ++ data &= ~(PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT7_MASK);\ ++ data |= newValue;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, data);\ ++} ++ ++ ++#define PRCMCM_CLKSEL2_CORECLKSEL_GPT6WriteSys32(baseAddress)\ ++{\ ++ const u32 offset = PRCM_CM_CLKSEL2_CORE_OFFSET;\ ++ const u32 newValue = (u32)PRCMCM_CLKSEL2_CORECLKSEL_GPT6Sys <<\ ++ PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT6_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((u32)(baseAddress)+offset);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT6WriteSys32);\ ++ data &= ~(PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT6_MASK);\ ++ data |= newValue;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, data);\ ++} ++ ++ ++#define PRCMCM_CLKSEL2_CORECLKSEL_GPT6WriteExt32(baseAddress)\ ++{\ ++ const u32 offset = PRCM_CM_CLKSEL2_CORE_OFFSET;\ ++ const u32 newValue = (u32)PRCMCM_CLKSEL2_CORECLKSEL_GPT6Ext <<\ ++ PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT6_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((u32)(baseAddress)+offset);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT6WriteExt32);\ ++ data &= ~(PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT6_MASK);\ ++ data |= newValue;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, data);\ ++} ++ ++ ++#define CM_CLKSEL_PER_GPT5Write32k32(baseAddress)\ ++{\ ++ const u32 offset = CM_CLKSEL_PER_OFFSET;\ ++ const u32 newValue = (u32)PRCMCM_CLKSEL2_CORECLKSEL_GPT532k <<\ ++ CM_CLKSEL_PER_GPT5_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((u32)(baseAddress)+offset);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_CM_CLKSEL_PER_GPT5Write32k32);\ ++ data &= ~(CM_CLKSEL_PER_GPT5_MASK);\ ++ data |= newValue;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, data);\ ++} ++ ++ ++#define CM_CLKSEL_PER_GPT6Write32k32(baseAddress)\ ++{\ ++ const u32 offset = CM_CLKSEL_PER_OFFSET;\ ++ const u32 newValue = (u32)PRCMCM_CLKSEL2_CORECLKSEL_GPT532k <<\ ++ CM_CLKSEL_PER_GPT6_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((u32)(baseAddress)+offset);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_CM_CLKSEL_PER_GPT6Write32k32);\ ++ data &= ~(CM_CLKSEL_PER_GPT6_MASK);\ ++ data |= newValue;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, data);\ ++} ++ ++ ++#define PRCMCM_CLKSEL2_CORECLKSEL_GPT5WriteSys32(baseAddress)\ ++{\ ++ const u32 offset = PRCM_CM_CLKSEL2_CORE_OFFSET;\ ++ const u32 newValue = (u32)PRCMCM_CLKSEL2_CORECLKSEL_GPT5Sys <<\ ++ PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT5_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((u32)(baseAddress)+offset);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT5WriteSys32);\ ++ data &= ~(PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT5_MASK);\ ++ data |= newValue;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, data);\ ++} ++ ++ ++#define PRCMCM_CLKSEL2_CORECLKSEL_GPT5WriteExt32(baseAddress)\ ++{\ ++ const u32 offset = PRCM_CM_CLKSEL2_CORE_OFFSET;\ ++ const u32 newValue = (u32)PRCMCM_CLKSEL2_CORECLKSEL_GPT5Ext <<\ ++ PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT5_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((u32)(baseAddress)+offset);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_CLKSEL2_CORECLKSEL_GPT5WriteExt32);\ ++ data &= ~(PRCM_CM_CLKSEL2_CORE_CLKSEL_GPT5_MASK);\ ++ data |= newValue;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, data);\ ++} ++ ++ ++#define PRCMCM_CLKSEL1_PLLAPLLs_ClkinRead32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_CLKSEL1_PLLAPLLs_ClkinRead32),\ ++ (((RD_MEM_32_VOLATILE((((u32)(baseAddress))+\ ++ (PRCM_CM_CLKSEL1_PLL_OFFSET)))) &\ ++ PRCM_CM_CLKSEL1_PLL_APLLs_Clkin_MASK) >>\ ++ PRCM_CM_CLKSEL1_PLL_APLLs_Clkin_OFFSET)) ++ ++ ++#define CM_FCLKEN_IVA2EN_DSPWrite32(baseAddress,value)\ ++{\ ++ const u32 offset = CM_FCLKEN_IVA2_OFFSET;\ ++ register u32 data = \ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_FCLKEN_DSPEN_DSPWrite32);\ ++ data &= ~(CM_FCLKEN_IVA2_EN_MASK);\ ++ newValue <<= CM_FCLKEN_IVA2_EN_OFFSET;\ ++ newValue &= CM_FCLKEN_IVA2_EN_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define PRCMCM_ICLKEN_DSPEN_DSP_IPIWrite32(baseAddress, value)\ ++{\ ++ const u32 offset = PRCM_CM_ICLKEN_DSP_OFFSET;\ ++ register u32 data = \ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_ICLKEN_DSPEN_DSP_IPIWrite32);\ ++ data &= ~(PRCM_CM_ICLKEN_DSP_EN_DSP_IPI_MASK);\ ++ newValue <<= PRCM_CM_ICLKEN_DSP_EN_DSP_IPI_OFFSET;\ ++ newValue &= PRCM_CM_ICLKEN_DSP_EN_DSP_IPI_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define PRCMCM_IDLEST_DSPReadRegister32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_IDLEST_DSPReadRegister32),\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+PRCM_CM_IDLEST_DSP_OFFSET)) ++ ++ ++#define PRCMCM_IDLEST_DSPST_IPIRead32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_IDLEST_DSPST_IPIRead32),\ ++ (((RD_MEM_32_VOLATILE((((u32)(baseAddress))+\ ++ (PRCM_CM_IDLEST_DSP_OFFSET)))) &\ ++ PRCM_CM_IDLEST_DSP_ST_IPI_MASK) >>\ ++ PRCM_CM_IDLEST_DSP_ST_IPI_OFFSET)) ++ ++ ++#define PRM_IDLEST_IVA2ST_IVA2Read32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_IDLEST_DSPST_DSPRead32),\ ++ (((RD_MEM_32_VOLATILE((((u32)(baseAddress))+\ ++ (CM_IDLEST_IVA2_OFFSET)))) &\ ++ CM_IDLEST_IVA2_ST_IVA2_MASK) >>\ ++ CM_IDLEST_IVA2_ST_IVA2_OFFSET)) ++ ++ ++#define PRCMCM_AUTOIDLE_DSPAUTO_DSP_IPIWrite32(baseAddress, value)\ ++{\ ++ const u32 offset = PRCM_CM_AUTOIDLE_DSP_OFFSET;\ ++ register u32 data =\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_AUTOIDLE_DSPAUTO_DSP_IPIWrite32);\ ++ data &= ~(PRCM_CM_AUTOIDLE_DSP_AUTO_DSP_IPI_MASK);\ ++ newValue <<= PRCM_CM_AUTOIDLE_DSP_AUTO_DSP_IPI_OFFSET;\ ++ newValue &= PRCM_CM_AUTOIDLE_DSP_AUTO_DSP_IPI_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define PRCMCM_CLKSEL_DSPSYNC_DSPWrite32(baseAddress,value)\ ++{\ ++ const u32 offset = PRCM_CM_CLKSEL_DSP_OFFSET;\ ++ register u32 data = \ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_CLKSEL_DSPSYNC_DSPWrite32);\ ++ data &= ~(PRCM_CM_CLKSEL_DSP_SYNC_DSP_MASK);\ ++ newValue <<= PRCM_CM_CLKSEL_DSP_SYNC_DSP_OFFSET;\ ++ newValue &= PRCM_CM_CLKSEL_DSP_SYNC_DSP_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define PRCMCM_CLKSEL_DSPCLKSEL_DSP_IFWrite32(baseAddress, value)\ ++{\ ++ const u32 offset = PRCM_CM_CLKSEL_DSP_OFFSET;\ ++ register u32 data = \ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_CLKSEL_DSPCLKSEL_DSP_IFWrite32);\ ++ data &= ~(PRCM_CM_CLKSEL_DSP_CLKSEL_DSP_IF_MASK);\ ++ newValue <<= PRCM_CM_CLKSEL_DSP_CLKSEL_DSP_IF_OFFSET;\ ++ newValue &= PRCM_CM_CLKSEL_DSP_CLKSEL_DSP_IF_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define PRCMCM_CLKSEL_DSPCLKSEL_DSPWrite32(baseAddress, value)\ ++{\ ++ const u32 offset = PRCM_CM_CLKSEL_DSP_OFFSET;\ ++ register u32 data = \ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_CLKSEL_DSPCLKSEL_DSPWrite32);\ ++ data &= ~(PRCM_CM_CLKSEL_DSP_CLKSEL_DSP_MASK);\ ++ newValue <<= PRCM_CM_CLKSEL_DSP_CLKSEL_DSP_OFFSET;\ ++ newValue &= PRCM_CM_CLKSEL_DSP_CLKSEL_DSP_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define PRCMCM_CLKSTCTRL_IVA2WriteRegister32(baseAddress, value)\ ++{\ ++ const u32 offset = PRCM_CM_CLKSTCTRL_IVA2_OFFSET;\ ++ register u32 data = \ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_CLKSTCTRL_IVA2WriteRegister32);\ ++ data &= ~(CM_CLKSTCTRL_IVA2_MASK);\ ++ newValue <<= CM_CLKSTCTRL_IVA2_OFFSET;\ ++ newValue &= CM_CLKSTCTRL_IVA2_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define PRCMCM_CLKSTCTRL_DSPAutostate_DSPRead32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_CLKSTCTRL_DSPAutostate_DSPRead32),\ ++ (((RD_MEM_32_VOLATILE((((u32)(baseAddress))+\ ++ (PRCM_CM_CLKSTCTRL_DSP_OFFSET)))) &\ ++ PRCM_CM_CLKSTCTRL_DSP_Autostate_DSP_MASK) >>\ ++ PRCM_CM_CLKSTCTRL_DSP_Autostate_DSP_OFFSET)) ++ ++ ++#define PRCMCM_CLKSTCTRL_DSPAutostate_DSPWrite32(baseAddress, value)\ ++{\ ++ const u32 offset = PRCM_CM_CLKSTCTRL_DSP_OFFSET;\ ++ register u32 data = \ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMCM_CLKSTCTRL_DSPAutostate_DSPWrite32);\ ++ data &= ~(PRCM_CM_CLKSTCTRL_DSP_Autostate_DSP_MASK);\ ++ newValue <<= PRCM_CM_CLKSTCTRL_DSP_Autostate_DSP_OFFSET;\ ++ newValue &= PRCM_CM_CLKSTCTRL_DSP_Autostate_DSP_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define PRCMRM_RSTCTRL_DSPReadRegister32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_PRCMRM_RSTCTRL_DSPReadRegister32),\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+PRCM_RM_RSTCTRL_DSP_OFFSET)) ++ ++ ++#define PRM_RSTCTRL_IVA2RST1_DSPWrite32(baseAddress,value)\ ++{\ ++ const u32 offset = PRM_RSTCTRL_IVA2_OFFSET;\ ++ register u32 data =\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMRM_RSTCTRL_DSPRST1_DSPWrite32);\ ++ data &= ~(PRM_RSTCTRL_IVA2_RST1_MASK);\ ++ newValue <<= PRM_RSTCTRL_IVA2_RST1_OFFSET;\ ++ newValue &= PRM_RSTCTRL_IVA2_RST1_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define PRM_RSTCTRL_IVA2RST2_DSPWrite32(baseAddress,value)\ ++{\ ++ const u32 offset = PRM_RSTCTRL_IVA2_OFFSET;\ ++ register u32 data =\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMRM_RSTCTRL_DSPRST1_DSPWrite32);\ ++ data &= ~(PRM_RSTCTRL_IVA2_RST2_MASK);\ ++ newValue <<= PRM_RSTCTRL_IVA2_RST2_OFFSET;\ ++ newValue &= PRM_RSTCTRL_IVA2_RST2_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define PRM_RSTCTRL_IVA2RST3_DSPWrite32(baseAddress,value)\ ++{\ ++ const u32 offset = PRM_RSTCTRL_IVA2_OFFSET;\ ++ register u32 data =\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMRM_RSTCTRL_DSPRST1_DSPWrite32);\ ++ data &= ~(PRM_RSTCTRL_IVA2_RST3_MASK);\ ++ newValue <<= PRM_RSTCTRL_IVA2_RST3_OFFSET;\ ++ newValue &= PRM_RSTCTRL_IVA2_RST3_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define PRCMRM_RSTST_DSPReadRegister32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_PRCMRM_RSTST_DSPReadRegister32),\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+PRCM_RM_RSTST_DSP_OFFSET)) ++ ++ ++#define PRCMRM_RSTST_DSPWriteRegister32(baseAddress,value)\ ++{\ ++ const u32 offset = PRCM_RM_RSTST_DSP_OFFSET;\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMRM_RSTST_DSPWriteRegister32);\ ++ WR_MEM_32_VOLATILE(((u32)(baseAddress))+offset, newValue);\ ++} ++ ++ ++#define PRCMPM_PWSTCTRL_DSPForceStateWrite32(baseAddress, value)\ ++{\ ++ const u32 offset = PRCM_PM_PWSTCTRL_DSP_OFFSET;\ ++ register u32 data = \ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+offset);\ ++ register u32 newValue = ((u32)(value));\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMPM_PWSTCTRL_DSPForceStateWrite32);\ ++ data &= ~(PRCM_PM_PWSTCTRL_DSP_ForceState_MASK);\ ++ newValue <<= PRCM_PM_PWSTCTRL_DSP_ForceState_OFFSET;\ ++ newValue &= PRCM_PM_PWSTCTRL_DSP_ForceState_MASK;\ ++ newValue |= data;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, newValue);\ ++} ++ ++ ++#define PRCMPM_PWSTCTRL_IVA2PowerStateWriteON32(baseAddress)\ ++{\ ++ const u32 offset = PRCM_PM_PWSTCTRL_IVA2_OFFSET;\ ++ const u32 newValue = (u32)PRCMPM_PWSTCTRL_IVA2PowerStateON <<\ ++ PRCM_PM_PWSTCTRL_IVA2_PowerState_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((u32)(baseAddress)+offset);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMPM_PWSTCTRL_IVA2PowerStateWriteON32);\ ++ data &= ~(PRCM_PM_PWSTCTRL_IVA2_PowerState_MASK);\ ++ data |= newValue;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, data);\ ++} ++ ++ ++#define PRCMPM_PWSTCTRL_IVA2PowerStateWriteOFF32(baseAddress)\ ++{\ ++ const u32 offset = PRCM_PM_PWSTCTRL_IVA2_OFFSET;\ ++ const u32 newValue = (u32)PRCMPM_PWSTCTRL_IVA2PowerStateOFF <<\ ++ PRCM_PM_PWSTCTRL_IVA2_PowerState_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((u32)(baseAddress)+offset);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMPM_PWSTCTRL_IVA2PowerStateWriteOFF32);\ ++ data &= ~(PRCM_PM_PWSTCTRL_IVA2_PowerState_MASK);\ ++ data |= newValue;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, data);\ ++} ++ ++ ++#define PRCMPM_PWSTCTRL_DSPPowerStateWriteRET32(baseAddress)\ ++{\ ++ const u32 offset = PRCM_PM_PWSTCTRL_DSP_OFFSET;\ ++ const u32 newValue = (u32)PRCMPM_PWSTCTRL_DSPPowerStateRET <<\ ++ PRCM_PM_PWSTCTRL_DSP_PowerState_OFFSET;\ ++ register u32 data = RD_MEM_32_VOLATILE((u32)(baseAddress)+offset);\ ++ _DEBUG_LEVEL_1_EASI(EASIL1_PRCMPM_PWSTCTRL_DSPPowerStateWriteRET32);\ ++ data &= ~(PRCM_PM_PWSTCTRL_DSP_PowerState_MASK);\ ++ data |= newValue;\ ++ WR_MEM_32_VOLATILE((u32)(baseAddress)+offset, data);\ ++} ++ ++ ++#define PRCMPM_PWSTST_DSPReadRegister32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_PRCMPM_PWSTST_DSPReadRegister32),\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+PRCM_PM_PWSTST_DSP_OFFSET)) ++ ++ ++#define PRCMPM_PWSTST_IVA2ReadRegister32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_PRCMPM_PWSTST_IVA2ReadRegister32),\ ++ RD_MEM_32_VOLATILE(((u32)(baseAddress))+PRCM_PM_PWSTST_IVA2_OFFSET)) ++ ++ ++#define PRCMPM_PWSTST_DSPInTransitionRead32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_PRCMPM_PWSTST_DSPInTransitionRead32),\ ++ (((RD_MEM_32_VOLATILE((((u32)(baseAddress))+\ ++ (PRCM_PM_PWSTST_DSP_OFFSET)))) &\ ++ PRCM_PM_PWSTST_DSP_InTransition_MASK) >>\ ++ PRCM_PM_PWSTST_DSP_InTransition_OFFSET)) ++ ++ ++#define PRCMPM_PWSTST_IVA2InTransitionRead32(baseAddress)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_PRCMPM_PWSTST_IVA2InTransitionRead32),\ ++ (((RD_MEM_32_VOLATILE((((u32)(baseAddress))+\ ++ (PRCM_PM_PWSTST_IVA2_OFFSET)))) &\ ++ PRCM_PM_PWSTST_IVA2_InTransition_MASK) >>\ ++ PRCM_PM_PWSTST_IVA2_InTransition_OFFSET)) ++ ++ ++#define PRCMPM_PWSTST_DSPPowerStateStGet32(var)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_PRCMPM_PWSTST_DSPPowerStateStGet32),\ ++ (u32)((((u32)(var)) & PRCM_PM_PWSTST_DSP_PowerStateSt_MASK) >>\ ++ PRCM_PM_PWSTST_DSP_PowerStateSt_OFFSET)) ++ ++ ++#define PRCMPM_PWSTST_IVA2PowerStateStGet32(var)\ ++ (_DEBUG_LEVEL_1_EASI(EASIL1_PRCMPM_PWSTST_IVA2PowerStateStGet32),\ ++ (u32)((((u32)(var)) & PRCM_PM_PWSTST_IVA2_PowerStateSt_MASK) >>\ ++ PRCM_PM_PWSTST_IVA2_PowerStateSt_OFFSET)) ++ ++ ++#endif /* USE_LEVEL_1_MACROS */ ++ ++#endif /* _PRCM_REG_ACM_H */ +diff --git a/drivers/dsp/bridge/hw/hw_defs.h b/drivers/dsp/bridge/hw/hw_defs.h +new file mode 100644 +index 0000000..a973f5c +--- /dev/null ++++ b/drivers/dsp/bridge/hw/hw_defs.h +@@ -0,0 +1,73 @@ ++/* ++ * hw_defs.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2007 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== hw_defs.h ======== ++ * Description: ++ * Global HW definitions ++ * ++ *! Revision History: ++ *! ================ ++ *! 19 Apr 2004 sb: Added generic page size, endianness and element size defns ++ *! 16 Feb 2003 sb: Initial version ++ */ ++#ifndef __HW_DEFS_H ++#define __HW_DEFS_H ++ ++#include ++ ++/* Page size */ ++#define HW_PAGE_SIZE_4KB 0x1000 ++#define HW_PAGE_SIZE_64KB 0x10000 ++#define HW_PAGE_SIZE_1MB 0x100000 ++#define HW_PAGE_SIZE_16MB 0x1000000 ++ ++/* HW_STATUS: return type for HW API */ ++typedef long HW_STATUS; ++ ++/* HW_SetClear_t: Enumerated Type used to set and clear any bit */ ++enum HW_SetClear_t { ++ HW_CLEAR, ++ HW_SET ++} ; ++ ++/* HW_Endianism_t: Enumerated Type used to specify the endianism ++ * Do NOT change these values. They are used as bit fields. */ ++enum HW_Endianism_t { ++ HW_LITTLE_ENDIAN, ++ HW_BIG_ENDIAN ++ ++} ; ++ ++/* HW_ElementSize_t: Enumerated Type used to specify the element size ++ * Do NOT change these values. They are used as bit fields. */ ++enum HW_ElementSize_t { ++ HW_ELEM_SIZE_8BIT, ++ HW_ELEM_SIZE_16BIT, ++ HW_ELEM_SIZE_32BIT, ++ HW_ELEM_SIZE_64BIT ++ ++} ; ++ ++/* HW_IdleMode_t: Enumerated Type used to specify Idle modes */ ++ enum HW_IdleMode_t { ++ HW_FORCE_IDLE, ++ HW_NO_IDLE, ++ HW_SMART_IDLE ++ } ; ++ ++#endif /* __HW_DEFS_H */ +diff --git a/drivers/dsp/bridge/hw/hw_dspssC64P.c b/drivers/dsp/bridge/hw/hw_dspssC64P.c +new file mode 100644 +index 0000000..a4b7c30 +--- /dev/null ++++ b/drivers/dsp/bridge/hw/hw_dspssC64P.c +@@ -0,0 +1,55 @@ ++/* ++ * hw_dspss64P.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== hw_dspss64P.c ======== ++ * Description: ++ * API definitions to configure DSP Subsystem modules like IPI ++ * ++ *! Revision History: ++ *! ================ ++ *! 19 Apr 2004 sb: Implemented HW_DSPSS_IPIEndianismSet ++ *! 16 Feb 2003 sb: Initial version ++ */ ++ ++/* PROJECT SPECIFIC INCLUDE FILES */ ++#include ++#include ++#include ++#include ++#include ++ ++/* HW FUNCTIONS */ ++HW_STATUS HW_DSPSS_BootModeSet(const u32 baseAddress, ++ enum HW_DSPSYSC_BootMode_t bootMode, ++ const u32 bootAddress) ++{ ++ HW_STATUS status = RET_OK; ++ u32 offset = SYSC_IVA2BOOTMOD_OFFSET; ++ u32 alignedBootAddr; ++ ++ /* if Boot mode it DIRECT BOOT, check that the bootAddress is ++ * aligned to atleast 1K :: TODO */ ++ WR_MEM_32_VOLATILE((baseAddress) + offset, bootMode); ++ ++ offset = SYSC_IVA2BOOTADDR_OFFSET; ++ ++ alignedBootAddr = bootAddress & SYSC_IVA2BOOTADDR_MASK; ++ ++ WR_MEM_32_VOLATILE((baseAddress) + offset, alignedBootAddr); ++ ++ return status; ++} +diff --git a/drivers/dsp/bridge/hw/hw_dspssC64P.h b/drivers/dsp/bridge/hw/hw_dspssC64P.h +new file mode 100644 +index 0000000..493effd +--- /dev/null ++++ b/drivers/dsp/bridge/hw/hw_dspssC64P.h +@@ -0,0 +1,48 @@ ++/* ++ * hw_dspssC64P.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== hw_dspss.h ======== ++ * Description: ++ * DSP Subsystem API declarations ++ * ++ *! Revision History: ++ *! ================ ++ *! 19-Apr-2004 sb: Removed redundant argument from HW_DSPSS_IPIEndianismSet ++ *! Moved endianness and element size to generic hw_defs.h ++ *! 16 Feb 2003 sb: Initial version ++ */ ++ ++#ifndef __HW_DSPSS_H ++#define __HW_DSPSS_H ++#include ++ ++ enum HW_DSPSYSC_BootMode_t { ++ HW_DSPSYSC_DIRECTBOOT = 0x0, ++ HW_DSPSYSC_IDLEBOOT = 0x1, ++ HW_DSPSYSC_SELFLOOPBOOT = 0x2, ++ HW_DSPSYSC_USRBOOTSTRAP = 0x3, ++ HW_DSPSYSC_DEFAULTRESTORE = 0x4 ++ } ; ++ ++#define HW_DSP_IDLEBOOT_ADDR 0x007E0000 ++ ++ extern HW_STATUS HW_DSPSS_BootModeSet(const u32 baseAddress, ++ enum HW_DSPSYSC_BootMode_t bootMode, ++ const u32 bootAddress); ++ ++#endif /* __HW_DSPSS_H */ +diff --git a/drivers/dsp/bridge/hw/hw_mbox.c b/drivers/dsp/bridge/hw/hw_mbox.c +new file mode 100644 +index 0000000..9f14f34 +--- /dev/null ++++ b/drivers/dsp/bridge/hw/hw_mbox.c +@@ -0,0 +1,244 @@ ++/* ++ * hw_mbox.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2007 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== hw_mbox.c ======== ++ * Description: ++ * Mailbox messaging & configuration API definitions ++ * ++ *! Revision History: ++ *! ================ ++ *! 16 Feb 2003 sb: Initial version ++ */ ++ ++#include ++#include "MLBRegAcM.h" ++#include ++#include ++ ++/* width in bits of MBOX Id */ ++#define HW_MBOX_ID_WIDTH 2 ++ ++struct MAILBOX_CONTEXT mboxsetting = {0x4, 0x1, 0x1}; ++ ++/* Saves the mailbox context */ ++HW_STATUS HW_MBOX_saveSettings(u32 baseAddress) ++{ ++ HW_STATUS status = RET_OK; ++ ++ mboxsetting.sysconfig = MLBMAILBOX_SYSCONFIGReadRegister32(baseAddress); ++ /* Get current enable status */ ++ mboxsetting.irqEnable0 = MLBMAILBOX_IRQENABLE___0_3ReadRegister32 ++ (baseAddress, HW_MBOX_U0_ARM); ++ mboxsetting.irqEnable1 = MLBMAILBOX_IRQENABLE___0_3ReadRegister32 ++ (baseAddress, HW_MBOX_U1_DSP1); ++ return status; ++} ++ ++/* Restores the mailbox context */ ++HW_STATUS HW_MBOX_restoreSettings(u32 baseAddress) ++{ ++ HW_STATUS status = RET_OK; ++ /* Restor IRQ enable status */ ++ MLBMAILBOX_IRQENABLE___0_3WriteRegister32(baseAddress, HW_MBOX_U0_ARM, ++ mboxsetting.irqEnable0); ++ MLBMAILBOX_IRQENABLE___0_3WriteRegister32(baseAddress, HW_MBOX_U1_DSP1, ++ mboxsetting.irqEnable1); ++ /* Restore Sysconfig register */ ++ MLBMAILBOX_SYSCONFIGWriteRegister32(baseAddress, mboxsetting.sysconfig); ++ return status; ++} ++ ++/* Reads a u32 from the sub module message box Specified. if there are no ++ * messages in the mailbox then and error is returned. */ ++HW_STATUS HW_MBOX_MsgRead(const u32 baseAddress, const HW_MBOX_Id_t mailBoxId, ++ u32 *const pReadValue) ++{ ++ HW_STATUS status = RET_OK; ++ ++ /* Check input parameters */ ++ CHECK_INPUT_PARAM(baseAddress, 0, RET_BAD_NULL_PARAM, RES_MBOX_BASE + ++ RES_INVALID_INPUT_PARAM); ++ CHECK_INPUT_PARAM(pReadValue, NULL, RET_BAD_NULL_PARAM, RES_MBOX_BASE + ++ RES_INVALID_INPUT_PARAM); ++ CHECK_INPUT_RANGE_MIN0(mailBoxId, HW_MBOX_ID_MAX, RET_INVALID_ID, ++ RES_MBOX_BASE + RES_INVALID_INPUT_PARAM); ++ ++ /* Read 32-bit message in mail box */ ++ *pReadValue = MLBMAILBOX_MESSAGE___0_15ReadRegister32(baseAddress, ++ (u32)mailBoxId); ++ ++ return status; ++} ++ ++/* Writes a u32 from the sub module message box Specified. */ ++HW_STATUS HW_MBOX_MsgWrite(const u32 baseAddress, const HW_MBOX_Id_t mailBoxId, ++ const u32 writeValue) ++{ ++ HW_STATUS status = RET_OK; ++ ++ /* Check input parameters */ ++ CHECK_INPUT_PARAM(baseAddress, 0, RET_BAD_NULL_PARAM, RES_MBOX_BASE + ++ RES_INVALID_INPUT_PARAM); ++ CHECK_INPUT_RANGE_MIN0(mailBoxId, HW_MBOX_ID_MAX, RET_INVALID_ID, ++ RES_MBOX_BASE + RES_INVALID_INPUT_PARAM); ++ ++ /* Write 32-bit value to mailbox */ ++ MLBMAILBOX_MESSAGE___0_15WriteRegister32(baseAddress, (u32)mailBoxId, ++ (u32)writeValue); ++ ++ return status; ++} ++ ++/* Gets number of messages in a specified mailbox. */ ++HW_STATUS HW_MBOX_NumMsgGet(const u32 baseAddress, const HW_MBOX_Id_t mailBoxId, ++ u32 *const pNumMsg) ++{ ++ HW_STATUS status = RET_OK; ++ ++ /* Check input parameters */ ++ CHECK_INPUT_PARAM(baseAddress, 0, RET_BAD_NULL_PARAM, RES_MBOX_BASE + ++ RES_INVALID_INPUT_PARAM); ++ CHECK_INPUT_PARAM(pNumMsg, NULL, RET_BAD_NULL_PARAM, RES_MBOX_BASE + ++ RES_INVALID_INPUT_PARAM); ++ ++ CHECK_INPUT_RANGE_MIN0(mailBoxId, HW_MBOX_ID_MAX, RET_INVALID_ID, ++ RES_MBOX_BASE + RES_INVALID_INPUT_PARAM); ++ ++ /* Get number of messages available for MailBox */ ++ *pNumMsg = MLBMAILBOX_MSGSTATUS___0_15NbOfMsgMBmRead32(baseAddress, ++ (u32)mailBoxId); ++ ++ return status; ++} ++ ++/* Enables the specified IRQ. */ ++HW_STATUS HW_MBOX_EventEnable(const u32 baseAddress, ++ const HW_MBOX_Id_t mailBoxId, ++ const HW_MBOX_UserId_t userId, ++ const u32 events) ++{ ++ HW_STATUS status = RET_OK; ++ u32 irqEnableReg; ++ ++ /* Check input parameters */ ++ CHECK_INPUT_PARAM(baseAddress, 0, RET_BAD_NULL_PARAM, RES_MBOX_BASE + ++ RES_INVALID_INPUT_PARAM); ++ CHECK_INPUT_RANGE_MIN0(mailBoxId, HW_MBOX_ID_MAX, RET_INVALID_ID, ++ RES_MBOX_BASE + RES_INVALID_INPUT_PARAM); ++ CHECK_INPUT_RANGE_MIN0(enableIrq, HW_MBOX_INT_MAX, RET_INVALID_ID, ++ RES_MBOX_BASE + RES_INVALID_INPUT_PARAM); ++ CHECK_INPUT_RANGE_MIN0(userId, HW_MBOX_USER_MAX, RET_INVALID_ID, ++ RES_MBOX_BASE + RES_INVALID_INPUT_PARAM); ++ ++ /* Get current enable status */ ++ irqEnableReg = MLBMAILBOX_IRQENABLE___0_3ReadRegister32(baseAddress, ++ (u32)userId); ++ ++ /* update enable value */ ++ irqEnableReg |= ((u32)(events)) << (((u32)(mailBoxId)) * ++ HW_MBOX_ID_WIDTH); ++ ++ /* write new enable status */ ++ MLBMAILBOX_IRQENABLE___0_3WriteRegister32(baseAddress, (u32)userId, ++ (u32)irqEnableReg); ++ ++ mboxsetting.sysconfig = MLBMAILBOX_SYSCONFIGReadRegister32(baseAddress); ++ /* Get current enable status */ ++ mboxsetting.irqEnable0 = MLBMAILBOX_IRQENABLE___0_3ReadRegister32 ++ (baseAddress, HW_MBOX_U0_ARM); ++ mboxsetting.irqEnable1 = MLBMAILBOX_IRQENABLE___0_3ReadRegister32 ++ (baseAddress, HW_MBOX_U1_DSP1); ++ return status; ++} ++ ++/* Disables the specified IRQ. */ ++HW_STATUS HW_MBOX_EventDisable(const u32 baseAddress, ++ const HW_MBOX_Id_t mailBoxId, ++ const HW_MBOX_UserId_t userId, ++ const u32 events) ++{ ++ HW_STATUS status = RET_OK; ++ u32 irqDisableReg; ++ ++ /* Check input parameters */ ++ CHECK_INPUT_PARAM(baseAddress, 0, RET_BAD_NULL_PARAM, RES_MBOX_BASE + ++ RES_INVALID_INPUT_PARAM); ++ CHECK_INPUT_RANGE_MIN0(mailBoxId, HW_MBOX_ID_MAX, RET_INVALID_ID, ++ RES_MBOX_BASE + RES_INVALID_INPUT_PARAM); ++ CHECK_INPUT_RANGE_MIN0(disableIrq, HW_MBOX_INT_MAX, RET_INVALID_ID, ++ RES_MBOX_BASE + RES_INVALID_INPUT_PARAM); ++ CHECK_INPUT_RANGE_MIN0(userId, HW_MBOX_USER_MAX, RET_INVALID_ID, ++ RES_MBOX_BASE + RES_INVALID_INPUT_PARAM); ++ ++ /* Get current enable status */ ++ irqDisableReg = MLBMAILBOX_IRQENABLE___0_3ReadRegister32(baseAddress, ++ (u32)userId); ++ ++ /* update enable value */ ++ irqDisableReg &= ~(((u32)(events)) << (((u32)(mailBoxId)) * ++ HW_MBOX_ID_WIDTH)); ++ ++ /* write new enable status */ ++ MLBMAILBOX_IRQENABLE___0_3WriteRegister32(baseAddress, (u32)userId, ++ (u32)irqDisableReg); ++ ++ return status; ++} ++ ++/* Sets the status of the specified IRQ. */ ++HW_STATUS HW_MBOX_EventAck(const u32 baseAddress, const HW_MBOX_Id_t mailBoxId, ++ const HW_MBOX_UserId_t userId, const u32 event) ++{ ++ HW_STATUS status = RET_OK; ++ u32 irqStatusReg; ++ ++ /* Check input parameters */ ++ CHECK_INPUT_PARAM(baseAddress, 0, RET_BAD_NULL_PARAM, RES_MBOX_BASE + ++ RES_INVALID_INPUT_PARAM); ++ ++ CHECK_INPUT_RANGE_MIN0(irqStatus, HW_MBOX_INT_MAX, RET_INVALID_ID, ++ RES_MBOX_BASE + RES_INVALID_INPUT_PARAM); ++ CHECK_INPUT_RANGE_MIN0(mailBoxId, HW_MBOX_ID_MAX, RET_INVALID_ID, ++ RES_MBOX_BASE + RES_INVALID_INPUT_PARAM); ++ CHECK_INPUT_RANGE_MIN0(userId, HW_MBOX_USER_MAX, RET_INVALID_ID, ++ RES_MBOX_BASE + RES_INVALID_INPUT_PARAM); ++ ++ /* calculate status to write */ ++ irqStatusReg = ((u32)event) << (((u32)(mailBoxId)) * ++ HW_MBOX_ID_WIDTH); ++ ++ /* clear Irq Status for specified mailbox/User Id */ ++ MLBMAILBOX_IRQSTATUS___0_3WriteRegister32(baseAddress, (u32)userId, ++ (u32)irqStatusReg); ++ ++ /* ++ * FIXME: Replace all this custom register access with standard ++ * __raw_read/write(). ++ * ++ * FIXME: Replace all interrupt handlers with standard linux style ++ * interrupt handlers. ++ * ++ * FIXME: Replace direct access to PRCM registers with omap standard ++ * PRCM register access. ++ * ++ * Flush posted write for the irq status to avoid spurious interrupts. ++ */ ++ MLBMAILBOX_IRQSTATUS___0_3ReadRegister32(baseAddress, (u32)userId); ++ ++ return status; ++} +diff --git a/drivers/dsp/bridge/hw/hw_mbox.h b/drivers/dsp/bridge/hw/hw_mbox.h +new file mode 100644 +index 0000000..d2981d3 +--- /dev/null ++++ b/drivers/dsp/bridge/hw/hw_mbox.h +@@ -0,0 +1,323 @@ ++/* ++ * hw_mbox.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2007 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== hw_mbox.h ======== ++ * Description: ++ * HW Mailbox API and types definitions ++ * ++ *! Revision History: ++ *! ================ ++ *! 16 Feb 2003 sb: Initial version ++ */ ++#ifndef __MBOX_H ++#define __MBOX_H ++ ++/* Bitmasks for Mailbox interrupt sources */ ++#define HW_MBOX_INT_NEW_MSG 0x1 ++#define HW_MBOX_INT_NOT_FULL 0x2 ++#define HW_MBOX_INT_ALL 0x3 ++ ++/* Maximum number of messages that mailbox can hald at a time. */ ++#define HW_MBOX_MAX_NUM_MESSAGES 4 ++ ++/* HW_MBOX_Id_t: Enumerated Type used to specify Mailbox Sub Module Id Number */ ++typedef enum HW_MBOX_Id_label { ++ HW_MBOX_ID_0, ++ HW_MBOX_ID_1, ++ HW_MBOX_ID_2, ++ HW_MBOX_ID_3, ++ HW_MBOX_ID_4, ++ HW_MBOX_ID_5 ++ ++} HW_MBOX_Id_t, *pHW_MBOX_Id_t; ++ ++/* HW_MBOX_UserId_t: Enumerated Type used to specify Mail box User Id */ ++typedef enum HW_MBOX_UserId_label { ++ HW_MBOX_U0_ARM, ++ HW_MBOX_U1_DSP1, ++ HW_MBOX_U2_DSP2, ++ HW_MBOX_U3_ARM ++ ++} HW_MBOX_UserId_t, *pHW_MBOX_UserId_t; ++ ++/* Mailbox context settings */ ++struct MAILBOX_CONTEXT { ++ u32 sysconfig; ++ u32 irqEnable0; ++ u32 irqEnable1; ++}; ++ ++/* ++* FUNCTION : HW_MBOX_MsgRead ++* ++* INPUTS: ++* ++* Identifier : baseAddress ++* Type : const u32 ++* Description : Base Address of instance of Mailbox module ++* ++* Identifier : mailBoxId ++* Type : const HW_MBOX_Id_t ++* Description : Mail Box Sub module Id to read ++* ++* OUTPUTS: ++* ++* Identifier : pReadValue ++* Type : u32 *const ++* Description : Value read from MailBox ++* ++* RETURNS: ++* ++* Type : ReturnCode_t ++* Description : RET_OK No errors occured ++* RET_BAD_NULL_PARAM Address/ptr Paramater was set to 0/NULL ++* RET_INVALID_ID Invalid Id used ++* RET_EMPTY Mailbox empty ++* ++* PURPOSE: : this function reads a u32 from the sub module message ++* box Specified. if there are no messages in the mailbox ++* then and error is returned. ++*/ ++extern HW_STATUS HW_MBOX_MsgRead(const u32 baseAddress, ++ const HW_MBOX_Id_t mailBoxId, ++ u32 *const pReadValue); ++ ++/* ++* FUNCTION : HW_MBOX_MsgWrite ++* ++* INPUTS: ++* ++* Identifier : baseAddress ++* Type : const u32 ++* Description : Base Address of instance of Mailbox module ++* ++* Identifier : mailBoxId ++* Type : const HW_MBOX_Id_t ++* Description : Mail Box Sub module Id to write ++* ++* Identifier : writeValue ++* Type : const u32 ++* Description : Value to write to MailBox ++* ++* RETURNS: ++* ++* Type : ReturnCode_t ++* Description : RET_OK No errors occured ++* RET_BAD_NULL_PARAM Address/pointer Paramater was set to 0/NULL ++* RET_INVALID_ID Invalid Id used ++* ++* PURPOSE: : this function writes a u32 from the sub module message ++* box Specified. ++*/ ++extern HW_STATUS HW_MBOX_MsgWrite( ++ const u32 baseAddress, ++ const HW_MBOX_Id_t mailBoxId, ++ const u32 writeValue ++ ); ++ ++/* ++* FUNCTION : HW_MBOX_NumMsgGet ++* ++* INPUTS: ++* ++* Identifier : baseAddress ++* Type : const u32 ++* Description : Base Address of instance of Mailbox module ++* ++* Identifier : mailBoxId ++* Type : const HW_MBOX_Id_t ++* Description : Mail Box Sub module Id to get num messages ++* ++* OUTPUTS: ++* ++* Identifier : pNumMsg ++* Type : u32 *const ++* Description : Number of messages in mailbox ++* ++* RETURNS: ++* ++* Type : ReturnCode_t ++* Description : RET_OK No errors occured ++* RET_BAD_NULL_PARAM Address/pointer Paramater was set to 0/NULL ++* RET_INVALID_ID Inavlid ID input at parameter ++* ++* PURPOSE: : this function gets number of messages in a specified mailbox. ++*/ ++extern HW_STATUS HW_MBOX_NumMsgGet( ++ const u32 baseAddress, ++ const HW_MBOX_Id_t mailBoxId, ++ u32 *const pNumMsg ++ ); ++ ++/* ++* FUNCTION : HW_MBOX_EventEnable ++* ++* INPUTS: ++* ++* Identifier : baseAddress ++* Type : const u32 ++* RET_BAD_NULL_PARAM Address/pointer Paramater was set to 0/NULL ++* ++* Identifier : mailBoxId ++* Type : const HW_MBOX_Id_t ++* Description : Mail Box Sub module Id to enable ++* ++* Identifier : userId ++* Type : const HW_MBOX_UserId_t ++* Description : Mail box User Id to enable ++* ++* Identifier : enableIrq ++* Type : const u32 ++* Description : Irq value to enable ++* ++* RETURNS: ++* ++* Type : ReturnCode_t ++* Description : RET_OK No errors occured ++* RET_BAD_NULL_PARAM A Pointer Paramater was set to NULL ++* RET_INVALID_ID Invalid Id used ++* ++* PURPOSE: : this function enables the specified IRQ. ++*/ ++extern HW_STATUS HW_MBOX_EventEnable( ++ const u32 baseAddress, ++ const HW_MBOX_Id_t mailBoxId, ++ const HW_MBOX_UserId_t userId, ++ const u32 events ++ ); ++ ++/* ++* FUNCTION : HW_MBOX_EventDisable ++* ++* INPUTS: ++* ++* Identifier : baseAddress ++* Type : const u32 ++* RET_BAD_NULL_PARAM Address/pointer Paramater was set to 0/NULL ++* ++* Identifier : mailBoxId ++* Type : const HW_MBOX_Id_t ++* Description : Mail Box Sub module Id to disable ++* ++* Identifier : userId ++* Type : const HW_MBOX_UserId_t ++* Description : Mail box User Id to disable ++* ++* Identifier : enableIrq ++* Type : const u32 ++* Description : Irq value to disable ++* ++* RETURNS: ++* ++* Type : ReturnCode_t ++* Description : RET_OK No errors occured ++* RET_BAD_NULL_PARAM A Pointer Paramater was set to NULL ++* RET_INVALID_ID Invalid Id used ++* ++* PURPOSE: : this function disables the specified IRQ. ++*/ ++extern HW_STATUS HW_MBOX_EventDisable( ++ const u32 baseAddress, ++ const HW_MBOX_Id_t mailBoxId, ++ const HW_MBOX_UserId_t userId, ++ const u32 events ++ ); ++ ++/* ++* FUNCTION : HW_MBOX_EventAck ++* ++* INPUTS: ++* ++* Identifier : baseAddress ++* Type : const u32 ++* Description : Base Address of instance of Mailbox module ++* ++* Identifier : mailBoxId ++* Type : const HW_MBOX_Id_t ++* Description : Mail Box Sub module Id to set ++* ++* Identifier : userId ++* Type : const HW_MBOX_UserId_t ++* Description : Mail box User Id to set ++* ++* Identifier : irqStatus ++* Type : const u32 ++* Description : The value to write IRQ status ++* ++* OUTPUTS: ++* ++* RETURNS: ++* ++* Type : ReturnCode_t ++* Description : RET_OK No errors occured ++* RET_BAD_NULL_PARAM Address Paramater was set to 0 ++* RET_INVALID_ID Invalid Id used ++* ++* PURPOSE: : this function sets the status of the specified IRQ. ++*/ ++extern HW_STATUS HW_MBOX_EventAck( ++ const u32 baseAddress, ++ const HW_MBOX_Id_t mailBoxId, ++ const HW_MBOX_UserId_t userId, ++ const u32 event ++ ); ++ ++/* ++* FUNCTION : HW_MBOX_saveSettings ++* ++* INPUTS: ++* ++* Identifier : baseAddress ++* Type : const u32 ++* Description : Base Address of instance of Mailbox module ++* ++* ++* RETURNS: ++* ++* Type : ReturnCode_t ++* Description : RET_OK No errors occured ++* RET_BAD_NULL_PARAM Address/pointer Paramater was set to 0/NULL ++* RET_INVALID_ID Invalid Id used ++* RET_EMPTY Mailbox empty ++* ++* PURPOSE: : this function saves the context of mailbox ++*/ ++extern HW_STATUS HW_MBOX_saveSettings(u32 baseAddres); ++ ++/* ++* FUNCTION : HW_MBOX_restoreSettings ++* ++* INPUTS: ++* ++* Identifier : baseAddress ++* Type : const u32 ++* Description : Base Address of instance of Mailbox module ++* ++* ++* RETURNS: ++* ++* Type : ReturnCode_t ++* Description : RET_OK No errors occured ++* RET_BAD_NULL_PARAM Address/pointer Paramater was set to 0/NULL ++* RET_INVALID_ID Invalid Id used ++* RET_EMPTY Mailbox empty ++* ++* PURPOSE: : this function restores the context of mailbox ++*/ ++extern HW_STATUS HW_MBOX_restoreSettings(u32 baseAddres); ++ ++#endif /* __MBOX_H */ +diff --git a/drivers/dsp/bridge/hw/hw_mmu.c b/drivers/dsp/bridge/hw/hw_mmu.c +new file mode 100644 +index 0000000..ab65de0 +--- /dev/null ++++ b/drivers/dsp/bridge/hw/hw_mmu.c +@@ -0,0 +1,598 @@ ++/* ++ * hw_mmu.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2007 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== hw_mmu.c ======== ++ * Description: ++ * API definitions to setup MMU TLB and PTE ++ * ++ *! Revision History: ++ *! ================ ++ *! 19-Apr-2004 sb TLBAdd and TLBFlush input the page size in bytes instead ++ of an enum. TLBAdd inputs mapping attributes struct instead ++ of individual arguments. ++ Removed MMU.h and other cosmetic updates. ++ *! 08-Mar-2004 sb Added the Page Table Management APIs ++ *! 16 Feb 2003 sb: Initial version ++ */ ++ ++#include ++#include "MMURegAcM.h" ++#include ++#include ++#include ++ ++#define MMU_BASE_VAL_MASK 0xFC00 ++#define MMU_PAGE_MAX 3 ++#define MMU_ELEMENTSIZE_MAX 3 ++#define MMU_ADDR_MASK 0xFFFFF000 ++#define MMU_TTB_MASK 0xFFFFC000 ++#define MMU_SECTION_ADDR_MASK 0xFFF00000 ++#define MMU_SSECTION_ADDR_MASK 0xFF000000 ++#define MMU_PAGE_TABLE_MASK 0xFFFFFC00 ++#define MMU_LARGE_PAGE_MASK 0xFFFF0000 ++#define MMU_SMALL_PAGE_MASK 0xFFFFF000 ++ ++#define MMU_LOAD_TLB 0x00000001 ++ ++/* HW_MMUPageSize_t: Enumerated Type used to specify the MMU Page Size(SLSS) */ ++enum HW_MMUPageSize_t { ++ HW_MMU_SECTION, ++ HW_MMU_LARGE_PAGE, ++ HW_MMU_SMALL_PAGE, ++ HW_MMU_SUPERSECTION ++} ; ++ ++/* ++* FUNCTION : MMU_FlushEntry ++* ++* INPUTS: ++* ++* Identifier : baseAddress ++* Type : const u32 ++* Description : Base Address of instance of MMU module ++* ++* RETURNS: ++* ++* Type : HW_STATUS ++* Description : RET_OK -- No errors occured ++* RET_BAD_NULL_PARAM -- A Pointer ++* Paramater was set to NULL ++* ++* PURPOSE: : Flush the TLB entry pointed by the ++* lock counter register ++* even if this entry is set protected ++* ++* METHOD: : Check the Input parameter and Flush a ++* single entry in the TLB. ++*/ ++static HW_STATUS MMU_FlushEntry(const u32 baseAddress); ++ ++/* ++* FUNCTION : MMU_SetCAMEntry ++* ++* INPUTS: ++* ++* Identifier : baseAddress ++* TypE : const u32 ++* Description : Base Address of instance of MMU module ++* ++* Identifier : pageSize ++* TypE : const u32 ++* Description : It indicates the page size ++* ++* Identifier : preservedBit ++* Type : const u32 ++* Description : It indicates the TLB entry is preserved entry ++* or not ++* ++* Identifier : validBit ++* Type : const u32 ++* Description : It indicates the TLB entry is valid entry or not ++* ++* ++* Identifier : virtualAddrTag ++* Type : const u32 ++* Description : virtual Address ++* ++* RETURNS: ++* ++* Type : HW_STATUS ++* Description : RET_OK -- No errors occured ++* RET_BAD_NULL_PARAM -- A Pointer Paramater ++* was set to NULL ++* RET_PARAM_OUT_OF_RANGE -- Input Parameter out ++* of Range ++* ++* PURPOSE: : Set MMU_CAM reg ++* ++* METHOD: : Check the Input parameters and set the CAM entry. ++*/ ++static HW_STATUS MMU_SetCAMEntry(const u32 baseAddress, ++ const u32 pageSize, ++ const u32 preservedBit, ++ const u32 validBit, ++ const u32 virtualAddrTag); ++ ++/* ++* FUNCTION : MMU_SetRAMEntry ++* ++* INPUTS: ++* ++* Identifier : baseAddress ++* Type : const u32 ++* Description : Base Address of instance of MMU module ++* ++* Identifier : physicalAddr ++* Type : const u32 ++* Description : Physical Address to which the corresponding ++* virtual Address shouldpoint ++* ++* Identifier : endianism ++* Type : HW_Endianism_t ++* Description : endianism for the given page ++* ++* Identifier : elementSize ++* Type : HW_ElementSize_t ++* Description : The element size ( 8,16, 32 or 64 bit) ++* ++* Identifier : mixedSize ++* Type : HW_MMUMixedSize_t ++* Description : Element Size to follow CPU or TLB ++* ++* RETURNS: ++* ++* Type : HW_STATUS ++* Description : RET_OK -- No errors occured ++* RET_BAD_NULL_PARAM -- A Pointer Paramater ++* was set to NULL ++* RET_PARAM_OUT_OF_RANGE -- Input Parameter ++* out of Range ++* ++* PURPOSE: : Set MMU_CAM reg ++* ++* METHOD: : Check the Input parameters and set the RAM entry. ++*/ ++static HW_STATUS MMU_SetRAMEntry(const u32 baseAddress, ++ const u32 physicalAddr, ++ enum HW_Endianism_t endianism, ++ enum HW_ElementSize_t elementSize, ++ enum HW_MMUMixedSize_t mixedSize); ++ ++/* HW FUNCTIONS */ ++ ++HW_STATUS HW_MMU_Enable(const u32 baseAddress) ++{ ++ HW_STATUS status = RET_OK; ++ ++ MMUMMU_CNTLMMUEnableWrite32(baseAddress, HW_SET); ++ ++ return status; ++} ++ ++HW_STATUS HW_MMU_Disable(const u32 baseAddress) ++{ ++ HW_STATUS status = RET_OK; ++ ++ MMUMMU_CNTLMMUEnableWrite32(baseAddress, HW_CLEAR); ++ ++ return status; ++} ++ ++HW_STATUS HW_MMU_NumLockedSet(const u32 baseAddress, ++ u32 numLockedEntries) ++{ ++ HW_STATUS status = RET_OK; ++ ++ MMUMMU_LOCKBaseValueWrite32(baseAddress, numLockedEntries); ++ ++ return status; ++} ++ ++HW_STATUS HW_MMU_VictimNumSet(const u32 baseAddress, ++ u32 victimEntryNum) ++{ ++ HW_STATUS status = RET_OK; ++ ++ MMUMMU_LOCKCurrentVictimWrite32(baseAddress, victimEntryNum); ++ ++ return status; ++} ++ ++HW_STATUS HW_MMU_EventAck(const u32 baseAddress, u32 irqMask) ++{ ++ HW_STATUS status = RET_OK; ++ ++ MMUMMU_IRQSTATUSWriteRegister32(baseAddress, irqMask); ++ ++ return status; ++} ++ ++HW_STATUS HW_MMU_EventDisable(const u32 baseAddress, ++ u32 irqMask) ++{ ++ HW_STATUS status = RET_OK; ++ u32 irqReg; ++ ++ irqReg = MMUMMU_IRQENABLEReadRegister32(baseAddress); ++ ++ MMUMMU_IRQENABLEWriteRegister32(baseAddress, irqReg & ~irqMask); ++ ++ return status; ++} ++ ++HW_STATUS HW_MMU_EventEnable(const u32 baseAddress, u32 irqMask) ++{ ++ HW_STATUS status = RET_OK; ++ u32 irqReg; ++ ++ irqReg = MMUMMU_IRQENABLEReadRegister32(baseAddress); ++ ++ MMUMMU_IRQENABLEWriteRegister32(baseAddress, irqReg | irqMask); ++ ++ return status; ++} ++ ++ ++HW_STATUS HW_MMU_EventStatus(const u32 baseAddress, u32 *irqMask) ++{ ++ HW_STATUS status = RET_OK; ++ ++ *irqMask = MMUMMU_IRQSTATUSReadRegister32(baseAddress); ++ ++ return status; ++} ++ ++ ++HW_STATUS HW_MMU_FaultAddrRead(const u32 baseAddress, u32 *addr) ++{ ++ HW_STATUS status = RET_OK; ++ ++ /*Check the input Parameters*/ ++ CHECK_INPUT_PARAM(baseAddress, 0, RET_BAD_NULL_PARAM, ++ RES_MMU_BASE + RES_INVALID_INPUT_PARAM); ++ ++ /* read values from register */ ++ *addr = MMUMMU_FAULT_ADReadRegister32(baseAddress); ++ ++ return status; ++} ++ ++HW_STATUS HW_MMU_TTBSet(const u32 baseAddress, u32 TTBPhysAddr) ++{ ++ HW_STATUS status = RET_OK; ++ u32 loadTTB; ++ ++ /*Check the input Parameters*/ ++ CHECK_INPUT_PARAM(baseAddress, 0, RET_BAD_NULL_PARAM, ++ RES_MMU_BASE + RES_INVALID_INPUT_PARAM); ++ ++ loadTTB = TTBPhysAddr & ~0x7FUL; ++ /* write values to register */ ++ MMUMMU_TTBWriteRegister32(baseAddress, loadTTB); ++ ++ return status; ++} ++ ++HW_STATUS HW_MMU_TWLEnable(const u32 baseAddress) ++{ ++ HW_STATUS status = RET_OK; ++ ++ MMUMMU_CNTLTWLEnableWrite32(baseAddress, HW_SET); ++ ++ return status; ++} ++ ++HW_STATUS HW_MMU_TWLDisable(const u32 baseAddress) ++{ ++ HW_STATUS status = RET_OK; ++ ++ MMUMMU_CNTLTWLEnableWrite32(baseAddress, HW_CLEAR); ++ ++ return status; ++} ++ ++HW_STATUS HW_MMU_TLBFlush(const u32 baseAddress, u32 virtualAddr, ++ u32 pageSize) ++{ ++ HW_STATUS status = RET_OK; ++ u32 virtualAddrTag; ++ enum HW_MMUPageSize_t pgSizeBits; ++ ++ switch (pageSize) { ++ case HW_PAGE_SIZE_4KB: ++ pgSizeBits = HW_MMU_SMALL_PAGE; ++ break; ++ ++ case HW_PAGE_SIZE_64KB: ++ pgSizeBits = HW_MMU_LARGE_PAGE; ++ break; ++ ++ case HW_PAGE_SIZE_1MB: ++ pgSizeBits = HW_MMU_SECTION; ++ break; ++ ++ case HW_PAGE_SIZE_16MB: ++ pgSizeBits = HW_MMU_SUPERSECTION; ++ break; ++ ++ default: ++ return RET_FAIL; ++ } ++ ++ /* Generate the 20-bit tag from virtual address */ ++ virtualAddrTag = ((virtualAddr & MMU_ADDR_MASK) >> 12); ++ ++ MMU_SetCAMEntry(baseAddress, pgSizeBits, 0, 0, virtualAddrTag); ++ ++ MMU_FlushEntry(baseAddress); ++ ++ return status; ++} ++ ++HW_STATUS HW_MMU_TLBAdd(const u32 baseAddress, ++ u32 physicalAddr, ++ u32 virtualAddr, ++ u32 pageSize, ++ u32 entryNum, ++ struct HW_MMUMapAttrs_t *mapAttrs, ++ enum HW_SetClear_t preservedBit, ++ enum HW_SetClear_t validBit) ++{ ++ HW_STATUS status = RET_OK; ++ u32 lockReg; ++ u32 virtualAddrTag; ++ enum HW_MMUPageSize_t mmuPgSize; ++ ++ /*Check the input Parameters*/ ++ CHECK_INPUT_PARAM(baseAddress, 0, RET_BAD_NULL_PARAM, ++ RES_MMU_BASE + RES_INVALID_INPUT_PARAM); ++ CHECK_INPUT_RANGE_MIN0(pageSize, MMU_PAGE_MAX, RET_PARAM_OUT_OF_RANGE, ++ RES_MMU_BASE + RES_INVALID_INPUT_PARAM); ++ CHECK_INPUT_RANGE_MIN0(mapAttrs->elementSize, MMU_ELEMENTSIZE_MAX, ++ RET_PARAM_OUT_OF_RANGE, RES_MMU_BASE + ++ RES_INVALID_INPUT_PARAM); ++ ++ switch (pageSize) { ++ case HW_PAGE_SIZE_4KB: ++ mmuPgSize = HW_MMU_SMALL_PAGE; ++ break; ++ ++ case HW_PAGE_SIZE_64KB: ++ mmuPgSize = HW_MMU_LARGE_PAGE; ++ break; ++ ++ case HW_PAGE_SIZE_1MB: ++ mmuPgSize = HW_MMU_SECTION; ++ break; ++ ++ case HW_PAGE_SIZE_16MB: ++ mmuPgSize = HW_MMU_SUPERSECTION; ++ break; ++ ++ default: ++ return RET_FAIL; ++ } ++ ++ lockReg = MMUMMU_LOCKReadRegister32(baseAddress); ++ ++ /* Generate the 20-bit tag from virtual address */ ++ virtualAddrTag = ((virtualAddr & MMU_ADDR_MASK) >> 12); ++ ++ /* Write the fields in the CAM Entry Register */ ++ MMU_SetCAMEntry(baseAddress, mmuPgSize, preservedBit, validBit, ++ virtualAddrTag); ++ ++ /* Write the different fields of the RAM Entry Register */ ++ /* endianism of the page,Element Size of the page (8, 16, 32, 64 bit)*/ ++ MMU_SetRAMEntry(baseAddress, physicalAddr, mapAttrs->endianism, ++ mapAttrs->elementSize, mapAttrs->mixedSize); ++ ++ /* Update the MMU Lock Register */ ++ /* currentVictim between lockedBaseValue and (MMU_Entries_Number - 1)*/ ++ MMUMMU_LOCKCurrentVictimWrite32(baseAddress, entryNum); ++ ++ /* Enable loading of an entry in TLB by writing 1 ++ into LD_TLB_REG register */ ++ MMUMMU_LD_TLBWriteRegister32(baseAddress, MMU_LOAD_TLB); ++ ++ ++ MMUMMU_LOCKWriteRegister32(baseAddress, lockReg); ++ ++ return status; ++} ++ ++HW_STATUS HW_MMU_PteSet(const u32 pgTblVa, ++ u32 physicalAddr, ++ u32 virtualAddr, ++ u32 pageSize, ++ struct HW_MMUMapAttrs_t *mapAttrs) ++{ ++ HW_STATUS status = RET_OK; ++ u32 pteAddr, pteVal; ++ s32 numEntries = 1; ++ ++ switch (pageSize) { ++ case HW_PAGE_SIZE_4KB: ++ pteAddr = HW_MMU_PteAddrL2(pgTblVa, ++ virtualAddr & MMU_SMALL_PAGE_MASK); ++ pteVal = ((physicalAddr & MMU_SMALL_PAGE_MASK) | ++ (mapAttrs->endianism << 9) | ++ (mapAttrs->elementSize << 4) | ++ (mapAttrs->mixedSize << 11) | 2 ++ ); ++ break; ++ ++ case HW_PAGE_SIZE_64KB: ++ numEntries = 16; ++ pteAddr = HW_MMU_PteAddrL2(pgTblVa, ++ virtualAddr & MMU_LARGE_PAGE_MASK); ++ pteVal = ((physicalAddr & MMU_LARGE_PAGE_MASK) | ++ (mapAttrs->endianism << 9) | ++ (mapAttrs->elementSize << 4) | ++ (mapAttrs->mixedSize << 11) | 1 ++ ); ++ break; ++ ++ case HW_PAGE_SIZE_1MB: ++ pteAddr = HW_MMU_PteAddrL1(pgTblVa, ++ virtualAddr & MMU_SECTION_ADDR_MASK); ++ pteVal = ((((physicalAddr & MMU_SECTION_ADDR_MASK) | ++ (mapAttrs->endianism << 15) | ++ (mapAttrs->elementSize << 10) | ++ (mapAttrs->mixedSize << 17)) & ++ ~0x40000) | 0x2 ++ ); ++ break; ++ ++ case HW_PAGE_SIZE_16MB: ++ numEntries = 16; ++ pteAddr = HW_MMU_PteAddrL1(pgTblVa, ++ virtualAddr & MMU_SSECTION_ADDR_MASK); ++ pteVal = (((physicalAddr & MMU_SSECTION_ADDR_MASK) | ++ (mapAttrs->endianism << 15) | ++ (mapAttrs->elementSize << 10) | ++ (mapAttrs->mixedSize << 17) ++ ) | 0x40000 | 0x2 ++ ); ++ break; ++ ++ case HW_MMU_COARSE_PAGE_SIZE: ++ pteAddr = HW_MMU_PteAddrL1(pgTblVa, ++ virtualAddr & MMU_SECTION_ADDR_MASK); ++ pteVal = (physicalAddr & MMU_PAGE_TABLE_MASK) | 1; ++ break; ++ ++ default: ++ return RET_FAIL; ++ } ++ ++ while (--numEntries >= 0) ++ ((u32 *)pteAddr)[numEntries] = pteVal; ++ ++ return status; ++} ++ ++HW_STATUS HW_MMU_PteClear(const u32 pgTblVa, ++ u32 virtualAddr, ++ u32 pgSize) ++{ ++ HW_STATUS status = RET_OK; ++ u32 pteAddr; ++ s32 numEntries = 1; ++ ++ switch (pgSize) { ++ case HW_PAGE_SIZE_4KB: ++ pteAddr = HW_MMU_PteAddrL2(pgTblVa, ++ virtualAddr & MMU_SMALL_PAGE_MASK); ++ break; ++ ++ case HW_PAGE_SIZE_64KB: ++ numEntries = 16; ++ pteAddr = HW_MMU_PteAddrL2(pgTblVa, ++ virtualAddr & MMU_LARGE_PAGE_MASK); ++ break; ++ ++ case HW_PAGE_SIZE_1MB: ++ case HW_MMU_COARSE_PAGE_SIZE: ++ pteAddr = HW_MMU_PteAddrL1(pgTblVa, ++ virtualAddr & MMU_SECTION_ADDR_MASK); ++ break; ++ ++ case HW_PAGE_SIZE_16MB: ++ numEntries = 16; ++ pteAddr = HW_MMU_PteAddrL1(pgTblVa, ++ virtualAddr & MMU_SSECTION_ADDR_MASK); ++ break; ++ ++ default: ++ return RET_FAIL; ++ } ++ ++ while (--numEntries >= 0) ++ ((u32 *)pteAddr)[numEntries] = 0; ++ ++ return status; ++} ++ ++/* MMU_FlushEntry */ ++static HW_STATUS MMU_FlushEntry(const u32 baseAddress) ++{ ++ HW_STATUS status = RET_OK; ++ u32 flushEntryData = 0x1; ++ ++ /*Check the input Parameters*/ ++ CHECK_INPUT_PARAM(baseAddress, 0, RET_BAD_NULL_PARAM, ++ RES_MMU_BASE + RES_INVALID_INPUT_PARAM); ++ ++ /* write values to register */ ++ MMUMMU_FLUSH_ENTRYWriteRegister32(baseAddress, flushEntryData); ++ ++ return status; ++} ++ ++/* MMU_SetCAMEntry */ ++static HW_STATUS MMU_SetCAMEntry(const u32 baseAddress, ++ const u32 pageSize, ++ const u32 preservedBit, ++ const u32 validBit, ++ const u32 virtualAddrTag) ++{ ++ HW_STATUS status = RET_OK; ++ u32 mmuCamReg; ++ ++ /*Check the input Parameters*/ ++ CHECK_INPUT_PARAM(baseAddress, 0, RET_BAD_NULL_PARAM, ++ RES_MMU_BASE + RES_INVALID_INPUT_PARAM); ++ ++ mmuCamReg = (virtualAddrTag << 12); ++ mmuCamReg = (mmuCamReg) | (pageSize) | (validBit << 2) | ++ (preservedBit << 3) ; ++ ++ /* write values to register */ ++ MMUMMU_CAMWriteRegister32(baseAddress, mmuCamReg); ++ ++ return status; ++} ++ ++/* MMU_SetRAMEntry */ ++static HW_STATUS MMU_SetRAMEntry(const u32 baseAddress, ++ const u32 physicalAddr, ++ enum HW_Endianism_t endianism, ++ enum HW_ElementSize_t elementSize, ++ enum HW_MMUMixedSize_t mixedSize) ++{ ++ HW_STATUS status = RET_OK; ++ u32 mmuRamReg; ++ ++ /*Check the input Parameters*/ ++ CHECK_INPUT_PARAM(baseAddress, 0, RET_BAD_NULL_PARAM, ++ RES_MMU_BASE + RES_INVALID_INPUT_PARAM); ++ CHECK_INPUT_RANGE_MIN0(elementSize, MMU_ELEMENTSIZE_MAX, ++ RET_PARAM_OUT_OF_RANGE, RES_MMU_BASE + ++ RES_INVALID_INPUT_PARAM); ++ ++ ++ mmuRamReg = (physicalAddr & MMU_ADDR_MASK); ++ mmuRamReg = (mmuRamReg) | ((endianism << 9) | (elementSize << 7) | ++ (mixedSize << 6)); ++ ++ /* write values to register */ ++ MMUMMU_RAMWriteRegister32(baseAddress, mmuRamReg); ++ ++ return status; ++ ++} +diff --git a/drivers/dsp/bridge/hw/hw_mmu.h b/drivers/dsp/bridge/hw/hw_mmu.h +new file mode 100644 +index 0000000..a3dd2a8 +--- /dev/null ++++ b/drivers/dsp/bridge/hw/hw_mmu.h +@@ -0,0 +1,177 @@ ++/* ++ * hw_mmu.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2007 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== hw_mmu.h ======== ++ * Description: ++ * MMU types and API declarations ++ * ++ *! Revision History: ++ *! ================ ++ *! 19-Apr-2004 sb Moved & renamed endianness, page size, element size ++ TLBAdd takes in MMUMapAttrs instead of separate arguments ++ *! 08-Mar-2004 sb Added the Page Table management APIs ++ *! 16 Feb 2003 sb: Initial version ++ */ ++#ifndef __HW_MMU_H ++#define __HW_MMU_H ++ ++#include ++ ++/* Bitmasks for interrupt sources */ ++#define HW_MMU_TRANSLATION_FAULT 0x2 ++#define HW_MMU_ALL_INTERRUPTS 0x1F ++ ++#define HW_MMU_COARSE_PAGE_SIZE 0x400 ++ ++/* HW_MMUMixedSize_t: Enumerated Type used to specify whether to follow ++ CPU/TLB Element size */ ++enum HW_MMUMixedSize_t { ++ HW_MMU_TLBES, ++ HW_MMU_CPUES ++ ++} ; ++ ++/* HW_MMUMapAttrs_t: Struct containing MMU mapping attributes */ ++struct HW_MMUMapAttrs_t { ++ enum HW_Endianism_t endianism; ++ enum HW_ElementSize_t elementSize; ++ enum HW_MMUMixedSize_t mixedSize; ++ bool donotlockmpupage; ++} ; ++ ++extern HW_STATUS HW_MMU_Enable(const u32 baseAddress); ++ ++extern HW_STATUS HW_MMU_Disable(const u32 baseAddress); ++ ++extern HW_STATUS HW_MMU_NumLockedSet(const u32 baseAddress, ++ u32 numLockedEntries); ++ ++extern HW_STATUS HW_MMU_VictimNumSet(const u32 baseAddress, ++ u32 victimEntryNum); ++ ++/* For MMU faults */ ++extern HW_STATUS HW_MMU_EventAck(const u32 baseAddress, ++ u32 irqMask); ++ ++extern HW_STATUS HW_MMU_EventDisable(const u32 baseAddress, ++ u32 irqMask); ++ ++extern HW_STATUS HW_MMU_EventEnable(const u32 baseAddress, ++ u32 irqMask); ++ ++extern HW_STATUS HW_MMU_EventStatus(const u32 baseAddress, ++ u32 *irqMask); ++ ++extern HW_STATUS HW_MMU_FaultAddrRead(const u32 baseAddress, ++ u32 *addr); ++ ++/* Set the TT base address */ ++extern HW_STATUS HW_MMU_TTBSet(const u32 baseAddress, ++ u32 TTBPhysAddr); ++ ++extern HW_STATUS HW_MMU_TWLEnable(const u32 baseAddress); ++ ++extern HW_STATUS HW_MMU_TWLDisable(const u32 baseAddress); ++ ++extern HW_STATUS HW_MMU_TLBFlush(const u32 baseAddress, ++ u32 virtualAddr, ++ u32 pageSize); ++ ++extern HW_STATUS HW_MMU_TLBAdd(const u32 baseAddress, ++ u32 physicalAddr, ++ u32 virtualAddr, ++ u32 pageSize, ++ u32 entryNum, ++ struct HW_MMUMapAttrs_t *mapAttrs, ++ enum HW_SetClear_t preservedBit, ++ enum HW_SetClear_t validBit); ++ ++ ++/* For PTEs */ ++extern HW_STATUS HW_MMU_PteSet(const u32 pgTblVa, ++ u32 physicalAddr, ++ u32 virtualAddr, ++ u32 pageSize, ++ struct HW_MMUMapAttrs_t *mapAttrs); ++ ++extern HW_STATUS HW_MMU_PteClear(const u32 pgTblVa, ++ u32 pgSize, ++ u32 virtualAddr); ++ ++static inline u32 HW_MMU_PteAddrL1(u32 L1_base, u32 va) ++{ ++ u32 pteAddr; ++ u32 VA_31_to_20; ++ ++ VA_31_to_20 = va >> (20 - 2); /* Left-shift by 2 here itself */ ++ VA_31_to_20 &= 0xFFFFFFFCUL; ++ pteAddr = L1_base + VA_31_to_20; ++ ++ return pteAddr; ++} ++ ++static inline u32 HW_MMU_PteAddrL2(u32 L2_base, u32 va) ++{ ++ u32 pteAddr; ++ ++ pteAddr = (L2_base & 0xFFFFFC00) | ((va >> 10) & 0x3FC); ++ ++ return pteAddr; ++} ++ ++static inline u32 HW_MMU_PteCoarseL1(u32 pteVal) ++{ ++ u32 pteCoarse; ++ ++ pteCoarse = pteVal & 0xFFFFFC00; ++ ++ return pteCoarse; ++} ++ ++static inline u32 HW_MMU_PteSizeL1(u32 pteVal) ++{ ++ u32 pteSize = 0; ++ ++ if ((pteVal & 0x3) == 0x1) { ++ /* Points to L2 PT */ ++ pteSize = HW_MMU_COARSE_PAGE_SIZE; ++ } ++ ++ if ((pteVal & 0x3) == 0x2) { ++ if (pteVal & (1 << 18)) ++ pteSize = HW_PAGE_SIZE_16MB; ++ else ++ pteSize = HW_PAGE_SIZE_1MB; ++ } ++ ++ return pteSize; ++} ++ ++static inline u32 HW_MMU_PteSizeL2(u32 pteVal) ++{ ++ u32 pteSize = 0; ++ ++ if (pteVal & 0x2) ++ pteSize = HW_PAGE_SIZE_4KB; ++ else if (pteVal & 0x1) ++ pteSize = HW_PAGE_SIZE_64KB; ++ ++ return pteSize; ++} ++ ++#endif /* __HW_MMU_H */ +diff --git a/drivers/dsp/bridge/hw/hw_prcm.c b/drivers/dsp/bridge/hw/hw_prcm.c +new file mode 100644 +index 0000000..61ff08f +--- /dev/null ++++ b/drivers/dsp/bridge/hw/hw_prcm.c +@@ -0,0 +1,167 @@ ++/* ++ * hw_prcm.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2007 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== hw_prcm.c ======== ++ * Description: ++ * API definitions to configure PRCM (Power, Reset & Clocks Manager) ++ * ++ *! Revision History: ++ *! ================ ++ *! 16 Feb 2003 sb: Initial version ++ */ ++ ++#include ++#include "PRCMRegAcM.h" ++#include ++#include ++ ++static HW_STATUS HW_RST_WriteVal(const u32 baseAddress, ++ enum HW_RstModule_t r, ++ enum HW_SetClear_t val); ++ ++HW_STATUS HW_RST_Reset(const u32 baseAddress, enum HW_RstModule_t r) ++{ ++ return HW_RST_WriteVal(baseAddress, r, HW_SET); ++} ++ ++HW_STATUS HW_RST_UnReset(const u32 baseAddress, enum HW_RstModule_t r) ++{ ++ return HW_RST_WriteVal(baseAddress, r, HW_CLEAR); ++} ++ ++static HW_STATUS HW_RST_WriteVal(const u32 baseAddress, ++ enum HW_RstModule_t r, ++ enum HW_SetClear_t val) ++{ ++ HW_STATUS status = RET_OK; ++ ++ switch (r) { ++ case HW_RST1_IVA2: ++ PRM_RSTCTRL_IVA2RST1_DSPWrite32(baseAddress, val); ++ break; ++ case HW_RST2_IVA2: ++ PRM_RSTCTRL_IVA2RST2_DSPWrite32(baseAddress, val); ++ break; ++ case HW_RST3_IVA2: ++ PRM_RSTCTRL_IVA2RST3_DSPWrite32(baseAddress, val); ++ break; ++ default: ++ status = RET_FAIL; ++ break; ++ } ++ return status; ++} ++ ++HW_STATUS HW_PWR_IVA2StateGet(const u32 baseAddress, enum HW_PwrModule_t p, ++ enum HW_PwrState_t *value) ++{ ++ HW_STATUS status = RET_OK; ++ u32 temp; ++ ++ switch (p) { ++ case HW_PWR_DOMAIN_DSP: ++ /* wait until Transition is complete */ ++ do { ++ /* mdelay(1); */ ++ temp = PRCMPM_PWSTST_IVA2InTransitionRead32 ++ (baseAddress); ++ ++ } while (temp); ++ ++ temp = PRCMPM_PWSTST_IVA2ReadRegister32(baseAddress); ++ *value = PRCMPM_PWSTST_IVA2PowerStateStGet32(temp); ++ break; ++ ++ default: ++ status = RET_FAIL; ++ break; ++ } ++ return status; ++} ++ ++HW_STATUS HW_PWRST_IVA2RegGet(const u32 baseAddress, u32 *value) ++{ ++ HW_STATUS status = RET_OK; ++ ++ *value = PRCMPM_PWSTST_IVA2ReadRegister32(baseAddress); ++ ++ return status; ++} ++ ++ ++HW_STATUS HW_PWR_IVA2PowerStateSet(const u32 baseAddress, ++ enum HW_PwrModule_t p, ++ enum HW_PwrState_t value) ++{ ++ HW_STATUS status = RET_OK; ++ ++ switch (p) { ++ case HW_PWR_DOMAIN_DSP: ++ switch (value) { ++ case HW_PWR_STATE_ON: ++ PRCMPM_PWSTCTRL_IVA2PowerStateWriteON32(baseAddress); ++ break; ++ case HW_PWR_STATE_RET: ++ PRCMPM_PWSTCTRL_DSPPowerStateWriteRET32(baseAddress); ++ break; ++ case HW_PWR_STATE_OFF: ++ PRCMPM_PWSTCTRL_IVA2PowerStateWriteOFF32(baseAddress); ++ break; ++ default: ++ status = RET_FAIL; ++ break; ++ } ++ break; ++ ++ default: ++ status = RET_FAIL; ++ break; ++ } ++ ++ return status; ++} ++ ++HW_STATUS HW_PWR_CLKCTRL_IVA2RegSet(const u32 baseAddress, ++ enum HW_TransitionState_t val) ++{ ++ HW_STATUS status = RET_OK; ++ ++ PRCMCM_CLKSTCTRL_IVA2WriteRegister32(baseAddress, val); ++ ++ return status; ++ ++} ++ ++HW_STATUS HW_RSTST_RegGet(const u32 baseAddress, enum HW_RstModule_t m, ++ u32 *value) ++{ ++ HW_STATUS status = RET_OK; ++ ++ *value = PRCMRM_RSTST_DSPReadRegister32(baseAddress); ++ ++ return status; ++} ++ ++HW_STATUS HW_RSTCTRL_RegGet(const u32 baseAddress, enum HW_RstModule_t m, ++ u32 *value) ++{ ++ HW_STATUS status = RET_OK; ++ ++ *value = PRCMRM_RSTCTRL_DSPReadRegister32(baseAddress); ++ ++ return status; ++} +diff --git a/drivers/dsp/bridge/hw/hw_prcm.h b/drivers/dsp/bridge/hw/hw_prcm.h +new file mode 100644 +index 0000000..928486c +--- /dev/null ++++ b/drivers/dsp/bridge/hw/hw_prcm.h +@@ -0,0 +1,168 @@ ++/* ++ * hw_prcm.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2007 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== hw_prcm.h ======== ++ * Description: ++ * PRCM types and API declarations ++ * ++ *! Revision History: ++ *! ================ ++ *! 16 Feb 2003 sb: Initial version ++ */ ++ ++#ifndef __HW_PRCM_H ++#define __HW_PRCM_H ++ ++/* HW_ClkModule: Enumerated Type used to specify the clock domain */ ++ ++enum HW_ClkModule_t { ++/* DSP Domain */ ++ HW_CLK_DSP_CPU, ++ HW_CLK_DSP_IPI_MMU, ++ HW_CLK_IVA_ARM, ++ HW_CLK_IVA_COP, /* IVA Coprocessor */ ++ ++/* Core Domain */ ++ HW_CLK_FN_WDT4, /* Functional Clock */ ++ HW_CLK_FN_WDT3, ++ HW_CLK_FN_UART2, ++ HW_CLK_FN_UART1, ++ HW_CLK_GPT5, ++ HW_CLK_GPT6, ++ HW_CLK_GPT7, ++ HW_CLK_GPT8, ++ ++ HW_CLK_IF_WDT4, /* Interface Clock */ ++ HW_CLK_IF_WDT3, ++ HW_CLK_IF_UART2, ++ HW_CLK_IF_UART1, ++ HW_CLK_IF_MBOX ++ ++} ; ++ ++enum HW_ClkSubsys_t { ++ HW_CLK_DSPSS, ++ HW_CLK_IVASS ++} ; ++ ++/* HW_GPtimers: General purpose timers */ ++enum HW_GPtimer_t { ++ HW_GPT5 = 5, ++ HW_GPT6 = 6, ++ HW_GPT7 = 7, ++ HW_GPT8 = 8 ++} ; ++ ++ ++/* GP timers Input clock type: General purpose timers */ ++enum HW_Clocktype_t { ++ HW_CLK_32KHz = 0, ++ HW_CLK_SYS = 1, ++ HW_CLK_EXT = 2 ++} ; ++ ++/* HW_ClkDiv: Clock divisors */ ++enum HW_ClkDiv_t { ++ HW_CLK_DIV_1 = 0x1, ++ HW_CLK_DIV_2 = 0x2, ++ HW_CLK_DIV_3 = 0x3, ++ HW_CLK_DIV_4 = 0x4, ++ HW_CLK_DIV_6 = 0x6, ++ HW_CLK_DIV_8 = 0x8, ++ HW_CLK_DIV_12 = 0xC ++} ; ++ ++/* HW_RstModule: Enumerated Type used to specify the module to be reset */ ++enum HW_RstModule_t { ++ HW_RST1_IVA2, /* Reset the DSP */ ++ HW_RST2_IVA2, /* Reset MMU and LEON HWa */ ++ HW_RST3_IVA2 /* Reset LEON sequencer */ ++} ; ++ ++/* HW_PwrModule: Enumerated Type used to specify the power domain */ ++enum HW_PwrModule_t { ++/* Domains */ ++ HW_PWR_DOMAIN_CORE, ++ HW_PWR_DOMAIN_MPU, ++ HW_PWR_DOMAIN_WAKEUP, ++ HW_PWR_DOMAIN_DSP, ++ ++/* Sub-domains */ ++ HW_PWR_DSP_IPI, /* IPI = Intrusive Port Interface */ ++ HW_PWR_IVA_ISP /* ISP = Intrusive Slave Port */ ++} ; ++ ++enum HW_PwrState_t { ++ HW_PWR_STATE_OFF, ++ HW_PWR_STATE_RET, ++ HW_PWR_STATE_INACT, ++ HW_PWR_STATE_ON = 3 ++} ; ++ ++enum HW_ForceState_t { ++ HW_FORCE_OFF, ++ HW_FORCE_ON ++} ; ++ ++enum HW_IdleState_t { ++ HW_ACTIVE, ++ HW_STANDBY ++ ++} ; ++ ++enum HW_TransitionState_t { ++ HW_AUTOTRANS_DIS, ++ HW_SW_SUP_SLEEP, ++ HW_SW_SUP_WAKEUP, ++ HW_AUTOTRANS_EN ++} ; ++ ++ ++extern HW_STATUS HW_RST_Reset(const u32 baseAddress, ++ enum HW_RstModule_t r); ++ ++extern HW_STATUS HW_RST_UnReset(const u32 baseAddress, ++ enum HW_RstModule_t r); ++ ++extern HW_STATUS HW_RSTCTRL_RegGet(const u32 baseAddress, ++ enum HW_RstModule_t p, ++ u32 *value); ++extern HW_STATUS HW_RSTST_RegGet(const u32 baseAddress, ++ enum HW_RstModule_t p, u32 *value); ++ ++extern HW_STATUS HW_PWR_PowerStateSet(const u32 baseAddress, ++ enum HW_PwrModule_t p, ++ enum HW_PwrState_t value); ++ ++extern HW_STATUS HW_CLK_SetInputClock(const u32 baseAddress, ++ enum HW_GPtimer_t gpt, ++ enum HW_Clocktype_t c); ++ ++extern HW_STATUS HW_PWR_IVA2StateGet(const u32 baseAddress, ++ enum HW_PwrModule_t p, ++ enum HW_PwrState_t *value); ++ ++extern HW_STATUS HW_PWRST_IVA2RegGet(const u32 baseAddress, u32 *value); ++ ++extern HW_STATUS HW_PWR_IVA2PowerStateSet(const u32 baseAddress, ++ enum HW_PwrModule_t p, ++ enum HW_PwrState_t value); ++ ++extern HW_STATUS HW_PWR_CLKCTRL_IVA2RegSet(const u32 baseAddress, ++ enum HW_TransitionState_t val); ++ ++#endif /* __HW_PRCM_H */ +diff --git a/drivers/dsp/bridge/pmgr/chnl.c b/drivers/dsp/bridge/pmgr/chnl.c +new file mode 100644 +index 0000000..6b5a0d9 +--- /dev/null ++++ b/drivers/dsp/bridge/pmgr/chnl.c +@@ -0,0 +1,260 @@ ++/* ++ * chnl.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== chnl.c ======== ++ * Description: ++ * WCD channel interface: multiplexes data streams through the single ++ * physical link managed by a 'Bridge mini-driver. ++ * ++ * Public Functions: ++ * CHNL_Close ++ * CHNL_CloseOrphans ++ * CHNL_Create ++ * CHNL_Destroy ++ * CHNL_Exit ++ * CHNL_GetHandle ++ * CHNL_GetProcessHandle ++ * CHNL_Init ++ * CHNL_Open ++ * ++ * Notes: ++ * This interface is basically a pass through to the WMD CHNL functions, ++ * except for the CHNL_Get() accessor functions which call ++ * WMD_CHNL_GetInfo(). ++ * ++ *! Revision History: ++ *! ================ ++ *! 24-Feb-2003 swa PMGR Code review comments incorporated. ++ *! 07-Jan-2002 ag CHNL_CloseOrphans() now closes supported # of channels. ++ *! 17-Nov-2000 jeh Removed IRQ, shared memory stuff from CHNL_Create. ++ *! 28-Feb-2000 rr: New GT USage Implementation ++ *! 03-Feb-2000 rr: GT and Module init/exit Changes.(Done up front from ++ *! SERVICES) ++ *! 21-Jan-2000 ag: Added code review comments. ++ *! 13-Jan-2000 rr: CFG_Get/SetPrivateDword renamed to CFG_Get/SetDevObject. ++ *! 08-Dec-1999 ag: CHNL_[Alloc|Free]Buffer bufs taken from client process heap. ++ *! 02-Dec-1999 ag: Implemented CHNL_GetEventHandle(). ++ *! 17-Nov-1999 ag: CHNL_AllocBuffer() allocs extra word for process mapping. ++ *! 28-Oct-1999 ag: WinCE port. Search for "WinCE" for changes(TBR). ++ *! 07-Jan-1998 gp: CHNL_[Alloc|Free]Buffer now call MEM_UMB functions. ++ *! 22-Oct-1997 gp: Removed requirement in CHNL_Open that hReserved1 != NULL. ++ *! 30-Aug-1997 cr: Renamed cfg.h wbwcd.h b/c of WINNT file name collision. ++ *! 10-Mar-1997 gp: Added GT trace. ++ *! 14-Jan-1997 gp: Updated based on code review feedback. ++ *! 03-Jan-1997 gp: Moved CHNL_AllocBuffer/CHNL_FreeBuffer code from udspsys. ++ *! 14-Dec-1996 gp: Added uChnlId parameter to CHNL_Open(). ++ *! 09-Sep-1996 gp: Added CHNL_GetProcessHandle(). ++ *! 15-Jul-1996 gp: Created. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++#include ++ ++/* ----------------------------------- Others */ ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++/* ----------------------------------- Globals */ ++static u32 cRefs; ++#if GT_TRACE ++static struct GT_Mask CHNL_DebugMask = { NULL, NULL }; /* WCD CHNL Mask */ ++#endif ++ ++ ++ ++/* ++ * ======== CHNL_Create ======== ++ * Purpose: ++ * Create a channel manager object, responsible for opening new channels ++ * and closing old ones for a given 'Bridge board. ++ */ ++DSP_STATUS CHNL_Create(OUT struct CHNL_MGR **phChnlMgr, ++ struct DEV_OBJECT *hDevObject, ++ IN CONST struct CHNL_MGRATTRS *pMgrAttrs) ++{ ++ DSP_STATUS status; ++ struct CHNL_MGR *hChnlMgr; ++ struct CHNL_MGR_ *pChnlMgr = NULL; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phChnlMgr != NULL); ++ DBC_Require(pMgrAttrs != NULL); ++ ++ GT_3trace(CHNL_DebugMask, GT_ENTER, ++ "Entered CHNL_Create: phChnlMgr: 0x%x\t" ++ "hDevObject: 0x%x\tpMgrAttrs:0x%x\n", ++ phChnlMgr, hDevObject, pMgrAttrs); ++ ++ *phChnlMgr = NULL; ++ ++ /* Validate args: */ ++ if ((0 < pMgrAttrs->cChannels) && ++ (pMgrAttrs->cChannels <= CHNL_MAXCHANNELS)) { ++ status = DSP_SOK; ++ } else if (pMgrAttrs->cChannels == 0) { ++ status = DSP_EINVALIDARG; ++ GT_0trace(CHNL_DebugMask, GT_7CLASS, ++ "CHNL_Create:Invalid Args\n"); ++ } else { ++ status = CHNL_E_MAXCHANNELS; ++ GT_0trace(CHNL_DebugMask, GT_7CLASS, ++ "CHNL_Create:Error Max Channels\n"); ++ } ++ if (pMgrAttrs->uWordSize == 0) { ++ status = CHNL_E_INVALIDWORDSIZE; ++ GT_0trace(CHNL_DebugMask, GT_7CLASS, ++ "CHNL_Create:Invalid Word size\n"); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ status = DEV_GetChnlMgr(hDevObject, &hChnlMgr); ++ if (DSP_SUCCEEDED(status) && hChnlMgr != NULL) ++ status = CHNL_E_MGREXISTS; ++ ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ DEV_GetIntfFxns(hDevObject, &pIntfFxns); ++ /* Let WMD channel module finish the create: */ ++ status = (*pIntfFxns->pfnChnlCreate)(&hChnlMgr, hDevObject, ++ pMgrAttrs); ++ if (DSP_SUCCEEDED(status)) { ++ /* Fill in WCD channel module's fields of the ++ * CHNL_MGR structure */ ++ pChnlMgr = (struct CHNL_MGR_ *)hChnlMgr; ++ pChnlMgr->pIntfFxns = pIntfFxns; ++ /* Finally, return the new channel manager handle: */ ++ *phChnlMgr = hChnlMgr; ++ GT_1trace(CHNL_DebugMask, GT_1CLASS, ++ "CHNL_Create: Success pChnlMgr:" ++ "0x%x\n", pChnlMgr); ++ } ++ } ++ ++ GT_2trace(CHNL_DebugMask, GT_ENTER, ++ "Exiting CHNL_Create: pChnlMgr: 0x%x," ++ "status: 0x%x\n", pChnlMgr, status); ++ DBC_Ensure(DSP_FAILED(status) || CHNL_IsValidMgr(pChnlMgr)); ++ ++ return status; ++} ++ ++/* ++ * ======== CHNL_Destroy ======== ++ * Purpose: ++ * Close all open channels, and destroy the channel manager. ++ */ ++DSP_STATUS CHNL_Destroy(struct CHNL_MGR *hChnlMgr) ++{ ++ struct CHNL_MGR_ *pChnlMgr = (struct CHNL_MGR_ *)hChnlMgr; ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ DSP_STATUS status; ++ ++ DBC_Require(cRefs > 0); ++ ++ GT_1trace(CHNL_DebugMask, GT_ENTER, ++ "Entered CHNL_Destroy: hChnlMgr: 0x%x\n", hChnlMgr); ++ if (CHNL_IsValidMgr(pChnlMgr)) { ++ pIntfFxns = pChnlMgr->pIntfFxns; ++ /* Let WMD channel module destroy the CHNL_MGR: */ ++ status = (*pIntfFxns->pfnChnlDestroy)(hChnlMgr); ++ } else { ++ GT_0trace(CHNL_DebugMask, GT_7CLASS, ++ "CHNL_Destroy:Invalid Handle\n"); ++ status = DSP_EHANDLE; ++ } ++ ++ GT_2trace(CHNL_DebugMask, GT_ENTER, ++ "Exiting CHNL_Destroy: pChnlMgr: 0x%x," ++ " status:0x%x\n", pChnlMgr, status); ++ DBC_Ensure(DSP_FAILED(status) || !CHNL_IsValidMgr(pChnlMgr)); ++ ++ return status; ++} ++ ++/* ++ * ======== CHNL_Exit ======== ++ * Purpose: ++ * Discontinue usage of the CHNL module. ++ */ ++void CHNL_Exit(void) ++{ ++ DBC_Require(cRefs > 0); ++ ++ cRefs--; ++ ++ GT_1trace(CHNL_DebugMask, GT_5CLASS, ++ "Entered CHNL_Exit, ref count: 0x%x\n", cRefs); ++ ++ DBC_Ensure(cRefs >= 0); ++} ++ ++ ++/* ++ * ======== CHNL_Init ======== ++ * Purpose: ++ * Initialize the CHNL module's private state. ++ */ ++bool CHNL_Init(void) ++{ ++ bool fRetval = true; ++ ++ DBC_Require(cRefs >= 0); ++ ++ if (cRefs == 0) { ++ DBC_Assert(!CHNL_DebugMask.flags); ++ GT_create(&CHNL_DebugMask, "CH"); /* "CH" for CHannel */ ++ } ++ ++ if (fRetval) ++ cRefs++; ++ ++ GT_1trace(CHNL_DebugMask, GT_5CLASS, ++ "Entered CHNL_Init, ref count: 0x%x\n", ++ cRefs); ++ ++ DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0))); ++ ++ return fRetval; ++} ++ ++ +diff --git a/drivers/dsp/bridge/pmgr/chnlobj.h b/drivers/dsp/bridge/pmgr/chnlobj.h +new file mode 100644 +index 0000000..da74c96 +--- /dev/null ++++ b/drivers/dsp/bridge/pmgr/chnlobj.h +@@ -0,0 +1,71 @@ ++/* ++ * chnlobj.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== chnlobj.h ======== ++ * Description: ++ * Structure subcomponents of channel class library channel objects which ++ * are exposed to class driver from mini-driver. ++ * ++ * Public Functions: ++ * None. ++ * ++ *! Revision History: ++ *! ================ ++ *! 24-Feb-2003 swa PMGR Code review comments incorporated. ++ *! 17-Nov-2000 jeh Removed some fields from CHNL_MGR_ to match CHNL_MGR ++ *! structure defined in _chnl_sm.h. ++ *! 16-Jan-1997 gp: Created from chnlpriv.h ++ */ ++ ++#ifndef CHNLOBJ_ ++#define CHNLOBJ_ ++ ++#include ++#include ++ ++/* Object validateion macros: */ ++#define CHNL_IsValidMgr(h) \ ++ ((h != NULL) && ((h)->dwSignature == CHNL_MGRSIGNATURE)) ++ ++#define CHNL_IsValidChnl(h)\ ++ ((h != NULL) && ((h)->dwSignature == CHNL_SIGNATURE)) ++ ++/* ++ * This struct is the first field in a CHNL_MGR struct, as implemented in ++ * a WMD channel class library. Other, implementation specific fields ++ * follow this structure in memory. ++ */ ++struct CHNL_MGR_ { ++ /* These must be the first fields in a CHNL_MGR struct: */ ++ u32 dwSignature; /* Used for object validation. */ ++ struct WMD_DRV_INTERFACE *pIntfFxns; /* Function interface to WMD. */ ++} ; ++ ++/* ++ * This struct is the first field in a CHNL_OBJECT struct, as implemented in ++ * a WMD channel class library. Other, implementation specific fields ++ * follow this structure in memory. ++ */ ++struct CHNL_OBJECT_ { ++ /* These must be the first fields in a CHNL_OBJECT struct: */ ++ u32 dwSignature; /* Used for object validation. */ ++ struct CHNL_MGR_ *pChnlMgr; /* Pointer back to channel manager. */ ++} ; ++ ++#endif /* CHNLOBJ_ */ ++ +diff --git a/drivers/dsp/bridge/pmgr/cmm.c b/drivers/dsp/bridge/pmgr/cmm.c +new file mode 100644 +index 0000000..99a2432 +--- /dev/null ++++ b/drivers/dsp/bridge/pmgr/cmm.c +@@ -0,0 +1,1291 @@ ++/* ++ * cmm.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== cmm.c ======== ++ * Purpose: ++ * The Communication(Shared) Memory Management(CMM) module provides ++ * shared memory management services for DSP/BIOS Bridge data streaming ++ * and messaging. ++ * ++ * Multiple shared memory segments can be registered with CMM. ++ * Each registered SM segment is represented by a SM "allocator" that ++ * describes a block of physically contiguous shared memory used for ++ * future allocations by CMM. ++ * ++ * Memory is coelesced back to the appropriate heap when a buffer is ++ * freed. ++ * ++ * Public Functions: ++ * CMM_CallocBuf ++ * CMM_Create ++ * CMM_Destroy ++ * CMM_Exit ++ * CMM_FreeBuf ++ * CMM_GetHandle ++ * CMM_GetInfo ++ * CMM_Init ++ * CMM_RegisterGPPSMSeg ++ * CMM_UnRegisterGPPSMSeg ++ * ++ * The CMM_Xlator[xxx] routines below are used by Node and Stream ++ * to perform SM address translation to the client process address space. ++ * A "translator" object is created by a node/stream for each SM seg used. ++ * ++ * Translator Routines: ++ * CMM_XlatorAllocBuf ++ * CMM_XlatorCreate ++ * CMM_XlatorDelete ++ * CMM_XlatorFreeBuf ++ * CMM_XlatorInfo ++ * CMM_XlatorTranslate ++ * ++ * Private Functions: ++ * AddToFreeList ++ * GetAllocator ++ * GetFreeBlock ++ * GetNode ++ * GetSlot ++ * UnRegisterGPPSMSeg ++ * ++ * Notes: ++ * Va: Virtual address. ++ * Pa: Physical or kernel system address. ++ * ++ *! Revision History: ++ *! ================ ++ *! 24-Feb-2003 swa PMGR Code review comments incorporated. ++ *! 16-Feb-2002 ag Code review cleanup. ++ *! PreOMAP address translation no longner supported. ++ *! 30-Jan-2002 ag Updates to CMM_XlatorTranslate() per TII, ANSI C++ ++ *! warnings. ++ *! 27-Jan-2002 ag Removed unused CMM_[Alloc][Free]Desc() & #ifdef USELOOKUP, ++ *! & unused VALIDATECMM and VaPaConvert(). ++ *! Removed bFastXlate from CMM_XLATOR. Always fast lookup. ++ *! 03-Jan-2002 ag Clear SM in CMM_AllocBuf(). Renamed to CMM_CallocBuf(). ++ *! 13-Nov-2001 ag Now delete pNodeFreeListHead and nodes in CMM_Destroy(). ++ *! 28-Aug-2001 ag CMM_GetHandle() returns CMM Mgr hndle given HPROCESSOR. ++ *! Removed unused CMM_[Un]RegisterDSPSMSeg() & ++ * CMM_[Un}ReserveVirtSpace fxns. Some cleanup. ++ *! 12-Aug-2001 ag Exposed CMM_UnRegisterGPP[DSP]SMSeg. ++ *! 13-Feb-2001 kc DSP/BIOS Bridge name update. ++ *! 21-Dec-2000 rr GetFreeBlock checks for pAllocator. ++ *! 09-Dec-2000 ag Added GPPPA2DSPPA, DSPPA2GPPPA macros. ++ *! 05-Dec-2000 ag CMM_XlatorDelete() optionally frees SM bufs and descriptors. ++ *! 30-Oct-2000 ag Buf size bug fixed in CMM_AllocBuf() causing leak. ++ *! Revamped XlatorTranslate() routine. ++ *! 10-Oct-2000 ag Added CMM_Xlator[xxx] functions. ++ *! 02-Aug-2000 ag Created. ++ *! ++ */ ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++/* ----------------------------------- Defines, Data Structures, Typedefs */ ++/* Object signatures */ ++#define CMMSIGNATURE 0x004d4d43 /* "CMM" (in reverse) */ ++#define SMEMSIGNATURE 0x4D454D53 /* "SMEM" SM space */ ++#define CMMXLATESIGNATURE 0x584d4d43 /* "CMMX" CMM Xlator */ ++ ++#define NEXT_PA(pNode) (pNode->dwPA + pNode->ulSize) ++ ++/* Other bus/platform translations */ ++#define DSPPA2GPPPA(base, x, y) ((x)+(y)) ++#define GPPPA2DSPPA(base, x, y) ((x)-(y)) ++ ++/* ++ * Allocators define a block of contiguous memory used for future allocations. ++ * ++ * sma - shared memory allocator. ++ * vma - virtual memory allocator.(not used). ++ */ ++struct CMM_ALLOCATOR { /* sma */ ++ u32 dwSignature; /* SMA allocator signature SMEMSIGNATURE */ ++ unsigned int dwSmBase; /* Start of physical SM block */ ++ u32 ulSmSize; /* Size of SM block in bytes */ ++ unsigned int dwVmBase; /* Start of VM block. (Dev driver ++ * context for 'sma') */ ++ u32 dwDSPPhysAddrOffset; /* DSP PA to GPP PA offset for this ++ * SM space */ ++ /* CMM_ADDTO[SUBFROM]DSPPA, _POMAPEMIF2DSPBUS */ ++ enum CMM_CNVTTYPE cFactor; ++ unsigned int dwDSPBase; /* DSP virt base byte address */ ++ u32 ulDSPSize; /* DSP seg size in bytes */ ++ struct CMM_OBJECT *hCmmMgr; /* back ref to parent mgr */ ++ struct LST_LIST *pFreeListHead; /* node list of available memory */ ++ struct LST_LIST *pInUseListHead; /* node list of memory in use */ ++} ; ++ ++struct CMM_XLATOR { /* Pa<->Va translator object */ ++ u32 dwSignature; /* "CMMX" */ ++ struct CMM_OBJECT *hCmmMgr; /* CMM object this translator associated */ ++ /* ++ * Client process virtual base address that corresponds to phys SM ++ * base address for translator's ulSegId. ++ * Only 1 segment ID currently supported. ++ */ ++ unsigned int dwVirtBase; /* virtual base address */ ++ u32 ulVirtSize; /* size of virt space in bytes */ ++ u32 ulSegId; /* Segment Id */ ++} ; ++ ++/* CMM Mgr */ ++struct CMM_OBJECT { ++ u32 dwSignature; /* Used for object validation */ ++ /* ++ * Cmm Lock is used to serialize access mem manager for multi-threads. ++ */ ++ struct SYNC_CSOBJECT *hCmmLock; /* Lock to access cmm mgr */ ++ struct LST_LIST *pNodeFreeListHead; /* Free list of memory nodes */ ++ u32 ulMinBlockSize; /* Min SM block; default 16 bytes */ ++ u32 dwPageSize; /* Memory Page size (1k/4k) */ ++ /* GPP SM segment ptrs */ ++ struct CMM_ALLOCATOR *paGPPSMSegTab[CMM_MAXGPPSEGS]; ++} ; ++ ++/* Default CMM Mgr attributes */ ++static struct CMM_MGRATTRS CMM_DFLTMGRATTRS = { ++ 16 /* ulMinBlockSize, min block size(bytes) allocated by cmm mgr */ ++}; ++ ++/* Default allocation attributes */ ++static struct CMM_ATTRS CMM_DFLTALCTATTRS = { ++ 1 /* ulSegId, default segment Id for allocator */ ++}; ++ ++/* Address translator default attrs */ ++static struct CMM_XLATORATTRS CMM_DFLTXLATORATTRS = { ++ 1, /* ulSegId, does not have to match CMM_DFLTALCTATTRS ulSegId */ ++ 0, /* dwDSPBufs */ ++ 0, /* dwDSPBufSize */ ++ NULL, /* pVmBase */ ++ 0, /* dwVmSize */ ++}; ++ ++/* SM node representing a block of memory. */ ++struct CMM_MNODE { ++ struct LST_ELEM link; /* must be 1st element */ ++ u32 dwPA; /* Phys addr */ ++ u32 dwVA; /* Virtual address in device process context */ ++ u32 ulSize; /* SM block size in bytes */ ++ u32 hClientProc; /* Process that allocated this mem block */ ++} ; ++ ++ ++/* ----------------------------------- Globals */ ++#if GT_TRACE ++static struct GT_Mask CMM_debugMask = { NULL, NULL }; /* GT trace variable */ ++#endif ++ ++static u32 cRefs; /* module reference count */ ++ ++/* ----------------------------------- Function Prototypes */ ++static void AddToFreeList(struct CMM_ALLOCATOR *pAllocator, ++ struct CMM_MNODE *pNode); ++static struct CMM_ALLOCATOR *GetAllocator(struct CMM_OBJECT *pCmmMgr, ++ u32 ulSegId); ++static struct CMM_MNODE *GetFreeBlock(struct CMM_ALLOCATOR *pAllocator, ++ u32 uSize); ++static struct CMM_MNODE *GetNode(struct CMM_OBJECT *pCmmMgr, u32 dwPA, ++ u32 dwVA, u32 ulSize); ++/* get available slot for new allocator */ ++static s32 GetSlot(struct CMM_OBJECT *hCmmMgr); ++static void UnRegisterGPPSMSeg(struct CMM_ALLOCATOR *pSMA); ++ ++/* ++ * ======== CMM_CallocBuf ======== ++ * Purpose: ++ * Allocate a SM buffer, zero contents, and return the physical address ++ * and optional driver context virtual address(ppBufVA). ++ * ++ * The freelist is sorted in increasing size order. Get the first ++ * block that satifies the request and sort the remaining back on ++ * the freelist; if large enough. The kept block is placed on the ++ * inUseList. ++ */ ++void *CMM_CallocBuf(struct CMM_OBJECT *hCmmMgr, u32 uSize, ++ struct CMM_ATTRS *pAttrs, OUT void **ppBufVA) ++{ ++ struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr; ++ void *pBufPA = NULL; ++ struct CMM_MNODE *pNode = NULL; ++ struct CMM_MNODE *pNewNode = NULL; ++ struct CMM_ALLOCATOR *pAllocator = NULL; ++ u32 uDeltaSize; ++ u8 *pByte = NULL; ++ s32 cnt; ++ ++ if (pAttrs == NULL) ++ pAttrs = &CMM_DFLTALCTATTRS; ++ ++ if (ppBufVA != NULL) ++ *ppBufVA = NULL; ++ ++ if ((MEM_IsValidHandle(pCmmMgr, CMMSIGNATURE)) && (uSize != 0)) { ++ if (pAttrs->ulSegId > 0) { ++ /* SegId > 0 is SM */ ++ /* get the allocator object for this segment id */ ++ pAllocator = GetAllocator(pCmmMgr, pAttrs->ulSegId); ++ /* keep block size a multiple of ulMinBlockSize */ ++ uSize = ((uSize - 1) & ~(pCmmMgr->ulMinBlockSize - 1)) ++ + pCmmMgr->ulMinBlockSize; ++ SYNC_EnterCS(pCmmMgr->hCmmLock); ++ pNode = GetFreeBlock(pAllocator, uSize); ++ } ++ if (pNode) { ++ uDeltaSize = (pNode->ulSize - uSize); ++ if (uDeltaSize >= pCmmMgr->ulMinBlockSize) { ++ /* create a new block with the leftovers and ++ * add to freelist */ ++ pNewNode = GetNode(pCmmMgr, pNode->dwPA + uSize, ++ pNode->dwVA + uSize, ++ (u32)uDeltaSize); ++ /* leftovers go free */ ++ AddToFreeList(pAllocator, pNewNode); ++ /* adjust our node's size */ ++ pNode->ulSize = uSize; ++ } ++ /* Tag node with client process requesting allocation ++ * We'll need to free up a process's alloc'd SM if the ++ * client process goes away. ++ */ ++ /* Return PID instead of process handle */ ++ pNode->hClientProc = current->pid; ++ ++ /* put our node on InUse list */ ++ LST_PutTail(pAllocator->pInUseListHead, ++ (struct LST_ELEM *)pNode); ++ pBufPA = (void *)pNode->dwPA; /* physical address */ ++ /* clear mem */ ++ pByte = (u8 *)pNode->dwVA; ++ for (cnt = 0; cnt < (s32) uSize; cnt++, pByte++) ++ *pByte = 0; ++ ++ if (ppBufVA != NULL) { ++ /* Virtual address */ ++ *ppBufVA = (void *)pNode->dwVA; ++ } ++ } ++ GT_3trace(CMM_debugMask, GT_3CLASS, ++ "CMM_CallocBuf dwPA %x, dwVA %x uSize" ++ "%x\n", pNode->dwPA, pNode->dwVA, uSize); ++ SYNC_LeaveCS(pCmmMgr->hCmmLock); ++ } ++ return pBufPA; ++} ++ ++/* ++ * ======== CMM_Create ======== ++ * Purpose: ++ * Create a communication memory manager object. ++ */ ++DSP_STATUS CMM_Create(OUT struct CMM_OBJECT **phCmmMgr, ++ struct DEV_OBJECT *hDevObject, ++ IN CONST struct CMM_MGRATTRS *pMgrAttrs) ++{ ++ struct CMM_OBJECT *pCmmObject = NULL; ++ DSP_STATUS status = DSP_SOK; ++ struct UTIL_SYSINFO sysInfo; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phCmmMgr != NULL); ++ ++ GT_3trace(CMM_debugMask, GT_ENTER, ++ "CMM_Create: phCmmMgr: 0x%x\thDevObject: " ++ "0x%x\tpMgrAttrs: 0x%x\n", phCmmMgr, hDevObject, pMgrAttrs); ++ *phCmmMgr = NULL; ++ /* create, zero, and tag a cmm mgr object */ ++ MEM_AllocObject(pCmmObject, struct CMM_OBJECT, CMMSIGNATURE); ++ if (pCmmObject != NULL) { ++ if (pMgrAttrs == NULL) ++ pMgrAttrs = &CMM_DFLTMGRATTRS; /* set defaults */ ++ ++ /* 4 bytes minimum */ ++ DBC_Assert(pMgrAttrs->ulMinBlockSize >= 4); ++ /* save away smallest block allocation for this cmm mgr */ ++ pCmmObject->ulMinBlockSize = pMgrAttrs->ulMinBlockSize; ++ /* save away the systems memory page size */ ++ sysInfo.dwPageSize = PAGE_SIZE; ++ sysInfo.dwAllocationGranularity = PAGE_SIZE; ++ sysInfo.dwNumberOfProcessors = 1; ++ if (DSP_SUCCEEDED(status)) { ++ GT_1trace(CMM_debugMask, GT_5CLASS, ++ "CMM_Create: Got system page size" ++ "= 0x%x\t\n", sysInfo.dwPageSize); ++ pCmmObject->dwPageSize = sysInfo.dwPageSize; ++ } else { ++ GT_0trace(CMM_debugMask, GT_7CLASS, ++ "CMM_Create: failed to get system" ++ "page size\n"); ++ pCmmObject->dwPageSize = 0; ++ status = DSP_EFAIL; ++ } ++ /* Note: DSP SM seg table(aDSPSMSegTab[]) zero'd by ++ * MEM_AllocObject */ ++ if (DSP_SUCCEEDED(status)) { ++ /* create node free list */ ++ pCmmObject->pNodeFreeListHead = LST_Create(); ++ if (pCmmObject->pNodeFreeListHead == NULL) { ++ GT_0trace(CMM_debugMask, GT_7CLASS, ++ "CMM_Create: LST_Create() " ++ "failed \n"); ++ status = DSP_EMEMORY; ++ } ++ } ++ if (DSP_SUCCEEDED(status)) ++ status = SYNC_InitializeCS(&pCmmObject->hCmmLock); ++ ++ if (DSP_SUCCEEDED(status)) ++ *phCmmMgr = pCmmObject; ++ else ++ CMM_Destroy(pCmmObject, true); ++ ++ } else { ++ GT_0trace(CMM_debugMask, GT_6CLASS, ++ "CMM_Create: Object Allocation " ++ "Failure(CMM Object)\n"); ++ status = DSP_EMEMORY; ++ } ++ return status; ++} ++ ++/* ++ * ======== CMM_Destroy ======== ++ * Purpose: ++ * Release the communication memory manager resources. ++ */ ++DSP_STATUS CMM_Destroy(struct CMM_OBJECT *hCmmMgr, bool bForce) ++{ ++ struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr; ++ struct CMM_INFO tempInfo; ++ DSP_STATUS status = DSP_SOK; ++ s32 nSlot; ++ struct CMM_MNODE *pNode; ++ ++ DBC_Require(cRefs > 0); ++ if (!MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) { ++ status = DSP_EHANDLE; ++ return status; ++ } ++ SYNC_EnterCS(pCmmMgr->hCmmLock); ++ /* If not force then fail if outstanding allocations exist */ ++ if (!bForce) { ++ /* Check for outstanding memory allocations */ ++ status = CMM_GetInfo(hCmmMgr, &tempInfo); ++ if (DSP_SUCCEEDED(status)) { ++ if (tempInfo.ulTotalInUseCnt > 0) { ++ /* outstanding allocations */ ++ status = DSP_EFAIL; ++ } ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* UnRegister SM allocator */ ++ for (nSlot = 0; nSlot < CMM_MAXGPPSEGS; nSlot++) { ++ if (pCmmMgr->paGPPSMSegTab[nSlot] != NULL) { ++ UnRegisterGPPSMSeg(pCmmMgr-> ++ paGPPSMSegTab[nSlot]); ++ /* Set slot to NULL for future reuse */ ++ pCmmMgr->paGPPSMSegTab[nSlot] = NULL; ++ } ++ } ++ } ++ if (pCmmMgr->pNodeFreeListHead != NULL) { ++ /* Free the free nodes */ ++ while (!LST_IsEmpty(pCmmMgr->pNodeFreeListHead)) { ++ /* (struct LST_ELEM*) pNode = ++ * LST_GetHead(pCmmMgr->pNodeFreeListHead);*/ ++ pNode = (struct CMM_MNODE *)LST_GetHead(pCmmMgr-> ++ pNodeFreeListHead); ++ MEM_Free(pNode); ++ } ++ /* delete NodeFreeList list */ ++ LST_Delete(pCmmMgr->pNodeFreeListHead); ++ } ++ SYNC_LeaveCS(pCmmMgr->hCmmLock); ++ if (DSP_SUCCEEDED(status)) { ++ /* delete CS & cmm mgr object */ ++ SYNC_DeleteCS(pCmmMgr->hCmmLock); ++ MEM_FreeObject(pCmmMgr); ++ } ++ return status; ++} ++ ++/* ++ * ======== CMM_Exit ======== ++ * Purpose: ++ * Discontinue usage of module; free resources when reference count ++ * reaches 0. ++ */ ++void CMM_Exit(void) ++{ ++ DBC_Require(cRefs > 0); ++ ++ cRefs--; ++ ++ GT_1trace(CMM_debugMask, GT_ENTER, ++ "exiting CMM_Exit,ref count:0x%x\n", cRefs); ++} ++ ++/* ++ * ======== CMM_FreeBuf ======== ++ * Purpose: ++ * Free the given buffer. ++ */ ++DSP_STATUS CMM_FreeBuf(struct CMM_OBJECT *hCmmMgr, void *pBufPA, u32 ulSegId) ++{ ++ struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr; ++ DSP_STATUS status = DSP_EPOINTER; ++ struct CMM_MNODE *pCurNode = NULL; ++ struct CMM_ALLOCATOR *pAllocator = NULL; ++ struct CMM_ATTRS *pAttrs; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pBufPA != NULL); ++ GT_1trace(CMM_debugMask, GT_ENTER, "CMM_FreeBuf pBufPA %x\n", pBufPA); ++ if (ulSegId == 0) { ++ pAttrs = &CMM_DFLTALCTATTRS; ++ ulSegId = pAttrs->ulSegId; ++ } ++ if (!(MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) || !(ulSegId > 0)) { ++ status = DSP_EHANDLE; ++ return status; ++ } ++ /* get the allocator for this segment id */ ++ pAllocator = GetAllocator(pCmmMgr, ulSegId); ++ if (pAllocator != NULL) { ++ SYNC_EnterCS(pCmmMgr->hCmmLock); ++ pCurNode = (struct CMM_MNODE *)LST_First(pAllocator-> ++ pInUseListHead); ++ while (pCurNode) { ++ if ((u32)pBufPA == pCurNode->dwPA) { ++ /* Found it */ ++ LST_RemoveElem(pAllocator->pInUseListHead, ++ (struct LST_ELEM *)pCurNode); ++ /* back to freelist */ ++ AddToFreeList(pAllocator, pCurNode); ++ status = DSP_SOK; /* all right! */ ++ break; ++ } ++ /* next node. */ ++ pCurNode = (struct CMM_MNODE *)LST_Next(pAllocator-> ++ pInUseListHead, (struct LST_ELEM *)pCurNode); ++ } ++ SYNC_LeaveCS(pCmmMgr->hCmmLock); ++ } ++ return status; ++} ++ ++/* ++ * ======== CMM_GetHandle ======== ++ * Purpose: ++ * Return the communication memory manager object for this device. ++ * This is typically called from the client process. ++ */ ++DSP_STATUS CMM_GetHandle(DSP_HPROCESSOR hProcessor, ++ OUT struct CMM_OBJECT **phCmmMgr) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEV_OBJECT *hDevObject; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phCmmMgr != NULL); ++ if (hProcessor != NULL) ++ status = PROC_GetDevObject(hProcessor, &hDevObject); ++ else ++ hDevObject = DEV_GetFirst(); /* default */ ++ ++ if (DSP_SUCCEEDED(status)) ++ status = DEV_GetCmmMgr(hDevObject, phCmmMgr); ++ ++ return status; ++} ++ ++/* ++ * ======== CMM_GetInfo ======== ++ * Purpose: ++ * Return the current memory utilization information. ++ */ ++DSP_STATUS CMM_GetInfo(struct CMM_OBJECT *hCmmMgr, ++ OUT struct CMM_INFO *pCmmInfo) ++{ ++ struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr; ++ u32 ulSeg; ++ DSP_STATUS status = DSP_SOK; ++ struct CMM_ALLOCATOR *pAltr; ++ struct CMM_MNODE *pCurNode = NULL; ++ ++ DBC_Require(pCmmInfo != NULL); ++ ++ if (!MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) { ++ status = DSP_EHANDLE; ++ return status; ++ } ++ SYNC_EnterCS(pCmmMgr->hCmmLock); ++ pCmmInfo->ulNumGPPSMSegs = 0; /* # of SM segments */ ++ pCmmInfo->ulTotalInUseCnt = 0; /* Total # of outstanding alloc */ ++ pCmmInfo->ulMinBlockSize = pCmmMgr->ulMinBlockSize; /* min block size */ ++ /* check SM memory segments */ ++ for (ulSeg = 1; ulSeg <= CMM_MAXGPPSEGS; ulSeg++) { ++ /* get the allocator object for this segment id */ ++ pAltr = GetAllocator(pCmmMgr, ulSeg); ++ if (pAltr != NULL) { ++ pCmmInfo->ulNumGPPSMSegs++; ++ pCmmInfo->segInfo[ulSeg - 1].dwSegBasePa = ++ pAltr->dwSmBase - pAltr->ulDSPSize; ++ pCmmInfo->segInfo[ulSeg - 1].ulTotalSegSize = ++ pAltr->ulDSPSize + pAltr->ulSmSize; ++ pCmmInfo->segInfo[ulSeg - 1].dwGPPBasePA = ++ pAltr->dwSmBase; ++ pCmmInfo->segInfo[ulSeg - 1].ulGPPSize = ++ pAltr->ulSmSize; ++ pCmmInfo->segInfo[ulSeg - 1].dwDSPBaseVA = ++ pAltr->dwDSPBase; ++ pCmmInfo->segInfo[ulSeg - 1].ulDSPSize = ++ pAltr->ulDSPSize; ++ pCmmInfo->segInfo[ulSeg - 1].dwSegBaseVa = ++ pAltr->dwVmBase - pAltr->ulDSPSize; ++ pCmmInfo->segInfo[ulSeg - 1].ulInUseCnt = 0; ++ pCurNode = (struct CMM_MNODE *)LST_First(pAltr-> ++ pInUseListHead); ++ /* Count inUse blocks */ ++ while (pCurNode) { ++ pCmmInfo->ulTotalInUseCnt++; ++ pCmmInfo->segInfo[ulSeg - 1].ulInUseCnt++; ++ /* next node. */ ++ pCurNode = (struct CMM_MNODE *)LST_Next(pAltr-> ++ pInUseListHead, ++ (struct LST_ELEM *)pCurNode); ++ } ++ } ++ } /* end for */ ++ SYNC_LeaveCS(pCmmMgr->hCmmLock); ++ return status; ++} ++ ++/* ++ * ======== CMM_Init ======== ++ * Purpose: ++ * Initializes private state of CMM module. ++ */ ++bool CMM_Init(void) ++{ ++ bool fRetval = true; ++ ++ DBC_Require(cRefs >= 0); ++ if (cRefs == 0) { ++ /* Set the Trace mask */ ++ /* "CM" for Comm Memory manager */ ++ GT_create(&CMM_debugMask, "CM"); ++ } ++ if (fRetval) ++ cRefs++; ++ ++ GT_1trace(CMM_debugMask, GT_ENTER, ++ "Entered CMM_Init,ref count:0x%x\n", cRefs); ++ ++ DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0))); ++ ++ return fRetval; ++} ++ ++/* ++ * ======== CMM_RegisterGPPSMSeg ======== ++ * Purpose: ++ * Register a block of SM with the CMM to be used for later GPP SM ++ * allocations. ++ */ ++DSP_STATUS CMM_RegisterGPPSMSeg(struct CMM_OBJECT *hCmmMgr, u32 dwGPPBasePA, ++ u32 ulSize, u32 dwDSPAddrOffset, ++ enum CMM_CNVTTYPE cFactor, u32 dwDSPBase, ++ u32 ulDSPSize, u32 *pulSegId, ++ u32 dwGPPBaseVA) ++{ ++ struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr; ++ struct CMM_ALLOCATOR *pSMA = NULL; ++ DSP_STATUS status = DSP_SOK; ++ struct CMM_MNODE *pNewNode; ++ s32 nSlot; ++ ++ DBC_Require(ulSize > 0); ++ DBC_Require(pulSegId != NULL); ++ DBC_Require(dwGPPBasePA != 0); ++ DBC_Require(dwGPPBaseVA != 0); ++ DBC_Require((cFactor <= CMM_ADDTODSPPA) && ++ (cFactor >= CMM_SUBFROMDSPPA)); ++ GT_6trace(CMM_debugMask, GT_ENTER, ++ "CMM_RegisterGPPSMSeg dwGPPBasePA %x " ++ "ulSize %x dwDSPAddrOffset %x dwDSPBase %x ulDSPSize %x " ++ "dwGPPBaseVA %x\n", dwGPPBasePA, ulSize, dwDSPAddrOffset, ++ dwDSPBase, ulDSPSize, dwGPPBaseVA); ++ if (!MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) { ++ status = DSP_EHANDLE; ++ return status; ++ } ++ /* make sure we have room for another allocator */ ++ SYNC_EnterCS(pCmmMgr->hCmmLock); ++ nSlot = GetSlot(pCmmMgr); ++ if (nSlot < 0) { ++ /* get a slot number */ ++ status = DSP_EFAIL; ++ goto func_end; ++ } ++ /* Check if input ulSize is big enough to alloc at least one block */ ++ if (DSP_SUCCEEDED(status)) { ++ if (ulSize < pCmmMgr->ulMinBlockSize) { ++ GT_0trace(CMM_debugMask, GT_7CLASS, ++ "CMM_RegisterGPPSMSeg: " ++ "ulSize too small\n"); ++ status = DSP_EINVALIDARG; ++ goto func_end; ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* create, zero, and tag an SM allocator object */ ++ MEM_AllocObject(pSMA, struct CMM_ALLOCATOR, SMEMSIGNATURE); ++ } ++ if (pSMA != NULL) { ++ pSMA->hCmmMgr = hCmmMgr; /* ref to parent */ ++ pSMA->dwSmBase = dwGPPBasePA; /* SM Base phys */ ++ pSMA->ulSmSize = ulSize; /* SM segment size in bytes */ ++ pSMA->dwVmBase = dwGPPBaseVA; ++ pSMA->dwDSPPhysAddrOffset = dwDSPAddrOffset; ++ pSMA->cFactor = cFactor; ++ pSMA->dwDSPBase = dwDSPBase; ++ pSMA->ulDSPSize = ulDSPSize; ++ if (pSMA->dwVmBase == 0) { ++ GT_0trace(CMM_debugMask, GT_7CLASS, ++ "CMM_RegisterGPPSMSeg: Error" ++ "MEM_LinearAddress()\n"); ++ status = DSP_EFAIL; ++ goto func_end; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* return the actual segment identifier */ ++ *pulSegId = (u32) nSlot + 1; ++ /* create memory free list */ ++ pSMA->pFreeListHead = LST_Create(); ++ if (pSMA->pFreeListHead == NULL) { ++ GT_0trace(CMM_debugMask, GT_7CLASS, ++ "CMM_RegisterGPPSMSeg: " ++ "Out Of Memory \n"); ++ status = DSP_EMEMORY; ++ goto func_end; ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* create memory in-use list */ ++ pSMA->pInUseListHead = LST_Create(); ++ if (pSMA->pInUseListHead == NULL) { ++ GT_0trace(CMM_debugMask, GT_7CLASS, ++ "CMM_RegisterGPPSMSeg: " ++ "LST_Create failed\n"); ++ status = DSP_EMEMORY; ++ goto func_end; ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Get a mem node for this hunk-o-memory */ ++ pNewNode = GetNode(pCmmMgr, dwGPPBasePA, ++ pSMA->dwVmBase, ulSize); ++ /* Place node on the SM allocator's free list */ ++ if (pNewNode) { ++ LST_PutTail(pSMA->pFreeListHead, ++ (struct LST_ELEM *)pNewNode); ++ } else { ++ status = DSP_EMEMORY; ++ goto func_end; ++ } ++ } ++ if (DSP_FAILED(status)) { ++ /* Cleanup allocator */ ++ UnRegisterGPPSMSeg(pSMA); ++ } ++ } else { ++ GT_0trace(CMM_debugMask, GT_6CLASS, ++ "CMM_RegisterGPPSMSeg: SMA Object " ++ "Allocation Failure\n"); ++ status = DSP_EMEMORY; ++ goto func_end; ++ } ++ /* make entry */ ++ if (DSP_SUCCEEDED(status)) ++ pCmmMgr->paGPPSMSegTab[nSlot] = pSMA; ++ ++func_end: ++ SYNC_LeaveCS(pCmmMgr->hCmmLock); ++ return status; ++} ++ ++/* ++ * ======== CMM_UnRegisterGPPSMSeg ======== ++ * Purpose: ++ * UnRegister GPP SM segments with the CMM. ++ */ ++DSP_STATUS CMM_UnRegisterGPPSMSeg(struct CMM_OBJECT *hCmmMgr, u32 ulSegId) ++{ ++ struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr; ++ DSP_STATUS status = DSP_SOK; ++ struct CMM_ALLOCATOR *pSMA; ++ u32 ulId = ulSegId; ++ ++ DBC_Require(ulSegId > 0); ++ if (MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) { ++ if (ulSegId == CMM_ALLSEGMENTS) ++ ulId = 1; ++ ++ if ((ulId > 0) && (ulId <= CMM_MAXGPPSEGS)) { ++ while (ulId <= CMM_MAXGPPSEGS) { ++ SYNC_EnterCS(pCmmMgr->hCmmLock); ++ /* slot = segId-1 */ ++ pSMA = pCmmMgr->paGPPSMSegTab[ulId - 1]; ++ if (pSMA != NULL) { ++ UnRegisterGPPSMSeg(pSMA); ++ /* Set alctr ptr to NULL for future ++ * reuse */ ++ pCmmMgr->paGPPSMSegTab[ulId - 1] = NULL; ++ } else if (ulSegId != CMM_ALLSEGMENTS) { ++ status = DSP_EFAIL; ++ } ++ SYNC_LeaveCS(pCmmMgr->hCmmLock); ++ if (ulSegId != CMM_ALLSEGMENTS) ++ break; ++ ++ ulId++; ++ } /* end while */ ++ } else { ++ status = DSP_EINVALIDARG; ++ GT_0trace(CMM_debugMask, GT_7CLASS, ++ "CMM_UnRegisterGPPSMSeg: Bad " ++ "segment Id\n"); ++ } ++ } else { ++ status = DSP_EHANDLE; ++ } ++ return status; ++} ++ ++/* ++ * ======== UnRegisterGPPSMSeg ======== ++ * Purpose: ++ * UnRegister the SM allocator by freeing all its resources and ++ * nulling cmm mgr table entry. ++ * Note: ++ * This routine is always called within cmm lock crit sect. ++ */ ++static void UnRegisterGPPSMSeg(struct CMM_ALLOCATOR *pSMA) ++{ ++ struct CMM_MNODE *pCurNode = NULL; ++ struct CMM_MNODE *pNextNode = NULL; ++ ++ DBC_Require(pSMA != NULL); ++ if (pSMA->pFreeListHead != NULL) { ++ /* free nodes on free list */ ++ pCurNode = (struct CMM_MNODE *)LST_First(pSMA->pFreeListHead); ++ while (pCurNode) { ++ pNextNode = (struct CMM_MNODE *)LST_Next(pSMA-> ++ pFreeListHead, ++ (struct LST_ELEM *)pCurNode); ++ LST_RemoveElem(pSMA->pFreeListHead, ++ (struct LST_ELEM *)pCurNode); ++ MEM_Free((void *) pCurNode); ++ /* next node. */ ++ pCurNode = pNextNode; ++ } ++ LST_Delete(pSMA->pFreeListHead); /* delete freelist */ ++ /* free nodes on InUse list */ ++ pCurNode = (struct CMM_MNODE *)LST_First(pSMA->pInUseListHead); ++ while (pCurNode) { ++ pNextNode = (struct CMM_MNODE *)LST_Next(pSMA-> ++ pInUseListHead, ++ (struct LST_ELEM *)pCurNode); ++ LST_RemoveElem(pSMA->pInUseListHead, ++ (struct LST_ELEM *)pCurNode); ++ MEM_Free((void *) pCurNode); ++ /* next node. */ ++ pCurNode = pNextNode; ++ } ++ LST_Delete(pSMA->pInUseListHead); /* delete InUse list */ ++ } ++ if ((void *) pSMA->dwVmBase != NULL) ++ MEM_UnmapLinearAddress((void *) pSMA->dwVmBase); ++ ++ /* Free allocator itself */ ++ MEM_FreeObject(pSMA); ++} ++ ++/* ++ * ======== GetSlot ======== ++ * Purpose: ++ * An available slot # is returned. Returns negative on failure. ++ */ ++static s32 GetSlot(struct CMM_OBJECT *pCmmMgr) ++{ ++ s32 nSlot = -1; /* neg on failure */ ++ DBC_Require(pCmmMgr != NULL); ++ /* get first available slot in cmm mgr SMSegTab[] */ ++ for (nSlot = 0; nSlot < CMM_MAXGPPSEGS; nSlot++) { ++ if (pCmmMgr->paGPPSMSegTab[nSlot] == NULL) ++ break; ++ ++ } ++ if (nSlot == CMM_MAXGPPSEGS) { ++ GT_0trace(CMM_debugMask, GT_7CLASS, ++ "CMM_RegisterGPPSMSeg: Allocator " ++ "entry failure, max exceeded\n"); ++ nSlot = -1; /* failed */ ++ } ++ return nSlot; ++} ++ ++/* ++ * ======== GetNode ======== ++ * Purpose: ++ * Get a memory node from freelist or create a new one. ++ */ ++static struct CMM_MNODE *GetNode(struct CMM_OBJECT *pCmmMgr, u32 dwPA, ++ u32 dwVA, u32 ulSize) ++{ ++ struct CMM_MNODE *pNode = NULL; ++ ++ DBC_Require(pCmmMgr != NULL); ++ DBC_Require(dwPA != 0); ++ DBC_Require(dwVA != 0); ++ DBC_Require(ulSize != 0); ++ /* Check cmm mgr's node freelist */ ++ if (LST_IsEmpty(pCmmMgr->pNodeFreeListHead)) { ++ pNode = (struct CMM_MNODE *)MEM_Calloc(sizeof(struct CMM_MNODE), ++ MEM_PAGED); ++ } else { ++ /* surely a valid element */ ++ /* (struct LST_ELEM*) pNode = LST_GetHead(pCmmMgr-> ++ * pNodeFreeListHead);*/ ++ pNode = (struct CMM_MNODE *)LST_GetHead(pCmmMgr-> ++ pNodeFreeListHead); ++ } ++ if (pNode == NULL) { ++ GT_0trace(CMM_debugMask, GT_7CLASS, "GetNode: Out Of Memory\n"); ++ } else { ++ LST_InitElem((struct LST_ELEM *) pNode); /* set self */ ++ pNode->dwPA = dwPA; /* Physical addr of start of block */ ++ pNode->dwVA = dwVA; /* Virtual " " */ ++ pNode->ulSize = ulSize; /* Size of block */ ++ } ++ return pNode; ++} ++ ++/* ++ * ======== DeleteNode ======== ++ * Purpose: ++ * Put a memory node on the cmm nodelist for later use. ++ * Doesn't actually delete the node. Heap thrashing friendly. ++ */ ++static void DeleteNode(struct CMM_OBJECT *pCmmMgr, struct CMM_MNODE *pNode) ++{ ++ DBC_Require(pNode != NULL); ++ LST_InitElem((struct LST_ELEM *) pNode); /* init .self ptr */ ++ LST_PutTail(pCmmMgr->pNodeFreeListHead, (struct LST_ELEM *) pNode); ++} ++ ++/* ++ * ====== GetFreeBlock ======== ++ * Purpose: ++ * Scan the free block list and return the first block that satisfies ++ * the size. ++ */ ++static struct CMM_MNODE *GetFreeBlock(struct CMM_ALLOCATOR *pAllocator, ++ u32 uSize) ++{ ++ if (pAllocator) { ++ struct CMM_MNODE *pCurNode = (struct CMM_MNODE *) ++ LST_First(pAllocator->pFreeListHead); ++ while (pCurNode) { ++ if (uSize <= (u32) pCurNode->ulSize) { ++ LST_RemoveElem(pAllocator->pFreeListHead, ++ (struct LST_ELEM *)pCurNode); ++ return pCurNode; ++ } ++ /* next node. */ ++ pCurNode = (struct CMM_MNODE *)LST_Next(pAllocator-> ++ pFreeListHead, (struct LST_ELEM *)pCurNode); ++ } ++ } ++ return NULL; ++} ++ ++/* ++ * ======== AddToFreeList ======== ++ * Purpose: ++ * Coelesce node into the freelist in ascending size order. ++ */ ++static void AddToFreeList(struct CMM_ALLOCATOR *pAllocator, ++ struct CMM_MNODE *pNode) ++{ ++ struct CMM_MNODE *pNodePrev = NULL; ++ struct CMM_MNODE *pNodeNext = NULL; ++ struct CMM_MNODE *pCurNode; ++ u32 dwThisPA; ++ u32 dwNextPA; ++ ++ DBC_Require(pNode != NULL); ++ DBC_Require(pAllocator != NULL); ++ dwThisPA = pNode->dwPA; ++ dwNextPA = NEXT_PA(pNode); ++ pCurNode = (struct CMM_MNODE *)LST_First(pAllocator->pFreeListHead); ++ while (pCurNode) { ++ if (dwThisPA == NEXT_PA(pCurNode)) { ++ /* found the block ahead of this one */ ++ pNodePrev = pCurNode; ++ } else if (dwNextPA == pCurNode->dwPA) { ++ pNodeNext = pCurNode; ++ } ++ if ((pNodePrev == NULL) || (pNodeNext == NULL)) { ++ /* next node. */ ++ pCurNode = (struct CMM_MNODE *)LST_Next(pAllocator-> ++ pFreeListHead, (struct LST_ELEM *)pCurNode); ++ } else { ++ /* got 'em */ ++ break; ++ } ++ } /* while */ ++ if (pNodePrev != NULL) { ++ /* combine with previous block */ ++ LST_RemoveElem(pAllocator->pFreeListHead, ++ (struct LST_ELEM *)pNodePrev); ++ /* grow node to hold both */ ++ pNode->ulSize += pNodePrev->ulSize; ++ pNode->dwPA = pNodePrev->dwPA; ++ pNode->dwVA = pNodePrev->dwVA; ++ /* place node on mgr nodeFreeList */ ++ DeleteNode((struct CMM_OBJECT *)pAllocator->hCmmMgr, pNodePrev); ++ } ++ if (pNodeNext != NULL) { ++ /* combine with next block */ ++ LST_RemoveElem(pAllocator->pFreeListHead, ++ (struct LST_ELEM *)pNodeNext); ++ /* grow da node */ ++ pNode->ulSize += pNodeNext->ulSize; ++ /* place node on mgr nodeFreeList */ ++ DeleteNode((struct CMM_OBJECT *)pAllocator->hCmmMgr, pNodeNext); ++ } ++ /* Now, let's add to freelist in increasing size order */ ++ pCurNode = (struct CMM_MNODE *)LST_First(pAllocator->pFreeListHead); ++ while (pCurNode) { ++ if (pNode->ulSize <= pCurNode->ulSize) ++ break; ++ ++ /* next node. */ ++ pCurNode = (struct CMM_MNODE *)LST_Next(pAllocator-> ++ pFreeListHead, (struct LST_ELEM *)pCurNode); ++ } ++ /* if pCurNode is NULL then add our pNode to the end of the freelist */ ++ if (pCurNode == NULL) { ++ LST_PutTail(pAllocator->pFreeListHead, ++ (struct LST_ELEM *)pNode); ++ } else { ++ /* insert our node before the current traversed node */ ++ LST_InsertBefore(pAllocator->pFreeListHead, ++ (struct LST_ELEM *)pNode, ++ (struct LST_ELEM *)pCurNode); ++ } ++} ++ ++/* ++ * ======== GetAllocator ======== ++ * Purpose: ++ * Return the allocator for the given SM Segid. ++ * SegIds: 1,2,3..max. ++ */ ++static struct CMM_ALLOCATOR *GetAllocator(struct CMM_OBJECT *pCmmMgr, ++ u32 ulSegId) ++{ ++ struct CMM_ALLOCATOR *pAllocator = NULL; ++ ++ DBC_Require(pCmmMgr != NULL); ++ DBC_Require((ulSegId > 0) && (ulSegId <= CMM_MAXGPPSEGS)); ++ pAllocator = pCmmMgr->paGPPSMSegTab[ulSegId - 1]; ++ if (pAllocator != NULL) { ++ /* make sure it's for real */ ++ if (!MEM_IsValidHandle(pAllocator, SMEMSIGNATURE)) { ++ pAllocator = NULL; ++ DBC_Assert(false); ++ } ++ } ++ return pAllocator; ++} ++ ++/* ++ * ======== CMM_XlatorCreate ======== ++ * Purpose: ++ * Create an address translator object. ++ */ ++DSP_STATUS CMM_XlatorCreate(OUT struct CMM_XLATOROBJECT **phXlator, ++ struct CMM_OBJECT *hCmmMgr, ++ struct CMM_XLATORATTRS *pXlatorAttrs) ++{ ++ struct CMM_XLATOR *pXlatorObject = NULL; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phXlator != NULL); ++ DBC_Require(hCmmMgr != NULL); ++ GT_3trace(CMM_debugMask, GT_ENTER, ++ "CMM_XlatorCreate: phXlator: 0x%x\t" ++ "phCmmMgr: 0x%x\tpXlAttrs: 0x%x\n", phXlator, ++ hCmmMgr, pXlatorAttrs); ++ *phXlator = NULL; ++ if (pXlatorAttrs == NULL) ++ pXlatorAttrs = &CMM_DFLTXLATORATTRS; /* set defaults */ ++ ++ MEM_AllocObject(pXlatorObject, struct CMM_XLATOR, CMMXLATESIGNATURE); ++ if (pXlatorObject != NULL) { ++ pXlatorObject->hCmmMgr = hCmmMgr; /* ref back to CMM */ ++ pXlatorObject->ulSegId = pXlatorAttrs->ulSegId; /* SM segId */ ++ } else { ++ GT_0trace(CMM_debugMask, GT_6CLASS, ++ "CMM_XlatorCreate: Object Allocation" ++ "Failure(CMM Xlator)\n"); ++ status = DSP_EMEMORY; ++ } ++ if (DSP_SUCCEEDED(status)) ++ *phXlator = (struct CMM_XLATOROBJECT *) pXlatorObject; ++ ++ return status; ++} ++ ++/* ++ * ======== CMM_XlatorDelete ======== ++ * Purpose: ++ * Free the Xlator resources. ++ * VM gets freed later. ++ */ ++DSP_STATUS CMM_XlatorDelete(struct CMM_XLATOROBJECT *hXlator, bool bForce) ++{ ++ struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ ++ if (MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE)) { ++ MEM_FreeObject(pXlator); ++ } else { ++ status = DSP_EHANDLE; ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== CMM_XlatorAllocBuf ======== ++ */ ++void *CMM_XlatorAllocBuf(struct CMM_XLATOROBJECT *hXlator, void *pVaBuf, ++ u32 uPaSize) ++{ ++ struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator; ++ void *pBuf = NULL; ++ struct CMM_ATTRS attrs; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(hXlator != NULL); ++ DBC_Require(pXlator->hCmmMgr != NULL); ++ DBC_Require(pVaBuf != NULL); ++ DBC_Require(uPaSize > 0); ++ DBC_Require(pXlator->ulSegId > 0); ++ ++ if (MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE)) { ++ attrs.ulSegId = pXlator->ulSegId; ++ *(volatile u32 *)pVaBuf = 0; ++ /* Alloc SM */ ++ pBuf = CMM_CallocBuf(pXlator->hCmmMgr, uPaSize, &attrs, NULL); ++ if (pBuf) { ++ /* convert to translator(node/strm) process Virtual ++ * address */ ++ *(volatile u32 **)pVaBuf = ++ (u32 *)CMM_XlatorTranslate(hXlator, ++ pBuf, CMM_PA2VA); ++ } ++ } ++ return pBuf; ++} ++ ++/* ++ * ======== CMM_XlatorFreeBuf ======== ++ * Purpose: ++ * Free the given SM buffer and descriptor. ++ * Does not free virtual memory. ++ */ ++DSP_STATUS CMM_XlatorFreeBuf(struct CMM_XLATOROBJECT *hXlator, void *pBufVa) ++{ ++ struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator; ++ DSP_STATUS status = DSP_EFAIL; ++ void *pBufPa = NULL; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pBufVa != NULL); ++ DBC_Require(pXlator->ulSegId > 0); ++ ++ if (MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE)) { ++ /* convert Va to Pa so we can free it. */ ++ pBufPa = CMM_XlatorTranslate(hXlator, pBufVa, CMM_VA2PA); ++ if (pBufPa) { ++ status = CMM_FreeBuf(pXlator->hCmmMgr, pBufPa, ++ pXlator->ulSegId); ++ if (DSP_FAILED(status)) { ++ /* Uh oh, this shouldn't happen. Descriptor ++ * gone! */ ++ GT_2trace(CMM_debugMask, GT_7CLASS, ++ "Cannot free DMA/ZCPY buffer" ++ "not allocated by MPU. PA %x, VA %x\n", ++ pBufPa, pBufVa); ++ DBC_Assert(false); /* CMM is leaking mem! */ ++ } ++ } ++ } ++ return status; ++} ++ ++/* ++ * ======== CMM_XlatorInfo ======== ++ * Purpose: ++ * Set/Get translator info. ++ */ ++DSP_STATUS CMM_XlatorInfo(struct CMM_XLATOROBJECT *hXlator, IN OUT u8 **pAddr, ++ u32 ulSize, u32 uSegId, bool bSetInfo) ++{ ++ struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pAddr != NULL); ++ DBC_Require((uSegId > 0) && (uSegId <= CMM_MAXGPPSEGS)); ++ ++ if (MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE)) { ++ if (bSetInfo) { ++ /* set translators virtual address range */ ++ pXlator->dwVirtBase = (u32)*pAddr; ++ pXlator->ulVirtSize = ulSize; ++ GT_2trace(CMM_debugMask, GT_3CLASS, ++ "pXlator->dwVirtBase %x, " ++ "ulVirtSize %x\n", pXlator->dwVirtBase, ++ pXlator->ulVirtSize); ++ } else { /* return virt base address */ ++ *pAddr = (u8 *)pXlator->dwVirtBase; ++ } ++ } else { ++ status = DSP_EHANDLE; ++ } ++ return status; ++} ++ ++/* ++ * ======== CMM_XlatorTranslate ======== ++ */ ++void *CMM_XlatorTranslate(struct CMM_XLATOROBJECT *hXlator, void *pAddr, ++ enum CMM_XLATETYPE xType) ++{ ++ u32 dwAddrXlate = 0; ++ struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator; ++ struct CMM_OBJECT *pCmmMgr = NULL; ++ struct CMM_ALLOCATOR *pAlctr = NULL; ++ u32 dwOffset = 0; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pAddr != NULL); ++ DBC_Require((xType >= CMM_VA2PA) && (xType <= CMM_DSPPA2PA)); ++ ++ if (!MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE)) ++ goto loop_cont; ++ ++ pCmmMgr = (struct CMM_OBJECT *)pXlator->hCmmMgr; ++ /* get this translator's default SM allocator */ ++ DBC_Assert(pXlator->ulSegId > 0); ++ pAlctr = pCmmMgr->paGPPSMSegTab[pXlator->ulSegId - 1]; ++ if (!MEM_IsValidHandle(pAlctr, SMEMSIGNATURE)) ++ goto loop_cont; ++ ++ if ((xType == CMM_VA2DSPPA) || (xType == CMM_VA2PA) || ++ (xType == CMM_PA2VA)) { ++ if (xType == CMM_PA2VA) { ++ /* Gpp Va = Va Base + offset */ ++ dwOffset = (u8 *)pAddr - (u8 *)(pAlctr->dwSmBase - ++ pAlctr->ulDSPSize); ++ dwAddrXlate = pXlator->dwVirtBase + dwOffset; ++ /* Check if translated Va base is in range */ ++ if ((dwAddrXlate < pXlator->dwVirtBase) || ++ (dwAddrXlate >= ++ (pXlator->dwVirtBase + pXlator->ulVirtSize))) { ++ dwAddrXlate = 0; /* bad address */ ++ GT_0trace(CMM_debugMask, GT_7CLASS, ++ "CMM_XlatorTranslate: " ++ "Virt addr out of range\n"); ++ } ++ } else { ++ /* Gpp PA = Gpp Base + offset */ ++ dwOffset = (u8 *)pAddr - (u8 *)pXlator->dwVirtBase; ++ dwAddrXlate = pAlctr->dwSmBase - pAlctr->ulDSPSize + ++ dwOffset; ++ } ++ } else { ++ dwAddrXlate = (u32)pAddr; ++ } ++ /*Now convert address to proper target physical address if needed*/ ++ if ((xType == CMM_VA2DSPPA) || (xType == CMM_PA2DSPPA)) { ++ /* Got Gpp Pa now, convert to DSP Pa */ ++ dwAddrXlate = GPPPA2DSPPA((pAlctr->dwSmBase - pAlctr-> ++ ulDSPSize), dwAddrXlate, ++ pAlctr->dwDSPPhysAddrOffset * ++ pAlctr->cFactor); ++ } else if (xType == CMM_DSPPA2PA) { ++ /* Got DSP Pa, convert to GPP Pa */ ++ dwAddrXlate = DSPPA2GPPPA(pAlctr->dwSmBase - pAlctr->ulDSPSize, ++ dwAddrXlate, ++ pAlctr->dwDSPPhysAddrOffset * ++ pAlctr->cFactor); ++ } ++loop_cont: ++ if (!dwAddrXlate) { ++ GT_2trace(CMM_debugMask, GT_7CLASS, ++ "CMM_XlatorTranslate: Can't translate" ++ " address: 0x%x xType %x\n", pAddr, xType); ++ } else { ++ GT_3trace(CMM_debugMask, GT_3CLASS, ++ "CMM_XlatorTranslate: pAddr %x, xType" ++ " %x, dwAddrXlate %x\n", pAddr, xType, dwAddrXlate); ++ } ++ return (void *)dwAddrXlate; ++} +diff --git a/drivers/dsp/bridge/pmgr/cod.c b/drivers/dsp/bridge/pmgr/cod.c +new file mode 100644 +index 0000000..6363f1e +--- /dev/null ++++ b/drivers/dsp/bridge/pmgr/cod.c +@@ -0,0 +1,683 @@ ++/* ++ * cod.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== cod.c ======== ++ * This module implements DSP code management for the DSP/BIOS Bridge ++ * environment. It is mostly a thin wrapper. ++ * ++ * This module provides an interface for loading both static and ++ * dynamic code objects onto DSP systems. ++ * ++ *! Revision History ++ *! ================ ++ *! 08-Apr-2003 map: Consolidated DBL to DBLL loader name ++ *! 24-Feb-2003 swa: PMGR Code review comments incorporated. ++ *! 18-Apr-2002 jeh: Added DBL function tables. ++ *! 20-Nov-2001 jeh: Removed call to ZL_loadArgs function. ++ *! 19-Oct-2001 jeh: Access DBL as a static library. Added COD_GetBaseLib, ++ *! COD_GetLoader, removed COD_LoadSection, COD_UnloadSection. ++ *! 07-Sep-2001 jeh: Added COD_LoadSection(), COD_UnloadSection(). ++ *! 07-Aug-2001 rr: hMgr->baseLib is updated after zlopen in COD_LoadBase. ++ *! 18-Apr-2001 jeh: Check for fLoaded flag before ZL_unload, to allow ++ *! COD_OpenBase to be used. ++ *! 11-Jan-2001 jeh: Added COD_OpenBase (not used yet, since there is an ++ *! occasional crash). ++ *! 02-Aug-2000 kc: Added COD_ReadSection to COD module. Incorporates use ++ *! of ZL_readSect (new function in ZL module). ++ *! 28-Feb-2000 rr: New GT Usage Implementation ++ *! 08-Dec-1999 ag: Removed x86 specific __asm int 3. ++ *! 02-Oct-1999 ag: Added #ifdef DEBUGINT3COD for debug. ++ *! 20-Sep-1999 ag: Removed call to GT_set(). ++ *! 04-Jun-1997 cr: Added validation of argc/argv pair in COD_LoadBase, as it ++ *! is a requirement to ZL_loadArgs. ++ *! 31-May-1997 cr: Changed COD_LoadBase argc value from u32 to int, added ++ *! DSP_ENOTIMPL return value to COD_Create when attrs != NULL. ++ *! 29-May-1997 cr: Added debugging support. ++ *! 24-Oct-1996 gp: Added COD_GetSection(). ++ *! 18-Jun-1996 gp: Updated GetSymValue() to check for lib; updated E_ codes. ++ *! 12-Jun-1996 gp: Imported CSL_ services for strcpyn(); Added ref counting. ++ *! 20-May-1996 mg: Adapted for new MEM and LDR modules. ++ *! 08-May-1996 mg: Created. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Platform Manager */ ++/* Include appropriate loader header file */ ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++/* magic number for handle validation */ ++#define MAGIC 0xc001beef ++ ++/* macro to validate COD manager handles */ ++#define IsValid(h) ((h) != NULL && (h)->ulMagic == MAGIC) ++ ++/* ++ * ======== COD_MANAGER ======== ++ */ ++struct COD_MANAGER { ++ struct DBLL_TarObj *target; ++ struct DBLL_LibraryObj *baseLib; ++ bool fLoaded; /* Base library loaded? */ ++ u32 ulEntry; ++ struct LDR_MODULE *hDll; ++ struct DBLL_Fxns fxns; ++ struct DBLL_Attrs attrs; ++ char szZLFile[COD_MAXPATHLENGTH]; ++ u32 ulMagic; ++} ; ++ ++/* ++ * ======== COD_LIBRARYOBJ ======== ++ */ ++struct COD_LIBRARYOBJ { ++ struct DBLL_LibraryObj *dbllLib; ++ struct COD_MANAGER *hCodMgr; ++} ; ++ ++static u32 cRefs = 0L; ++ ++#if GT_TRACE ++static struct GT_Mask COD_debugMask = { NULL, NULL }; ++#endif ++ ++static struct DBLL_Fxns dbllFxns = { ++ (DBLL_CloseFxn) DBLL_close, ++ (DBLL_CreateFxn) DBLL_create, ++ (DBLL_DeleteFxn) DBLL_delete, ++ (DBLL_ExitFxn) DBLL_exit, ++ (DBLL_GetAttrsFxn) DBLL_getAttrs, ++ (DBLL_GetAddrFxn) DBLL_getAddr, ++ (DBLL_GetCAddrFxn) DBLL_getCAddr, ++ (DBLL_GetSectFxn) DBLL_getSect, ++ (DBLL_InitFxn) DBLL_init, ++ (DBLL_LoadFxn) DBLL_load, ++ (DBLL_LoadSectFxn) DBLL_loadSect, ++ (DBLL_OpenFxn) DBLL_open, ++ (DBLL_ReadSectFxn) DBLL_readSect, ++ (DBLL_SetAttrsFxn) DBLL_setAttrs, ++ (DBLL_UnloadFxn) DBLL_unload, ++ (DBLL_UnloadSectFxn) DBLL_unloadSect, ++}; ++ ++static bool NoOp(void); ++ ++/* ++ * ======== COD_Close ======== ++ */ ++void COD_Close(struct COD_LIBRARYOBJ *lib) ++{ ++ struct COD_MANAGER *hMgr; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(lib != NULL); ++ DBC_Require(IsValid(((struct COD_LIBRARYOBJ *)lib)->hCodMgr)); ++ ++ hMgr = lib->hCodMgr; ++ hMgr->fxns.closeFxn(lib->dbllLib); ++ ++ MEM_Free(lib); ++} ++ ++/* ++ * ======== COD_Create ======== ++ * Purpose: ++ * Create an object to manage code on a DSP system. ++ * This object can be used to load an initial program image with ++ * arguments that can later be expanded with ++ * dynamically loaded object files. ++ * ++ */ ++DSP_STATUS COD_Create(OUT struct COD_MANAGER **phMgr, char *pstrDummyFile, ++ IN OPTIONAL CONST struct COD_ATTRS *attrs) ++{ ++ struct COD_MANAGER *hMgrNew; ++ struct DBLL_Attrs zlAttrs; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phMgr != NULL); ++ ++ GT_3trace(COD_debugMask, GT_ENTER, ++ "Entered COD_Create, Args: \t\nphMgr: " ++ "0x%x\t\npstrDummyFile: 0x%x\t\nattr: 0x%x\n", ++ phMgr, pstrDummyFile, attrs); ++ /* assume failure */ ++ *phMgr = NULL; ++ ++ /* we don't support non-default attrs yet */ ++ if (attrs != NULL) ++ return DSP_ENOTIMPL; ++ ++ hMgrNew = MEM_Calloc(sizeof(struct COD_MANAGER), MEM_NONPAGED); ++ if (hMgrNew == NULL) { ++ GT_0trace(COD_debugMask, GT_7CLASS, ++ "COD_Create: Out Of Memory\n"); ++ return DSP_EMEMORY; ++ } ++ ++ hMgrNew->ulMagic = MAGIC; ++ ++ /* Set up loader functions */ ++ hMgrNew->fxns = dbllFxns; ++ ++ /* initialize the ZL module */ ++ hMgrNew->fxns.initFxn(); ++ ++ zlAttrs.alloc = (DBLL_AllocFxn)NoOp; ++ zlAttrs.free = (DBLL_FreeFxn)NoOp; ++ zlAttrs.fread = (DBLL_ReadFxn)KFILE_Read; ++ zlAttrs.fseek = (DBLL_SeekFxn)KFILE_Seek; ++ zlAttrs.ftell = (DBLL_TellFxn)KFILE_Tell; ++ zlAttrs.fclose = (DBLL_FCloseFxn)KFILE_Close; ++ zlAttrs.fopen = (DBLL_FOpenFxn)KFILE_Open; ++ zlAttrs.symLookup = NULL; ++ zlAttrs.baseImage = true; ++ zlAttrs.logWrite = NULL; ++ zlAttrs.logWriteHandle = NULL; ++ zlAttrs.write = NULL; ++ zlAttrs.rmmHandle = NULL; ++ zlAttrs.wHandle = NULL; ++ zlAttrs.symHandle = NULL; ++ zlAttrs.symArg = NULL; ++ ++ hMgrNew->attrs = zlAttrs; ++ ++ status = hMgrNew->fxns.createFxn(&hMgrNew->target, &zlAttrs); ++ ++ if (DSP_FAILED(status)) { ++ COD_Delete(hMgrNew); ++ GT_1trace(COD_debugMask, GT_7CLASS, ++ "COD_Create:ZL Create Failed: 0x%x\n", status); ++ return COD_E_ZLCREATEFAILED; ++ } ++ ++ /* return the new manager */ ++ *phMgr = hMgrNew; ++ GT_1trace(COD_debugMask, GT_1CLASS, ++ "COD_Create: Success CodMgr: 0x%x\n", *phMgr); ++ return DSP_SOK; ++} ++ ++/* ++ * ======== COD_Delete ======== ++ * Purpose: ++ * Delete a code manager object. ++ */ ++void COD_Delete(struct COD_MANAGER *hMgr) ++{ ++ DBC_Require(cRefs > 0); ++ DBC_Require(IsValid(hMgr)); ++ ++ GT_1trace(COD_debugMask, GT_ENTER, "COD_Delete:hMgr 0x%x\n", hMgr); ++ if (hMgr->baseLib) { ++ if (hMgr->fLoaded) ++ hMgr->fxns.unloadFxn(hMgr->baseLib, &hMgr->attrs); ++ ++ hMgr->fxns.closeFxn(hMgr->baseLib); ++ } ++ if (hMgr->target) { ++ hMgr->fxns.deleteFxn(hMgr->target); ++ hMgr->fxns.exitFxn(); ++ } ++ hMgr->ulMagic = ~MAGIC; ++ MEM_Free(hMgr); ++} ++ ++/* ++ * ======== COD_Exit ======== ++ * Purpose: ++ * Discontinue usage of the COD module. ++ * ++ */ ++void COD_Exit(void) ++{ ++ DBC_Require(cRefs > 0); ++ ++ cRefs--; ++ ++ GT_1trace(COD_debugMask, GT_ENTER, ++ "Entered COD_Exit, ref count: 0x%x\n", cRefs); ++ ++ DBC_Ensure(cRefs >= 0); ++} ++ ++/* ++ * ======== COD_GetBaseLib ======== ++ * Purpose: ++ * Get handle to the base image DBL library. ++ */ ++DSP_STATUS COD_GetBaseLib(struct COD_MANAGER *hManager, ++ struct DBLL_LibraryObj **plib) ++{ ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(IsValid(hManager)); ++ DBC_Require(plib != NULL); ++ ++ *plib = (struct DBLL_LibraryObj *) hManager->baseLib; ++ ++ return status; ++} ++ ++/* ++ * ======== COD_GetBaseName ======== ++ */ ++DSP_STATUS COD_GetBaseName(struct COD_MANAGER *hManager, char *pszName, ++ u32 uSize) ++{ ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(IsValid(hManager)); ++ DBC_Require(pszName != NULL); ++ ++ if (uSize <= COD_MAXPATHLENGTH) ++ strncpy(pszName, hManager->szZLFile, uSize); ++ else ++ status = DSP_EFAIL; ++ ++ return status; ++} ++ ++/* ++ * ======== COD_GetEntry ======== ++ * Purpose: ++ * Retrieve the entry point of a loaded DSP program image ++ * ++ */ ++DSP_STATUS COD_GetEntry(struct COD_MANAGER *hManager, u32 *pulEntry) ++{ ++ DBC_Require(cRefs > 0); ++ DBC_Require(IsValid(hManager)); ++ DBC_Require(pulEntry != NULL); ++ ++ *pulEntry = hManager->ulEntry; ++ ++ GT_1trace(COD_debugMask, GT_ENTER, "COD_GetEntry:ulEntr 0x%x\n", ++ *pulEntry); ++ ++ return DSP_SOK; ++} ++ ++/* ++ * ======== COD_GetLoader ======== ++ * Purpose: ++ * Get handle to the DBLL loader. ++ */ ++DSP_STATUS COD_GetLoader(struct COD_MANAGER *hManager, ++ struct DBLL_TarObj **phLoader) ++{ ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(IsValid(hManager)); ++ DBC_Require(phLoader != NULL); ++ ++ *phLoader = (struct DBLL_TarObj *)hManager->target; ++ ++ return status; ++} ++ ++/* ++ * ======== COD_GetSection ======== ++ * Purpose: ++ * Retrieve the starting address and length of a section in the COFF file ++ * given the section name. ++ */ ++DSP_STATUS COD_GetSection(struct COD_LIBRARYOBJ *lib, IN char *pstrSect, ++ OUT u32 *puAddr, OUT u32 *puLen) ++{ ++ struct COD_MANAGER *hManager; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(lib != NULL); ++ DBC_Require(IsValid(lib->hCodMgr)); ++ DBC_Require(pstrSect != NULL); ++ DBC_Require(puAddr != NULL); ++ DBC_Require(puLen != NULL); ++ ++ GT_4trace(COD_debugMask, GT_ENTER, ++ "Entered COD_GetSection Args \t\n lib: " ++ "0x%x\t\npstrsect: 0x%x\t\npuAddr: 0x%x\t\npuLen: 0x%x\n", ++ lib, pstrSect, puAddr, puLen); ++ *puAddr = 0; ++ *puLen = 0; ++ if (lib != NULL) { ++ hManager = lib->hCodMgr; ++ status = hManager->fxns.getSectFxn(lib->dbllLib, pstrSect, ++ puAddr, puLen); ++ if (DSP_FAILED(status)) { ++ GT_1trace(COD_debugMask, GT_7CLASS, ++ "COD_GetSection: Section %s not" ++ "found\n", pstrSect); ++ } ++ } else { ++ status = COD_E_NOSYMBOLSLOADED; ++ GT_0trace(COD_debugMask, GT_7CLASS, ++ "COD_GetSection:No Symbols loaded\n"); ++ } ++ ++ DBC_Ensure(DSP_SUCCEEDED(status) || ((*puAddr == 0) && (*puLen == 0))); ++ ++ return status; ++} ++ ++/* ++ * ======== COD_GetSymValue ======== ++ * Purpose: ++ * Retrieve the value for the specified symbol. The symbol is first ++ * searched for literally and then, if not found, searched for as a ++ * C symbol. ++ * ++ */ ++DSP_STATUS COD_GetSymValue(struct COD_MANAGER *hMgr, char *pstrSym, ++ u32 *pulValue) ++{ ++ struct DBLL_Symbol *pSym; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(IsValid(hMgr)); ++ DBC_Require(pstrSym != NULL); ++ DBC_Require(pulValue != NULL); ++ ++ GT_3trace(COD_debugMask, GT_ENTER, "Entered COD_GetSymValue Args \t\n" ++ "hMgr: 0x%x\t\npstrSym: 0x%x\t\npulValue: 0x%x\n", ++ hMgr, pstrSym, pulValue); ++ if (hMgr->baseLib) { ++ if (!hMgr->fxns.getAddrFxn(hMgr->baseLib, pstrSym, &pSym)) { ++ if (!hMgr->fxns.getCAddrFxn(hMgr->baseLib, pstrSym, ++ &pSym)) { ++ GT_0trace(COD_debugMask, GT_7CLASS, ++ "COD_GetSymValue: " ++ "Symbols not found\n"); ++ return COD_E_SYMBOLNOTFOUND; ++ } ++ } ++ } else { ++ GT_0trace(COD_debugMask, GT_7CLASS, "COD_GetSymValue: " ++ "No Symbols loaded\n"); ++ return COD_E_NOSYMBOLSLOADED; ++ } ++ ++ *pulValue = pSym->value; ++ ++ return DSP_SOK; ++} ++ ++/* ++ * ======== COD_Init ======== ++ * Purpose: ++ * Initialize the COD module's private state. ++ * ++ */ ++bool COD_Init(void) ++{ ++ bool fRetVal = true; ++ ++ DBC_Require(cRefs >= 0); ++ ++ if (cRefs == 0) { ++ DBC_Assert(!COD_debugMask.flags); ++ GT_create(&COD_debugMask, "CO"); ++ } ++ ++ if (fRetVal) ++ cRefs++; ++ ++ ++ GT_1trace(COD_debugMask, GT_1CLASS, ++ "Entered COD_Init, ref count: 0x%x\n", cRefs); ++ DBC_Ensure((fRetVal && cRefs > 0) || (!fRetVal && cRefs >= 0)); ++ return fRetVal; ++} ++ ++/* ++ * ======== COD_LoadBase ======== ++ * Purpose: ++ * Load the initial program image, optionally with command-line arguments, ++ * on the DSP system managed by the supplied handle. The program to be ++ * loaded must be the first element of the args array and must be a fully ++ * qualified pathname. ++ * Details: ++ * if nArgc doesn't match the number of arguments in the aArgs array, the ++ * aArgs array is searched for a NULL terminating entry, and argc is ++ * recalculated to reflect this. In this way, we can support NULL ++ * terminating aArgs arrays, if nArgc is very large. ++ */ ++DSP_STATUS COD_LoadBase(struct COD_MANAGER *hMgr, u32 nArgc, char *aArgs[], ++ COD_WRITEFXN pfnWrite, void *pArb, char *envp[]) ++{ ++ DBLL_Flags flags; ++ struct DBLL_Attrs saveAttrs; ++ struct DBLL_Attrs newAttrs; ++ DSP_STATUS status; ++ u32 i; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(IsValid(hMgr)); ++ DBC_Require(nArgc > 0); ++ DBC_Require(aArgs != NULL); ++ DBC_Require(aArgs[0] != NULL); ++ DBC_Require(pfnWrite != NULL); ++ DBC_Require(hMgr->baseLib != NULL); ++ ++ GT_6trace(COD_debugMask, GT_ENTER, ++ "Entered COD_LoadBase, hMgr: 0x%x\n \t" ++ "nArgc: 0x%x\n\taArgs: 0x%x\n\tpfnWrite: 0x%x\n\tpArb:" ++ " 0x%x\n \tenvp: 0x%x\n", hMgr, nArgc, aArgs, pfnWrite, ++ pArb, envp); ++ /* ++ * Make sure every argv[] stated in argc has a value, or change argc to ++ * reflect true number in NULL terminated argv array. ++ */ ++ for (i = 0; i < nArgc; i++) { ++ if (aArgs[i] == NULL) { ++ nArgc = i; ++ break; ++ } ++ } ++ ++ /* set the write function for this operation */ ++ hMgr->fxns.getAttrsFxn(hMgr->target, &saveAttrs); ++ ++ newAttrs = saveAttrs; ++ newAttrs.write = (DBLL_WriteFxn)pfnWrite; ++ newAttrs.wHandle = pArb; ++ newAttrs.alloc = (DBLL_AllocFxn)NoOp; ++ newAttrs.free = (DBLL_FreeFxn)NoOp; ++ newAttrs.logWrite = NULL; ++ newAttrs.logWriteHandle = NULL; ++ ++ /* Load the image */ ++ flags = DBLL_CODE | DBLL_DATA | DBLL_SYMB; ++ status = hMgr->fxns.loadFxn(hMgr->baseLib, flags, &newAttrs, ++ &hMgr->ulEntry); ++ if (DSP_FAILED(status)) { ++ hMgr->fxns.closeFxn(hMgr->baseLib); ++ GT_1trace(COD_debugMask, GT_7CLASS, ++ "COD_LoadBase: COD Load failed: " ++ "0x%x\n", status); ++ } ++ if (DSP_SUCCEEDED(status)) ++ hMgr->fLoaded = true; ++ else ++ hMgr->baseLib = NULL; ++ ++ return status; ++} ++ ++/* ++ * ======== COD_Open ======== ++ * Open library for reading sections. ++ */ ++DSP_STATUS COD_Open(struct COD_MANAGER *hMgr, IN char *pszCoffPath, ++ COD_FLAGS flags, struct COD_LIBRARYOBJ **pLib) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct COD_LIBRARYOBJ *lib = NULL; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(IsValid(hMgr)); ++ DBC_Require(pszCoffPath != NULL); ++ DBC_Require(flags == COD_NOLOAD || flags == COD_SYMB); ++ DBC_Require(pLib != NULL); ++ ++ GT_4trace(COD_debugMask, GT_ENTER, "Entered COD_Open, hMgr: 0x%x\n\t " ++ "pszCoffPath: 0x%x\tflags: 0x%x\tlib: 0x%x\n", hMgr, ++ pszCoffPath, flags, pLib); ++ ++ *pLib = NULL; ++ ++ lib = MEM_Calloc(sizeof(struct COD_LIBRARYOBJ), MEM_NONPAGED); ++ if (lib == NULL) { ++ GT_0trace(COD_debugMask, GT_7CLASS, ++ "COD_Open: Out Of Memory\n"); ++ status = DSP_EMEMORY; ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ lib->hCodMgr = hMgr; ++ status = hMgr->fxns.openFxn(hMgr->target, pszCoffPath, flags, ++ &lib->dbllLib); ++ if (DSP_FAILED(status)) { ++ GT_1trace(COD_debugMask, GT_7CLASS, ++ "COD_Open failed: 0x%x\n", status); ++ } else { ++ *pLib = lib; ++ } ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== COD_OpenBase ======== ++ * Purpose: ++ * Open base image for reading sections. ++ */ ++DSP_STATUS COD_OpenBase(struct COD_MANAGER *hMgr, IN char *pszCoffPath, ++ DBLL_Flags flags) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DBLL_LibraryObj *lib; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(IsValid(hMgr)); ++ DBC_Require(pszCoffPath != NULL); ++ ++ GT_2trace(COD_debugMask, GT_ENTER, ++ "Entered COD_OpenBase, hMgr: 0x%x\n\t" ++ "pszCoffPath: 0x%x\n", hMgr, pszCoffPath); ++ ++ /* if we previously opened a base image, close it now */ ++ if (hMgr->baseLib) { ++ if (hMgr->fLoaded) { ++ GT_0trace(COD_debugMask, GT_7CLASS, ++ "Base Image is already loaded. " ++ "Unloading it...\n"); ++ hMgr->fxns.unloadFxn(hMgr->baseLib, &hMgr->attrs); ++ hMgr->fLoaded = false; ++ } ++ hMgr->fxns.closeFxn(hMgr->baseLib); ++ hMgr->baseLib = NULL; ++ } else { ++ GT_0trace(COD_debugMask, GT_1CLASS, ++ "COD_OpenBase: Opening the base image ...\n"); ++ } ++ status = hMgr->fxns.openFxn(hMgr->target, pszCoffPath, flags, &lib); ++ if (DSP_FAILED(status)) { ++ GT_0trace(COD_debugMask, GT_7CLASS, ++ "COD_OpenBase: COD Open failed\n"); ++ } else { ++ /* hang onto the library for subsequent sym table usage */ ++ hMgr->baseLib = lib; ++ strncpy(hMgr->szZLFile, pszCoffPath, COD_MAXPATHLENGTH); ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== COD_ReadSection ======== ++ * Purpose: ++ * Retrieve the content of a code section given the section name. ++ */ ++DSP_STATUS COD_ReadSection(struct COD_LIBRARYOBJ *lib, IN char *pstrSect, ++ OUT char *pstrContent, IN u32 cContentSize) ++{ ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(lib != NULL); ++ DBC_Require(IsValid(lib->hCodMgr)); ++ DBC_Require(pstrSect != NULL); ++ DBC_Require(pstrContent != NULL); ++ ++ GT_4trace(COD_debugMask, GT_ENTER, "Entered COD_ReadSection Args: 0x%x," ++ " 0x%x, 0x%x, 0x%x\n", lib, pstrSect, pstrContent, ++ cContentSize); ++ ++ if (lib != NULL) { ++ status = lib->hCodMgr->fxns.readSectFxn(lib->dbllLib, pstrSect, ++ pstrContent, ++ cContentSize); ++ if (DSP_FAILED(status)) { ++ GT_1trace(COD_debugMask, GT_7CLASS, ++ "COD_ReadSection failed: 0x%lx\n", status); ++ } ++ } else { ++ status = COD_E_NOSYMBOLSLOADED; ++ GT_0trace(COD_debugMask, GT_7CLASS, ++ "COD_ReadSection: No Symbols loaded\n"); ++ } ++ return status; ++} ++ ++/* ++ * ======== NoOp ======== ++ * Purpose: ++ * No Operation. ++ * ++ */ ++static bool NoOp(void) ++{ ++ return true; ++} ++ +diff --git a/drivers/dsp/bridge/pmgr/dbl.c b/drivers/dsp/bridge/pmgr/dbl.c +new file mode 100644 +index 0000000..641b011 +--- /dev/null ++++ b/drivers/dsp/bridge/pmgr/dbl.c +@@ -0,0 +1,1385 @@ ++/* ++ * dbl.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== dbl.c ======== ++ * Dynamic BOF Loader library. Contains functions related to ++ * loading and unloading symbols/code/data on DSP. ++ * Also contains other support functions. ++ * ++ *! Revision History ++ *! ================ ++ *! 24-Feb-2003 swa PMGR Code review comments incorporated. ++ *! 24-May-2002 jeh Free DCD sects in DBL_close(). ++ *! 19-Mar-2002 jeh Changes made to match dynamic loader (dbll.c): Pass ++ *! DBL_Library to DBL_getAddr() instead of DBL_Target, ++ *! eliminate scope param, use DBL_Symbol. Pass attrs to ++ *! DBL_load(), DBL_unload(). ++ *! 20-Nov-2001 jeh Removed DBL_loadArgs(). ++ *! 07-Sep-2001 jeh Added overlay support. ++ *! 31-Jul-2001 jeh Include windows.h. ++ *! 06-Jun-2001 jeh Created. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++#include ++ ++#define DBL_TARGSIGNATURE 0x544c4244 /* "TLBD" */ ++#define DBL_LIBSIGNATURE 0x4c4c4244 /* "LLBD" */ ++ ++#define C54TARG 0 ++#define C55TARG 1 ++#define NUMTARGS 2 ++ ++#define C54MAGIC 0x98 /* Magic number for TI C54 COF */ ++#define C55MAGIC 0x9c /* Magic number for LEAD3 (C55) COF */ ++ ++/* Three task phases */ ++#define CREATEPHASE 0 ++#define DELETEPHASE 1 ++#define EXECUTEPHASE 2 ++#define NONE 3 /* For overlay section with phase not specified */ ++ ++/* Default load buffer size */ ++#define LOADBUFSIZE 0x800 ++ ++#define SWAPLONG(x) ((((x) << 24) & 0xFF000000) | (((x) << 8) & 0xFF0000L) | \ ++ (((x) >> 8) & 0xFF00L) | (((x) >> 24) & 0xFF)) ++ ++#define SWAPWORD(x) ((((x) << 8) & 0xFF00) | (((x) >> 8) & 0xFF)) ++ ++/* ++ * Macros for accessing the following types of overlay data within a ++ * structure of type OvlyData: ++ * - Overlay data not associated with a particular phase ++ * - Create phase overlay data ++ * - Delete phase overlay data ++ * - Execute phase overlay data ++ */ ++#define numOtherSects(pOvlyData) ((pOvlyData)->hdr.dbofHdr.numOtherSects) ++#define numCreateSects(pOvlyData) ((pOvlyData)->hdr.dbofHdr.numCreateSects) ++#define numDeleteSects(pOvlyData) ((pOvlyData)->hdr.dbofHdr.numDeleteSects) ++#define numExecuteSects(pOvlyData) ((pOvlyData)->hdr.dbofHdr.numExecuteSects) ++#define otherOffset(pOvlyData) 0 ++#define createOffset(pOvlyData) ((pOvlyData)->hdr.dbofHdr.numOtherSects) ++#define deleteOffset(pOvlyData) (createOffset(pOvlyData) + \ ++ (pOvlyData->hdr.dbofHdr.numCreateSects)) ++#define executeOffset(pOvlyData) (deleteOffset(pOvlyData) + \ ++ (pOvlyData->hdr.dbofHdr.numDeleteSects)) ++/* ++ * ======== OvlyHdr ======== ++ */ ++struct OvlyHdr { ++ struct DBOF_OvlySectHdr dbofHdr; ++ char *pName; /* Name of overlay section */ ++ u16 createRef; /* Reference count for create phase */ ++ u16 deleteRef; /* Reference count for delete phase */ ++ u16 executeRef; /* Execute phase ref count */ ++ u16 otherRef; /* Unspecified phase ref count */ ++} ; ++ ++/* ++ * ======== OvlyData ======== ++ */ ++struct OvlyData { ++ struct OvlyHdr hdr; ++ struct DBOF_OvlySectData data[1]; ++} ; ++ ++/* ++ * ======== Symbol ======== ++ */ ++struct Symbol { ++ struct DBL_Symbol sym; ++ char *pSymName; ++}; ++ ++/* ++ * ======== DCDSect ======== ++ */ ++struct DCDSect { ++ struct DBOF_DCDSectHdr sectHdr; ++ char *pData; ++} ; ++ ++/* ++ * ======== DBL_TargetObj ======== ++ */ ++struct DBL_TargetObj { ++ u32 dwSignature; /* For object validation */ ++ struct DBL_Attrs dblAttrs; /* file read, write, etc. functions */ ++ char *pBuf; /* Load buffer */ ++}; ++ ++/* ++ * ======== TargetInfo ======== ++ */ ++struct TargetInfo { ++ u16 dspType; /* eg, C54TARG, C55TARG */ ++ u32 magic; /* COFF magic number, identifies target type */ ++ u16 wordSize; /* Size of a DSP word */ ++ u16 mauSize; /* Size of minimum addressable unit */ ++ u16 charSize; /* For C55x, mausize = 1, but charsize = 2 */ ++} ; ++ ++/* ++ * ======== DBL_LibraryObj ======== ++ * Represents a library loaded on a target. ++ */ ++struct DBL_LibraryObj { ++ u32 dwSignature; /* For object validation */ ++ struct DBL_TargetObj *pTarget; /* Target for this library */ ++ struct KFILE_FileObj *file; /* DBOF file handle */ ++ bool byteSwapped; /* Are bytes swapped? */ ++ struct DBOF_FileHdr fileHdr; /* Header of DBOF file */ ++ u16 nSymbols; /* Number of DSP/Bridge symbols */ ++ struct Symbol *symbols; /* Table of DSP/Bridge symbols */ ++ u16 nDCDSects; /* Number of DCD sections */ ++ u16 nOvlySects; /* Number of overlay nodes */ ++ struct DCDSect *dcdSects; /* DCD section data */ ++ struct OvlyData **ppOvlyData; /* Array of overlay section data */ ++ struct TargetInfo *pTargetInfo; /* Entry in targetTab[] below */ ++} ; ++ ++#if GT_TRACE ++static struct GT_Mask DBL_debugMask = { NULL, NULL }; /* GT trace variable */ ++#endif ++ ++static u32 cRefs; /* module reference count */ ++ ++static u32 magicTab[NUMTARGS] = { C54MAGIC, C55MAGIC }; ++ ++static struct TargetInfo targetTab[] = { ++ /* targ magic wordsize mausize charsize */ ++ {C54TARG, C54MAGIC, 2, 2, 2}, /* C54 */ ++ {C55TARG, C55MAGIC, 2, 1, 2}, /* C55 */ ++}; ++ ++static void freeSects(struct DBL_TargetObj *dbl, struct OvlyData *pOvlyData, ++ s32 offset, s32 nSects); ++static DSP_STATUS loadSect(struct DBL_TargetObj *dbl, ++ struct DBL_LibraryObj *pdblLib); ++static DSP_STATUS readDCDSects(struct DBL_TargetObj *dbl, ++ struct DBL_LibraryObj *pdblLib); ++static DSP_STATUS readHeader(struct DBL_TargetObj *dbl, ++ struct DBL_LibraryObj *pdblLib); ++static DSP_STATUS readOvlySects(struct DBL_TargetObj *dbl, ++ struct DBL_LibraryObj *pdblLib); ++static DSP_STATUS readSymbols(struct DBL_TargetObj *dbl, ++ struct DBL_LibraryObj *pdblLib); ++ ++/* ++ * ======== DBL_close ======== ++ * Purpose: ++ * Close library opened with DBL_open. ++ */ ++void DBL_close(struct DBL_LibraryObj *lib) ++{ ++ struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib; ++ u16 i; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE)); ++ ++ GT_1trace(DBL_debugMask, GT_ENTER, "DBL_close: lib: 0x%x\n", lib); ++ ++ /* Free symbols */ ++ if (pdblLib->symbols) { ++ for (i = 0; i < pdblLib->nSymbols; i++) { ++ if (pdblLib->symbols[i].pSymName) ++ MEM_Free(pdblLib->symbols[i].pSymName); ++ ++ } ++ MEM_Free(pdblLib->symbols); ++ } ++ ++ /* Free DCD sects */ ++ if (pdblLib->dcdSects) { ++ for (i = 0; i < pdblLib->nDCDSects; i++) { ++ if (pdblLib->dcdSects[i].pData) ++ MEM_Free(pdblLib->dcdSects[i].pData); ++ ++ } ++ MEM_Free(pdblLib->dcdSects); ++ } ++ ++ /* Free overlay sects */ ++ if (pdblLib->ppOvlyData) { ++ for (i = 0; i < pdblLib->nOvlySects; i++) { ++ if (pdblLib->ppOvlyData[i]) { ++ if (pdblLib->ppOvlyData[i]->hdr.pName) { ++ MEM_Free(pdblLib->ppOvlyData[i]-> ++ hdr.pName); ++ } ++ MEM_Free(pdblLib->ppOvlyData[i]); ++ } ++ } ++ MEM_Free(pdblLib->ppOvlyData); ++ } ++ ++ /* Close the file */ ++ if (pdblLib->file) ++ (*pdblLib->pTarget->dblAttrs.fclose) (pdblLib->file); ++ ++ ++ MEM_FreeObject(pdblLib); ++} ++ ++/* ++ * ======== DBL_create ======== ++ * Purpose: ++ * Create a target object by specifying the alloc, free, and ++ * write functions for the target. ++ */ ++DSP_STATUS DBL_create(struct DBL_TargetObj **pTarget, struct DBL_Attrs *pAttrs) ++{ ++ struct DBL_TargetObj *pdblTarget = NULL; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pAttrs != NULL); ++ DBC_Require(pTarget != NULL); ++ ++ GT_2trace(DBL_debugMask, GT_ENTER, ++ "DBL_create: pTarget: 0x%x pAttrs: 0x%x\n", ++ pTarget, pAttrs); ++ /* Allocate DBL target object */ ++ MEM_AllocObject(pdblTarget, struct DBL_TargetObj, DBL_TARGSIGNATURE); ++ if (pdblTarget == NULL) { ++ GT_0trace(DBL_debugMask, GT_6CLASS, ++ "DBL_create: Memory allocation failed\n"); ++ status = DSP_EMEMORY; ++ } else { ++ pdblTarget->dblAttrs = *pAttrs; ++ /* Allocate buffer for loading target */ ++ pdblTarget->pBuf = MEM_Calloc(LOADBUFSIZE, MEM_PAGED); ++ if (pdblTarget->pBuf == NULL) ++ status = DSP_EMEMORY; ++ ++ } ++ if (DSP_SUCCEEDED(status)) { ++ *pTarget = pdblTarget; ++ } else { ++ *pTarget = NULL; ++ if (pdblTarget) ++ DBL_delete(pdblTarget); ++ ++ } ++ DBC_Ensure(DSP_SUCCEEDED(status) && ++ ((MEM_IsValidHandle((*pTarget), DBL_TARGSIGNATURE)) || ++ (DSP_FAILED(status) && *pTarget == NULL))); ++ return status; ++} ++ ++/* ++ * ======== DBL_delete ======== ++ * Purpose: ++ * Delete target object and free resources for any loaded libraries. ++ */ ++void DBL_delete(struct DBL_TargetObj *target) ++{ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(target, DBL_TARGSIGNATURE)); ++ ++ GT_1trace(DBL_debugMask, GT_ENTER, ++ "DBL_delete: target: 0x%x\n", target); ++ ++ if (target->pBuf) ++ MEM_Free(target->pBuf); ++ ++ MEM_FreeObject(target); ++} ++ ++/* ++ * ======== DBL_exit ======== ++ * Purpose ++ * Discontinue usage of DBL module. ++ */ ++void DBL_exit() ++{ ++ DBC_Require(cRefs > 0); ++ cRefs--; ++ GT_1trace(DBL_debugMask, GT_5CLASS, ++ "DBL_exit() ref count: 0x%x\n", cRefs); ++ DBC_Ensure(cRefs >= 0); ++} ++ ++/* ++ * ======== DBL_getAddr ======== ++ * Purpose: ++ * Get address of name in the specified library. ++ */ ++bool DBL_getAddr(struct DBL_LibraryObj *lib, char *name, ++ struct DBL_Symbol **ppSym) ++{ ++ bool retVal = false; ++ struct Symbol *symbol; ++ u16 i; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE)); ++ DBC_Require(name != NULL); ++ DBC_Require(ppSym != NULL); ++ ++ GT_3trace(DBL_debugMask, GT_ENTER, ++ "DBL_getAddr: libt: 0x%x name: %s pAddr: " ++ "0x%x\n", lib, name, ppSym); ++ for (i = 0; i < lib->nSymbols; i++) { ++ symbol = &lib->symbols[i]; ++ if (CSL_Strcmp(name, symbol->pSymName) == 0) { ++ /* Found it */ ++ *ppSym = &lib->symbols[i].sym; ++ retVal = true; ++ break; ++ } ++ } ++ return retVal; ++} ++ ++/* ++ * ======== DBL_getAttrs ======== ++ * Purpose: ++ * Retrieve the attributes of the target. ++ */ ++void DBL_getAttrs(struct DBL_TargetObj *target, struct DBL_Attrs *pAttrs) ++{ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(target, DBL_TARGSIGNATURE)); ++ DBC_Require(pAttrs != NULL); ++ GT_2trace(DBL_debugMask, GT_ENTER, "DBL_getAttrs: target: 0x%x pAttrs: " ++ "0x%x\n", target, pAttrs); ++ *pAttrs = target->dblAttrs; ++} ++ ++/* ++ * ======== DBL_getCAddr ======== ++ * Purpose: ++ * Get address of "C" name in the specified library. ++ */ ++bool DBL_getCAddr(struct DBL_LibraryObj *lib, char *name, ++ struct DBL_Symbol **ppSym) ++{ ++ bool retVal = false; ++ struct Symbol *symbol; ++ u16 i; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE)); ++ DBC_Require(name != NULL); ++ DBC_Require(ppSym != NULL); ++ ++ GT_3trace(DBL_debugMask, GT_ENTER, ++ "DBL_getCAddr: target: 0x%x name:%s pAddr:" ++ " 0x%x\n", lib, name, ppSym); ++ for (i = 0; i < lib->nSymbols; i++) { ++ symbol = &lib->symbols[i]; ++ if ((CSL_Strcmp(name, symbol->pSymName) == 0) || ++ (CSL_Strcmp(name, symbol->pSymName + 1) == 0 && ++ symbol->pSymName[0] == '_')) { ++ /* Found it */ ++ *ppSym = &lib->symbols[i].sym; ++ retVal = true; ++ break; ++ } ++ } ++ return retVal; ++} ++ ++/* ++ * ======== DBL_getEntry ======== ++ * Purpose: ++ * Get program entry point. ++ * ++ */ ++bool DBL_getEntry(struct DBL_LibraryObj *lib, u32 *pEntry) ++{ ++ struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE)); ++ DBC_Require(pEntry != NULL); ++ ++ GT_2trace(DBL_debugMask, GT_ENTER, ++ "DBL_getEntry: lib: 0x%x pEntry: 0x%x\n", lib, pEntry); ++ *pEntry = pdblLib->fileHdr.entry; ++ ++ return true; ++} ++ ++/* ++ * ======== DBL_getSect ======== ++ * Purpose: ++ * Get address and size of a named section. ++ */ ++DSP_STATUS DBL_getSect(struct DBL_LibraryObj *lib, char *name, u32 *pAddr, ++ u32 *pSize) ++{ ++ struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib; ++ u16 i; ++ DSP_STATUS status = DSP_ENOSECT; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(name != NULL); ++ DBC_Require(pAddr != NULL); ++ DBC_Require(pSize != NULL); ++ DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE)); ++ ++ GT_4trace(DBL_debugMask, GT_ENTER, ++ "DBL_getSect: lib: 0x%x name: %s pAddr:" ++ " 0x%x pSize: 0x%x\n", lib, name, pAddr, pSize); ++ ++ /* ++ * Check for DCD and overlay sections. Overlay loader uses DBL_getSect ++ * to determine whether or not a node has overlay sections. ++ * DCD section names begin with '.' ++ */ ++ if (name[0] == '.') { ++ /* Get DCD section size (address is 0, since it's a NOLOAD). */ ++ for (i = 0; i < pdblLib->nDCDSects; i++) { ++ if (CSL_Strcmp(pdblLib->dcdSects[i].sectHdr.name, ++ name) == 0) { ++ *pAddr = 0; ++ *pSize = pdblLib->dcdSects[i].sectHdr.size * ++ pdblLib->pTargetInfo->mauSize; ++ status = DSP_SOK; ++ break; ++ } ++ } ++ } else { ++ /* Check for overlay section */ ++ for (i = 0; i < pdblLib->nOvlySects; i++) { ++ if (CSL_Strcmp(pdblLib->ppOvlyData[i]->hdr.pName, ++ name) == 0) { ++ /* Address and size are meaningless */ ++ *pAddr = 0; ++ *pSize = 0; ++ status = DSP_SOK; ++ break; ++ } ++ } ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== DBL_init ======== ++ * Purpose: ++ * Initialize DBL module. ++ */ ++bool DBL_init(void) ++{ ++ bool retVal = true; ++ ++ DBC_Require(cRefs >= 0); ++ ++ if (cRefs == 0) { ++ DBC_Assert(!DBL_debugMask.flags); ++ GT_create(&DBL_debugMask, "BL"); /* "BL" for dBL */ ++ ++ } ++ ++ if (retVal) ++ cRefs++; ++ ++ ++ GT_1trace(DBL_debugMask, GT_5CLASS, "DBL_init(), ref count: 0x%x\n", ++ cRefs); ++ ++ DBC_Ensure((retVal && (cRefs > 0)) || (!retVal && (cRefs >= 0))); ++ ++ return retVal; ++} ++ ++/* ++ * ======== DBL_load ======== ++ * Purpose: ++ * Add symbols/code/data defined in file to that already present ++ * on the target. ++ */ ++DSP_STATUS DBL_load(struct DBL_LibraryObj *lib, DBL_Flags flags, ++ struct DBL_Attrs *attrs, u32 *pEntry) ++{ ++ struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib; ++ struct DBL_TargetObj *dbl; ++ u16 i; ++ u16 nSects; ++ DSP_STATUS status = DSP_EFAIL; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE)); ++ DBC_Require(pEntry != NULL); ++ DBC_Require(attrs != NULL); ++ ++ GT_4trace(DBL_debugMask, GT_ENTER, "DBL_load: lib: 0x%x flags: " ++ "0x%x attrs: 0x%x pEntry: 0x%x\n", lib, flags, attrs, pEntry); ++ ++ dbl = pdblLib->pTarget; ++ *pEntry = pdblLib->fileHdr.entry; ++ nSects = pdblLib->fileHdr.numSects; ++ dbl->dblAttrs = *attrs; ++ ++ for (i = 0; i < nSects; i++) { ++ /* Load the section at the current file offset */ ++ status = loadSect(dbl, lib); ++ if (DSP_FAILED(status)) ++ break; ++ ++ } ++ ++ /* Done with file, we can close it */ ++ if (pdblLib->file) { ++ (*pdblLib->pTarget->dblAttrs.fclose) (pdblLib->file); ++ pdblLib->file = NULL; ++ } ++ return status; ++} ++ ++/* ++ * ======== DBL_loadSect ======== ++ * Purpose: ++ * Load a named section from an library (for overlay support). ++ */ ++DSP_STATUS DBL_loadSect(struct DBL_LibraryObj *lib, char *sectName, ++ struct DBL_Attrs *attrs) ++{ ++ struct DBL_TargetObj *dbl; ++ s32 i; ++ s32 phase; ++ s32 offset = -1; ++ s32 nSects = -1; ++ s32 allocdSects = 0; ++ u32 loadAddr; ++ u32 runAddr; ++ u32 size; ++ u32 space; ++ u32 ulBytes; ++ u16 mauSize; ++ u16 wordSize; ++ u16 *phaseRef = NULL; ++ u16 *otherRef = NULL; ++ char *name = NULL; ++ struct OvlyData *pOvlyData; ++ DSP_STATUS status = DSP_ENOSECT; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE)); ++ DBC_Require(sectName != NULL); ++ DBC_Require(attrs != NULL); ++ DBC_Require(attrs->write != NULL); ++ GT_3trace(DBL_debugMask, GT_ENTER, ++ "DBL_loadSect: lib: 0x%x sectName: %s " ++ "attrs: 0x%x\n", lib, sectName, attrs); ++ dbl = lib->pTarget; ++ mauSize = lib->pTargetInfo->mauSize; ++ wordSize = lib->pTargetInfo->wordSize; ++ /* Check for match of sect name in overlay table */ ++ for (i = 0; i < lib->nOvlySects; i++) { ++ name = lib->ppOvlyData[i]->hdr.pName; ++ if (!CSL_Strncmp(name, sectName, CSL_Strlen(name))) { ++ /* Match found */ ++ status = DSP_SOK; ++ break; ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ DBC_Assert(i < lib->nOvlySects); ++ pOvlyData = lib->ppOvlyData[i]; ++ /* ++ * If node overlay, phase will be encoded in name. If not node ++ * overlay, set phase to NONE. ++ */ ++ phase = (CSL_Strcmp(name, sectName)) ? ++ CSL_Atoi(sectName + CSL_Strlen(sectName) - 1) : NONE; ++ /* Get reference count of node phase to be loaded, offset into ++ * overlay data array, and number of sections to overlay. */ ++ switch (phase) { ++ case NONE: ++ /* Not a node overlay */ ++ phaseRef = &pOvlyData->hdr.otherRef; ++ nSects = numOtherSects(pOvlyData); ++ offset = otherOffset(pOvlyData); ++ break; ++ case CREATEPHASE: ++ phaseRef = &pOvlyData->hdr.createRef; ++ otherRef = &pOvlyData->hdr.otherRef; ++ if (*otherRef) { ++ /* The overlay sections where node phase was ++ * not specified, have already been loaded. */ ++ nSects = numCreateSects(pOvlyData); ++ offset = createOffset(pOvlyData); ++ } else { ++ /* Overlay sections where node phase was not ++ * specified get loaded at create time, along ++ * with create sects. */ ++ nSects = numCreateSects(pOvlyData) + ++ numOtherSects(pOvlyData); ++ offset = otherOffset(pOvlyData); ++ } ++ break; ++ case DELETEPHASE: ++ phaseRef = &pOvlyData->hdr.deleteRef; ++ nSects = numDeleteSects(pOvlyData); ++ offset = deleteOffset(pOvlyData); ++ break; ++ case EXECUTEPHASE: ++ phaseRef = &pOvlyData->hdr.executeRef; ++ nSects = numExecuteSects(pOvlyData); ++ offset = executeOffset(pOvlyData); ++ break; ++ default: ++ /* ERROR */ ++ DBC_Assert(false); ++ break; ++ } ++ /* Do overlay if reference count is 0 */ ++ if (!(*phaseRef)) { ++ /* "Allocate" all sections */ ++ for (i = 0; i < nSects; i++) { ++ runAddr = pOvlyData->data[offset + i].runAddr; ++ size = pOvlyData->data[offset + i].size; ++ space = pOvlyData->data[offset + i].page; ++ status = (dbl->dblAttrs.alloc)(dbl->dblAttrs. ++ rmmHandle, space, size, 0, ++ &runAddr, true); ++ if (DSP_FAILED(status)) ++ break; ++ ++ allocdSects++; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Load sections */ ++ for (i = 0; i < nSects; i++) { ++ loadAddr = pOvlyData->data[offset + i]. ++ loadAddr; ++ runAddr = pOvlyData->data[offset + i]. ++ runAddr; ++ size = pOvlyData->data[offset + i]. ++ size; ++ space = pOvlyData->data[offset + i]. ++ page; ++ /* Convert to word address, call ++ * write function */ ++ loadAddr /= (wordSize / mauSize); ++ runAddr /= (wordSize / mauSize); ++ ulBytes = size * mauSize; ++ if ((*attrs->write)(attrs->wHandle, ++ runAddr, (void *)loadAddr, ulBytes, ++ space) != ulBytes) { ++ GT_0trace(DBL_debugMask, ++ GT_6CLASS, ++ "DBL_loadSect: write" ++ " failed\n"); ++ status = DSP_EFWRITE; ++ break; ++ } ++ } ++ } ++ /* Free sections on failure */ ++ if (DSP_FAILED(status)) ++ freeSects(dbl, pOvlyData, offset, allocdSects); ++ ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Increment reference counts */ ++ if (otherRef) ++ *otherRef = *otherRef + 1; ++ ++ *phaseRef = *phaseRef + 1; ++ } ++ return status; ++} ++ ++/* ++ * ======== DBL_open ======== ++ * Purpose: ++ * DBL_open() returns a library handle that can be used to ++ * load/unload the symbols/code/data via DBL_load()/DBL_unload(). ++ */ ++DSP_STATUS DBL_open(struct DBL_TargetObj *target, char *file, DBL_Flags flags, ++ struct DBL_LibraryObj **pLib) ++{ ++ struct DBL_LibraryObj *pdblLib = NULL; ++ u16 nSymbols; ++ u16 nDCDSects; ++ DSP_STATUS status = DSP_SOK; ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(target, DBL_TARGSIGNATURE)); ++ DBC_Require(target->dblAttrs.fopen != NULL); ++ DBC_Require(file != NULL); ++ DBC_Require(pLib != NULL); ++ ++ GT_3trace(DBL_debugMask, GT_ENTER, "DBL_open: target: 0x%x file: %s " ++ "pLib: 0x%x\n", target, file, pLib); ++ /* Allocate DBL library object */ ++ MEM_AllocObject(pdblLib, struct DBL_LibraryObj, DBL_LIBSIGNATURE); ++ if (pdblLib == NULL) ++ status = DSP_EMEMORY; ++ ++ /* Open the file */ ++ if (DSP_SUCCEEDED(status)) { ++ pdblLib->pTarget = target; ++ pdblLib->file = (*target->dblAttrs.fopen)(file, "rb"); ++ if (pdblLib->file == NULL) ++ status = DSP_EFOPEN; ++ ++ } ++ /* Read file header */ ++ if (DSP_SUCCEEDED(status)) { ++ status = readHeader(target, pdblLib); ++ if (DSP_FAILED(status)) { ++ GT_0trace(DBL_debugMask, GT_6CLASS, ++ "DBL_open(): Failed to read file header\n"); ++ } ++ } ++ /* Allocate symbol table */ ++ if (DSP_SUCCEEDED(status)) { ++ nSymbols = pdblLib->nSymbols = pdblLib->fileHdr.numSymbols; ++ pdblLib->symbols = MEM_Calloc(nSymbols * sizeof(struct Symbol), ++ MEM_PAGED); ++ if (pdblLib->symbols == NULL) ++ status = DSP_EMEMORY; ++ ++ } ++ /* Read all the symbols */ ++ if (DSP_SUCCEEDED(status)) { ++ status = readSymbols(target, pdblLib); ++ if (DSP_FAILED(status)) { ++ GT_0trace(DBL_debugMask, GT_6CLASS, ++ "DBL_open(): Failed to read symbols\n"); ++ } ++ } ++ /* Allocate DCD sect table */ ++ if (DSP_SUCCEEDED(status)) { ++ nDCDSects = pdblLib->nDCDSects = pdblLib->fileHdr.numDCDSects; ++ pdblLib->dcdSects = MEM_Calloc(nDCDSects * ++ sizeof(struct DCDSect), MEM_PAGED); ++ if (pdblLib->dcdSects == NULL) ++ status = DSP_EMEMORY; ++ ++ } ++ /* Read DCD sections */ ++ if (DSP_SUCCEEDED(status)) { ++ status = readDCDSects(target, pdblLib); ++ if (DSP_FAILED(status)) { ++ GT_0trace(DBL_debugMask, GT_6CLASS, ++ "DBL_open(): Failed to read DCD sections\n"); ++ } ++ } ++ /* Read overlay sections */ ++ if (DSP_SUCCEEDED(status)) { ++ status = readOvlySects(target, pdblLib); ++ if (DSP_FAILED(status)) { ++ GT_0trace(DBL_debugMask, GT_6CLASS, ++ "DBL_open(): Failed to read " ++ "overlay sections\n"); ++ } ++ } ++ if (DSP_FAILED(status)) { ++ *pLib = NULL; ++ if (pdblLib != NULL) ++ DBL_close((struct DBL_LibraryObj *) pdblLib); ++ ++ } else { ++ *pLib = pdblLib; ++ } ++ DBC_Ensure((DSP_SUCCEEDED(status) && ++ (MEM_IsValidHandle((*pLib), DBL_LIBSIGNATURE))) || ++ (DSP_FAILED(status) && *pLib == NULL)); ++ return status; ++} ++ ++/* ++ * ======== DBL_readSect ======== ++ * Purpose: ++ * Read COFF section into a character buffer. ++ */ ++DSP_STATUS DBL_readSect(struct DBL_LibraryObj *lib, char *name, char *pContent, ++ u32 size) ++{ ++ struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib; ++ u16 i; ++ u32 mauSize; ++ u32 max; ++ DSP_STATUS status = DSP_ENOSECT; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE)); ++ DBC_Require(name != NULL); ++ DBC_Require(pContent != NULL); ++ DBC_Require(size != 0); ++ GT_4trace(DBL_debugMask, GT_ENTER, "DBL_readSect: lib: 0x%x name: %s " ++ "pContent: 0x%x size: 0x%x\n", lib, name, pContent, size); ++ ++ mauSize = pdblLib->pTargetInfo->mauSize; ++ ++ /* Attempt to find match with DCD section names. */ ++ for (i = 0; i < pdblLib->nDCDSects; i++) { ++ if (CSL_Strcmp(pdblLib->dcdSects[i].sectHdr.name, name) == 0) { ++ /* Match found */ ++ max = pdblLib->dcdSects[i].sectHdr.size * mauSize; ++ max = (max > size) ? size : max; ++ memcpy(pContent, pdblLib->dcdSects[i].pData, max); ++ status = DSP_SOK; ++ break; ++ } ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== DBL_setAttrs ======== ++ * Purpose: ++ * Set the attributes of the target. ++ */ ++void DBL_setAttrs(struct DBL_TargetObj *target, struct DBL_Attrs *pAttrs) ++{ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(target, DBL_TARGSIGNATURE)); ++ DBC_Require(pAttrs != NULL); ++ ++ GT_2trace(DBL_debugMask, GT_ENTER, "DBL_setAttrs: target: 0x%x pAttrs: " ++ "0x%x\n", target, pAttrs); ++ ++ target->dblAttrs = *pAttrs; ++} ++ ++/* ++ * ======== DBL_unload ======== ++ * Purpose: ++ * Remove the symbols/code/data corresponding to the library lib. ++ */ ++void DBL_unload(struct DBL_LibraryObj *lib, struct DBL_Attrs *attrs) ++{ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE)); ++ ++ GT_1trace(DBL_debugMask, GT_ENTER, "DBL_unload: lib: 0x%x\n", lib); ++ ++ /* Nothing to do for static loading */ ++} ++ ++/* ++ * ======== DBL_unloadSect ======== ++ * Purpose: ++ * Unload a named section from an library (for overlay support). ++ */ ++DSP_STATUS DBL_unloadSect(struct DBL_LibraryObj *lib, char *sectName, ++ struct DBL_Attrs *attrs) ++{ ++ struct DBL_TargetObj *dbl; ++ s32 i; ++ s32 phase; ++ s32 offset = -1; ++ s32 nSects = -1; ++ u16 *phaseRef = NULL; ++ u16 *otherRef = NULL; ++ char *pName = NULL; ++ struct OvlyData *pOvlyData; ++ DSP_STATUS status = DSP_ENOSECT; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE)); ++ DBC_Require(sectName != NULL); ++ ++ GT_2trace(DBL_debugMask, GT_ENTER, ++ "DBL_unloadSect: lib: 0x%x sectName: %s\n", lib, sectName); ++ dbl = lib->pTarget; ++ /* Check for match of sect name in overlay table */ ++ for (i = 0; i < lib->nOvlySects; i++) { ++ pName = lib->ppOvlyData[i]->hdr.pName; ++ if (!CSL_Strncmp(pName, sectName, CSL_Strlen(pName))) { ++ /* Match found */ ++ status = DSP_SOK; ++ break; ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ DBC_Assert(i < lib->nOvlySects); ++ pOvlyData = lib->ppOvlyData[i]; ++ /* If node overlay, phase will be encoded in name. */ ++ phase = (CSL_Strcmp(pName, sectName)) ? ++ CSL_Atoi(sectName + CSL_Strlen(sectName) - 1) : NONE; ++ switch (phase) { ++ case NONE: ++ nSects = numOtherSects(pOvlyData); ++ phaseRef = &pOvlyData->hdr.otherRef; ++ offset = otherOffset(pOvlyData); ++ break; ++ case CREATEPHASE: ++ nSects = numCreateSects(pOvlyData); ++ offset = createOffset(pOvlyData); ++ phaseRef = &pOvlyData->hdr.createRef; ++ break; ++ case DELETEPHASE: ++ nSects = numDeleteSects(pOvlyData); ++ offset = deleteOffset(pOvlyData); ++ phaseRef = &pOvlyData->hdr.deleteRef; ++ otherRef = &pOvlyData->hdr.otherRef; ++ break; ++ case EXECUTEPHASE: ++ nSects = numExecuteSects(pOvlyData); ++ offset = executeOffset(pOvlyData); ++ phaseRef = &pOvlyData->hdr.executeRef; ++ break; ++ default: ++ /* ERROR */ ++ DBC_Assert(false); ++ break; ++ } ++ if (*phaseRef) { ++ *phaseRef = *phaseRef - 1; ++ if (*phaseRef == 0) { ++ /* Unload overlay sections for phase */ ++ freeSects(dbl, pOvlyData, offset, nSects); ++ } ++ if (phase == DELETEPHASE) { ++ DBC_Assert(*otherRef); ++ *otherRef = *otherRef - 1; ++ if (*otherRef == 0) { ++ /* Unload other overlay sections */ ++ nSects = numOtherSects(pOvlyData); ++ offset = otherOffset(pOvlyData); ++ freeSects(dbl, pOvlyData, offset, ++ nSects); ++ } ++ } ++ } ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== freeSects ======== ++ * Purpose: ++ * Free section ++ */ ++static void freeSects(struct DBL_TargetObj *dbl, struct OvlyData *pOvlyData, ++ s32 offset, s32 nSects) ++{ ++ u32 runAddr; ++ u32 size; ++ u32 space; ++ s32 i; ++ ++ for (i = 0; i < nSects; i++) { ++ runAddr = pOvlyData->data[offset + i].runAddr; ++ size = pOvlyData->data[offset + i].size; ++ space = pOvlyData->data[offset + i].page; ++ if (!(dbl->dblAttrs.free) ++ (dbl->dblAttrs.rmmHandle, space, runAddr, size, true)) { ++ /* ++ * Free function will not fail for overlay, unless ++ * address passed in is bad. ++ */ ++ DBC_Assert(false); ++ } ++ } ++} ++ ++/* ++ * ======== loadSect ======== ++ * Purpose: ++ * Load section to target ++ */ ++static DSP_STATUS loadSect(struct DBL_TargetObj *dbl, ++ struct DBL_LibraryObj *pdblLib) ++{ ++ struct DBOF_SectHdr sectHdr; ++ char *pBuf; ++ struct KFILE_FileObj *file; ++ u32 space; ++ u32 addr; ++ u32 total; ++ u32 nWords = 0; ++ u32 nBytes = 0; ++ u16 mauSize; ++ u32 bufSize; ++ DSP_STATUS status = DSP_SOK; ++ ++ file = pdblLib->file; ++ mauSize = pdblLib->pTargetInfo->mauSize; ++ bufSize = LOADBUFSIZE / mauSize; ++ pBuf = dbl->pBuf; ++ ++ /* Read the section header */ ++ if ((*dbl->dblAttrs.fread)(§Hdr, sizeof(struct DBOF_SectHdr), ++ 1, file) != 1) { ++ GT_0trace(DBL_debugMask, GT_6CLASS, ++ "Failed to read DCD sect header\n"); ++ status = DSP_EFREAD; ++ } else { ++ if (pdblLib->byteSwapped) { ++ sectHdr.size = SWAPLONG(sectHdr.size); ++ sectHdr.addr = SWAPLONG(sectHdr.addr); ++ sectHdr.page = SWAPWORD(sectHdr.page); ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ addr = sectHdr.addr; ++ space = sectHdr.page; ++ for (total = sectHdr.size; total > 0; total -= nWords) { ++ nWords = min(total, bufSize); ++ nBytes = nWords * mauSize; ++ /* Read section data */ ++ if ((*dbl->dblAttrs.fread)(pBuf, nBytes, 1, ++ file) != 1) { ++ GT_0trace(DBL_debugMask, GT_6CLASS, ++ "Failed to read DCD sect header\n"); ++ status = DSP_EFREAD; ++ break; ++ } ++ /* Write section to target */ ++ if (!(*dbl->dblAttrs.write)(dbl->dblAttrs.wHandle, ++ addr, pBuf, nBytes, space)) { ++ GT_0trace(DBL_debugMask, GT_6CLASS, ++ "Failed to write section data\n"); ++ status = DSP_EFWRITE; ++ break; ++ } ++ addr += nWords; ++ } ++ } ++ return status; ++} ++ ++/* ++ * ======== readDCDSects ======== ++ * Purpose: ++ * Read DCD sections. ++ */ ++static DSP_STATUS readDCDSects(struct DBL_TargetObj *dbl, ++ struct DBL_LibraryObj *pdblLib) ++{ ++ struct DBOF_DCDSectHdr *pSectHdr; ++ struct DCDSect *pSect; ++ struct KFILE_FileObj *file; ++ u16 nSects; ++ u16 i; ++ u16 mauSize; ++ DSP_STATUS status = DSP_SOK; ++ ++ file = pdblLib->file; ++ mauSize = pdblLib->pTargetInfo->mauSize; ++ nSects = pdblLib->fileHdr.numDCDSects; ++ for (i = 0; i < nSects; i++) { ++ pSect = &pdblLib->dcdSects[i]; ++ pSectHdr = &pdblLib->dcdSects[i].sectHdr; ++ /* Read sect header */ ++ if ((*dbl->dblAttrs.fread)(pSectHdr, ++ sizeof(struct DBOF_DCDSectHdr), 1, file) != 1) { ++ GT_0trace(DBL_debugMask, GT_6CLASS, ++ "Failed to read DCD sect header\n"); ++ status = DSP_EFREAD; ++ break; ++ } ++ if (pdblLib->byteSwapped) ++ pSectHdr->size = SWAPLONG(pSectHdr->size); ++ ++ pSect->pData = (char *)MEM_Calloc(pSectHdr->size * ++ mauSize, MEM_PAGED); ++ if (pSect->pData == NULL) { ++ GT_2trace(DBL_debugMask, GT_6CLASS, ++ "Memory allocation for sect %s " ++ "data failed: Size: 0x%lx\n", pSectHdr->name, ++ pSectHdr->size); ++ status = DSP_EMEMORY; ++ break; ++ } ++ /* Read DCD sect data */ ++ if ((*dbl->dblAttrs.fread)(pSect->pData, mauSize, ++ pSectHdr->size, file) != pSectHdr->size) { ++ GT_0trace(DBL_debugMask, GT_6CLASS, ++ "Failed to read DCD sect data\n"); ++ status = DSP_EFREAD; ++ break; ++ } ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== readHeader ======== ++ * Purpose: ++ * Read Header. ++ */ ++static DSP_STATUS readHeader(struct DBL_TargetObj *dbl, ++ struct DBL_LibraryObj *pdblLib) ++{ ++ struct KFILE_FileObj *file; ++ s32 i; ++ struct DBOF_FileHdr *pHdr; ++ u32 swapMagic; ++ DSP_STATUS status = DSP_SOK; ++ ++ pdblLib->byteSwapped = false; ++ file = pdblLib->file; ++ pHdr = &pdblLib->fileHdr; ++ if ((*dbl->dblAttrs.fread)(pHdr, sizeof(struct DBOF_FileHdr), 1, ++ file) != 1) { ++ GT_0trace(DBL_debugMask, GT_6CLASS, ++ "readHeader: Failed to read file header\n"); ++ status = DSP_EFREAD; ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* Determine if byte swapped */ ++ for (i = 0; i < NUMTARGS; i++) { ++ swapMagic = SWAPLONG(pHdr->magic); ++ if (pHdr->magic == magicTab[i] || swapMagic == ++ magicTab[i]) { ++ if (swapMagic == magicTab[i]) { ++ pdblLib->byteSwapped = true; ++ pHdr->magic = SWAPLONG(pHdr->magic); ++ pHdr->entry = SWAPLONG(pHdr->entry); ++ pHdr->symOffset = SWAPLONG(pHdr-> ++ symOffset); ++ pHdr->dcdSectOffset = SWAPLONG(pHdr-> ++ dcdSectOffset); ++ pHdr->loadSectOffset = SWAPLONG(pHdr-> ++ loadSectOffset); ++ pHdr->ovlySectOffset = SWAPLONG(pHdr-> ++ ovlySectOffset); ++ pHdr->numSymbols = SWAPWORD(pHdr-> ++ numSymbols); ++ pHdr->numDCDSects = SWAPWORD(pHdr-> ++ numDCDSects); ++ pHdr->numSects = SWAPWORD(pHdr-> ++ numSects); ++ pHdr->numOvlySects = SWAPWORD(pHdr-> ++ numOvlySects); ++ } ++ break; ++ } ++ } ++ if (i == NUMTARGS) { ++ GT_0trace(DBL_debugMask, GT_6CLASS, ++ "readHeader: Failed to determine" ++ " target type\n"); ++ status = DSP_ECORRUPTFILE; ++ } else { ++ pdblLib->pTargetInfo = &targetTab[i]; ++ GT_1trace(DBL_debugMask, GT_ENTER, ++ "COF type: 0x%lx\n", pHdr->magic); ++ GT_1trace(DBL_debugMask, GT_ENTER, ++ "Entry point:0x%lx\n", pHdr->entry); ++ } ++ } ++ return status; ++} ++ ++/* ++ * ======== readOvlySects ======== ++ * Purpose: ++ * Read Overlay Sections ++ */ ++static DSP_STATUS readOvlySects(struct DBL_TargetObj *dbl, ++ struct DBL_LibraryObj *pdblLib) ++{ ++ struct DBOF_OvlySectHdr hdr; ++ struct DBOF_OvlySectData *pData; ++ struct OvlyData *pOvlyData; ++ char *pName; ++ struct KFILE_FileObj *file; ++ u16 i, j; ++ u16 nSects; ++ u16 n; ++ DSP_STATUS status = DSP_SOK; ++ ++ pdblLib->nOvlySects = nSects = pdblLib->fileHdr.numOvlySects; ++ file = pdblLib->file; ++ if (nSects > 0) { ++ pdblLib->ppOvlyData = MEM_Calloc(nSects * sizeof(OvlyData *), ++ MEM_PAGED); ++ if (pdblLib->ppOvlyData == NULL) { ++ GT_0trace(DBL_debugMask, GT_7CLASS, ++ "Failed to allocatate overlay " ++ "data memory\n"); ++ status = DSP_EMEMORY; ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Read overlay data for each node */ ++ for (i = 0; i < nSects; i++) { ++ /* Read overlay section header */ ++ if ((*dbl->dblAttrs.fread)(&hdr, ++ sizeof(struct DBOF_OvlySectHdr), 1, file) != 1) { ++ GT_0trace(DBL_debugMask, GT_6CLASS, ++ "Failed to read overlay sect" ++ " header\n"); ++ status = DSP_EFREAD; ++ break; ++ } ++ if (pdblLib->byteSwapped) { ++ hdr.nameLen = SWAPWORD(hdr.nameLen); ++ hdr.numCreateSects = ++ SWAPWORD(hdr.numCreateSects); ++ hdr.numDeleteSects = ++ SWAPWORD(hdr.numDeleteSects); ++ hdr.numExecuteSects = ++ SWAPWORD(hdr.numExecuteSects); ++ hdr.numOtherSects = ++ SWAPWORD(hdr.numOtherSects); ++ hdr.resvd = SWAPWORD(hdr.resvd); ++ } ++ n = hdr.numCreateSects + hdr.numDeleteSects + ++ hdr.numExecuteSects + hdr.numOtherSects; ++ ++ /* Allocate memory for node's overlay data */ ++ pOvlyData = (struct OvlyData *)MEM_Calloc ++ (sizeof(struct OvlyHdr) + ++ n * sizeof(struct DBOF_OvlySectData), ++ MEM_PAGED); ++ if (pOvlyData == NULL) { ++ GT_0trace(DBL_debugMask, GT_7CLASS, ++ "Failed to allocatate ovlyay" ++ " data memory\n"); ++ status = DSP_EMEMORY; ++ break; ++ } ++ pOvlyData->hdr.dbofHdr = hdr; ++ pdblLib->ppOvlyData[i] = pOvlyData; ++ /* Allocate memory for section name */ ++ pName = (char *)MEM_Calloc(hdr.nameLen + 1, MEM_PAGED); ++ if (pName == NULL) { ++ GT_0trace(DBL_debugMask, GT_7CLASS, ++ "Failed to allocatate ovlyay" ++ " section name\n"); ++ status = DSP_EMEMORY; ++ break; ++ } ++ pOvlyData->hdr.pName = pName; ++ /* Read the overlay section name */ ++ if ((*dbl->dblAttrs.fread)(pName, sizeof(char), ++ hdr.nameLen, file) != hdr.nameLen) { ++ GT_0trace(DBL_debugMask, GT_7CLASS, ++ "readOvlySects: Unable to " ++ "read overlay name.\n"); ++ status = DSP_EFREAD; ++ break; ++ } ++ /* Read the overlay section data */ ++ pData = pOvlyData->data; ++ if ((*dbl->dblAttrs.fread)(pData, ++ sizeof(struct DBOF_OvlySectData), n, file) != n) { ++ GT_0trace(DBL_debugMask, GT_7CLASS, ++ "readOvlySects: Unable to " ++ "read overlay data.\n"); ++ status = DSP_EFREAD; ++ break; ++ } ++ /* Swap overlay data, if necessary */ ++ if (pdblLib->byteSwapped) { ++ for (j = 0; j < n; j++) { ++ pData[j].loadAddr = ++ SWAPLONG(pData[j].loadAddr); ++ pData[j].runAddr = ++ SWAPLONG(pData[j].runAddr); ++ pData[j].size = ++ SWAPLONG(pData[j].size); ++ pData[j].page = ++ SWAPWORD(pData[j].page); ++ } ++ } ++ } ++ } ++ return status; ++} ++ ++/* ++ * ======== readSymbols ======== ++ * Purpose: ++ * Read Symbols ++ */ ++static DSP_STATUS readSymbols(struct DBL_TargetObj *dbl, ++ struct DBL_LibraryObj *pdblLib) ++{ ++ struct DBOF_SymbolHdr symHdr; ++ struct KFILE_FileObj *file; ++ u16 i; ++ u16 nSymbols; ++ u16 len; ++ char *pName = NULL; ++ DSP_STATUS status = DSP_SOK; ++ ++ file = pdblLib->file; ++ ++ nSymbols = pdblLib->fileHdr.numSymbols; ++ ++ for (i = 0; i < nSymbols; i++) { ++ /* Read symbol value */ ++ if ((*dbl->dblAttrs.fread)(&symHdr, ++ sizeof(struct DBOF_SymbolHdr), 1, file) != 1) { ++ GT_0trace(DBL_debugMask, GT_6CLASS, ++ "Failed to read symbol value\n"); ++ status = DSP_EFREAD; ++ break; ++ } ++ if (pdblLib->byteSwapped) { ++ symHdr.nameLen = SWAPWORD(symHdr.nameLen); ++ symHdr.value = SWAPLONG(symHdr.value); ++ } ++ /* Allocate buffer for symbol name */ ++ len = symHdr.nameLen; ++ pName = (char *)MEM_Calloc(len + 1, MEM_PAGED); ++ if (pName == NULL) { ++ GT_0trace(DBL_debugMask, GT_6CLASS, ++ "Memory allocation failed\n"); ++ status = DSP_EMEMORY; ++ break; ++ } ++ pdblLib->symbols[i].pSymName = pName; ++ pdblLib->symbols[i].sym.value = symHdr.value; ++ /* Read symbol name */ ++ if ((*dbl->dblAttrs.fread) (pName, sizeof(char), len, file) != ++ len) { ++ GT_0trace(DBL_debugMask, GT_6CLASS, ++ "Failed to read symbol value\n"); ++ status = DSP_EFREAD; ++ break; ++ } else { ++ pName[len] = '\0'; ++ GT_2trace(DBL_debugMask, GT_ENTER, ++ "Symbol: %s Value: 0x%lx\n", ++ pName, symHdr.value); ++ } ++ } ++ return status; ++} ++ +diff --git a/drivers/dsp/bridge/pmgr/dbll.c b/drivers/dsp/bridge/pmgr/dbll.c +new file mode 100644 +index 0000000..82430a3 +--- /dev/null ++++ b/drivers/dsp/bridge/pmgr/dbll.c +@@ -0,0 +1,1564 @@ ++/* ++ * dbll.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== dbll.c ======== ++ * ++ *! Revision History ++ *! ================ ++ *! 25-Apr-2030 map: Fixed symbol redefinition bug + unload and return error ++ *! 08-Apr-2003 map: Consolidated DBL with DBLL loader name ++ *! 24-Mar-2003 map: Updated findSymbol to support dllview update ++ *! 23-Jan-2003 map: Updated rmmAlloc to support memory granularity ++ *! 21-Nov-2002 map: Combine fopen and DLOAD_module_open to increase ++ *! performance on start. ++ *! 04-Oct-2002 map: Integrated new TIP dynamic loader w/ DOF api. ++ *! 27-Sep-2002 map: Changed handle passed to RemoteFree, instead of ++ *! RMM_free; added GT_trace to rmmDealloc ++ *! 20-Sep-2002 map: Updated from Code Review ++ *! 08-Aug-2002 jeh: Updated to support overlays. ++ *! 25-Jun-2002 jeh: Pass RMM_Addr object to alloc function in rmmAlloc(). ++ *! 20-Mar-2002 jeh: Created. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++ ++/* Dynamic loader library interface */ ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++#include ++ ++#define DBLL_TARGSIGNATURE 0x544c4c44 /* "TLLD" */ ++#define DBLL_LIBSIGNATURE 0x4c4c4c44 /* "LLLD" */ ++ ++/* Number of buckets for symbol hash table */ ++#define MAXBUCKETS 211 ++ ++/* Max buffer length */ ++#define MAXEXPR 128 ++ ++#ifndef UINT32_C ++#define UINT32_C(zzz) ((uint32_t)zzz) ++#endif ++#define DOFF_ALIGN(x) (((x) + 3) & ~UINT32_C(3)) ++ ++/* ++ * ======== struct DBLL_TarObj* ======== ++ * A target may have one or more libraries of symbols/code/data loaded ++ * onto it, where a library is simply the symbols/code/data contained ++ * in a DOFF file. ++ */ ++/* ++ * ======== DBLL_TarObj ======== ++ */ ++struct DBLL_TarObj { ++ u32 dwSignature; /* For object validation */ ++ struct DBLL_Attrs attrs; ++ struct DBLL_LibraryObj *head; /* List of all opened libraries */ ++} ; ++ ++/* ++ * The following 4 typedefs are "super classes" of the dynamic loader ++ * library types used in dynamic loader functions (dynamic_loader.h). ++ */ ++/* ++ * ======== DBLLStream ======== ++ * Contains Dynamic_Loader_Stream ++ */ ++struct DBLLStream { ++ struct Dynamic_Loader_Stream dlStream; ++ struct DBLL_LibraryObj *lib; ++} ; ++ ++/* ++ * ======== DBLLSymbol ======== ++ */ ++struct DBLLSymbol { ++ struct Dynamic_Loader_Sym dlSymbol; ++ struct DBLL_LibraryObj *lib; ++} ; ++ ++/* ++ * ======== DBLLAlloc ======== ++ */ ++ struct DBLLAlloc { ++ struct Dynamic_Loader_Allocate dlAlloc; ++ struct DBLL_LibraryObj *lib; ++} ; ++ ++/* ++ * ======== DBLLInit ======== ++ */ ++struct DBLLInit { ++ struct Dynamic_Loader_Initialize dlInit; ++ struct DBLL_LibraryObj *lib; ++}; ++ ++/* ++ * ======== DBLL_Library ======== ++ * A library handle is returned by DBLL_Open() and is passed to DBLL_load() ++ * to load symbols/code/data, and to DBLL_unload(), to remove the ++ * symbols/code/data loaded by DBLL_load(). ++ */ ++ ++/* ++ * ======== DBLL_LibraryObj ======== ++ */ ++ struct DBLL_LibraryObj { ++ u32 dwSignature; /* For object validation */ ++ struct DBLL_LibraryObj *next; /* Next library in target's list */ ++ struct DBLL_LibraryObj *prev; /* Previous in the list */ ++ struct DBLL_TarObj *pTarget; /* target for this library */ ++ ++ /* Objects needed by dynamic loader */ ++ struct DBLLStream stream; ++ struct DBLLSymbol symbol; ++ struct DBLLAlloc allocate; ++ struct DBLLInit init; ++ DLOAD_mhandle mHandle; ++ ++ char *fileName; /* COFF file name */ ++ void *fp; /* Opaque file handle */ ++ u32 entry; /* Entry point */ ++ DLOAD_mhandle desc; /* desc of DOFF file loaded */ ++ u32 openRef; /* Number of times opened */ ++ u32 loadRef; /* Number of times loaded */ ++ struct GH_THashTab *symTab; /* Hash table of symbols */ ++ u32 ulPos; ++} ; ++ ++/* ++ * ======== Symbol ======== ++ */ ++struct Symbol { ++ struct DBLL_Symbol value; ++ char *name; ++} ; ++extern bool bSymbolsReloaded; ++ ++static void dofClose(struct DBLL_LibraryObj *zlLib); ++static DSP_STATUS dofOpen(struct DBLL_LibraryObj *zlLib); ++static s32 NoOp(struct Dynamic_Loader_Initialize *thisptr, void *bufr, ++ LDR_ADDR locn, struct LDR_SECTION_INFO *info, unsigned bytsiz); ++ ++/* ++ * Functions called by dynamic loader ++ * ++ */ ++/* Dynamic_Loader_Stream */ ++static int readBuffer(struct Dynamic_Loader_Stream *this, void *buffer, ++ unsigned bufsize); ++static int setFilePosn(struct Dynamic_Loader_Stream *this, unsigned int pos); ++/* Dynamic_Loader_Sym */ ++static struct dynload_symbol *findSymbol(struct Dynamic_Loader_Sym *this, ++ const char *name); ++static struct dynload_symbol *addToSymbolTable(struct Dynamic_Loader_Sym *this, ++ const char *name, ++ unsigned moduleId); ++static struct dynload_symbol *findInSymbolTable(struct Dynamic_Loader_Sym *this, ++ const char *name, ++ unsigned moduleid); ++static void purgeSymbolTable(struct Dynamic_Loader_Sym *this, ++ unsigned moduleId); ++static void *allocate(struct Dynamic_Loader_Sym *this, unsigned memsize); ++static void deallocate(struct Dynamic_Loader_Sym *this, void *memPtr); ++static void errorReport(struct Dynamic_Loader_Sym *this, const char *errstr, ++ va_list args); ++/* Dynamic_Loader_Allocate */ ++static int rmmAlloc(struct Dynamic_Loader_Allocate *this, ++ struct LDR_SECTION_INFO *info, unsigned align); ++static void rmmDealloc(struct Dynamic_Loader_Allocate *this, ++ struct LDR_SECTION_INFO *info); ++ ++/* Dynamic_Loader_Initialize */ ++static int connect(struct Dynamic_Loader_Initialize *this); ++static int readMem(struct Dynamic_Loader_Initialize *this, void *buf, ++ LDR_ADDR addr, struct LDR_SECTION_INFO *info, ++ unsigned nbytes); ++static int writeMem(struct Dynamic_Loader_Initialize *this, void *buf, ++ LDR_ADDR addr, struct LDR_SECTION_INFO *info, ++ unsigned nbytes); ++static int fillMem(struct Dynamic_Loader_Initialize *this, LDR_ADDR addr, ++ struct LDR_SECTION_INFO *info, unsigned nbytes, ++ unsigned val); ++static int execute(struct Dynamic_Loader_Initialize *this, LDR_ADDR start); ++static void release(struct Dynamic_Loader_Initialize *this); ++ ++/* symbol table hash functions */ ++static u16 nameHash(void *name, u16 maxBucket); ++static bool nameMatch(void *name, void *sp); ++static void symDelete(void *sp); ++ ++#if GT_TRACE ++static struct GT_Mask DBLL_debugMask = { NULL, NULL }; /* GT trace variable */ ++#endif ++ ++static u32 cRefs; /* module reference count */ ++ ++/* Symbol Redefinition */ ++static int bRedefinedSymbol; ++static int bGblSearch = 1; ++ ++/* ++ * ======== DBLL_close ======== ++ */ ++void DBLL_close(struct DBLL_LibraryObj *zlLib) ++{ ++ struct DBLL_TarObj *zlTarget; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE)); ++ DBC_Require(zlLib->openRef > 0); ++ zlTarget = zlLib->pTarget; ++ GT_1trace(DBLL_debugMask, GT_ENTER, "DBLL_close: lib: 0x%x\n", zlLib); ++ zlLib->openRef--; ++ if (zlLib->openRef == 0) { ++ /* Remove library from list */ ++ if (zlTarget->head == zlLib) ++ zlTarget->head = zlLib->next; ++ ++ if (zlLib->prev) ++ (zlLib->prev)->next = zlLib->next; ++ ++ if (zlLib->next) ++ (zlLib->next)->prev = zlLib->prev; ++ ++ /* Free DOF resources */ ++ dofClose(zlLib); ++ if (zlLib->fileName) ++ MEM_Free(zlLib->fileName); ++ ++ /* remove symbols from symbol table */ ++ if (zlLib->symTab) ++ GH_delete(zlLib->symTab); ++ ++ /* remove the library object itself */ ++ MEM_FreeObject(zlLib); ++ zlLib = NULL; ++ } ++} ++ ++/* ++ * ======== DBLL_create ======== ++ */ ++DSP_STATUS DBLL_create(struct DBLL_TarObj **pTarget, struct DBLL_Attrs *pAttrs) ++{ ++ struct DBLL_TarObj *pzlTarget; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pAttrs != NULL); ++ DBC_Require(pTarget != NULL); ++ ++ GT_2trace(DBLL_debugMask, GT_ENTER, ++ "DBLL_create: pTarget: 0x%x pAttrs: " ++ "0x%x\n", pTarget, pAttrs); ++ /* Allocate DBL target object */ ++ MEM_AllocObject(pzlTarget, struct DBLL_TarObj, DBLL_TARGSIGNATURE); ++ if (pTarget != NULL) { ++ if (pzlTarget == NULL) { ++ GT_0trace(DBLL_debugMask, GT_6CLASS, ++ "DBLL_create: Memory allocation" ++ " failed\n"); ++ *pTarget = NULL; ++ status = DSP_EMEMORY; ++ } else { ++ pzlTarget->attrs = *pAttrs; ++ *pTarget = (struct DBLL_TarObj *)pzlTarget; ++ } ++ DBC_Ensure((DSP_SUCCEEDED(status) && ++ MEM_IsValidHandle(((struct DBLL_TarObj *)(*pTarget)), ++ DBLL_TARGSIGNATURE)) || (DSP_FAILED(status) && ++ *pTarget == NULL)); ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== DBLL_delete ======== ++ */ ++void DBLL_delete(struct DBLL_TarObj *target) ++{ ++ struct DBLL_TarObj *zlTarget = (struct DBLL_TarObj *)target; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(zlTarget, DBLL_TARGSIGNATURE)); ++ ++ GT_1trace(DBLL_debugMask, GT_ENTER, "DBLL_delete: target: 0x%x\n", ++ target); ++ ++ if (zlTarget != NULL) ++ MEM_FreeObject(zlTarget); ++ ++} ++ ++/* ++ * ======== DBLL_exit ======== ++ * Discontinue usage of DBL module. ++ */ ++void DBLL_exit(void) ++{ ++ DBC_Require(cRefs > 0); ++ ++ cRefs--; ++ ++ GT_1trace(DBLL_debugMask, GT_5CLASS, "DBLL_exit() ref count: 0x%x\n", ++ cRefs); ++ ++ if (cRefs == 0) { ++ MEM_Exit(); ++ CSL_Exit(); ++ GH_exit(); ++#if GT_TRACE ++ DBLL_debugMask.flags = NULL; ++#endif ++ } ++ ++ DBC_Ensure(cRefs >= 0); ++} ++ ++/* ++ * ======== DBLL_getAddr ======== ++ * Get address of name in the specified library. ++ */ ++bool DBLL_getAddr(struct DBLL_LibraryObj *zlLib, char *name, ++ struct DBLL_Symbol **ppSym) ++{ ++ struct Symbol *sym; ++ bool status = false; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE)); ++ DBC_Require(name != NULL); ++ DBC_Require(ppSym != NULL); ++ DBC_Require(zlLib->symTab != NULL); ++ ++ GT_3trace(DBLL_debugMask, GT_ENTER, ++ "DBLL_getAddr: lib: 0x%x name: %s pAddr:" ++ " 0x%x\n", zlLib, name, ppSym); ++ sym = (struct Symbol *)GH_find(zlLib->symTab, name); ++ if (sym != NULL) { ++ *ppSym = &sym->value; ++ status = true; ++ } ++ return status; ++} ++ ++/* ++ * ======== DBLL_getAttrs ======== ++ * Retrieve the attributes of the target. ++ */ ++void DBLL_getAttrs(struct DBLL_TarObj *target, struct DBLL_Attrs *pAttrs) ++{ ++ struct DBLL_TarObj *zlTarget = (struct DBLL_TarObj *)target; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(zlTarget, DBLL_TARGSIGNATURE)); ++ DBC_Require(pAttrs != NULL); ++ ++ if ((pAttrs != NULL) && (zlTarget != NULL)) ++ *pAttrs = zlTarget->attrs; ++ ++} ++ ++/* ++ * ======== DBLL_getCAddr ======== ++ * Get address of a "C" name in the specified library. ++ */ ++bool DBLL_getCAddr(struct DBLL_LibraryObj *zlLib, char *name, ++ struct DBLL_Symbol **ppSym) ++{ ++ struct Symbol *sym; ++ char cname[MAXEXPR + 1]; ++ bool status = false; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE)); ++ DBC_Require(ppSym != NULL); ++ DBC_Require(zlLib->symTab != NULL); ++ DBC_Require(name != NULL); ++ ++ cname[0] = '_'; ++ ++ strncpy(cname + 1, name, sizeof(cname) - 2); ++ cname[MAXEXPR] = '\0'; /* insure '\0' string termination */ ++ ++ /* Check for C name, if not found */ ++ sym = (struct Symbol *)GH_find(zlLib->symTab, cname); ++ ++ if (sym != NULL) { ++ *ppSym = &sym->value; ++ status = true; ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== DBLL_getSect ======== ++ * Get the base address and size (in bytes) of a COFF section. ++ */ ++DSP_STATUS DBLL_getSect(struct DBLL_LibraryObj *lib, char *name, u32 *pAddr, ++ u32 *pSize) ++{ ++ u32 uByteSize; ++ bool fOpenedDoff = false; ++ const struct LDR_SECTION_INFO *sect = NULL; ++ struct DBLL_LibraryObj *zlLib = (struct DBLL_LibraryObj *)lib; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(name != NULL); ++ DBC_Require(pAddr != NULL); ++ DBC_Require(pSize != NULL); ++ DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE)); ++ ++ GT_4trace(DBLL_debugMask, GT_ENTER, ++ "DBLL_getSect: lib: 0x%x name: %s pAddr:" ++ " 0x%x pSize: 0x%x\n", lib, name, pAddr, pSize); ++ /* If DOFF file is not open, we open it. */ ++ if (zlLib != NULL) { ++ if (zlLib->fp == NULL) { ++ status = dofOpen(zlLib); ++ if (DSP_SUCCEEDED(status)) ++ fOpenedDoff = true; ++ ++ } else { ++ (*(zlLib->pTarget->attrs.fseek))(zlLib->fp, ++ zlLib->ulPos, SEEK_SET); ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ uByteSize = 1; ++ if (DLOAD_GetSectionInfo(zlLib->desc, name, §)) { ++ *pAddr = sect->load_addr; ++ *pSize = sect->size * uByteSize; ++ /* Make sure size is even for good swap */ ++ if (*pSize % 2) ++ (*pSize)++; ++ ++ /* Align size */ ++ *pSize = DOFF_ALIGN(*pSize); ++ } else { ++ status = DSP_ENOSECT; ++ } ++ } ++ if (fOpenedDoff) { ++ dofClose(zlLib); ++ fOpenedDoff = false; ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== DBLL_init ======== ++ */ ++bool DBLL_init(void) ++{ ++ bool retVal = true; ++ ++ DBC_Require(cRefs >= 0); ++ ++ if (cRefs == 0) { ++ DBC_Assert(!DBLL_debugMask.flags); ++ GT_create(&DBLL_debugMask, "DL"); /* "DL" for dbDL */ ++ GH_init(); ++ CSL_Init(); ++ retVal = MEM_Init(); ++ if (!retVal) ++ MEM_Exit(); ++ ++ } ++ ++ if (retVal) ++ cRefs++; ++ ++ ++ GT_1trace(DBLL_debugMask, GT_5CLASS, "DBLL_init(), ref count: 0x%x\n", ++ cRefs); ++ ++ DBC_Ensure((retVal && (cRefs > 0)) || (!retVal && (cRefs >= 0))); ++ ++ return retVal; ++} ++ ++/* ++ * ======== DBLL_load ======== ++ */ ++DSP_STATUS DBLL_load(struct DBLL_LibraryObj *lib, DBLL_Flags flags, ++ struct DBLL_Attrs *attrs, u32 *pEntry) ++{ ++ struct DBLL_LibraryObj *zlLib = (struct DBLL_LibraryObj *)lib; ++ struct DBLL_TarObj *dbzl; ++ bool gotSymbols = true; ++ s32 err; ++ DSP_STATUS status = DSP_SOK; ++ bool fOpenedDoff = false; ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE)); ++ DBC_Require(pEntry != NULL); ++ DBC_Require(attrs != NULL); ++ ++ GT_4trace(DBLL_debugMask, GT_ENTER, ++ "DBLL_load: lib: 0x%x flags: 0x%x pEntry:" ++ " 0x%x\n", lib, flags, attrs, pEntry); ++ /* ++ * Load if not already loaded. ++ */ ++ if (zlLib->loadRef == 0 || !(flags & DBLL_DYNAMIC)) { ++ dbzl = zlLib->pTarget; ++ dbzl->attrs = *attrs; ++ /* Create a hash table for symbols if not already created */ ++ if (zlLib->symTab == NULL) { ++ gotSymbols = false; ++ zlLib->symTab = GH_create(MAXBUCKETS, ++ sizeof(struct Symbol), ++ nameHash, ++ nameMatch, symDelete); ++ if (zlLib->symTab == NULL) ++ status = DSP_EMEMORY; ++ ++ } ++ /* ++ * Set up objects needed by the dynamic loader ++ */ ++ /* Stream */ ++ zlLib->stream.dlStream.read_buffer = readBuffer; ++ zlLib->stream.dlStream.set_file_posn = setFilePosn; ++ zlLib->stream.lib = zlLib; ++ /* Symbol */ ++ zlLib->symbol.dlSymbol.Find_Matching_Symbol = findSymbol; ++ if (gotSymbols) { ++ zlLib->symbol.dlSymbol.Add_To_Symbol_Table = ++ findInSymbolTable; ++ } else { ++ zlLib->symbol.dlSymbol.Add_To_Symbol_Table = ++ addToSymbolTable; ++ } ++ zlLib->symbol.dlSymbol.Purge_Symbol_Table = purgeSymbolTable; ++ zlLib->symbol.dlSymbol.Allocate = allocate; ++ zlLib->symbol.dlSymbol.Deallocate = deallocate; ++ zlLib->symbol.dlSymbol.Error_Report = errorReport; ++ zlLib->symbol.lib = zlLib; ++ /* Allocate */ ++ zlLib->allocate.dlAlloc.Allocate = rmmAlloc; ++ zlLib->allocate.dlAlloc.Deallocate = rmmDealloc; ++ zlLib->allocate.lib = zlLib; ++ /* Init */ ++ zlLib->init.dlInit.connect = connect; ++ zlLib->init.dlInit.readmem = readMem; ++ zlLib->init.dlInit.writemem = writeMem; ++ zlLib->init.dlInit.fillmem = fillMem; ++ zlLib->init.dlInit.execute = execute; ++ zlLib->init.dlInit.release = release; ++ zlLib->init.lib = zlLib; ++ /* If COFF file is not open, we open it. */ ++ if (zlLib->fp == NULL) { ++ status = dofOpen(zlLib); ++ if (DSP_SUCCEEDED(status)) ++ fOpenedDoff = true; ++ ++ } ++ if (DSP_SUCCEEDED(status)) { ++ zlLib->ulPos = (*(zlLib->pTarget->attrs.ftell)) ++ (zlLib->fp); ++ /* Reset file cursor */ ++ (*(zlLib->pTarget->attrs.fseek))(zlLib->fp, (long)0, ++ SEEK_SET); ++ bSymbolsReloaded = true; ++ /* The 5th argument, DLOAD_INITBSS, tells the DLL ++ * module to zero-init all BSS sections. In general, ++ * this is not necessary and also increases load time. ++ * We may want to make this configurable by the user */ ++ err = Dynamic_Load_Module(&zlLib->stream.dlStream, ++ &zlLib->symbol.dlSymbol, &zlLib->allocate.dlAlloc, ++ &zlLib->init.dlInit, DLOAD_INITBSS, ++ &zlLib->mHandle); ++ ++ if (err != 0) { ++ GT_1trace(DBLL_debugMask, GT_6CLASS, ++ "DBLL_load: " ++ "Dynamic_Load_Module failed: 0x%lx\n", ++ err); ++ status = DSP_EDYNLOAD; ++ } else if (bRedefinedSymbol) { ++ zlLib->loadRef++; ++ DBLL_unload(zlLib, (struct DBLL_Attrs *) attrs); ++ bRedefinedSymbol = false; ++ status = DSP_EDYNLOAD; ++ } else { ++ *pEntry = zlLib->entry; ++ } ++ } ++ } ++ if (DSP_SUCCEEDED(status)) ++ zlLib->loadRef++; ++ ++ /* Clean up DOFF resources */ ++ if (fOpenedDoff) ++ dofClose(zlLib); ++ ++ DBC_Ensure(DSP_FAILED(status) || zlLib->loadRef > 0); ++ return status; ++} ++ ++/* ++ * ======== DBLL_loadSect ======== ++ * Not supported for COFF. ++ */ ++DSP_STATUS DBLL_loadSect(struct DBLL_LibraryObj *zlLib, char *sectName, ++ struct DBLL_Attrs *attrs) ++{ ++ DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE)); ++ ++ return DSP_ENOTIMPL; ++} ++ ++/* ++ * ======== DBLL_open ======== ++ */ ++DSP_STATUS DBLL_open(struct DBLL_TarObj *target, char *file, DBLL_Flags flags, ++ struct DBLL_LibraryObj **pLib) ++{ ++ struct DBLL_TarObj *zlTarget = (struct DBLL_TarObj *)target; ++ struct DBLL_LibraryObj *zlLib = NULL; ++ s32 err; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(zlTarget, DBLL_TARGSIGNATURE)); ++ DBC_Require(zlTarget->attrs.fopen != NULL); ++ DBC_Require(file != NULL); ++ DBC_Require(pLib != NULL); ++ ++ GT_3trace(DBLL_debugMask, GT_ENTER, ++ "DBLL_open: target: 0x%x file: %s pLib:" ++ " 0x%x\n", target, file, pLib); ++ zlLib = zlTarget->head; ++ while (zlLib != NULL) { ++ if (strcmp(zlLib->fileName, file) == 0) { ++ /* Library is already opened */ ++ zlLib->openRef++; ++ break; ++ } ++ zlLib = zlLib->next; ++ } ++ if (zlLib == NULL) { ++ /* Allocate DBL library object */ ++ MEM_AllocObject(zlLib, struct DBLL_LibraryObj, ++ DBLL_LIBSIGNATURE); ++ if (zlLib == NULL) { ++ GT_0trace(DBLL_debugMask, GT_6CLASS, ++ "DBLL_open: Memory allocation failed\n"); ++ status = DSP_EMEMORY; ++ } else { ++ zlLib->ulPos = 0; ++ /* Increment ref count to allow close on failure ++ * later on */ ++ zlLib->openRef++; ++ zlLib->pTarget = zlTarget; ++ /* Keep a copy of the file name */ ++ zlLib->fileName = MEM_Calloc(strlen(file) + 1, ++ MEM_PAGED); ++ if (zlLib->fileName == NULL) { ++ GT_0trace(DBLL_debugMask, GT_6CLASS, ++ "DBLL_open: Memory " ++ "allocation failed\n"); ++ status = DSP_EMEMORY; ++ } else { ++ strncpy(zlLib->fileName, file, ++ strlen(file) + 1); ++ } ++ zlLib->symTab = NULL; ++ } ++ } ++ /* ++ * Set up objects needed by the dynamic loader ++ */ ++ if (DSP_FAILED(status)) ++ goto func_cont; ++ ++ /* Stream */ ++ zlLib->stream.dlStream.read_buffer = readBuffer; ++ zlLib->stream.dlStream.set_file_posn = setFilePosn; ++ zlLib->stream.lib = zlLib; ++ /* Symbol */ ++ zlLib->symbol.dlSymbol.Add_To_Symbol_Table = addToSymbolTable; ++ zlLib->symbol.dlSymbol.Find_Matching_Symbol = findSymbol; ++ zlLib->symbol.dlSymbol.Purge_Symbol_Table = purgeSymbolTable; ++ zlLib->symbol.dlSymbol.Allocate = allocate; ++ zlLib->symbol.dlSymbol.Deallocate = deallocate; ++ zlLib->symbol.dlSymbol.Error_Report = errorReport; ++ zlLib->symbol.lib = zlLib; ++ /* Allocate */ ++ zlLib->allocate.dlAlloc.Allocate = rmmAlloc; ++ zlLib->allocate.dlAlloc.Deallocate = rmmDealloc; ++ zlLib->allocate.lib = zlLib; ++ /* Init */ ++ zlLib->init.dlInit.connect = connect; ++ zlLib->init.dlInit.readmem = readMem; ++ zlLib->init.dlInit.writemem = writeMem; ++ zlLib->init.dlInit.fillmem = fillMem; ++ zlLib->init.dlInit.execute = execute; ++ zlLib->init.dlInit.release = release; ++ zlLib->init.lib = zlLib; ++ if (DSP_SUCCEEDED(status) && zlLib->fp == NULL) ++ status = dofOpen(zlLib); ++ ++ zlLib->ulPos = (*(zlLib->pTarget->attrs.ftell)) (zlLib->fp); ++ (*(zlLib->pTarget->attrs.fseek))(zlLib->fp, (long) 0, SEEK_SET); ++ /* Create a hash table for symbols if flag is set */ ++ if (zlLib->symTab != NULL || !(flags & DBLL_SYMB)) ++ goto func_cont; ++ ++ zlLib->symTab = GH_create(MAXBUCKETS, sizeof(struct Symbol), nameHash, ++ nameMatch, symDelete); ++ if (zlLib->symTab == NULL) { ++ status = DSP_EMEMORY; ++ } else { ++ /* Do a fake load to get symbols - set write function to NoOp */ ++ zlLib->init.dlInit.writemem = NoOp; ++ err = Dynamic_Open_Module(&zlLib->stream.dlStream, ++ &zlLib->symbol.dlSymbol, ++ &zlLib->allocate.dlAlloc, ++ &zlLib->init.dlInit, 0, ++ &zlLib->mHandle); ++ if (err != 0) { ++ GT_1trace(DBLL_debugMask, GT_6CLASS, "DBLL_open: " ++ "Dynamic_Load_Module failed: 0x%lx\n", err); ++ status = DSP_EDYNLOAD; ++ } else { ++ /* Now that we have the symbol table, we can unload */ ++ err = Dynamic_Unload_Module(zlLib->mHandle, ++ &zlLib->symbol.dlSymbol, ++ &zlLib->allocate.dlAlloc, ++ &zlLib->init.dlInit); ++ if (err != 0) { ++ GT_1trace(DBLL_debugMask, GT_6CLASS, ++ "DBLL_open: " ++ "Dynamic_Unload_Module failed: 0x%lx\n", ++ err); ++ status = DSP_EDYNLOAD; ++ } ++ zlLib->mHandle = NULL; ++ } ++ } ++func_cont: ++ if (DSP_SUCCEEDED(status)) { ++ if (zlLib->openRef == 1) { ++ /* First time opened - insert in list */ ++ if (zlTarget->head) ++ (zlTarget->head)->prev = zlLib; ++ ++ zlLib->prev = NULL; ++ zlLib->next = zlTarget->head; ++ zlTarget->head = zlLib; ++ } ++ *pLib = (struct DBLL_LibraryObj *)zlLib; ++ } else { ++ *pLib = NULL; ++ if (zlLib != NULL) ++ DBLL_close((struct DBLL_LibraryObj *)zlLib); ++ ++ } ++ DBC_Ensure((DSP_SUCCEEDED(status) && (zlLib->openRef > 0) && ++ MEM_IsValidHandle(((struct DBLL_LibraryObj *)(*pLib)), ++ DBLL_LIBSIGNATURE)) || (DSP_FAILED(status) && *pLib == NULL)); ++ return status; ++} ++ ++/* ++ * ======== DBLL_readSect ======== ++ * Get the content of a COFF section. ++ */ ++DSP_STATUS DBLL_readSect(struct DBLL_LibraryObj *lib, char *name, ++ char *pContent, u32 size) ++{ ++ struct DBLL_LibraryObj *zlLib = (struct DBLL_LibraryObj *)lib; ++ bool fOpenedDoff = false; ++ u32 uByteSize; /* size of bytes */ ++ u32 ulSectSize; /* size of section */ ++ const struct LDR_SECTION_INFO *sect = NULL; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE)); ++ DBC_Require(name != NULL); ++ DBC_Require(pContent != NULL); ++ DBC_Require(size != 0); ++ ++ GT_4trace(DBLL_debugMask, GT_ENTER, ++ "DBLL_readSect: lib: 0x%x name: %s " ++ "pContent: 0x%x size: 0x%x\n", lib, name, pContent, size); ++ /* If DOFF file is not open, we open it. */ ++ if (zlLib != NULL) { ++ if (zlLib->fp == NULL) { ++ status = dofOpen(zlLib); ++ if (DSP_SUCCEEDED(status)) ++ fOpenedDoff = true; ++ ++ } else { ++ (*(zlLib->pTarget->attrs.fseek))(zlLib->fp, ++ zlLib->ulPos, SEEK_SET); ++ } ++ } ++ ++ if (DSP_FAILED(status)) ++ goto func_cont; ++ ++ uByteSize = 1; ++ if (!DLOAD_GetSectionInfo(zlLib->desc, name, §)) { ++ status = DSP_ENOSECT; ++ goto func_cont; ++ } ++ /* ++ * Ensure the supplied buffer size is sufficient to store ++ * the section content to be read. ++ */ ++ ulSectSize = sect->size * uByteSize; ++ /* Make sure size is even for good swap */ ++ if (ulSectSize % 2) ++ ulSectSize++; ++ ++ /* Align size */ ++ ulSectSize = DOFF_ALIGN(ulSectSize); ++ if (ulSectSize > size) { ++ status = DSP_EFAIL; ++ } else { ++ if (!DLOAD_GetSection(zlLib->desc, sect, pContent)) ++ status = DSP_EFREAD; ++ ++ } ++func_cont: ++ if (fOpenedDoff) { ++ dofClose(zlLib); ++ fOpenedDoff = false; ++ } ++ return status; ++} ++ ++/* ++ * ======== DBLL_setAttrs ======== ++ * Set the attributes of the target. ++ */ ++void DBLL_setAttrs(struct DBLL_TarObj *target, struct DBLL_Attrs *pAttrs) ++{ ++ struct DBLL_TarObj *zlTarget = (struct DBLL_TarObj *)target; ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(zlTarget, DBLL_TARGSIGNATURE)); ++ DBC_Require(pAttrs != NULL); ++ GT_2trace(DBLL_debugMask, GT_ENTER, ++ "DBLL_setAttrs: target: 0x%x pAttrs: " ++ "0x%x\n", target, pAttrs); ++ if ((pAttrs != NULL) && (zlTarget != NULL)) ++ zlTarget->attrs = *pAttrs; ++ ++} ++ ++/* ++ * ======== DBLL_unload ======== ++ */ ++void DBLL_unload(struct DBLL_LibraryObj *lib, struct DBLL_Attrs *attrs) ++{ ++ struct DBLL_LibraryObj *zlLib = (struct DBLL_LibraryObj *)lib; ++ s32 err = 0; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE)); ++ DBC_Require(zlLib->loadRef > 0); ++ GT_1trace(DBLL_debugMask, GT_ENTER, "DBLL_unload: lib: 0x%x\n", lib); ++ zlLib->loadRef--; ++ /* Unload only if reference count is 0 */ ++ if (zlLib->loadRef != 0) ++ goto func_end; ++ ++ zlLib->pTarget->attrs = *attrs; ++ if (zlLib != NULL) { ++ if (zlLib->mHandle) { ++ err = Dynamic_Unload_Module(zlLib->mHandle, ++ &zlLib->symbol.dlSymbol, ++ &zlLib->allocate.dlAlloc, &zlLib->init.dlInit); ++ if (err != 0) { ++ GT_1trace(DBLL_debugMask, GT_5CLASS, ++ "Dynamic_Unload_Module " ++ "failed: 0x%x\n", err); ++ } ++ } ++ /* remove symbols from symbol table */ ++ if (zlLib->symTab != NULL) { ++ GH_delete(zlLib->symTab); ++ zlLib->symTab = NULL; ++ } ++ /* delete DOFF desc since it holds *lots* of host OS ++ * resources */ ++ dofClose(zlLib); ++ } ++func_end: ++ DBC_Ensure(zlLib->loadRef >= 0); ++} ++ ++/* ++ * ======== DBLL_unloadSect ======== ++ * Not supported for COFF. ++ */ ++DSP_STATUS DBLL_unloadSect(struct DBLL_LibraryObj *lib, char *sectName, ++ struct DBLL_Attrs *attrs) ++{ ++ DBC_Require(cRefs > 0); ++ DBC_Require(sectName != NULL); ++ GT_2trace(DBLL_debugMask, GT_ENTER, ++ "DBLL_unloadSect: lib: 0x%x sectName: " ++ "%s\n", lib, sectName); ++ return DSP_ENOTIMPL; ++} ++ ++/* ++ * ======== dofClose ======== ++ */ ++static void dofClose(struct DBLL_LibraryObj *zlLib) ++{ ++ if (zlLib->desc) { ++ DLOAD_module_close(zlLib->desc); ++ zlLib->desc = NULL; ++ } ++ /* close file */ ++ if (zlLib->fp) { ++ (zlLib->pTarget->attrs.fclose) (zlLib->fp); ++ zlLib->fp = NULL; ++ } ++} ++ ++/* ++ * ======== dofOpen ======== ++ */ ++static DSP_STATUS dofOpen(struct DBLL_LibraryObj *zlLib) ++{ ++ void *open = *(zlLib->pTarget->attrs.fopen); ++ DSP_STATUS status = DSP_SOK; ++ ++ /* First open the file for the dynamic loader, then open COF */ ++ zlLib->fp = (void *)((DBLL_FOpenFxn)(open))(zlLib->fileName, "rb"); ++ ++ /* Open DOFF module */ ++ if (zlLib->fp && zlLib->desc == NULL) { ++ (*(zlLib->pTarget->attrs.fseek))(zlLib->fp, (long)0, SEEK_SET); ++ zlLib->desc = DLOAD_module_open(&zlLib->stream.dlStream, ++ &zlLib->symbol.dlSymbol); ++ if (zlLib->desc == NULL) { ++ (zlLib->pTarget->attrs.fclose)(zlLib->fp); ++ zlLib->fp = NULL; ++ status = DSP_EFOPEN; ++ } ++ } else { ++ status = DSP_EFOPEN; ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== nameHash ======== ++ */ ++static u16 nameHash(void *key, u16 maxBucket) ++{ ++ u16 ret; ++ u16 hash; ++ char *name = (char *)key; ++ ++ DBC_Require(name != NULL); ++ ++ hash = 0; ++ ++ while (*name) { ++ hash <<= 1; ++ hash ^= *name++; ++ } ++ ++ ret = hash % maxBucket; ++ ++ return ret; ++} ++ ++/* ++ * ======== nameMatch ======== ++ */ ++static bool nameMatch(void *key, void *value) ++{ ++ DBC_Require(key != NULL); ++ DBC_Require(value != NULL); ++ ++ if ((key != NULL) && (value != NULL)) { ++ if (strcmp((char *)key, ((struct Symbol *)value)->name) == 0) ++ return true; ++ } ++ return false; ++} ++ ++/* ++ * ======== NoOp ======== ++ */ ++static int NoOp(struct Dynamic_Loader_Initialize *thisptr, void *bufr, ++ LDR_ADDR locn, struct LDR_SECTION_INFO *info, unsigned bytsize) ++{ ++ return 1; ++} ++ ++/* ++ * ======== symDelete ======== ++ */ ++static void symDelete(void *value) ++{ ++ struct Symbol *sp = (struct Symbol *)value; ++ ++ MEM_Free(sp->name); ++} ++ ++/* ++ * Dynamic Loader Functions ++ */ ++ ++/* Dynamic_Loader_Stream */ ++/* ++ * ======== readBuffer ======== ++ */ ++static int readBuffer(struct Dynamic_Loader_Stream *this, void *buffer, ++ unsigned bufsize) ++{ ++ struct DBLLStream *pStream = (struct DBLLStream *)this; ++ struct DBLL_LibraryObj *lib; ++ int bytesRead = 0; ++ ++ DBC_Require(this != NULL); ++ lib = pStream->lib; ++ DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE)); ++ ++ if (lib != NULL) { ++ bytesRead = (*(lib->pTarget->attrs.fread))(buffer, 1, bufsize, ++ lib->fp); ++ } ++ return bytesRead; ++} ++ ++/* ++ * ======== setFilePosn ======== ++ */ ++static int setFilePosn(struct Dynamic_Loader_Stream *this, unsigned int pos) ++{ ++ struct DBLLStream *pStream = (struct DBLLStream *)this; ++ struct DBLL_LibraryObj *lib; ++ int status = 0; /* Success */ ++ ++ DBC_Require(this != NULL); ++ lib = pStream->lib; ++ DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE)); ++ ++ if (lib != NULL) { ++ status = (*(lib->pTarget->attrs.fseek))(lib->fp, (long)pos, ++ SEEK_SET); ++ } ++ ++ return status; ++} ++ ++/* Dynamic_Loader_Sym */ ++ ++/* ++ * ======== findSymbol ======== ++ */ ++static struct dynload_symbol *findSymbol(struct Dynamic_Loader_Sym *this, ++ const char *name) ++{ ++ struct dynload_symbol *retSym; ++ struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this; ++ struct DBLL_LibraryObj *lib; ++ struct DBLL_Symbol *pSym = NULL; ++ bool status = false; /* Symbol not found yet */ ++ ++ DBC_Require(this != NULL); ++ lib = pSymbol->lib; ++ DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE)); ++ ++ if (lib != NULL) { ++ if (lib->pTarget->attrs.symLookup) { ++ /* Check current lib + base lib + dep lib + ++ * persistent lib */ ++ status = (*(lib->pTarget->attrs.symLookup)) ++ (lib->pTarget->attrs.symHandle, ++ lib->pTarget->attrs.symArg, ++ lib->pTarget->attrs.rmmHandle, name, &pSym); ++ } else { ++ /* Just check current lib for symbol */ ++ status = DBLL_getAddr((struct DBLL_LibraryObj *)lib, ++ (char *)name, &pSym); ++ if (!status) { ++ status = ++ DBLL_getCAddr((struct DBLL_LibraryObj *)lib, ++ (char *)name, &pSym); ++ } ++ } ++ } ++ ++ if (!status && bGblSearch) { ++ GT_1trace(DBLL_debugMask, GT_6CLASS, ++ "findSymbol: Symbol not found: %s\n", name); ++ } ++ ++ DBC_Assert((status && (pSym != NULL)) || (!status && (pSym == NULL))); ++ ++ retSym = (struct dynload_symbol *)pSym; ++ return retSym; ++} ++ ++/* ++ * ======== findInSymbolTable ======== ++ */ ++static struct dynload_symbol *findInSymbolTable(struct Dynamic_Loader_Sym *this, ++ const char *name, ++ unsigned moduleid) ++{ ++ struct dynload_symbol *retSym; ++ struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this; ++ struct DBLL_LibraryObj *lib; ++ struct Symbol *sym; ++ ++ DBC_Require(this != NULL); ++ lib = pSymbol->lib; ++ DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE)); ++ DBC_Require(lib->symTab != NULL); ++ ++ sym = (struct Symbol *)GH_find(lib->symTab, (char *) name); ++ ++ retSym = (struct dynload_symbol *)&sym->value; ++ return retSym; ++} ++ ++/* ++ * ======== addToSymbolTable ======== ++ */ ++static struct dynload_symbol *addToSymbolTable(struct Dynamic_Loader_Sym *this, ++ const char *name, ++ unsigned moduleId) ++{ ++ struct Symbol *symPtr = NULL; ++ struct Symbol symbol; ++ struct dynload_symbol *pSym = NULL; ++ struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this; ++ struct DBLL_LibraryObj *lib; ++ struct dynload_symbol *retVal; ++ ++ DBC_Require(this != NULL); ++ DBC_Require(name); ++ lib = pSymbol->lib; ++ DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE)); ++ ++ /* Check to see if symbol is already defined in symbol table */ ++ if (!(lib->pTarget->attrs.baseImage)) { ++ bGblSearch = false; ++ pSym = findSymbol(this, name); ++ bGblSearch = true; ++ if (pSym) { ++ bRedefinedSymbol = true; ++ GT_1trace(DBLL_debugMask, GT_6CLASS, ++ "Symbol already defined in " ++ "symbol table: %s\n", name); ++ return NULL; ++ } ++ } ++ /* Allocate string to copy symbol name */ ++ symbol.name = (char *)MEM_Calloc(strlen((char *const)name) + 1, ++ MEM_PAGED); ++ if (symbol.name == NULL) ++ return NULL; ++ ++ if (symbol.name != NULL) { ++ /* Just copy name (value will be filled in by dynamic loader) */ ++ strncpy(symbol.name, (char *const)name, ++ strlen((char *const)name) + 1); ++ ++ /* Add symbol to symbol table */ ++ symPtr = (struct Symbol *)GH_insert(lib->symTab, (void *)name, ++ (void *)&symbol); ++ if (symPtr == NULL) ++ MEM_Free(symbol.name); ++ ++ } ++ if (symPtr != NULL) ++ retVal = (struct dynload_symbol *)&symPtr->value; ++ else ++ retVal = NULL; ++ ++ return retVal; ++} ++ ++/* ++ * ======== purgeSymbolTable ======== ++ */ ++static void purgeSymbolTable(struct Dynamic_Loader_Sym *this, unsigned moduleId) ++{ ++ struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this; ++ struct DBLL_LibraryObj *lib; ++ ++ DBC_Require(this != NULL); ++ lib = pSymbol->lib; ++ DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE)); ++ ++ /* May not need to do anything */ ++} ++ ++/* ++ * ======== allocate ======== ++ */ ++static void *allocate(struct Dynamic_Loader_Sym *this, unsigned memsize) ++{ ++ struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this; ++ struct DBLL_LibraryObj *lib; ++ void *buf; ++ ++ DBC_Require(this != NULL); ++ lib = pSymbol->lib; ++ DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE)); ++ ++ buf = MEM_Calloc(memsize, MEM_PAGED); ++ ++ return buf; ++} ++ ++/* ++ * ======== deallocate ======== ++ */ ++static void deallocate(struct Dynamic_Loader_Sym *this, void *memPtr) ++{ ++ struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this; ++ struct DBLL_LibraryObj *lib; ++ ++ DBC_Require(this != NULL); ++ lib = pSymbol->lib; ++ DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE)); ++ ++ MEM_Free(memPtr); ++} ++ ++/* ++ * ======== errorReport ======== ++ */ ++static void errorReport(struct Dynamic_Loader_Sym *this, const char *errstr, ++ va_list args) ++{ ++ struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this; ++ struct DBLL_LibraryObj *lib; ++ char tempBuf[MAXEXPR]; ++ ++ DBC_Require(this != NULL); ++ lib = pSymbol->lib; ++ DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE)); ++ vsnprintf((char *)tempBuf, MAXEXPR, (char *)errstr, args); ++ GT_1trace(DBLL_debugMask, GT_5CLASS, "%s\n", tempBuf); ++} ++ ++/* Dynamic_Loader_Allocate */ ++ ++/* ++ * ======== rmmAlloc ======== ++ */ ++static int rmmAlloc(struct Dynamic_Loader_Allocate *this, ++ struct LDR_SECTION_INFO *info, unsigned align) ++{ ++ struct DBLLAlloc *pAlloc = (struct DBLLAlloc *)this; ++ struct DBLL_LibraryObj *lib; ++ DSP_STATUS status = DSP_SOK; ++ u32 memType; ++ struct RMM_Addr rmmAddr; ++ s32 retVal = TRUE; ++ unsigned stype = DLOAD_SECTION_TYPE(info->type); ++ char *pToken = NULL; ++ char *szSecLastToken = NULL; ++ char *szLastToken = NULL; ++ char *szSectName = NULL; ++ char *pszCur; ++ s32 tokenLen = 0; ++ s32 segId = -1; ++ s32 req = -1; ++ s32 count = 0; ++ u32 allocSize = 0; ++ ++ DBC_Require(this != NULL); ++ lib = pAlloc->lib; ++ DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE)); ++ ++ memType = (stype == DLOAD_TEXT) ? DBLL_CODE : (stype == DLOAD_BSS) ? ++ DBLL_BSS : DBLL_DATA; ++ ++ /* Attempt to extract the segment ID and requirement information from ++ the name of the section */ ++ DBC_Require(info->name); ++ tokenLen = strlen((char *)(info->name)) + 1; ++ ++ szSectName = MEM_Calloc(tokenLen, MEM_PAGED); ++ szLastToken = MEM_Calloc(tokenLen, MEM_PAGED); ++ szSecLastToken = MEM_Calloc(tokenLen, MEM_PAGED); ++ ++ if (szSectName == NULL || szSecLastToken == NULL || ++ szLastToken == NULL) { ++ status = DSP_EMEMORY; ++ goto func_cont; ++ } ++ strncpy(szSectName, (char *)(info->name), tokenLen); ++ pszCur = szSectName; ++ while ((pToken = strsep(&pszCur, ":")) && *pToken != '\0') { ++ strncpy(szSecLastToken, szLastToken, strlen(szLastToken) + 1); ++ strncpy(szLastToken, pToken, strlen(pToken) + 1); ++ pToken = strsep(&pszCur, ":"); ++ count++; /* optimizes processing*/ ++ } ++ /* If pToken is 0 or 1, and szSecLastToken is DYN_DARAM or DYN_SARAM, ++ or DYN_EXTERNAL, then mem granularity information is present ++ within the section name - only process if there are at least three ++ tokens within the section name (just a minor optimization)*/ ++ if (count >= 3) ++ strict_strtol(szLastToken, 10, (long *)&req); ++ ++ if ((req == 0) || (req == 1)) { ++ if (strcmp(szSecLastToken, "DYN_DARAM") == 0) { ++ segId = 0; ++ } else { ++ if (strcmp(szSecLastToken, "DYN_SARAM") == 0) { ++ segId = 1; ++ } else { ++ if (strcmp(szSecLastToken, ++ "DYN_EXTERNAL") == 0) { ++ segId = 2; ++ } ++ } ++ } ++ if (segId != -1) { ++ GT_2trace(DBLL_debugMask, GT_5CLASS, ++ "Extracted values for memory" ++ " granularity req [%d] segId [%d]\n", ++ req, segId); ++ } ++ } ++ MEM_Free(szSectName); ++ szSectName = NULL; ++ MEM_Free(szLastToken); ++ szLastToken = NULL; ++ MEM_Free(szSecLastToken); ++ szSecLastToken = NULL; ++func_cont: ++ if (memType == DBLL_CODE) ++ allocSize = info->size + GEM_L1P_PREFETCH_SIZE; ++ else ++ allocSize = info->size; ++ /* TODO - ideally, we can pass the alignment requirement also ++ * from here */ ++ if (lib != NULL) { ++ status = (lib->pTarget->attrs.alloc)(lib->pTarget-> ++ attrs.rmmHandle, memType, allocSize, align, ++ (u32 *)&rmmAddr, segId, req, FALSE); ++ } ++ if (DSP_FAILED(status)) { ++ retVal = false; ++ } else { ++ /* RMM gives word address. Need to convert to byte address */ ++ info->load_addr = rmmAddr.addr * DSPWORDSIZE; ++ info->run_addr = info->load_addr; ++ info->context = (u32)rmmAddr.segid; ++ GT_3trace(DBLL_debugMask, GT_5CLASS, ++ "Remote alloc: %s base = 0x%lx len" ++ "= 0x%lx\n", info->name, info->load_addr / DSPWORDSIZE, ++ info->size / DSPWORDSIZE); ++ } ++ return retVal; ++} ++ ++/* ++ * ======== rmmDealloc ======== ++ */ ++static void rmmDealloc(struct Dynamic_Loader_Allocate *this, ++ struct LDR_SECTION_INFO *info) ++{ ++ struct DBLLAlloc *pAlloc = (struct DBLLAlloc *)this; ++ struct DBLL_LibraryObj *lib; ++ u32 segid; ++ DSP_STATUS status = DSP_SOK; ++ unsigned stype = DLOAD_SECTION_TYPE(info->type); ++ u32 memType; ++ u32 freeSize = 0; ++ ++ memType = (stype == DLOAD_TEXT) ? DBLL_CODE : (stype == DLOAD_BSS) ? ++ DBLL_BSS : DBLL_DATA; ++ DBC_Require(this != NULL); ++ lib = pAlloc->lib; ++ DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE)); ++ /* segid was set by alloc function */ ++ segid = (u32)info->context; ++ if (memType == DBLL_CODE) ++ freeSize = info->size + GEM_L1P_PREFETCH_SIZE; ++ else ++ freeSize = info->size; ++ if (lib != NULL) { ++ status = (lib->pTarget->attrs.free)(lib->pTarget-> ++ attrs.symHandle, segid, info->load_addr / DSPWORDSIZE, ++ freeSize, false); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ GT_2trace(DBLL_debugMask, GT_5CLASS, ++ "Remote dealloc: base = 0x%lx len =" ++ "0x%lx\n", info->load_addr / DSPWORDSIZE, ++ freeSize / DSPWORDSIZE); ++ } ++} ++ ++/* Dynamic_Loader_Initialize */ ++/* ++ * ======== connect ======== ++ */ ++static int connect(struct Dynamic_Loader_Initialize *this) ++{ ++ return true; ++} ++ ++/* ++ * ======== readMem ======== ++ * This function does not need to be implemented. ++ */ ++static int readMem(struct Dynamic_Loader_Initialize *this, void *buf, ++ LDR_ADDR addr, struct LDR_SECTION_INFO *info, ++ unsigned nbytes) ++{ ++ struct DBLLInit *pInit = (struct DBLLInit *)this; ++ struct DBLL_LibraryObj *lib; ++ int bytesRead = 0; ++ ++ DBC_Require(this != NULL); ++ lib = pInit->lib; ++ DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE)); ++ /* Need WMD_BRD_Read function */ ++ return bytesRead; ++} ++ ++/* ++ * ======== writeMem ======== ++ */ ++static int writeMem(struct Dynamic_Loader_Initialize *this, void *buf, ++ LDR_ADDR addr, struct LDR_SECTION_INFO *info, ++ unsigned nBytes) ++{ ++ struct DBLLInit *pInit = (struct DBLLInit *)this; ++ struct DBLL_LibraryObj *lib; ++ struct DBLL_SectInfo sectInfo; ++ u32 memType; ++ bool retVal = true; ++ ++ DBC_Require(this != NULL); ++ lib = pInit->lib; ++ DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE)); ++ ++ memType = (DLOAD_SECTION_TYPE(info->type) == DLOAD_TEXT) ? DBLL_CODE : ++ DBLL_DATA; ++ if (lib != NULL) { ++ retVal = (*lib->pTarget->attrs.write)(lib->pTarget-> ++ attrs.wHandle, addr, buf, nBytes, memType); ++ } ++ if (lib->pTarget->attrs.logWrite) { ++ sectInfo.name = info->name; ++ sectInfo.runAddr = info->run_addr; ++ sectInfo.loadAddr = info->load_addr; ++ sectInfo.size = info->size; ++ sectInfo.type = memType; ++ /* Pass the information about what we've written to ++ * another module */ ++ (*lib->pTarget->attrs.logWrite)(lib->pTarget-> ++ attrs.logWriteHandle, §Info, addr, nBytes); ++ } ++ return retVal; ++} ++ ++/* ++ * ======== fillMem ======== ++ * Fill nBytes of memory at a given address with a given value by ++ * writing from a buffer containing the given value. Write in ++ * sets of MAXEXPR (128) bytes to avoid large stack buffer issues. ++ */ ++static int fillMem(struct Dynamic_Loader_Initialize *this, LDR_ADDR addr, ++ struct LDR_SECTION_INFO *info, unsigned nBytes, ++ unsigned val) ++{ ++ bool retVal = true; ++ char *pBuf; ++ struct DBLL_LibraryObj *lib; ++ struct DBLLInit *pInit = (struct DBLLInit *)this; ++ ++ DBC_Require(this != NULL); ++ lib = pInit->lib; ++ pBuf = NULL; ++ /* Pass the NULL pointer to writeMem to get the start address of Shared ++ memory. This is a trick to just get the start address, there is no ++ writing taking place with this Writemem ++ */ ++ if ((lib->pTarget->attrs.write) != (DBLL_WriteFxn)NoOp) ++ writeMem(this, &pBuf, addr, info, 0); ++ if (pBuf) ++ memset(pBuf, val, nBytes); ++ ++ return retVal; ++} ++ ++/* ++ * ======== execute ======== ++ */ ++static int execute(struct Dynamic_Loader_Initialize *this, LDR_ADDR start) ++{ ++ struct DBLLInit *pInit = (struct DBLLInit *)this; ++ struct DBLL_LibraryObj *lib; ++ bool retVal = true; ++ ++ DBC_Require(this != NULL); ++ lib = pInit->lib; ++ DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE)); ++ /* Save entry point */ ++ if (lib != NULL) ++ lib->entry = (u32)start; ++ ++ return retVal; ++} ++ ++/* ++ * ======== release ======== ++ */ ++static void release(struct Dynamic_Loader_Initialize *this) ++{ ++} ++ +diff --git a/drivers/dsp/bridge/pmgr/dev.c b/drivers/dsp/bridge/pmgr/dev.c +new file mode 100644 +index 0000000..1c2f7d5 +--- /dev/null ++++ b/drivers/dsp/bridge/pmgr/dev.c +@@ -0,0 +1,1476 @@ ++/* ++ * dev.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== dev.c ======== ++ * Description: ++ * Implementation of 'Bridge Mini-driver device operations. ++ * ++ * Public Functions: ++ * DEV_BrdWriteFxn ++ * DEV_CreateDevice ++ * DEV_Create2 ++ * DEV_Destroy2 ++ * DEV_DestroyDevice ++ * DEV_GetChnlMgr ++ * DEV_GetCmmMgr ++ * DEV_GetCodMgr ++ * DEV_GetDehMgr ++ * DEV_GetDevNode ++ * DEV_GetDSPWordSize ++ * DEV_GetFirst ++ * DEV_GetIntfFxns ++ * DEV_GetIOMgr ++ * DEV_GetNext ++ * DEV_GetNodeManager ++ * DEV_GetSymbol ++ * DEV_GetWMDContext ++ * DEV_Exit ++ * DEV_Init ++ * DEV_InsertProcObject ++ * DEV_IsLocked ++ * DEV_NotifyClient ++ * DEV_RegisterNotify ++ * DEV_ReleaseCodMgr ++ * DEV_RemoveDevice ++ * DEV_RemoveProcObject ++ * DEV_SetChnlMgr ++ * DEV_SetMsgMgr ++ * DEV_SetLockOwner ++ * DEV_StartDevice ++ * ++ * Private Functions: ++ * FxnNotImplemented ++ * InitCodMgr ++ * InsertDevObject ++ * IsValidHandle ++ * RemoveDevObject ++ * StoreInterfaceFxns ++ * ++ *! Revision History: ++ *! ================ ++ *! 03-Jan-2005 hn Support for IVA DEH ++ *! 08-Mar-2004 sb Added the Dynamic Memory Mapping feature ++ *! 09-Feb-2004 vp Updated to support IVA. ++ *! 24-Feb-2003 swa PMGR Code review comments incorporated. ++ *! 29-Nov-2001 jeh Check for DSP_ENOTIMPL status of DEH create function. ++ *! 05-Nov-2001 kc Added support for DEH module. ++ *! 05-Aug-2001 ag Shared memory registration moved to WMD_IO_OnLoaded(). ++ *! 11-Jul-2001 jeh Moved MGR_Create() from DSP_Init() to DEV_StartDevice(). ++ *! 11-Apr-2001 rr: Removed CMM_RegisterGPPSMSeg. ++ *! 02-Apr-2001 rr: CHNL_Create failure is printed out. ++ *! 15-Jan-2001 jeh Removed call to IO_OnLoaded() from DEV_Create2(). ++ *! 13-Feb-2001 kc: DSP/BIOS Bridge name update. ++ *! 15-Dec-2000 rr: Dev_Create2 returns error if NODE_CreateMgr fails. ++ *! 05-Dec-2000 jeh Moved IO_OnLoaded() to PROC_Load. Added DEV_SetMsgMgr. ++ *! 05-Dev-2000 ag SM Heap for messaging registered via CMM_RegisterGPPSMSeg(). ++ *! SM heap base and size currently taken from registry. ++ *! 29-Nov-2000 rr: Incorporated code review changes. ++ *! 17-Nov-2000 jeh Added calls to get IO manager (IO_Create), IO_OnLoaded(). ++ *! 06-Oct-2000 rr: DEV_Destroy2 and DEV_Create2 added. ++ *! 02-Oct-2000 rr: DEV_GetNodeManager added. ++ *! 11-Aug-2000 ag: Added DEV_GetCmmMgr(), CMM_Init() & CMM_Exit(). ++ *! Removed & , added ++ *! 10-Aug-2000 rr: DEV_InsertProcObject/RemoveProcObject added. ++ *! DEV_Cleanup calls PROC_Detach if it is a matching process. ++ *! 27-Jul-2000 rr: DEV is in new directoy DEV and produces devlib.lib ++ *! 17-Jul-2000 rr: DRV Object holds the list of Dev Objects. DEV gets ++ *! the List and Next devices through DRV. ++ *! DEV object has a back pointer to DRV Object. ++ *! 06-Jun-2000 jeh Added DEV_GetSymbol(). ++ *! 09-May-2000 rr: dwMemBase has index for multiple windows need. ++ *! 28-Feb-2000 rr: New GT Usage implemented. ++ *! 03-Feb-2000 rr: GT and Module init/exit Changes.(Done up front from ++ *! SERVICES) ++ *! 31-Jan-2000 rr: Comments changed after code review. ++ *! 21-Jan-2000 rr: windows.h, tchar.h, HMODULE removed. FreeLibrary replaced ++ *! with LDR_FreeModule ++ *! 17-Jan-2000 rr: CFG_Get/SetPrivateDword renamed to CFG_Get/SetDevObject. ++ *! StoreInterfaceFxns stores the new fxn WMD_BRD_SETSTATE. ++ *! 20-Nov-1999 ag: Actual uSMLength = total - monitor offset. ++ *! 12-Nov-1999 rr: bIRQ and IRQAttrib taken from the struct CFG_HOSTRES. ++ *! dMemBase is added with offset for monitor taken from ++ *! registry. ++ *! 31-Oct-1999 ag: Added CHNL support. ++ *! 10-Sep-1999 rr: GT Enabled. DEV_Create will Load the Mini Driver and will ++ *! find its fxn table. Right now lot of things are hardcoded ++ *! as the REG is not ready. ++ *! 10-Jun-1996 rr: Created from WSX ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Resource Manager */ ++#include ++#include ++ ++/* ----------------------------------- Others */ ++#include ++#include /* WCD version info. */ ++ ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++/* ----------------------------------- Defines, Data Structures, Typedefs */ ++ ++#define SIGNATURE 0x5f564544 /* "DEV_" (in reverse) */ ++#define MAKEVERSION(major, minor) (major * 10 + minor) ++#define WCDVERSION MAKEVERSION(WCD_MAJOR_VERSION, WCD_MINOR_VERSION) ++ ++/* The WMD device object: */ ++struct DEV_OBJECT { ++ /* LST requires "link" to be first field! */ ++ struct LST_ELEM link; /* Link to next DEV_OBJECT. */ ++ u32 devType; /* Device Type */ ++ u32 dwSignature; /* Used for object validation. */ ++ struct CFG_DEVNODE *hDevNode; /* Platform specific device id */ ++ struct WMD_DEV_CONTEXT *hWmdContext; /* WMD Context Handle */ ++ struct WMD_DRV_INTERFACE intfFxns; /* Function interface to WMD. */ ++ struct BRD_OBJECT *lockOwner; /* Client with exclusive access. */ ++ struct COD_MANAGER *hCodMgr; /* Code manager handle. */ ++ struct CHNL_MGR *hChnlMgr; /* Channel manager. */ ++ struct DEH_MGR *hDehMgr; /* DEH manager. */ ++ struct MSG_MGR *hMsgMgr; /* Message manager. */ ++ struct IO_MGR *hIOMgr; /* IO manager (CHNL, MSG) */ ++ struct CMM_OBJECT *hCmmMgr; /* SM memory manager. */ ++ struct DMM_OBJECT *hDmmMgr; /* Dynamic memory manager. */ ++ struct LDR_MODULE *hModule; /* WMD Module handle. */ ++ u32 uWordSize; /* DSP word size: quick access. */ ++ struct DRV_OBJECT *hDrvObject; /* Driver Object */ ++ struct LST_LIST *procList; /* List of Proceeosr attached to ++ * this device */ ++ struct NODE_MGR *hNodeMgr; ++} ; ++ ++/* ----------------------------------- Globals */ ++static u32 cRefs; /* Module reference count */ ++#if GT_TRACE ++static struct GT_Mask debugMask = { NULL, NULL }; /* For debugging */ ++#endif ++ ++/* ----------------------------------- Function Prototypes */ ++static DSP_STATUS FxnNotImplemented(int arg, ...); ++static DSP_STATUS InitCodMgr(struct DEV_OBJECT *pDevObject); ++static bool IsValidHandle(struct DEV_OBJECT *hObj); ++static void StoreInterfaceFxns(struct WMD_DRV_INTERFACE *pDrvFxns, ++ OUT struct WMD_DRV_INTERFACE *pIntfFxns); ++/* ++ * ======== DEV_BrdWriteFxn ======== ++ * Purpose: ++ * Exported function to be used as the COD write function. This function ++ * is passed a handle to a DEV_hObject, then calls the ++ * device's WMD_BRD_Write() function. ++ */ ++u32 DEV_BrdWriteFxn(void *pArb, u32 ulDspAddr, void *pHostBuf, ++ u32 ulNumBytes, u32 nMemSpace) ++{ ++ struct DEV_OBJECT *pDevObject = (struct DEV_OBJECT *)pArb; ++ u32 ulWritten = 0; ++ DSP_STATUS status; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pHostBuf != NULL); /* Required of BrdWrite(). */ ++ GT_5trace(debugMask, GT_ENTER, ++ "Entered DEV_BrdWriteFxn, pArb: 0x%x\n\t\t" ++ "ulDspAddr: 0x%x\n\t\tpHostBuf: 0x%x\n \t\tulNumBytes: 0x%x\n" ++ "\t\tnMemSpace: 0x%x\n", pArb, ulDspAddr, pHostBuf, ++ ulNumBytes, nMemSpace); ++ if (IsValidHandle(pDevObject)) { ++ /* Require of BrdWrite() */ ++ DBC_Assert(pDevObject->hWmdContext != NULL); ++ status = (*pDevObject->intfFxns.pfnBrdWrite)(pDevObject-> ++ hWmdContext, pHostBuf, ulDspAddr, ulNumBytes, ++ nMemSpace); ++ /* Special case of getting the address only */ ++ if (ulNumBytes == 0) ++ ulNumBytes = 1; ++ if (DSP_SUCCEEDED(status)) ++ ulWritten = ulNumBytes; ++ ++ } ++ GT_1trace(debugMask, GT_ENTER, "Exit DEV_BrdWriteFxn ulWritten: 0x%x\n", ++ ulWritten); ++ return ulWritten; ++} ++ ++/* ++ * ======== DEV_CreateDevice ======== ++ * Purpose: ++ * Called by the operating system to load the PM Mini Driver for a ++ * PM board (device). ++ */ ++DSP_STATUS DEV_CreateDevice(OUT struct DEV_OBJECT **phDevObject, ++ IN CONST char *pstrWMDFileName, ++ IN CONST struct CFG_HOSTRES *pHostConfig, ++ IN CONST struct CFG_DSPRES *pDspConfig, ++ struct CFG_DEVNODE *hDevNode) ++{ ++ struct LDR_MODULE *hModule = NULL; ++ struct WMD_DRV_INTERFACE *pDrvFxns = NULL; ++ struct DEV_OBJECT *pDevObject = NULL; ++ struct CHNL_MGRATTRS mgrAttrs; ++ struct IO_ATTRS ioMgrAttrs; ++ u32 uNumWindows; ++ struct DRV_OBJECT *hDrvObject = NULL; ++ DSP_STATUS status = DSP_SOK; ++ DBC_Require(cRefs > 0); ++ DBC_Require(phDevObject != NULL); ++ DBC_Require(pstrWMDFileName != NULL); ++ DBC_Require(pHostConfig != NULL); ++ DBC_Require(pDspConfig != NULL); ++ ++ GT_5trace(debugMask, GT_ENTER, ++ "Entered DEV_CreateDevice, phDevObject: 0x%x\n" ++ "\t\tpstrWMDFileName: 0x%x\n\t\tpHostConfig:0x%x\n\t\t" ++ "pDspConfig: 0x%x\n\t\tnhDevNode: 0x%x\n", phDevObject, ++ pstrWMDFileName, pHostConfig, pDspConfig, hDevNode); ++ /* Get the WMD interface functions*/ ++ WMD_DRV_Entry(&pDrvFxns, pstrWMDFileName); ++ if (DSP_FAILED(CFG_GetObject((u32 *) &hDrvObject, REG_DRV_OBJECT))) { ++ /* don't propogate CFG errors from this PROC function */ ++ GT_0trace(debugMask, GT_7CLASS, ++ "Failed to get the DRV Object \n"); ++ status = DSP_EFAIL; ++ } ++ /* Create the device object, and pass a handle to the WMD for ++ * storage. */ ++ if (DSP_SUCCEEDED(status)) { ++ DBC_Assert(pDrvFxns); ++ MEM_AllocObject(pDevObject, struct DEV_OBJECT, SIGNATURE); ++ if (pDevObject) { ++ /* Fill out the rest of the Dev Object structure: */ ++ pDevObject->hDevNode = hDevNode; ++ pDevObject->hModule = hModule; ++ pDevObject->hCodMgr = NULL; ++ pDevObject->hChnlMgr = NULL; ++ pDevObject->hDehMgr = NULL; ++ pDevObject->lockOwner = NULL; ++ pDevObject->uWordSize = pDspConfig->uWordSize; ++ pDevObject->hDrvObject = hDrvObject; ++ pDevObject->devType = DSP_UNIT; ++ /* Store this WMD's interface functions, based on its ++ * version. */ ++ StoreInterfaceFxns(pDrvFxns, &pDevObject->intfFxns); ++ /* Call WMD_DEV_CREATE() to get the WMD's device ++ * context handle. */ ++ status = (pDevObject->intfFxns.pfnDevCreate) ++ (&pDevObject->hWmdContext, pDevObject, ++ pHostConfig, pDspConfig); ++ /* Assert WMD_DEV_Create()'s ensure clause: */ ++ DBC_Assert(DSP_FAILED(status) || (pDevObject-> ++ hWmdContext != NULL)); ++ } else { ++ GT_0trace(debugMask, GT_7CLASS, ++ "DEV_Create: Out Of Memory"); ++ status = DSP_EMEMORY; ++ } ++ } ++ /* Attempt to create the COD manager for this device: */ ++ if (DSP_SUCCEEDED(status)) ++ status = InitCodMgr(pDevObject); ++ ++ /* Attempt to create the channel manager for this device: */ ++ if (DSP_SUCCEEDED(status)) { ++ mgrAttrs.cChannels = CHNL_MAXCHANNELS; ++ ioMgrAttrs.bIRQ = pHostConfig->bIRQRegisters; ++ ioMgrAttrs.fShared = (pHostConfig->bIRQAttrib & CFG_IRQSHARED); ++ ioMgrAttrs.uWordSize = pDspConfig->uWordSize; ++ mgrAttrs.uWordSize = pDspConfig->uWordSize; ++ uNumWindows = pHostConfig->wNumMemWindows; ++ if (uNumWindows) { ++ /* Assume last memory window is for CHNL */ ++ ioMgrAttrs.dwSMBase = pHostConfig->dwMemBase[1] + ++ pHostConfig->dwOffsetForMonitor; ++ ioMgrAttrs.uSMLength = pHostConfig->dwMemLength[1] - ++ pHostConfig->dwOffsetForMonitor; ++ } else { ++ ioMgrAttrs.dwSMBase = 0; ++ ioMgrAttrs.uSMLength = 0; ++ GT_0trace(debugMask, GT_7CLASS, ++ "**There is no memory reserved for " ++ "shared structures**\n"); ++ } ++ status = CHNL_Create(&pDevObject->hChnlMgr, pDevObject, ++ &mgrAttrs); ++ if (status == DSP_ENOTIMPL) { ++ /* It's OK for a device not to have a channel ++ * manager: */ ++ status = DSP_SOK; ++ } ++ /* Create CMM mgr even if Msg Mgr not impl. */ ++ status = CMM_Create(&pDevObject->hCmmMgr, ++ (struct DEV_OBJECT *)pDevObject, NULL); ++ if (DSP_FAILED(status)) { ++ GT_0trace(debugMask, GT_7CLASS, ++ "DEV_Create: Failed to Create SM " ++ "Manager\n"); ++ } ++ /* Only create IO manager if we have a channel manager */ ++ if (DSP_SUCCEEDED(status) && pDevObject->hChnlMgr) { ++ status = IO_Create(&pDevObject->hIOMgr, pDevObject, ++ &ioMgrAttrs); ++ } ++ /* Only create DEH manager if we have an IO manager */ ++ if (DSP_SUCCEEDED(status)) { ++ /* Instantiate the DEH module */ ++ status = (*pDevObject->intfFxns.pfnDehCreate) ++ (&pDevObject->hDehMgr, pDevObject); ++ } ++ /* Create DMM mgr . */ ++ status = DMM_Create(&pDevObject->hDmmMgr, ++ (struct DEV_OBJECT *)pDevObject, NULL); ++ if (DSP_FAILED(status)) { ++ GT_0trace(debugMask, GT_7CLASS, ++ "DEV_Create: Failed to Create DMM " ++ "Manager\n"); ++ } ++ } ++ /* Add the new DEV_Object to the global list: */ ++ if (DSP_SUCCEEDED(status)) { ++ LST_InitElem(&pDevObject->link); ++ status = DRV_InsertDevObject(hDrvObject, pDevObject); ++ } ++ /* Create the Processor List */ ++ if (DSP_SUCCEEDED(status)) { ++ pDevObject->procList = LST_Create(); ++ if (!(pDevObject->procList)) { ++ status = DSP_EFAIL; ++ GT_0trace(debugMask, GT_7CLASS, "DEV_Create: " ++ "Failed to Create Proc List"); ++ } ++ } ++ /* If all went well, return a handle to the dev object; ++ * else, cleanup and return NULL in the OUT parameter. */ ++ if (DSP_SUCCEEDED(status)) { ++ *phDevObject = pDevObject; ++ GT_1trace(debugMask, GT_1CLASS, ++ "DEV_CreateDevice Succeeded \nDevObject " ++ "0x%x\n", pDevObject); ++ } else { ++ if (pDevObject && pDevObject->procList) ++ LST_Delete(pDevObject->procList); ++ ++ if (pDevObject && pDevObject->hCodMgr) ++ COD_Delete(pDevObject->hCodMgr); ++ ++ if (pDevObject && pDevObject->hDmmMgr) ++ DMM_Destroy(pDevObject->hDmmMgr); ++ ++ if (pDevObject) ++ MEM_FreeObject(pDevObject); ++ ++ *phDevObject = NULL; ++ GT_0trace(debugMask, GT_7CLASS, "DEV_CreateDevice Failed\n"); ++ } ++ GT_1trace(debugMask, GT_1CLASS, "Exiting DEV_Create: DevObject 0x%x\n", ++ *phDevObject); ++ DBC_Ensure((DSP_SUCCEEDED(status) && IsValidHandle(*phDevObject)) || ++ (DSP_FAILED(status) && !*phDevObject)); ++ return status; ++} ++ ++/* ++ * ======== DEV_Create2 ======== ++ * Purpose: ++ * After successful loading of the image from WCD_InitComplete2 ++ * (PROC Auto_Start) or PROC_Load this fxn is called. This creates ++ * the Node Manager and updates the DEV Object. ++ */ ++DSP_STATUS DEV_Create2(struct DEV_OBJECT *hDevObject) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEV_OBJECT *pDevObject = hDevObject; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(IsValidHandle(hDevObject)); ++ ++ GT_1trace(debugMask, GT_ENTER, ++ "Entered DEV_Create2, hDevObject: 0x%x\n", hDevObject); ++ /* There can be only one Node Manager per DEV object */ ++ DBC_Assert(!pDevObject->hNodeMgr); ++ status = NODE_CreateMgr(&pDevObject->hNodeMgr, hDevObject); ++ if (DSP_FAILED(status)) { ++ GT_1trace(debugMask, GT_7CLASS, ++ "DEV_Create2: NODE_CreateMgr failed, " ++ "0x%x!\n", status); ++ pDevObject->hNodeMgr = NULL; ++ GT_0trace(debugMask, GT_7CLASS, "DEV_Create2: Failed!!\n"); ++ } ++ DBC_Ensure((DSP_SUCCEEDED(status) && pDevObject->hNodeMgr != NULL) ++ || (DSP_FAILED(status) && pDevObject->hNodeMgr == NULL)); ++ GT_2trace(debugMask, GT_ENTER, ++ "Exiting DEV_Create2, hNodeMgr: 0x%x, status:" ++ " 0x%x\n", pDevObject->hNodeMgr, status); ++ return status; ++} ++ ++/* ++ * ======== DEV_Destroy2 ======== ++ * Purpose: ++ * Destroys the Node manager for this device. ++ */ ++DSP_STATUS DEV_Destroy2(struct DEV_OBJECT *hDevObject) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEV_OBJECT *pDevObject = hDevObject; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(IsValidHandle(hDevObject)); ++ ++ GT_1trace(debugMask, GT_ENTER, ++ "Entered DEV_Destroy2, hDevObject: 0x%x\n", ++ hDevObject); ++ if (pDevObject->hNodeMgr) { ++ if (DSP_FAILED(NODE_DeleteMgr(pDevObject->hNodeMgr))) ++ status = DSP_EFAIL; ++ else ++ pDevObject->hNodeMgr = NULL; ++ ++ } ++ if (DSP_FAILED(status)) ++ GT_0trace(debugMask, GT_7CLASS, "DEV_Destroy2 failed!!\n"); ++ ++ DBC_Ensure((DSP_SUCCEEDED(status) && pDevObject->hNodeMgr == NULL) || ++ DSP_FAILED(status)); ++ GT_2trace(debugMask, GT_ENTER, ++ "Exiting DEV_Destroy2, hNodeMgr: 0x%x, status" ++ " = 0x%x\n", pDevObject->hNodeMgr, status); ++ return status; ++} ++ ++/* ++ * ======== DEV_DestroyDevice ======== ++ * Purpose: ++ * Destroys the channel manager for this device, if any, calls ++ * WMD_DEV_Destroy(), and then attempts to unload the WMD module. ++ */ ++DSP_STATUS DEV_DestroyDevice(struct DEV_OBJECT *hDevObject) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEV_OBJECT *pDevObject = hDevObject; ++ ++ DBC_Require(cRefs > 0); ++ ++ GT_1trace(debugMask, GT_ENTER, "Entered DEV_DestroyDevice, hDevObject: " ++ "0x%x\n", hDevObject); ++ if (IsValidHandle(hDevObject)) { ++ if (pDevObject->hCodMgr) ++ COD_Delete(pDevObject->hCodMgr); ++ ++ if (pDevObject->hNodeMgr) ++ NODE_DeleteMgr(pDevObject->hNodeMgr); ++ ++ /* Free the io, channel, and message managers for this board: */ ++ if (pDevObject->hIOMgr) { ++ IO_Destroy(pDevObject->hIOMgr); ++ pDevObject->hIOMgr = NULL; ++ } ++ if (pDevObject->hChnlMgr) { ++ CHNL_Destroy(pDevObject->hChnlMgr); ++ pDevObject->hChnlMgr = NULL; ++ } ++ if (pDevObject->hMsgMgr) ++ MSG_Delete(pDevObject->hMsgMgr); ++ ++ if (pDevObject->hDehMgr) { ++ /* Uninitialize DEH module. */ ++ (*pDevObject->intfFxns.pfnDehDestroy) ++ (pDevObject->hDehMgr); ++ } ++ if (pDevObject->hCmmMgr) ++ CMM_Destroy(pDevObject->hCmmMgr, true); ++ ++ if (pDevObject->hDmmMgr) ++ DMM_Destroy(pDevObject->hDmmMgr); ++ ++ /* Call the driver's WMD_DEV_Destroy() function: */ ++ /* Require of DevDestroy */ ++ DBC_Assert(pDevObject->hWmdContext != NULL); ++ status = (*pDevObject->intfFxns.pfnDevDestroy) ++ (pDevObject->hWmdContext); ++ if (DSP_SUCCEEDED(status)) { ++ if (pDevObject->procList) ++ LST_Delete(pDevObject->procList); ++ ++ /* Remove this DEV_Object from the global list: */ ++ DRV_RemoveDevObject(pDevObject->hDrvObject, pDevObject); ++ /* Free The library * LDR_FreeModule ++ * (pDevObject->hModule);*/ ++ /* Free this dev object: */ ++ MEM_FreeObject(pDevObject); ++ } ++ } else { ++ GT_0trace(debugMask, GT_7CLASS, "DEV_Destroy: Invlaid handle"); ++ status = DSP_EHANDLE; ++ } ++ GT_1trace(debugMask, GT_ENTER, "Exit DEV_destroy: status 0x%x\n", ++ status); ++ return status; ++} ++ ++/* ++ * ======== DEV_GetChnlMgr ======== ++ * Purpose: ++ * Retrieve the handle to the channel manager handle created for this ++ * device. ++ */ ++DSP_STATUS DEV_GetChnlMgr(struct DEV_OBJECT *hDevObject, ++ OUT struct CHNL_MGR **phMgr) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEV_OBJECT *pDevObject = hDevObject; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phMgr != NULL); ++ ++ GT_2trace(debugMask, GT_ENTER, ++ "Entered DEV_GetChnlMgr, hDevObject: 0x%x\n\t" ++ "\tphMgr: 0x%x\n", hDevObject, phMgr); ++ if (IsValidHandle(hDevObject)) { ++ *phMgr = pDevObject->hChnlMgr; ++ } else { ++ *phMgr = NULL; ++ status = DSP_EHANDLE; ++ GT_0trace(debugMask, GT_7CLASS, ++ "DEV_GetChnlMgr: Invalid handle"); ++ } ++ GT_2trace(debugMask, GT_ENTER, ++ "Exit DEV_GetChnlMgr: status 0x%x\t\n hMgr: " ++ "0x%x\n", status, *phMgr); ++ DBC_Ensure(DSP_SUCCEEDED(status) || ((phMgr != NULL) && ++ (*phMgr == NULL))); ++ return status; ++} ++ ++/* ++ * ======== DEV_GetCmmMgr ======== ++ * Purpose: ++ * Retrieve the handle to the shared memory manager created for this ++ * device. ++ */ ++DSP_STATUS DEV_GetCmmMgr(struct DEV_OBJECT *hDevObject, ++ OUT struct CMM_OBJECT **phMgr) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEV_OBJECT *pDevObject = hDevObject; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phMgr != NULL); ++ GT_2trace(debugMask, GT_ENTER, ++ "Entered DEV_GetCmmMgr, hDevObject: 0x%x\n\t" ++ "\tphMgr: 0x%x\n", hDevObject, phMgr); ++ if (IsValidHandle(hDevObject)) { ++ *phMgr = pDevObject->hCmmMgr; ++ } else { ++ *phMgr = NULL; ++ status = DSP_EHANDLE; ++ GT_0trace(debugMask, GT_7CLASS, ++ "DEV_GetCmmMgr: Invalid handle"); ++ } ++ GT_2trace(debugMask, GT_ENTER, ++ "Exit DEV_GetCmmMgr: status 0x%x\t\nhMgr: " ++ "0x%x\n", status, *phMgr); ++ DBC_Ensure(DSP_SUCCEEDED(status) || ((phMgr != NULL) && ++ (*phMgr == NULL))); ++ return status; ++} ++ ++/* ++ * ======== DEV_GetDmmMgr ======== ++ * Purpose: ++ * Retrieve the handle to the dynamic memory manager created for this ++ * device. ++ */ ++DSP_STATUS DEV_GetDmmMgr(struct DEV_OBJECT *hDevObject, ++ OUT struct DMM_OBJECT **phMgr) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEV_OBJECT *pDevObject = hDevObject; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phMgr != NULL); ++ ++ GT_2trace(debugMask, GT_ENTER, "Entered DEV_GetDmmMgr, hDevObject: " ++ "0x%x\n\t\tphMgr: 0x%x\n", hDevObject, phMgr); ++ if (IsValidHandle(hDevObject)) { ++ *phMgr = pDevObject->hDmmMgr; ++ } else { ++ *phMgr = NULL; ++ status = DSP_EHANDLE; ++ GT_0trace(debugMask, GT_7CLASS, ++ "DEV_GetDmmMgr: Invalid handle"); ++ } ++ GT_2trace(debugMask, GT_ENTER, ++ "Exit DEV_GetDmmMgr: status 0x%x\t\n hMgr: " ++ "0x%x\n", status, *phMgr); ++ DBC_Ensure(DSP_SUCCEEDED(status) || ((phMgr != NULL) && ++ (*phMgr == NULL))); ++ return status; ++} ++ ++/* ++ * ======== DEV_GetCodMgr ======== ++ * Purpose: ++ * Retrieve the COD manager create for this device. ++ */ ++DSP_STATUS DEV_GetCodMgr(struct DEV_OBJECT *hDevObject, ++ OUT struct COD_MANAGER **phCodMgr) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEV_OBJECT *pDevObject = hDevObject; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phCodMgr != NULL); ++ ++ GT_2trace(debugMask, GT_ENTER, ++ "Entered DEV_GetCodMgr, hDevObject: 0x%x\n\t\t" ++ "phCodMgr: 0x%x\n", hDevObject, phCodMgr); ++ if (IsValidHandle(hDevObject)) { ++ *phCodMgr = pDevObject->hCodMgr; ++ } else { ++ *phCodMgr = NULL; ++ status = DSP_EHANDLE; ++ GT_1trace(debugMask, GT_7CLASS, ++ "DEV_GetCodMgr, invalid handle: 0x%x\n", ++ hDevObject); ++ } ++ GT_2trace(debugMask, GT_ENTER, ++ "Exit DEV_GetCodMgr: status 0x%x\t\n hCodMgr:" ++ " 0x%x\n", status, *phCodMgr); ++ DBC_Ensure(DSP_SUCCEEDED(status) || ((phCodMgr != NULL) && ++ (*phCodMgr == NULL))); ++ return status; ++} ++ ++/* ++ * ========= DEV_GetDehMgr ======== ++ */ ++DSP_STATUS DEV_GetDehMgr(struct DEV_OBJECT *hDevObject, ++ OUT struct DEH_MGR **phDehMgr) ++{ ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phDehMgr != NULL); ++ DBC_Require(MEM_IsValidHandle(hDevObject, SIGNATURE)); ++ if (IsValidHandle(hDevObject)) { ++ *phDehMgr = hDevObject->hDehMgr; ++ } else { ++ *phDehMgr = NULL; ++ status = DSP_EHANDLE; ++ GT_0trace(debugMask, GT_7CLASS, ++ "DEV_GetDehMgr: Invalid handle"); ++ } ++ return status; ++} ++ ++/* ++ * ======== DEV_GetDevNode ======== ++ * Purpose: ++ * Retrieve the platform specific device ID for this device. ++ */ ++DSP_STATUS DEV_GetDevNode(struct DEV_OBJECT *hDevObject, ++ OUT struct CFG_DEVNODE **phDevNode) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEV_OBJECT *pDevObject = hDevObject; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phDevNode != NULL); ++ ++ GT_2trace(debugMask, GT_ENTER, ++ "Entered DEV_GetDevNode, hDevObject: 0x%x\n\t" ++ "\tphDevNode: 0x%x\n", hDevObject, phDevNode); ++ if (IsValidHandle(hDevObject)) { ++ *phDevNode = pDevObject->hDevNode; ++ } else { ++ *phDevNode = NULL; ++ status = DSP_EHANDLE; ++ GT_0trace(debugMask, GT_7CLASS, ++ "DEV_GetDevNode: Invalid handle"); ++ } ++ GT_2trace(debugMask, GT_ENTER, ++ "Exit DEV_GetDevNode: status 0x%x\t\nhDevNode:" ++ "0x%x\n", status, *phDevNode); ++ DBC_Ensure(DSP_SUCCEEDED(status) || ((phDevNode != NULL) && ++ (*phDevNode == NULL))); ++ return status; ++} ++ ++/* ++ * ======== DEV_GetFirst ======== ++ * Purpose: ++ * Retrieve the first Device Object handle from an internal linked list ++ * DEV_OBJECTs maintained by DEV. ++ */ ++struct DEV_OBJECT *DEV_GetFirst(void) ++{ ++ struct DEV_OBJECT *pDevObject = NULL; ++ ++ pDevObject = (struct DEV_OBJECT *)DRV_GetFirstDevObject(); ++ ++ DBC_Ensure((pDevObject == NULL) || IsValidHandle(pDevObject)); ++ ++ return pDevObject; ++} ++ ++/* ++ * ======== DEV_GetIntfFxns ======== ++ * Purpose: ++ * Retrieve the WMD interface function structure for the loaded WMD. ++ * ppIntfFxns != NULL. ++ */ ++DSP_STATUS DEV_GetIntfFxns(struct DEV_OBJECT *hDevObject, ++ OUT struct WMD_DRV_INTERFACE **ppIntfFxns) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEV_OBJECT *pDevObject = hDevObject; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(ppIntfFxns != NULL); ++ ++ GT_2trace(debugMask, GT_ENTER, ++ "Entered DEV_GetIntfFxns, hDevObject: 0x%x\n\t" ++ "\tppIntfFxns: 0x%x\n", hDevObject, ppIntfFxns); ++ if (IsValidHandle(hDevObject)) { ++ *ppIntfFxns = &pDevObject->intfFxns; ++ } else { ++ *ppIntfFxns = NULL; ++ status = DSP_EHANDLE; ++ GT_0trace(debugMask, GT_7CLASS, ++ "DEV_GetIntDxns: Invalid handle"); ++ } ++ GT_2trace(debugMask, GT_ENTER, "Exit DEV_GetIntFxns: status 0x%x\t\n" ++ "ppIntFxns: 0x%x\n", status, *ppIntfFxns); ++ DBC_Ensure(DSP_SUCCEEDED(status) || ((ppIntfFxns != NULL) && ++ (*ppIntfFxns == NULL))); ++ return status; ++} ++ ++/* ++ * ========= DEV_GetIOMgr ======== ++ */ ++DSP_STATUS DEV_GetIOMgr(struct DEV_OBJECT *hDevObject, ++ OUT struct IO_MGR **phIOMgr) ++{ ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phIOMgr != NULL); ++ DBC_Require(MEM_IsValidHandle(hDevObject, SIGNATURE)); ++ ++ if (IsValidHandle(hDevObject)) { ++ *phIOMgr = hDevObject->hIOMgr; ++ } else { ++ *phIOMgr = NULL; ++ status = DSP_EHANDLE; ++ GT_0trace(debugMask, GT_7CLASS, "DEV_GetIOMgr: Invalid handle"); ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== DEV_GetNext ======== ++ * Purpose: ++ * Retrieve the next Device Object handle from an internal linked list ++ * of DEV_OBJECTs maintained by DEV, after having previously called ++ * DEV_GetFirst() and zero or more DEV_GetNext ++ */ ++struct DEV_OBJECT *DEV_GetNext(struct DEV_OBJECT *hDevObject) ++{ ++ struct DEV_OBJECT *pNextDevObject = NULL; ++ ++ if (IsValidHandle(hDevObject)) { ++ pNextDevObject = (struct DEV_OBJECT *) ++ DRV_GetNextDevObject((u32)hDevObject); ++ } ++ DBC_Ensure((pNextDevObject == NULL) || IsValidHandle(pNextDevObject)); ++ return pNextDevObject; ++} ++ ++/* ++ * ========= DEV_GetMsgMgr ======== ++ */ ++void DEV_GetMsgMgr(struct DEV_OBJECT *hDevObject, ++ OUT struct MSG_MGR **phMsgMgr) ++{ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phMsgMgr != NULL); ++ DBC_Require(MEM_IsValidHandle(hDevObject, SIGNATURE)); ++ ++ *phMsgMgr = hDevObject->hMsgMgr; ++} ++ ++/* ++ * ======== DEV_GetNodeManager ======== ++ * Purpose: ++ * Retrieve the Node Manager Handle ++ */ ++DSP_STATUS DEV_GetNodeManager(struct DEV_OBJECT *hDevObject, ++ OUT struct NODE_MGR **phNodeMgr) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEV_OBJECT *pDevObject = hDevObject; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phNodeMgr != NULL); ++ ++ GT_2trace(debugMask, GT_ENTER, ++ "Entered DEV_GetNodeManager, hDevObject: 0x%x" ++ "\n\t\tphNodeMgr: 0x%x\n", hDevObject, phNodeMgr); ++ if (IsValidHandle(hDevObject)) { ++ *phNodeMgr = pDevObject->hNodeMgr; ++ } else { ++ *phNodeMgr = NULL; ++ status = DSP_EHANDLE; ++ GT_1trace(debugMask, GT_7CLASS, ++ "DEV_GetNodeManager, invalid handle: 0x" ++ "%x\n", hDevObject); ++ } ++ GT_2trace(debugMask, GT_ENTER, ++ "Exit DEV_GetNodeManager: status 0x%x\t\nhMgr:" ++ " 0x%x\n", status, *phNodeMgr); ++ DBC_Ensure(DSP_SUCCEEDED(status) || ((phNodeMgr != NULL) && ++ (*phNodeMgr == NULL))); ++ return status; ++} ++ ++/* ++ * ======== DEV_GetSymbol ======== ++ */ ++DSP_STATUS DEV_GetSymbol(struct DEV_OBJECT *hDevObject, ++ IN CONST char *pstrSym, OUT u32 *pulValue) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct COD_MANAGER *hCodMgr; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pstrSym != NULL && pulValue != NULL); ++ ++ GT_3trace(debugMask, GT_ENTER, ++ "Entered DEV_GetSymbol, hDevObject: 0x%x\n\t\t" ++ "pstrSym: 0x%x\n\t\tpulValue: 0x%x\n", hDevObject, pstrSym, ++ pulValue); ++ if (IsValidHandle(hDevObject)) { ++ status = DEV_GetCodMgr(hDevObject, &hCodMgr); ++ if (DSP_SUCCEEDED(status)) { ++ DBC_Assert(hCodMgr != NULL); ++ status = COD_GetSymValue(hCodMgr, (char *)pstrSym, ++ pulValue); ++ } ++ } else { ++ status = DSP_EHANDLE; ++ GT_0trace(debugMask, GT_7CLASS, ++ "DEV_GetSymbol: Invalid handle"); ++ } ++ GT_2trace(debugMask, GT_ENTER, "Exit DEV_GetSymbol: status 0x%x\t\n" ++ "hWmdContext: 0x%x\n", status, *pulValue); ++ return status; ++} ++ ++/* ++ * ======== DEV_GetWMDContext ======== ++ * Purpose: ++ * Retrieve the WMD Context handle, as returned by the WMD_Create fxn. ++ */ ++DSP_STATUS DEV_GetWMDContext(struct DEV_OBJECT *hDevObject, ++ OUT struct WMD_DEV_CONTEXT **phWmdContext) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEV_OBJECT *pDevObject = hDevObject; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phWmdContext != NULL); ++ GT_2trace(debugMask, GT_ENTER, ++ "Entered DEV_GetWMDContext, hDevObject: 0x%x\n" ++ "\t\tphWmdContext: 0x%x\n", hDevObject, phWmdContext); ++ if (IsValidHandle(hDevObject)) { ++ *phWmdContext = pDevObject->hWmdContext; ++ } else { ++ *phWmdContext = NULL; ++ status = DSP_EHANDLE; ++ GT_0trace(debugMask, GT_7CLASS, ++ "DEV_GetWMDContext: Invalid handle"); ++ } ++ ++ GT_2trace(debugMask, GT_ENTER, ++ "Exit DEV_GetWMDContext: status 0x%x\t\n" ++ "hWmdContext: 0x%x\n", status, *phWmdContext); ++ DBC_Ensure(DSP_SUCCEEDED(status) || ((phWmdContext != NULL) && ++ (*phWmdContext == NULL))); ++ return status; ++} ++ ++/* ++ * ======== DEV_Exit ======== ++ * Purpose: ++ * Decrement reference count, and free resources when reference count is ++ * 0. ++ */ ++void DEV_Exit(void) ++{ ++ DBC_Require(cRefs > 0); ++ ++ cRefs--; ++ ++ if (cRefs == 0) { ++ CMM_Exit(); ++ DMM_Exit(); ++ } ++ ++ GT_1trace(debugMask, GT_5CLASS, "Entered DEV_Exit, ref count: 0x%x\n", ++ cRefs); ++ ++ DBC_Ensure(cRefs >= 0); ++} ++ ++/* ++ * ======== DEV_Init ======== ++ * Purpose: ++ * Initialize DEV's private state, keeping a reference count on each call. ++ */ ++bool DEV_Init(void) ++{ ++ bool fCmm, fDmm, fRetval = true; ++ ++ DBC_Require(cRefs >= 0); ++ ++ if (cRefs == 0) { ++ /* Set the Trace mask */ ++ DBC_Assert(!debugMask.flags); ++ GT_create(&debugMask, "DV"); /* "DV" for DeVice */ ++ fCmm = CMM_Init(); ++ fDmm = DMM_Init(); ++ ++ fRetval = fCmm && fDmm; ++ ++ if (!fRetval) { ++ if (fCmm) ++ CMM_Exit(); ++ ++ ++ if (fDmm) ++ DMM_Exit(); ++ ++ } ++ } ++ ++ if (fRetval) ++ cRefs++; ++ ++ ++ GT_1trace(debugMask, GT_5CLASS, "Entered DEV_Init, ref count: 0x%x\n", ++ cRefs); ++ ++ DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0))); ++ ++ return fRetval; ++} ++ ++/* ++ * ======== DEV_NotifyClients ======== ++ * Purpose: ++ * Notify all clients of this device of a change in device status. ++ */ ++DSP_STATUS DEV_NotifyClients(struct DEV_OBJECT *hDevObject, u32 ulStatus) ++{ ++ DSP_STATUS status = DSP_SOK; ++ ++ struct DEV_OBJECT *pDevObject = hDevObject; ++ DSP_HPROCESSOR hProcObject; ++ ++ GT_2trace(debugMask, GT_ENTER, ++ "Entered DEV_NotifyClients, hDevObject: 0x%x\n" ++ "\t\tulStatus: 0x%x\n", hDevObject, ulStatus); ++ for (hProcObject = (DSP_HPROCESSOR)LST_First(pDevObject->procList); ++ hProcObject != NULL; ++ hProcObject = (DSP_HPROCESSOR)LST_Next(pDevObject->procList, ++ (struct LST_ELEM *)hProcObject)) ++ PROC_NotifyClients(hProcObject, (u32) ulStatus); ++ ++ return status; ++} ++ ++/* ++ * ======== DEV_RemoveDevice ======== ++ */ ++DSP_STATUS DEV_RemoveDevice(struct CFG_DEVNODE *hDevNode) ++{ ++ struct DEV_OBJECT *hDevObject; /* handle to device object */ ++ DSP_STATUS status = DSP_SOK; ++ struct DEV_OBJECT *pDevObject; ++ ++ GT_1trace(debugMask, GT_ENTER, ++ "Entered DEV_RemoveDevice, hDevNode: 0x%x\n", hDevNode); ++ /* Retrieve the device object handle originaly stored with ++ * the DevNode: */ ++ status = CFG_GetDevObject(hDevNode, (u32 *)&hDevObject); ++ if (DSP_SUCCEEDED(status)) { ++ /* Remove the Processor List */ ++ pDevObject = (struct DEV_OBJECT *)hDevObject; ++ /* Destroy the device object. */ ++ status = DEV_DestroyDevice(hDevObject); ++ if (DSP_SUCCEEDED(status)) { ++ /* Null out the handle stored with the DevNode. */ ++ GT_0trace(debugMask, GT_1CLASS, ++ "DEV_RemoveDevice, success"); ++ } ++ } ++ GT_1trace(debugMask, GT_ENTER, "Exit DEV_RemoveDevice, status: 0x%x\n", ++ status); ++ return status; ++} ++ ++/* ++ * ======== DEV_SetChnlMgr ======== ++ * Purpose: ++ * Set the channel manager for this device. ++ */ ++DSP_STATUS DEV_SetChnlMgr(struct DEV_OBJECT *hDevObject, struct CHNL_MGR *hMgr) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEV_OBJECT *pDevObject = hDevObject; ++ ++ DBC_Require(cRefs > 0); ++ ++ GT_2trace(debugMask, GT_ENTER, ++ "Entered DEV_SetChnlMgr, hDevObject: 0x%x\n\t" ++ "\thMgr:0x%x\n", hDevObject, hMgr); ++ if (IsValidHandle(hDevObject)) { ++ pDevObject->hChnlMgr = hMgr; ++ } else { ++ status = DSP_EHANDLE; ++ GT_0trace(debugMask, GT_7CLASS, ++ "DEV_SetChnlMgr, Invalid handle\n"); ++ } ++ DBC_Ensure(DSP_FAILED(status) || (pDevObject->hChnlMgr == hMgr)); ++ return status; ++} ++ ++/* ++ * ======== DEV_SetMsgMgr ======== ++ * Purpose: ++ * Set the message manager for this device. ++ */ ++void DEV_SetMsgMgr(struct DEV_OBJECT *hDevObject, struct MSG_MGR *hMgr) ++{ ++ DBC_Require(cRefs > 0); ++ DBC_Require(IsValidHandle(hDevObject)); ++ GT_2trace(debugMask, GT_ENTER, ++ "Entered DEV_SetMsgMgr, hDevObject: 0x%x\n\t\t" ++ "hMgr: 0x%x\n", hDevObject, hMgr); ++ hDevObject->hMsgMgr = hMgr; ++} ++ ++/* ++ * ======== DEV_StartDevice ======== ++ * Purpose: ++ * Initializes the new device with the BRIDGE environment. ++ */ ++DSP_STATUS DEV_StartDevice(struct CFG_DEVNODE *hDevNode) ++{ ++ struct DEV_OBJECT *hDevObject = NULL; /* handle to 'Bridge Device */ ++ struct CFG_HOSTRES hostRes; /* resources struct. */ ++ struct CFG_DSPRES dspRes; /* DSP resources struct */ ++ char szWMDFileName[CFG_MAXSEARCHPATHLEN] = "UMA"; /* wmd filename */ ++ DSP_STATUS status; ++ struct MGR_OBJECT *hMgrObject = NULL; ++ ++ DBC_Require(cRefs > 0); ++ ++ GT_1trace(debugMask, GT_ENTER, ++ "Entered DEV_StartDevice, hDevObject: 0x%x\n", hDevNode); ++ status = CFG_GetHostResources(hDevNode, &hostRes); ++ if (DSP_SUCCEEDED(status)) { ++ /* Get DSP resources of device from Registry: */ ++ status = CFG_GetDSPResources(hDevNode, &dspRes); ++ if (DSP_FAILED(status)) { ++ GT_1trace(debugMask, GT_7CLASS, ++ "Failed to get WMD DSP resources" ++ " from registry: 0x%x ", status); ++ } ++ } else { ++ GT_1trace(debugMask, GT_7CLASS, ++ "Failed to get WMD Host resources " ++ "from registry: 0x%x ", status); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Given all resources, create a device object. */ ++ status = DEV_CreateDevice(&hDevObject, szWMDFileName, &hostRes, ++ &dspRes, hDevNode); ++ if (DSP_SUCCEEDED(status)) { ++ /* Store away the hDevObject with the DEVNODE */ ++ status = CFG_SetDevObject(hDevNode, (u32)hDevObject); ++ if (DSP_FAILED(status)) { ++ /* Clean up */ ++ GT_1trace(debugMask, GT_7CLASS, ++ "Failed to set DevObject in the " ++ "Registry: 0x%x", status); ++ DEV_DestroyDevice(hDevObject); ++ hDevObject = NULL; ++ } ++ } else { ++ GT_1trace(debugMask, GT_7CLASS, ++ "Failed to Create Device: 0x%x", ++ status); ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Create the Manager Object */ ++ status = MGR_Create(&hMgrObject, hDevNode); ++ } ++ if (DSP_FAILED(status)) { ++ GT_1trace(debugMask, GT_7CLASS, "Failed to MGR object: 0x%x", ++ status); ++ status = DSP_EFAIL; ++ } ++ if (DSP_FAILED(status)) { ++ if (hDevObject) ++ DEV_DestroyDevice(hDevObject); ++ ++ /* Ensure the device extension is NULL */ ++ CFG_SetDevObject(hDevNode, 0L); ++ } ++ GT_1trace(debugMask, GT_ENTER, "Exiting DEV_StartDevice status 0x%x\n", ++ status); ++ return status; ++} ++ ++/* ++ * ======== FxnNotImplemented ======== ++ * Purpose: ++ * Takes the place of a WMD Null Function. ++ * Parameters: ++ * Multiple, optional. ++ * Returns: ++ * DSP_ENOTIMPL: Always. ++ */ ++static DSP_STATUS FxnNotImplemented(int arg, ...) ++{ ++ DBG_Trace(DBG_LEVEL1, ++ "WARNING: Calling a non-implemented WMD function.\n"); ++ ++ return DSP_ENOTIMPL; ++} ++ ++/* ++ * ======== IsValidHandle ======== ++ * Purpose: ++ * Validate the device object handle. ++ * Parameters: ++ * hDevObject: Handle to device object created with ++ * DEV_CreateDevice(). ++ * Returns: ++ * true if handle is valid; false otherwise. ++ * Requires: ++ * Ensures: ++ */ ++static bool IsValidHandle(struct DEV_OBJECT *hObj) ++{ ++ bool retVal; ++ ++ retVal = (hObj != NULL) && (hObj->dwSignature == SIGNATURE); ++ ++ return retVal; ++} ++ ++/* ++ * ======== InitCodMgr ======== ++ * Purpose: ++ * Create a COD manager for this device. ++ * Parameters: ++ * pDevObject: Pointer to device object created with ++ * DEV_CreateDevice() ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EHANDLE: Invalid hDevObject. ++ * Requires: ++ * Should only be called once by DEV_CreateDevice() for a given DevObject. ++ * Ensures: ++ */ ++static DSP_STATUS InitCodMgr(struct DEV_OBJECT *pDevObject) ++{ ++ DSP_STATUS status = DSP_SOK; ++ char *szDummyFile = "dummy"; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(!IsValidHandle(pDevObject) || ++ (pDevObject->hCodMgr == NULL)); ++ GT_1trace(debugMask, GT_ENTER, "Entering InitCodMgr pDevObject: 0x%x", ++ pDevObject); ++ status = COD_Create(&pDevObject->hCodMgr, szDummyFile, NULL); ++ GT_1trace(debugMask, GT_ENTER, "Exiting InitCodMgr status 0x%x\n ", ++ status); ++ return status; ++} ++ ++/* ++ * ======== DEV_InsertProcObject ======== ++ * Purpose: ++ * Insert a ProcObject into the list maintained by DEV. ++ * Parameters: ++ * pProcObject: Ptr to ProcObject to insert. ++ * pDevObject: Ptr to Dev Object where the list is. ++ * pbAlreadyAttached: Ptr to return the bool ++ * Returns: ++ * DSP_SOK: If successful. ++ * Requires: ++ * List Exists ++ * hDevObject is Valid handle ++ * DEV Initialized ++ * pbAlreadyAttached != NULL ++ * hProcObject != 0 ++ * Ensures: ++ * DSP_SOK and List is not Empty. ++ */ ++DSP_STATUS DEV_InsertProcObject(struct DEV_OBJECT *hDevObject, ++ u32 hProcObject, ++ OUT bool *pbAlreadyAttached) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEV_OBJECT *pDevObject = (struct DEV_OBJECT *)hDevObject; ++ ++ GT_2trace(debugMask, GT_ENTER, ++ "Entering DEV_InsetProcObject pProcObject 0x%x" ++ "pDevObject 0x%x\n", hProcObject, hDevObject); ++ DBC_Require(cRefs > 0); ++ DBC_Require(IsValidHandle(pDevObject)); ++ DBC_Require(hProcObject != 0); ++ DBC_Require(pDevObject->procList != NULL); ++ DBC_Require(pbAlreadyAttached != NULL); ++ if (!LST_IsEmpty(pDevObject->procList)) ++ *pbAlreadyAttached = true; ++ ++ /* Add DevObject to tail. */ ++ LST_PutTail(pDevObject->procList, (struct LST_ELEM *)hProcObject); ++ ++ GT_1trace(debugMask, GT_ENTER, ++ "Exiting DEV_InsetProcObject status 0x%x\n", status); ++ DBC_Ensure(DSP_SUCCEEDED(status) && !LST_IsEmpty(pDevObject->procList)); ++ ++ return status; ++} ++ ++/* ++ * ======== DEV_RemoveProcObject ======== ++ * Purpose: ++ * Search for and remove a Proc object from the given list maintained ++ * by the DEV ++ * Parameters: ++ * pProcObject: Ptr to ProcObject to insert. ++ * pDevObject Ptr to Dev Object where the list is. ++ * Returns: ++ * DSP_SOK: If successful. ++ * Requires: ++ * List exists and is not empty ++ * hProcObject != 0 ++ * hDevObject is a valid Dev handle. ++ * Ensures: ++ * Details: ++ * List will be deleted when the DEV is destroyed. ++ */ ++DSP_STATUS DEV_RemoveProcObject(struct DEV_OBJECT *hDevObject, ++ u32 hProcObject) ++{ ++ DSP_STATUS status = DSP_EFAIL; ++ struct LST_ELEM *pCurElem; ++ struct DEV_OBJECT *pDevObject = (struct DEV_OBJECT *)hDevObject; ++ ++ DBC_Require(IsValidHandle(pDevObject)); ++ DBC_Require(hProcObject != 0); ++ DBC_Require(pDevObject->procList != NULL); ++ DBC_Require(!LST_IsEmpty(pDevObject->procList)); ++ ++ GT_1trace(debugMask, GT_ENTER, ++ "Entering DEV_RemoveProcObject hDevObject " ++ "0x%x\n", hDevObject); ++ /* Search list for pDevObject: */ ++ for (pCurElem = LST_First(pDevObject->procList); pCurElem != NULL; ++ pCurElem = LST_Next(pDevObject->procList, pCurElem)) { ++ /* If found, remove it. */ ++ if ((u32)pCurElem == hProcObject) { ++ LST_RemoveElem(pDevObject->procList, pCurElem); ++ status = DSP_SOK; ++ break; ++ } ++ } ++ GT_1trace(debugMask, GT_ENTER, "DEV_RemoveProcObject returning 0x%x\n", ++ status); ++ return status; ++} ++ ++DSP_STATUS DEV_GetDevType(struct DEV_OBJECT *hdevObject, u32 *devType) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEV_OBJECT *pDevObject = (struct DEV_OBJECT *)hdevObject; ++ ++ *devType = pDevObject->devType; ++ ++ return status; ++} ++ ++/* ++ * ======== StoreInterfaceFxns ======== ++ * Purpose: ++ * Copy the WMD's interface functions into the device object, ++ * ensuring that FxnNotImplemented() is set for: ++ * ++ * 1. All WMD function pointers which are NULL; and ++ * 2. All function slots in the struct DEV_OBJECT structure which have no ++ * corresponding slots in the the WMD's interface, because the WMD ++ * is of an *older* version. ++ * Parameters: ++ * pIntfFxns: Interface Fxn Structure of the WCD's Dev Object. ++ * pDrvFxns: Interface Fxns offered by the WMD during DEV_Create(). ++ * Returns: ++ * Requires: ++ * Input pointers are valid. ++ * WMD is *not* written for a newer WCD. ++ * Ensures: ++ * All function pointers in the dev object's Fxn interface are not NULL. ++ */ ++static void StoreInterfaceFxns(struct WMD_DRV_INTERFACE *pDrvFxns, ++ OUT struct WMD_DRV_INTERFACE *pIntfFxns) ++{ ++ u32 dwWMDVersion; ++ ++ /* Local helper macro: */ ++#define StoreFxn(cast, pfn) \ ++ (pIntfFxns->pfn = ((pDrvFxns->pfn != NULL) ? pDrvFxns->pfn : \ ++ (cast)FxnNotImplemented)) ++ ++ DBC_Require(pIntfFxns != NULL); ++ DBC_Require(pDrvFxns != NULL); ++ DBC_Require(MAKEVERSION(pDrvFxns->dwWCDMajorVersion, ++ pDrvFxns->dwWCDMinorVersion) <= WCDVERSION); ++ dwWMDVersion = MAKEVERSION(pDrvFxns->dwWCDMajorVersion, ++ pDrvFxns->dwWCDMinorVersion); ++ pIntfFxns->dwWCDMajorVersion = pDrvFxns->dwWCDMajorVersion; ++ pIntfFxns->dwWCDMinorVersion = pDrvFxns->dwWCDMinorVersion; ++ /* Install functions up to WCD version .80 (first alpha): */ ++ if (dwWMDVersion > 0) { ++ StoreFxn(WMD_DEV_CREATE, pfnDevCreate); ++ StoreFxn(WMD_DEV_DESTROY, pfnDevDestroy); ++ StoreFxn(WMD_DEV_CTRL, pfnDevCntrl); ++ StoreFxn(WMD_BRD_MONITOR, pfnBrdMonitor); ++ StoreFxn(WMD_BRD_START, pfnBrdStart); ++ StoreFxn(WMD_BRD_STOP, pfnBrdStop); ++ StoreFxn(WMD_BRD_STATUS, pfnBrdStatus); ++ StoreFxn(WMD_BRD_READ, pfnBrdRead); ++ StoreFxn(WMD_BRD_WRITE, pfnBrdWrite); ++ StoreFxn(WMD_BRD_SETSTATE, pfnBrdSetState); ++ StoreFxn(WMD_BRD_MEMCOPY, pfnBrdMemCopy); ++ StoreFxn(WMD_BRD_MEMWRITE, pfnBrdMemWrite); ++ StoreFxn(WMD_BRD_MEMMAP, pfnBrdMemMap); ++ StoreFxn(WMD_BRD_MEMUNMAP, pfnBrdMemUnMap); ++ StoreFxn(WMD_CHNL_CREATE, pfnChnlCreate); ++ StoreFxn(WMD_CHNL_DESTROY, pfnChnlDestroy); ++ StoreFxn(WMD_CHNL_OPEN, pfnChnlOpen); ++ StoreFxn(WMD_CHNL_CLOSE, pfnChnlClose); ++ StoreFxn(WMD_CHNL_ADDIOREQ, pfnChnlAddIOReq); ++ StoreFxn(WMD_CHNL_GETIOC, pfnChnlGetIOC); ++ StoreFxn(WMD_CHNL_CANCELIO, pfnChnlCancelIO); ++ StoreFxn(WMD_CHNL_FLUSHIO, pfnChnlFlushIO); ++ StoreFxn(WMD_CHNL_GETINFO, pfnChnlGetInfo); ++ StoreFxn(WMD_CHNL_GETMGRINFO, pfnChnlGetMgrInfo); ++ StoreFxn(WMD_CHNL_IDLE, pfnChnlIdle); ++ StoreFxn(WMD_CHNL_REGISTERNOTIFY, pfnChnlRegisterNotify); ++ StoreFxn(WMD_DEH_CREATE, pfnDehCreate); ++ StoreFxn(WMD_DEH_DESTROY, pfnDehDestroy); ++ StoreFxn(WMD_DEH_NOTIFY, pfnDehNotify); ++ StoreFxn(WMD_DEH_REGISTERNOTIFY, pfnDehRegisterNotify); ++ StoreFxn(WMD_DEH_GETINFO, pfnDehGetInfo); ++ StoreFxn(WMD_IO_CREATE, pfnIOCreate); ++ StoreFxn(WMD_IO_DESTROY, pfnIODestroy); ++ StoreFxn(WMD_IO_ONLOADED, pfnIOOnLoaded); ++ StoreFxn(WMD_IO_GETPROCLOAD, pfnIOGetProcLoad); ++ StoreFxn(WMD_MSG_CREATE, pfnMsgCreate); ++ StoreFxn(WMD_MSG_CREATEQUEUE, pfnMsgCreateQueue); ++ StoreFxn(WMD_MSG_DELETE, pfnMsgDelete); ++ StoreFxn(WMD_MSG_DELETEQUEUE, pfnMsgDeleteQueue); ++ StoreFxn(WMD_MSG_GET, pfnMsgGet); ++ StoreFxn(WMD_MSG_PUT, pfnMsgPut); ++ StoreFxn(WMD_MSG_REGISTERNOTIFY, pfnMsgRegisterNotify); ++ StoreFxn(WMD_MSG_SETQUEUEID, pfnMsgSetQueueId); ++ } ++ /* Add code for any additional functions in newer WMD versions here: */ ++ /* Ensure postcondition: */ ++ DBC_Ensure(pIntfFxns->pfnDevCreate != NULL); ++ DBC_Ensure(pIntfFxns->pfnDevDestroy != NULL); ++ DBC_Ensure(pIntfFxns->pfnDevCntrl != NULL); ++ DBC_Ensure(pIntfFxns->pfnBrdMonitor != NULL); ++ DBC_Ensure(pIntfFxns->pfnBrdStart != NULL); ++ DBC_Ensure(pIntfFxns->pfnBrdStop != NULL); ++ DBC_Ensure(pIntfFxns->pfnBrdStatus != NULL); ++ DBC_Ensure(pIntfFxns->pfnBrdRead != NULL); ++ DBC_Ensure(pIntfFxns->pfnBrdWrite != NULL); ++ DBC_Ensure(pIntfFxns->pfnChnlCreate != NULL); ++ DBC_Ensure(pIntfFxns->pfnChnlDestroy != NULL); ++ DBC_Ensure(pIntfFxns->pfnChnlOpen != NULL); ++ DBC_Ensure(pIntfFxns->pfnChnlClose != NULL); ++ DBC_Ensure(pIntfFxns->pfnChnlAddIOReq != NULL); ++ DBC_Ensure(pIntfFxns->pfnChnlGetIOC != NULL); ++ DBC_Ensure(pIntfFxns->pfnChnlCancelIO != NULL); ++ DBC_Ensure(pIntfFxns->pfnChnlFlushIO != NULL); ++ DBC_Ensure(pIntfFxns->pfnChnlGetInfo != NULL); ++ DBC_Ensure(pIntfFxns->pfnChnlGetMgrInfo != NULL); ++ DBC_Ensure(pIntfFxns->pfnChnlIdle != NULL); ++ DBC_Ensure(pIntfFxns->pfnChnlRegisterNotify != NULL); ++ DBC_Ensure(pIntfFxns->pfnDehCreate != NULL); ++ DBC_Ensure(pIntfFxns->pfnDehDestroy != NULL); ++ DBC_Ensure(pIntfFxns->pfnDehNotify != NULL); ++ DBC_Ensure(pIntfFxns->pfnDehRegisterNotify != NULL); ++ DBC_Ensure(pIntfFxns->pfnDehGetInfo != NULL); ++ DBC_Ensure(pIntfFxns->pfnIOCreate != NULL); ++ DBC_Ensure(pIntfFxns->pfnIODestroy != NULL); ++ DBC_Ensure(pIntfFxns->pfnIOOnLoaded != NULL); ++ DBC_Ensure(pIntfFxns->pfnIOGetProcLoad != NULL); ++ DBC_Ensure(pIntfFxns->pfnMsgSetQueueId != NULL); ++ ++#undef StoreFxn ++} ++ +diff --git a/drivers/dsp/bridge/pmgr/dmm.c b/drivers/dsp/bridge/pmgr/dmm.c +new file mode 100644 +index 0000000..803de93 +--- /dev/null ++++ b/drivers/dsp/bridge/pmgr/dmm.c +@@ -0,0 +1,692 @@ ++/* ++ * dmm.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== dmm.c ======== ++ * Purpose: ++ * The Dynamic Memory Manager (DMM) module manages the DSP Virtual address ++ * space that can be directly mapped to any MPU buffer or memory region ++ * ++ * Public Functions: ++ * DMM_CreateTables ++ * DMM_Create ++ * DMM_Destroy ++ * DMM_Exit ++ * DMM_Init ++ * DMM_MapMemory ++ * DMM_Reset ++ * DMM_ReserveMemory ++ * DMM_UnMapMemory ++ * DMM_UnReserveMemory ++ * ++ * Private Functions: ++ * AddRegion ++ * CreateRegion ++ * GetRegion ++ * GetFreeRegion ++ * GetMappedRegion ++ * ++ * Notes: ++ * Region: Generic memory entitiy having a start address and a size ++ * Chunk: Reserved region ++ * ++ * ++ *! Revision History: ++ *! ================ ++ *! 04-Jun-2008 Hari K : Optimized DMM implementation. Removed linked list ++ *! and instead used Table approach. ++ *! 19-Apr-2004 sb: Integrated Alan's code review updates. ++ *! 17-Mar-2004 ap: Fixed GetRegion for size=0 using tighter bound. ++ *! 20-Feb-2004 sb: Created. ++ *! ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++/* ----------------------------------- Defines, Data Structures, Typedefs */ ++/* Object signatures */ ++#define DMMSIGNATURE 0x004d4d44 /* "DMM" (in reverse) */ ++ ++#define DMM_ADDR_VIRTUAL(a) \ ++ (((struct MapPage *)(a) - pVirtualMappingTable) * PG_SIZE_4K +\ ++ dynMemMapBeg) ++#define DMM_ADDR_TO_INDEX(a) (((a) - dynMemMapBeg) / PG_SIZE_4K) ++ ++/* DMM Mgr */ ++struct DMM_OBJECT { ++ u32 dwSignature; /* Used for object validation */ ++ /* Dmm Lock is used to serialize access mem manager for ++ * multi-threads. */ ++ struct SYNC_CSOBJECT *hDmmLock; /* Lock to access dmm mgr */ ++}; ++ ++ ++/* ----------------------------------- Globals */ ++#if GT_TRACE ++static struct GT_Mask DMM_debugMask = { NULL, NULL }; /* GT trace variable */ ++#endif ++ ++static u32 cRefs; /* module reference count */ ++struct MapPage { ++ u32 RegionSize:15; ++ u32 MappedSize:15; ++ u32 bReserved:1; ++ u32 bMapped:1; ++}; ++ ++/* Create the free list */ ++static struct MapPage *pVirtualMappingTable; ++static u32 iFreeRegion; /* The index of free region */ ++static u32 iFreeSize; ++static u32 *pPhysicalAddrTable; /* Physical address of MPU buffer */ ++static u32 dynMemMapBeg; /* The Beginning of dynamic memory mapping */ ++static u32 TableSize;/* The size of virtual and physical pages tables */ ++ ++/* ----------------------------------- Function Prototypes */ ++static struct MapPage *GetRegion(u32 addr); ++static struct MapPage *GetFreeRegion(u32 aSize); ++static struct MapPage *GetMappedRegion(u32 aAddr); ++#ifdef DSP_DMM_DEBUG ++u32 DMM_MemMapDump(struct DMM_OBJECT *hDmmMgr); ++#endif ++ ++/* ======== DMM_CreateTables ======== ++ * Purpose: ++ * Create table to hold the information of physical address ++ * the buffer pages that is passed by the user, and the table ++ * to hold the information of the virtual memory that is reserved ++ * for DSP. ++ */ ++DSP_STATUS DMM_CreateTables(struct DMM_OBJECT *hDmmMgr, u32 addr, u32 size) ++{ ++ struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr; ++ DSP_STATUS status = DSP_SOK; ++ ++ GT_3trace(DMM_debugMask, GT_ENTER, ++ "Entered DMM_CreateTables () hDmmMgr %x, addr" ++ " %x, size %x\n", hDmmMgr, addr, size); ++ status = DMM_DeleteTables(pDmmObj); ++ if (DSP_SUCCEEDED(status)) { ++ SYNC_EnterCS(pDmmObj->hDmmLock); ++ dynMemMapBeg = addr; ++ TableSize = (size/PG_SIZE_4K) + 1; ++ /* Create the free list */ ++ pVirtualMappingTable = (struct MapPage *) MEM_Calloc ++ (TableSize*sizeof(struct MapPage), MEM_NONPAGED); ++ if (pVirtualMappingTable == NULL) ++ status = DSP_EMEMORY; ++ else { ++ /* This table will be used ++ * to store the virtual to physical ++ * address translations ++ */ ++ pPhysicalAddrTable = (u32 *)MEM_Calloc ++ (TableSize*sizeof(u32), MEM_NONPAGED); ++ GT_1trace(DMM_debugMask, GT_4CLASS, ++ "DMM_CreateTables: Allocate" ++ "memory for pPhysicalAddrTable=%d entries\n", ++ TableSize); ++ if (pPhysicalAddrTable == NULL) { ++ status = DSP_EMEMORY; ++ GT_0trace(DMM_debugMask, GT_7CLASS, ++ "DMM_CreateTables: Memory allocation for " ++ "pPhysicalAddrTable failed\n"); ++ } else { ++ /* On successful allocation, ++ * all entries are zero ('free') */ ++ iFreeRegion = 0; ++ iFreeSize = TableSize*PG_SIZE_4K; ++ pVirtualMappingTable[0].RegionSize = TableSize; ++ } ++ } ++ SYNC_LeaveCS(pDmmObj->hDmmLock); ++ } else ++ GT_0trace(DMM_debugMask, GT_7CLASS, ++ "DMM_CreateTables: DMM_DeleteTables" ++ "Failure\n"); ++ ++ GT_1trace(DMM_debugMask, GT_4CLASS, "Leaving DMM_CreateTables status" ++ "0x%x\n", status); ++ return status; ++} ++ ++/* ++ * ======== DMM_Create ======== ++ * Purpose: ++ * Create a dynamic memory manager object. ++ */ ++DSP_STATUS DMM_Create(OUT struct DMM_OBJECT **phDmmMgr, ++ struct DEV_OBJECT *hDevObject, ++ IN CONST struct DMM_MGRATTRS *pMgrAttrs) ++{ ++ struct DMM_OBJECT *pDmmObject = NULL; ++ DSP_STATUS status = DSP_SOK; ++ DBC_Require(cRefs > 0); ++ DBC_Require(phDmmMgr != NULL); ++ ++ GT_3trace(DMM_debugMask, GT_ENTER, ++ "DMM_Create: phDmmMgr: 0x%x hDevObject: " ++ "0x%x pMgrAttrs: 0x%x\n", phDmmMgr, hDevObject, pMgrAttrs); ++ *phDmmMgr = NULL; ++ /* create, zero, and tag a cmm mgr object */ ++ MEM_AllocObject(pDmmObject, struct DMM_OBJECT, DMMSIGNATURE); ++ if (pDmmObject != NULL) { ++ status = SYNC_InitializeCS(&pDmmObject->hDmmLock); ++ if (DSP_SUCCEEDED(status)) ++ *phDmmMgr = pDmmObject; ++ else ++ DMM_Destroy(pDmmObject); ++ } else { ++ GT_0trace(DMM_debugMask, GT_7CLASS, ++ "DMM_Create: Object Allocation " ++ "Failure(DMM Object)\n"); ++ status = DSP_EMEMORY; ++ } ++ GT_2trace(DMM_debugMask, GT_4CLASS, ++ "Leaving DMM_Create status %x pDmmObject %x\n", ++ status, pDmmObject); ++ ++ return status; ++} ++ ++/* ++ * ======== DMM_Destroy ======== ++ * Purpose: ++ * Release the communication memory manager resources. ++ */ ++DSP_STATUS DMM_Destroy(struct DMM_OBJECT *hDmmMgr) ++{ ++ struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr; ++ DSP_STATUS status = DSP_SOK; ++ ++ GT_1trace(DMM_debugMask, GT_ENTER, ++ "Entered DMM_Destroy () hDmmMgr %x\n", hDmmMgr); ++ DBC_Require(cRefs > 0); ++ if (MEM_IsValidHandle(hDmmMgr, DMMSIGNATURE)) { ++ status = DMM_DeleteTables(pDmmObj); ++ if (DSP_SUCCEEDED(status)) { ++ /* Delete CS & dmm mgr object */ ++ SYNC_DeleteCS(pDmmObj->hDmmLock); ++ MEM_FreeObject(pDmmObj); ++ } else ++ GT_0trace(DMM_debugMask, GT_7CLASS, ++ "DMM_Destroy: DMM_DeleteTables " ++ "Failure\n"); ++ } else ++ status = DSP_EHANDLE; ++ GT_1trace(DMM_debugMask, GT_4CLASS, "Leaving DMM_Destroy status %x\n", ++ status); ++ return status; ++} ++ ++ ++/* ++ * ======== DMM_DeleteTables ======== ++ * Purpose: ++ * Delete DMM Tables. ++ */ ++DSP_STATUS DMM_DeleteTables(struct DMM_OBJECT *hDmmMgr) ++{ ++ struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr; ++ DSP_STATUS status = DSP_SOK; ++ ++ GT_1trace(DMM_debugMask, GT_ENTER, ++ "Entered DMM_DeleteTables () hDmmMgr %x\n", hDmmMgr); ++ DBC_Require(cRefs > 0); ++ if (MEM_IsValidHandle(hDmmMgr, DMMSIGNATURE)) { ++ /* Delete all DMM tables */ ++ SYNC_EnterCS(pDmmObj->hDmmLock); ++ ++ if (pVirtualMappingTable != NULL) ++ MEM_Free(pVirtualMappingTable); ++ ++ if (pPhysicalAddrTable != NULL) ++ MEM_Free(pPhysicalAddrTable); ++ ++ SYNC_LeaveCS(pDmmObj->hDmmLock); ++ } else ++ status = DSP_EHANDLE; ++ GT_1trace(DMM_debugMask, GT_4CLASS, ++ "Leaving DMM_DeleteTables status %x\n", status); ++ return status; ++} ++ ++ ++ ++ ++/* ++ * ======== DMM_Exit ======== ++ * Purpose: ++ * Discontinue usage of module; free resources when reference count ++ * reaches 0. ++ */ ++void DMM_Exit(void) ++{ ++ DBC_Require(cRefs > 0); ++ ++ cRefs--; ++ ++ GT_1trace(DMM_debugMask, GT_ENTER, ++ "exiting DMM_Exit, ref count:0x%x\n", cRefs); ++} ++ ++/* ++ * ======== DMM_GetHandle ======== ++ * Purpose: ++ * Return the dynamic memory manager object for this device. ++ * This is typically called from the client process. ++ */ ++DSP_STATUS DMM_GetHandle(DSP_HPROCESSOR hProcessor, ++ OUT struct DMM_OBJECT **phDmmMgr) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEV_OBJECT *hDevObject; ++ ++ GT_2trace(DMM_debugMask, GT_ENTER, ++ "DMM_GetHandle: hProcessor %x, phDmmMgr" ++ "%x\n", hProcessor, phDmmMgr); ++ DBC_Require(cRefs > 0); ++ DBC_Require(phDmmMgr != NULL); ++ if (hProcessor != NULL) ++ status = PROC_GetDevObject(hProcessor, &hDevObject); ++ else ++ hDevObject = DEV_GetFirst(); /* default */ ++ ++ if (DSP_SUCCEEDED(status)) ++ status = DEV_GetDmmMgr(hDevObject, phDmmMgr); ++ ++ GT_2trace(DMM_debugMask, GT_4CLASS, "Leaving DMM_GetHandle status %x, " ++ "*phDmmMgr %x\n", status, phDmmMgr ? *phDmmMgr : NULL); ++ return status; ++} ++ ++/* ++ * ======== DMM_Init ======== ++ * Purpose: ++ * Initializes private state of DMM module. ++ */ ++bool DMM_Init(void) ++{ ++ bool fRetval = true; ++ ++ DBC_Require(cRefs >= 0); ++ ++ if (cRefs == 0) { ++ /* Set the Trace mask */ ++ /*"DM" for Dymanic Memory Manager */ ++ GT_create(&DMM_debugMask, "DM"); ++ } ++ ++ if (fRetval) ++ cRefs++; ++ ++ GT_1trace(DMM_debugMask, GT_ENTER, ++ "Entered DMM_Init, ref count:0x%x\n", cRefs); ++ ++ DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0))); ++ ++ pVirtualMappingTable = NULL ; ++ pPhysicalAddrTable = NULL ; ++ TableSize = 0; ++ ++ return fRetval; ++} ++ ++/* ++ * ======== DMM_MapMemory ======== ++ * Purpose: ++ * Add a mapping block to the reserved chunk. DMM assumes that this block ++ * will be mapped in the DSP/IVA's address space. DMM returns an error if a ++ * mapping overlaps another one. This function stores the info that will be ++ * required later while unmapping the block. ++ */ ++DSP_STATUS DMM_MapMemory(struct DMM_OBJECT *hDmmMgr, u32 addr, u32 size) ++{ ++ struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr; ++ struct MapPage *chunk; ++ DSP_STATUS status = DSP_SOK; ++ ++ GT_3trace(DMM_debugMask, GT_ENTER, ++ "Entered DMM_MapMemory () hDmmMgr %x, " ++ "addr %x, size %x\n", hDmmMgr, addr, size); ++ SYNC_EnterCS(pDmmObj->hDmmLock); ++ /* Find the Reserved memory chunk containing the DSP block to ++ * be mapped */ ++ chunk = (struct MapPage *)GetRegion(addr); ++ if (chunk != NULL) { ++ /* Mark the region 'mapped', leave the 'reserved' info as-is */ ++ chunk->bMapped = true; ++ chunk->MappedSize = (size/PG_SIZE_4K); ++ } else ++ status = DSP_ENOTFOUND; ++ SYNC_LeaveCS(pDmmObj->hDmmLock); ++ GT_2trace(DMM_debugMask, GT_4CLASS, ++ "Leaving DMM_MapMemory status %x, chunk %x\n", ++ status, chunk); ++ return status; ++} ++ ++/* ++ * ======== DMM_ReserveMemory ======== ++ * Purpose: ++ * Reserve a chunk of virtually contiguous DSP/IVA address space. ++ */ ++DSP_STATUS DMM_ReserveMemory(struct DMM_OBJECT *hDmmMgr, u32 size, ++ u32 *pRsvAddr) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr; ++ struct MapPage *node; ++ u32 rsvAddr = 0; ++ u32 rsvSize = 0; ++ ++ GT_3trace(DMM_debugMask, GT_ENTER, ++ "Entered DMM_ReserveMemory () hDmmMgr %x, " ++ "size %x, pRsvAddr %x\n", hDmmMgr, size, pRsvAddr); ++ SYNC_EnterCS(pDmmObj->hDmmLock); ++ ++ /* Try to get a DSP chunk from the free list */ ++ node = GetFreeRegion(size); ++ if (node != NULL) { ++ /* DSP chunk of given size is available. */ ++ rsvAddr = DMM_ADDR_VIRTUAL(node); ++ /* Calculate the number entries to use */ ++ rsvSize = size/PG_SIZE_4K; ++ if (rsvSize < node->RegionSize) { ++ /* Mark remainder of free region */ ++ node[rsvSize].bMapped = false; ++ node[rsvSize].bReserved = false; ++ node[rsvSize].RegionSize = node->RegionSize - rsvSize; ++ node[rsvSize].MappedSize = 0; ++ } ++ /* GetRegion will return first fit chunk. But we only use what ++ is requested. */ ++ node->bMapped = false; ++ node->bReserved = true; ++ node->RegionSize = rsvSize; ++ node->MappedSize = 0; ++ /* Return the chunk's starting address */ ++ *pRsvAddr = rsvAddr; ++ } else ++ /*dSP chunk of given size is not available */ ++ status = DSP_EMEMORY; ++ ++ SYNC_LeaveCS(pDmmObj->hDmmLock); ++ GT_3trace(DMM_debugMask, GT_4CLASS, ++ "Leaving ReserveMemory status %x, rsvAddr" ++ " %x, rsvSize %x\n", status, rsvAddr, rsvSize); ++ return status; ++} ++ ++ ++/* ++ * ======== DMM_UnMapMemory ======== ++ * Purpose: ++ * Remove the mapped block from the reserved chunk. ++ */ ++DSP_STATUS DMM_UnMapMemory(struct DMM_OBJECT *hDmmMgr, u32 addr, u32 *pSize) ++{ ++ struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr; ++ struct MapPage *chunk; ++ DSP_STATUS status = DSP_SOK; ++ ++ GT_3trace(DMM_debugMask, GT_ENTER, ++ "Entered DMM_UnMapMemory () hDmmMgr %x, " ++ "addr %x, pSize %x\n", hDmmMgr, addr, pSize); ++ SYNC_EnterCS(pDmmObj->hDmmLock); ++ chunk = GetMappedRegion(addr) ; ++ if (chunk == NULL) ++ status = DSP_ENOTFOUND ; ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* Unmap the region */ ++ *pSize = chunk->MappedSize * PG_SIZE_4K; ++ chunk->bMapped = false; ++ chunk->MappedSize = 0; ++ } ++ SYNC_LeaveCS(pDmmObj->hDmmLock); ++ GT_3trace(DMM_debugMask, GT_ENTER, ++ "Leaving DMM_UnMapMemory status %x, chunk" ++ " %x, *pSize %x\n", status, chunk, *pSize); ++ ++ return status; ++} ++ ++/* ++ * ======== DMM_UnReserveMemory ======== ++ * Purpose: ++ * Free a chunk of reserved DSP/IVA address space. ++ */ ++DSP_STATUS DMM_UnReserveMemory(struct DMM_OBJECT *hDmmMgr, u32 rsvAddr) ++{ ++ struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr; ++ struct MapPage *chunk; ++ u32 i; ++ DSP_STATUS status = DSP_SOK; ++ u32 chunkSize; ++ ++ GT_2trace(DMM_debugMask, GT_ENTER, ++ "Entered DMM_UnReserveMemory () hDmmMgr " ++ "%x, rsvAddr %x\n", hDmmMgr, rsvAddr); ++ ++ SYNC_EnterCS(pDmmObj->hDmmLock); ++ ++ /* Find the chunk containing the reserved address */ ++ chunk = GetMappedRegion(rsvAddr); ++ if (chunk == NULL) ++ status = DSP_ENOTFOUND; ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* Free all the mapped pages for this reserved region */ ++ i = 0; ++ while (i < chunk->RegionSize) { ++ if (chunk[i].bMapped) { ++ /* Remove mapping from the page tables. */ ++ chunkSize = chunk[i].MappedSize; ++ /* Clear the mapping flags */ ++ chunk[i].bMapped = false; ++ chunk[i].MappedSize = 0; ++ i += chunkSize; ++ } else ++ i++; ++ } ++ /* Clear the flags (mark the region 'free') */ ++ chunk->bReserved = false; ++ /* NOTE: We do NOT coalesce free regions here. ++ * Free regions are coalesced in GetRegion(), as it traverses ++ *the whole mapping table ++ */ ++ } ++ SYNC_LeaveCS(pDmmObj->hDmmLock); ++ GT_2trace(DMM_debugMask, GT_ENTER, ++ "Leaving DMM_UnReserveMemory status %x" ++ " chunk %x\n", status, chunk); ++ return status; ++} ++ ++ ++/* ++ * ======== GetRegion ======== ++ * Purpose: ++ * Returns a region containing the specified memory region ++ */ ++static struct MapPage *GetRegion(u32 aAddr) ++{ ++ struct MapPage *currRegion = NULL; ++ u32 i = 0; ++ ++ GT_1trace(DMM_debugMask, GT_ENTER, "Entered GetRegion () " ++ " aAddr %x\n", aAddr); ++ ++ if (pVirtualMappingTable != NULL) { ++ /* find page mapped by this address */ ++ i = DMM_ADDR_TO_INDEX(aAddr); ++ if (i < TableSize) ++ currRegion = pVirtualMappingTable + i; ++ } ++ GT_3trace(DMM_debugMask, GT_4CLASS, ++ "Leaving GetRegion currRegion %x, iFreeRegion %d\n," ++ "iFreeSize %d\n", currRegion, iFreeRegion, iFreeSize) ; ++ return currRegion; ++} ++ ++/* ++ * ======== GetFreeRegion ======== ++ * Purpose: ++ * Returns the requested free region ++ */ ++static struct MapPage *GetFreeRegion(u32 aSize) ++{ ++ struct MapPage *currRegion = NULL; ++ u32 i = 0; ++ u32 RegionSize = 0; ++ u32 nextI = 0; ++ GT_1trace(DMM_debugMask, GT_ENTER, "Entered GetFreeRegion () " ++ "aSize 0x%x\n", aSize); ++ ++ if (pVirtualMappingTable == NULL) ++ return currRegion; ++ if (aSize > iFreeSize) { ++ /* Find the largest free region ++ * (coalesce during the traversal) */ ++ while (i < TableSize) { ++ RegionSize = pVirtualMappingTable[i].RegionSize; ++ nextI = i+RegionSize; ++ if (pVirtualMappingTable[i].bReserved == false) { ++ /* Coalesce, if possible */ ++ if (nextI < TableSize && ++ pVirtualMappingTable[nextI].bReserved ++ == false) { ++ pVirtualMappingTable[i].RegionSize += ++ pVirtualMappingTable[nextI].RegionSize; ++ continue; ++ } ++ RegionSize *= PG_SIZE_4K; ++ if (RegionSize > iFreeSize) { ++ iFreeRegion = i; ++ iFreeSize = RegionSize; ++ } ++ } ++ i = nextI; ++ } ++ } ++ if (aSize <= iFreeSize) { ++ currRegion = pVirtualMappingTable + iFreeRegion; ++ iFreeRegion += (aSize / PG_SIZE_4K); ++ iFreeSize -= aSize; ++ } ++ return currRegion; ++} ++ ++/* ++ * ======== GetMappedRegion ======== ++ * Purpose: ++ * Returns the requestedmapped region ++ */ ++static struct MapPage *GetMappedRegion(u32 aAddr) ++{ ++ u32 i = 0; ++ struct MapPage *currRegion = NULL; ++ GT_1trace(DMM_debugMask, GT_ENTER, "Entered GetMappedRegion () " ++ "aAddr 0x%x\n", aAddr); ++ ++ if (pVirtualMappingTable == NULL) ++ return currRegion; ++ ++ i = DMM_ADDR_TO_INDEX(aAddr); ++ if (i < TableSize && (pVirtualMappingTable[i].bMapped || ++ pVirtualMappingTable[i].bReserved)) ++ currRegion = pVirtualMappingTable + i; ++ return currRegion; ++} ++ ++/* ++ * ======== DMM_GetPhysicalAddrTable ======== ++ * Purpose: ++ * Returns the physical table address ++ */ ++u32 *DMM_GetPhysicalAddrTable(void) ++{ ++ GT_1trace(DMM_debugMask, GT_ENTER, "Entered " ++ "DMM_GetPhysicalAddrTable()- pPhysicalAddrTable 0x%x\n", ++ pPhysicalAddrTable); ++ return pPhysicalAddrTable; ++} ++ ++#ifdef DSP_DMM_DEBUG ++u32 DMM_MemMapDump(struct DMM_OBJECT *hDmmMgr) ++{ ++ struct MapPage *curNode = NULL; ++ u32 i; ++ u32 freemem = 0; ++ u32 bigsize = 0; ++ ++ SYNC_EnterCS(hDmmMgr->hDmmLock); ++ ++ if (pVirtualMappingTable != NULL) { ++ for (i = 0; i < TableSize; i += ++ pVirtualMappingTable[i].RegionSize) { ++ curNode = pVirtualMappingTable + i; ++ if (curNode->bReserved == TRUE) { ++ /*printk("RESERVED size = 0x%x, " ++ "Map size = 0x%x\n", ++ (curNode->RegionSize * PG_SIZE_4K), ++ (curNode->bMapped == false) ? 0 : ++ (curNode->MappedSize * PG_SIZE_4K)); ++*/ ++ } else { ++/* printk("UNRESERVED size = 0x%x\n", ++ (curNode->RegionSize * PG_SIZE_4K)); ++*/ ++ freemem += (curNode->RegionSize * PG_SIZE_4K); ++ if (curNode->RegionSize > bigsize) ++ bigsize = curNode->RegionSize; ++ } ++ } ++ } ++ printk(KERN_INFO "Total DSP VA FREE memory = %d Mbytes\n", ++ freemem/(1024*1024)); ++ printk(KERN_INFO "Total DSP VA USED memory= %d Mbytes \n", ++ (((TableSize * PG_SIZE_4K)-freemem))/(1024*1024)); ++ printk(KERN_INFO "DSP VA - Biggest FREE block = %d Mbytes \n\n", ++ (bigsize*PG_SIZE_4K/(1024*1024))); ++ SYNC_LeaveCS(hDmmMgr->hDmmLock); ++ ++ return 0; ++} ++#endif +diff --git a/drivers/dsp/bridge/pmgr/io.c b/drivers/dsp/bridge/pmgr/io.c +new file mode 100644 +index 0000000..cdfe0dc +--- /dev/null ++++ b/drivers/dsp/bridge/pmgr/io.c +@@ -0,0 +1,205 @@ ++/* ++ * io.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== io.c ======== ++ * Description: ++ * IO manager interface: Manages IO between CHNL and MSG. ++ * ++ * Public Functions: ++ * IO_Create ++ * IO_Destroy ++ * IO_Exit ++ * IO_Init ++ * IO_OnLoaded ++ * ++ * Notes: ++ * This interface is basically a pass through to the WMD IO functions. ++ * ++ *! Revision History: ++ *! ================ ++ *! 24-Feb-2003 swa PMGR Code review comments incorporated. ++ *! 04-Apr-2001 rr WSX_STATUS initialized in IO_Create. ++ *! 07-Nov-2000 jeh Created. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++ ++/* ----------------------------------- This */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Globals */ ++static u32 cRefs; ++ ++#if GT_TRACE ++static struct GT_Mask IO_DebugMask = { NULL, NULL }; /* WCD IO Mask */ ++#endif ++ ++/* ++ * ======== IO_Create ======== ++ * Purpose: ++ * Create an IO manager object, responsible for managing IO between ++ * CHNL and MSG ++ */ ++DSP_STATUS IO_Create(OUT struct IO_MGR **phIOMgr, struct DEV_OBJECT *hDevObject, ++ IN CONST struct IO_ATTRS *pMgrAttrs) ++{ ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ struct IO_MGR *hIOMgr = NULL; ++ struct IO_MGR_ *pIOMgr = NULL; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phIOMgr != NULL); ++ DBC_Require(pMgrAttrs != NULL); ++ ++ GT_3trace(IO_DebugMask, GT_ENTER, "Entered IO_Create: phIOMgr: 0x%x\t " ++ "hDevObject: 0x%x\tpMgrAttrs: 0x%x\n", ++ phIOMgr, hDevObject, pMgrAttrs); ++ ++ *phIOMgr = NULL; ++ ++ /* A memory base of 0 implies no memory base: */ ++ if ((pMgrAttrs->dwSMBase != 0) && (pMgrAttrs->uSMLength == 0)) { ++ status = CHNL_E_INVALIDMEMBASE; ++ GT_0trace(IO_DebugMask, GT_7CLASS, ++ "IO_Create:Invalid Mem Base\n"); ++ } ++ ++ if (pMgrAttrs->uWordSize == 0) { ++ status = CHNL_E_INVALIDWORDSIZE; ++ GT_0trace(IO_DebugMask, GT_7CLASS, ++ "IO_Create:Invalid Word size\n"); ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ DEV_GetIntfFxns(hDevObject, &pIntfFxns); ++ ++ /* Let WMD channel module finish the create: */ ++ status = (*pIntfFxns->pfnIOCreate)(&hIOMgr, hDevObject, ++ pMgrAttrs); ++ ++ if (DSP_SUCCEEDED(status)) { ++ pIOMgr = (struct IO_MGR_ *) hIOMgr; ++ pIOMgr->pIntfFxns = pIntfFxns; ++ pIOMgr->hDevObject = hDevObject; ++ ++ /* Return the new channel manager handle: */ ++ *phIOMgr = hIOMgr; ++ GT_1trace(IO_DebugMask, GT_1CLASS, ++ "IO_Create: Success hIOMgr: 0x%x\n", ++ hIOMgr); ++ } ++ } ++ ++ GT_2trace(IO_DebugMask, GT_ENTER, ++ "Exiting IO_Create: hIOMgr: 0x%x, status:" ++ " 0x%x\n", hIOMgr, status); ++ ++ return status; ++} ++ ++/* ++ * ======== IO_Destroy ======== ++ * Purpose: ++ * Delete IO manager. ++ */ ++DSP_STATUS IO_Destroy(struct IO_MGR *hIOMgr) ++{ ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ struct IO_MGR_ *pIOMgr = (struct IO_MGR_ *)hIOMgr; ++ DSP_STATUS status; ++ ++ DBC_Require(cRefs > 0); ++ ++ GT_1trace(IO_DebugMask, GT_ENTER, "Entered IO_Destroy: hIOMgr: 0x%x\n", ++ hIOMgr); ++ ++ pIntfFxns = pIOMgr->pIntfFxns; ++ ++ /* Let WMD channel module destroy the IO_MGR: */ ++ status = (*pIntfFxns->pfnIODestroy) (hIOMgr); ++ ++ GT_2trace(IO_DebugMask, GT_ENTER, ++ "Exiting IO_Destroy: pIOMgr: 0x%x, status:" ++ " 0x%x\n", pIOMgr, status); ++ return status; ++} ++ ++/* ++ * ======== IO_Exit ======== ++ * Purpose: ++ * Discontinue usage of the IO module. ++ */ ++void IO_Exit(void) ++{ ++ DBC_Require(cRefs > 0); ++ ++ cRefs--; ++ ++ GT_1trace(IO_DebugMask, GT_5CLASS, ++ "Entered IO_Exit, ref count: 0x%x\n", cRefs); ++ ++ DBC_Ensure(cRefs >= 0); ++} ++ ++/* ++ * ======== IO_Init ======== ++ * Purpose: ++ * Initialize the IO module's private state. ++ */ ++bool IO_Init(void) ++{ ++ bool fRetval = true; ++ ++ DBC_Require(cRefs >= 0); ++ ++ if (cRefs == 0) { ++ DBC_Assert(!IO_DebugMask.flags); ++ GT_create(&IO_DebugMask, "IO"); /* "IO" for IO */ ++ } ++ ++ if (fRetval) ++ cRefs++; ++ ++ ++ GT_1trace(IO_DebugMask, GT_5CLASS, ++ "Entered IO_Init, ref count: 0x%x\n", cRefs); ++ ++ DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0))); ++ ++ return fRetval; ++} +diff --git a/drivers/dsp/bridge/pmgr/ioobj.h b/drivers/dsp/bridge/pmgr/ioobj.h +new file mode 100644 +index 0000000..f473a63 +--- /dev/null ++++ b/drivers/dsp/bridge/pmgr/ioobj.h +@@ -0,0 +1,52 @@ ++/* ++ * ioobj.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== ioobj.h ======== ++ * Description: ++ * Structure subcomponents of channel class library IO objects which ++ * are exposed to class driver from mini-driver. ++ * ++ * Public Functions: ++ * None. ++ * ++ *! Revision History: ++ *! ================ ++ *! 24-Feb-2003 swa PMGR Code review comments incorporated. ++ *! 01/16/97 gp: Created from chnlpriv.h ++ */ ++ ++#ifndef IOOBJ_ ++#define IOOBJ_ ++ ++#include ++#include ++ ++/* ++ * This struct is the first field in a IO_MGR struct, as implemented in ++ * a WMD channel class library. Other, implementation specific fields ++ * follow this structure in memory. ++ */ ++struct IO_MGR_ { ++ /* These must be the first fields in a IO_MGR struct: */ ++ u32 dwSignature; /* Used for object validation. */ ++ struct WMD_DEV_CONTEXT *hWmdContext; /* WMD device context. */ ++ struct WMD_DRV_INTERFACE *pIntfFxns; /* Function interface to WMD. */ ++ struct DEV_OBJECT *hDevObject; /* Device this board represents. */ ++} ; ++ ++#endif /* IOOBJ_ */ +diff --git a/drivers/dsp/bridge/pmgr/msg.c b/drivers/dsp/bridge/pmgr/msg.c +new file mode 100644 +index 0000000..bbf5174 +--- /dev/null ++++ b/drivers/dsp/bridge/pmgr/msg.c +@@ -0,0 +1,173 @@ ++/* ++ * msg.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== msg.c ======== ++ * Description: ++ * DSP/BIOS Bridge MSG Module. ++ * ++ * Public Functions: ++ * MSG_Create ++ * MSG_Delete ++ * MSG_Exit ++ * MSG_Init ++ * ++ *! Revision History: ++ *! ================= ++ *! 24-Feb-2003 swa PMGR Code review comments incorporated. ++ *! 15-May-2001 ag Changed SUCCEEDED to DSP_SUCCEEDED. ++ *! 16-Feb-2001 jeh Fixed some comments. ++ *! 15-Dec-2000 rr MSG_Create returns DSP_EFAIL if pfnMsgCreate fails. ++ *! 12-Sep-2000 jeh Created. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++ ++/* ----------------------------------- Mini Driver */ ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++ ++/* ----------------------------------- This */ ++#include ++#include ++ ++/* ----------------------------------- Globals */ ++#if GT_TRACE ++static struct GT_Mask MSG_debugMask = { NULL, NULL }; /* GT trace variable */ ++#endif ++static u32 cRefs; /* module reference count */ ++ ++/* ++ * ======== MSG_Create ======== ++ * Purpose: ++ * Create an object to manage message queues. Only one of these objects ++ * can exist per device object. ++ */ ++DSP_STATUS MSG_Create(OUT struct MSG_MGR **phMsgMgr, ++ struct DEV_OBJECT *hDevObject, MSG_ONEXIT msgCallback) ++{ ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ struct MSG_MGR_ *pMsgMgr; ++ struct MSG_MGR *hMsgMgr; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phMsgMgr != NULL); ++ DBC_Require(msgCallback != NULL); ++ DBC_Require(hDevObject != NULL); ++ ++ GT_3trace(MSG_debugMask, GT_ENTER, "MSG_Create: phMsgMgr: 0x%x\t" ++ "hDevObject: 0x%x\tmsgCallback: 0x%x\n", ++ phMsgMgr, hDevObject, msgCallback); ++ ++ *phMsgMgr = NULL; ++ ++ DEV_GetIntfFxns(hDevObject, &pIntfFxns); ++ ++ /* Let WMD message module finish the create: */ ++ status = (*pIntfFxns->pfnMsgCreate)(&hMsgMgr, hDevObject, msgCallback); ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* Fill in WCD message module's fields of the MSG_MGR ++ * structure */ ++ pMsgMgr = (struct MSG_MGR_ *)hMsgMgr; ++ pMsgMgr->pIntfFxns = pIntfFxns; ++ ++ /* Finally, return the new message manager handle: */ ++ *phMsgMgr = hMsgMgr; ++ GT_1trace(MSG_debugMask, GT_1CLASS, ++ "MSG_Create: Success pMsgMgr: 0x%x\n", pMsgMgr); ++ } else { ++ status = DSP_EFAIL; ++ } ++ return status; ++} ++ ++/* ++ * ======== MSG_Delete ======== ++ * Purpose: ++ * Delete a MSG manager allocated in MSG_Create(). ++ */ ++void MSG_Delete(struct MSG_MGR *hMsgMgr) ++{ ++ struct MSG_MGR_ *pMsgMgr = (struct MSG_MGR_ *)hMsgMgr; ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(pMsgMgr, MSGMGR_SIGNATURE)); ++ ++ GT_1trace(MSG_debugMask, GT_ENTER, "MSG_Delete: hMsgMgr: 0x%x\n", ++ hMsgMgr); ++ ++ pIntfFxns = pMsgMgr->pIntfFxns; ++ ++ /* Let WMD message module destroy the MSG_MGR: */ ++ (*pIntfFxns->pfnMsgDelete)(hMsgMgr); ++ ++ DBC_Ensure(!MEM_IsValidHandle(pMsgMgr, MSGMGR_SIGNATURE)); ++} ++ ++/* ++ * ======== MSG_Exit ======== ++ */ ++void MSG_Exit(void) ++{ ++ DBC_Require(cRefs > 0); ++ cRefs--; ++ GT_1trace(MSG_debugMask, GT_5CLASS, ++ "Entered MSG_Exit, ref count: 0x%x\n", cRefs); ++ DBC_Ensure(cRefs >= 0); ++} ++ ++/* ++ * ======== MSG_Init ======== ++ */ ++bool MSG_Init(void) ++{ ++ DBC_Require(cRefs >= 0); ++ ++ if (cRefs == 0) { ++ DBC_Assert(!MSG_debugMask.flags); ++ GT_create(&MSG_debugMask, "MG"); /* "MG" for MsG */ ++ } ++ ++ cRefs++; ++ ++ GT_1trace(MSG_debugMask, GT_5CLASS, "MSG_Init(), ref count: 0x%x\n", ++ cRefs); ++ ++ DBC_Ensure(cRefs >= 0); ++ ++ return true; ++} ++ +diff --git a/drivers/dsp/bridge/pmgr/msgobj.h b/drivers/dsp/bridge/pmgr/msgobj.h +new file mode 100644 +index 0000000..63d025b +--- /dev/null ++++ b/drivers/dsp/bridge/pmgr/msgobj.h +@@ -0,0 +1,52 @@ ++/* ++ * msgobj.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== msgobj.h ======== ++ * Description: ++ * Structure subcomponents of channel class library MSG objects which ++ * are exposed to class driver from mini-driver. ++ * ++ * Public Functions: ++ * None. ++ * ++ *! Revision History: ++ *! ================ ++ *! 24-Feb-2003 swa PMGR Code review comments incorporated. ++ *! 17-Nov-2000 jeh Created. ++ */ ++ ++#ifndef MSGOBJ_ ++#define MSGOBJ_ ++ ++#include ++ ++#include ++ ++/* ++ * This struct is the first field in a MSG_MGR struct, as implemented in ++ * a WMD channel class library. Other, implementation specific fields ++ * follow this structure in memory. ++ */ ++struct MSG_MGR_ { ++ /* The first two fields must match those in msgobj.h */ ++ u32 dwSignature; ++ struct WMD_DRV_INTERFACE *pIntfFxns; /* Function interface to WMD. */ ++}; ++ ++#endif /* MSGOBJ_ */ ++ +diff --git a/drivers/dsp/bridge/pmgr/wcd.c b/drivers/dsp/bridge/pmgr/wcd.c +new file mode 100644 +index 0000000..859043d +--- /dev/null ++++ b/drivers/dsp/bridge/pmgr/wcd.c +@@ -0,0 +1,1647 @@ ++/* ++ * wcd.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== wcd.c ======== ++ * Description: ++ * Common WCD functions, also includes the wrapper ++ * functions called directly by the DeviceIOControl interface. ++ * ++ * Public Functions: ++ * WCD_CallDevIOCtl ++ * WCD_Init ++ * WCD_InitComplete2 ++ * WCD_Exit ++ * WRAP_* ++ * ++ *! Revision History: ++ *! ================ ++ *! 29-Apr-2004 hp Call PROC_AutoStart only for DSP device ++ *! 19-Apr-2004 sb Aligned DMM definitions with Symbian ++ *! 08-Mar-2004 sb Added the Dynamic Memory Mapping APIs ++ *! 03-Apr-2003 sb Process environment pointer in PROCWRAP_Load ++ *! 24-Feb-2003 swa PMGR Code review comments incorporated. ++ *! 30-Jan-2002 ag CMMWRAP_AllocBuf name changed to CMMWRAP_CallocBuf ++ *! 15-Jan-2002 ag Added actual bufSize param to STRMWRAP_Reclaim[issue]. ++ *! 14-Dec-2001 rr ARGS_NODE_CONNECT maps the pAttr. ++ *! 03-Oct-2001 rr ARGS_NODE_ALLOCMSGBUF/FREEMSGBUF maps the pAttr. ++ *! 10-Sep-2001 ag Added CMD_CMM_GETHANDLE. ++ *! 23-Apr-2001 jeh Pass pStatus to NODE_Terminate. ++ *! 11-Apr-2001 jeh STRMWRAP_Reclaim embedded pointer is mapped and unmapped. ++ *! 13-Feb-2001 kc: DSP/BIOS Bridge name updates. ++ *! 06-Dec-2000 jeh WRAP_MAP2CALLER pointers in RegisterNotify calls. ++ *! 05-Dec-2000 ag: Removed MAP2CALLER in NODEWRAP_FreeMsgBuf(). ++ *! 22-Nov-2000 kc: Added MGRWRAP_GetPerf_Data(). ++ *! 20-Nov-2000 jeh Added MSG_Init()/MSG_Exit(), IO_Init()/IO_Exit(). ++ *! WRAP pointers to handles for PROC_Attach, NODE_Allocate. ++ *! 27-Oct-2000 jeh Added NODEWRAP_AllocMsgBuf, NODEWRAP_FreeMsgBuf. Removed ++ *! NODEWRAP_GetMessageStream. ++ *! 12-Oct-2000 ag: Added user CMM wrappers. ++ *! 05-Oct-2000 rr: WcdInitComplete2 will fail even if one BRD or PROC ++ *! AutoStart fails. ++ *! 25-Sep-2000 rr: Updated to Version 0.9 ++ *! 13-Sep-2000 jeh Pass ARGS_NODE_CONNECT.pAttrs to NODE_Connect(). ++ *! 11-Aug-2000 rr: Part of node enabled. ++ *! 31-Jul-2000 rr: UTIL_Wrap and MEM_Wrap added to RM. ++ *! 27-Jul-2000 rr: PROCWRAP, NODEWRAP and STRMWRAP implemented. ++ *! STRM and some NODE Wrappers are not implemented. ++ *! 27-Jun-2000 rr: MGRWRAP fxns added.IFDEF to build for PM or DSP/BIOS Bridge ++ *! 08-Feb-2000 rr File name changed to wcd.c ++ *! 03-Feb-2000 rr: Module initialization are done by SERVICES init. GT Class ++ *! changes for module init/exit fxns. ++ *! 24-Jan-2000 rr: Merged with Scott's code. ++ *! 21-Jan-1999 sg: Changed ARGS_CHNL_GETMODE field name from pdwMode to pMode. ++ *! 17-Jan-2000 rr: BRD_GetStatus does WRAP_MAP2CALLER for state. ++ *! 14-Dec-1999 ag: Removed _MAP2CALLER in CHNL_GetMgr(). ++ *! 13-Dec-1999 rr: BRDWRAP_GetSymbol, BRDWRAP_GetTrace uses WRAP_MAP2CALLER ++ *! macros.BRDWRAP_Load maps and unmaps embedded pointers. ++ *! 10-Dec-1999 ag: User CHNL bufs mapped in _AddIOReq & _GetIOCompletion. ++ *! 09-Dec-1999 rr: BRDWRAP_Open and CHNLWRAP_GetMgr does not map ++ *! pointer as there was a change in config.c ++ *! 06-Dec-1999 rr: BRD_Read and Write Maps the buf pointers. ++ *! 03-Dec-1999 rr: CHNLWRAP_GetMgr and BRDWRAP_Open maps hDevNode pointer. ++ *! WCD_InitComplete2 Included for BRD_AutoStart. ++ *! 16-Nov-1999 ag: Map buf to process in CHNLWRAP_AllocBuffer(). ++ *! CHNL_GetMgr() Mapping Fix. ++ *! 10-Nov-1999 ag: Removed unnecessary calls to WRAP_MAP2CALLER. ++ *! 08-Nov-1999 kc: Added MEMRY & enabled BRD_IOCtl for tests. ++ *! 29-Oct-1999 ag: Added CHNL. ++ *! 29-Oct-1999 kc: Added trace statements; added ptr mapping; updated ++ *! use of UTIL module API. ++ *! 29-Oct-1999 rr: Wrapper functions does the Mapping of the Pointers. ++ *! in WinCE all the explicit pointers will be converted ++ *! by the OS during interprocess but not the embedded pointers. ++ *! 16-Oct-1999 kc: Code review cleanup. ++ *! 07-Oct-1999 kc: Added UTILWRAP_TestDll() to run PM test harness. See ++ *! /src/doc/pmtest.doc for more detail. ++ *! 09-Sep-1999 rr: After exactly two years(!). Adopted for WinCE. GT Enabled. ++ *! 09-Sep-1997 gp: Created. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++#include ++#include ++ ++#include ++#include ++ ++/* ----------------------------------- Resource Manager */ ++#include ++#include ++#include ++#include ++ ++ ++/* ----------------------------------- Others */ ++#include ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++#include ++ ++#ifndef RES_CLEANUP_DISABLE ++#include ++#endif ++ ++/* ----------------------------------- Defines, Data Structures, Typedefs */ ++#define MAX_TRACEBUFLEN 255 ++#define MAX_LOADARGS 16 ++#define MAX_NODES 64 ++#define MAX_STREAMS 16 ++#define MAX_BUFS 64 ++ ++/* Following two macros should ideally have do{}while(0) */ ++ ++#define cp_fm_usr(dest, src, status, elements) \ ++ if (DSP_SUCCEEDED(status)) {\ ++ if (unlikely(src == NULL) || \ ++ unlikely(copy_from_user(dest, src, elements * sizeof(*(dest))))) { \ ++ GT_1trace(WCD_debugMask, GT_7CLASS, \ ++ "copy_from_user failed, src=0x%x\n", src); \ ++ status = DSP_EPOINTER ; \ ++ } \ ++ } ++ ++#define cp_to_usr(dest, src, status, elements) \ ++ if (DSP_SUCCEEDED(status)) {\ ++ if (unlikely(dest == NULL) || \ ++ unlikely(copy_to_user(dest, src, elements * sizeof(*(src))))) { \ ++ GT_1trace(WCD_debugMask, GT_7CLASS, \ ++ "copy_to_user failed, dest=0x%x\n", dest); \ ++ status = DSP_EPOINTER ;\ ++ } \ ++ } ++ ++/* Device IOCtl function pointer */ ++struct WCD_Cmd { ++ u32(*fxn)(union Trapped_Args *args); ++ u32 dwIndex; ++} ; ++ ++/* ----------------------------------- Globals */ ++#if GT_TRACE ++static struct GT_Mask WCD_debugMask = { NULL, NULL }; /* Core VxD Mask */ ++#endif ++static u32 WCD_cRefs; ++ ++/* ++ * Function table. ++ * The order of these functions MUST be the same as the order of the command ++ * numbers defined in wcdioctl.h This is how an IOCTL number in user mode ++ * turns into a function call in kernel mode. ++ */ ++static struct WCD_Cmd WCD_cmdTable[] = { ++ /* MGR module */ ++ {MGRWRAP_EnumNode_Info, CMD_MGR_ENUMNODE_INFO_OFFSET}, ++ {MGRWRAP_EnumProc_Info, CMD_MGR_ENUMPROC_INFO_OFFSET}, ++ {MGRWRAP_RegisterObject, CMD_MGR_REGISTEROBJECT_OFFSET}, ++ {MGRWRAP_UnregisterObject, CMD_MGR_UNREGISTEROBJECT_OFFSET}, ++ {MGRWRAP_WaitForBridgeEvents, CMD_MGR_WAIT_OFFSET}, ++#ifndef RES_CLEANUP_DISABLE ++ {MGRWRAP_GetProcessResourcesInfo, CMD_MGR_RESOUCES_OFFSET}, ++#endif ++ /* PROC Module */ ++ {PROCWRAP_Attach, CMD_PROC_ATTACH_OFFSET}, ++ {PROCWRAP_Ctrl, CMD_PROC_CTRL_OFFSET}, ++ {PROCWRAP_Detach, CMD_PROC_DETACH_OFFSET}, ++ {PROCWRAP_EnumNode_Info, CMD_PROC_ENUMNODE_OFFSET}, ++ {PROCWRAP_EnumResources, CMD_PROC_ENUMRESOURCES_OFFSET}, ++ {PROCWRAP_GetState, CMD_PROC_GETSTATE_OFFSET}, ++ {PROCWRAP_GetTrace, CMD_PROC_GETTRACE_OFFSET}, ++ {PROCWRAP_Load, CMD_PROC_LOAD_OFFSET}, ++ {PROCWRAP_RegisterNotify, CMD_PROC_REGISTERNOTIFY_OFFSET}, ++ {PROCWRAP_Start, CMD_PROC_START_OFFSET}, ++ {PROCWRAP_ReserveMemory, CMD_PROC_RSVMEM_OFFSET}, ++ {PROCWRAP_UnReserveMemory, CMD_PROC_UNRSVMEM_OFFSET}, ++ {PROCWRAP_Map, CMD_PROC_MAPMEM_OFFSET}, ++ {PROCWRAP_UnMap, CMD_PROC_UNMAPMEM_OFFSET}, ++ {PROCWRAP_FlushMemory, CMD_PROC_FLUSHMEMORY_OFFSET}, ++ {PROCWRAP_Stop, CMD_PROC_STOP_OFFSET}, ++ {PROCWRAP_InvalidateMemory, CMD_PROC_INVALIDATEMEMORY_OFFSET}, ++ /* NODE Module */ ++ {NODEWRAP_Allocate, CMD_NODE_ALLOCATE_OFFSET}, ++ {NODEWRAP_AllocMsgBuf, CMD_NODE_ALLOCMSGBUF_OFFSET}, ++ {NODEWRAP_ChangePriority, CMD_NODE_CHANGEPRIORITY_OFFSET}, ++ {NODEWRAP_Connect, CMD_NODE_CONNECT_OFFSET}, ++ {NODEWRAP_Create, CMD_NODE_CREATE_OFFSET}, ++ {NODEWRAP_Delete, CMD_NODE_DELETE_OFFSET}, ++ {NODEWRAP_FreeMsgBuf, CMD_NODE_FREEMSGBUF_OFFSET}, ++ {NODEWRAP_GetAttr, CMD_NODE_GETATTR_OFFSET}, ++ {NODEWRAP_GetMessage, CMD_NODE_GETMESSAGE_OFFSET}, ++ {NODEWRAP_Pause, CMD_NODE_PAUSE_OFFSET}, ++ {NODEWRAP_PutMessage, CMD_NODE_PUTMESSAGE_OFFSET}, ++ {NODEWRAP_RegisterNotify, CMD_NODE_REGISTERNOTIFY_OFFSET}, ++ {NODEWRAP_Run, CMD_NODE_RUN_OFFSET}, ++ {NODEWRAP_Terminate, CMD_NODE_TERMINATE_OFFSET}, ++ {NODEWRAP_GetUUIDProps, CMD_NODE_GETUUIDPROPS_OFFSET}, ++ /* STRM wrapper functions */ ++ {STRMWRAP_AllocateBuffer, CMD_STRM_ALLOCATEBUFFER_OFFSET}, ++ {STRMWRAP_Close, CMD_STRM_CLOSE_OFFSET}, ++ {STRMWRAP_FreeBuffer, CMD_STRM_FREEBUFFER_OFFSET}, ++ {STRMWRAP_GetEventHandle, CMD_STRM_GETEVENTHANDLE_OFFSET}, ++ {STRMWRAP_GetInfo, CMD_STRM_GETINFO_OFFSET}, ++ {STRMWRAP_Idle, CMD_STRM_IDLE_OFFSET}, ++ {STRMWRAP_Issue, CMD_STRM_ISSUE_OFFSET}, ++ {STRMWRAP_Open, CMD_STRM_OPEN_OFFSET}, ++ {STRMWRAP_Reclaim, CMD_STRM_RECLAIM_OFFSET}, ++ {STRMWRAP_RegisterNotify, CMD_STRM_REGISTERNOTIFY_OFFSET}, ++ {STRMWRAP_Select, CMD_STRM_SELECT_OFFSET}, ++ /* CMM module */ ++ {CMMWRAP_CallocBuf, CMD_CMM_ALLOCBUF_OFFSET}, ++ {CMMWRAP_FreeBuf, CMD_CMM_FREEBUF_OFFSET}, ++ {CMMWRAP_GetHandle, CMD_CMM_GETHANDLE_OFFSET}, ++ {CMMWRAP_GetInfo, CMD_CMM_GETINFO_OFFSET} ++}; ++ ++/* ++ * ======== WCD_CallDevIOCtl ======== ++ * Purpose: ++ * Call the (wrapper) function for the corresponding WCD IOCTL. ++ */ ++inline DSP_STATUS WCD_CallDevIOCtl(u32 cmd, union Trapped_Args *args, ++ u32 *pResult) ++{ ++ if ((cmd < (sizeof(WCD_cmdTable) / sizeof(struct WCD_Cmd)))) { ++ /* make the fxn call via the cmd table */ ++ *pResult = (*WCD_cmdTable[cmd].fxn) (args); ++ return DSP_SOK; ++ } else { ++ return DSP_EINVALIDARG; ++ } ++} ++ ++/* ++ * ======== WCD_Exit ======== ++ */ ++void WCD_Exit(void) ++{ ++ DBC_Require(WCD_cRefs > 0); ++ WCD_cRefs--; ++ GT_1trace(WCD_debugMask, GT_5CLASS, ++ "Entered WCD_Exit, ref count: 0x%x\n", WCD_cRefs); ++ if (WCD_cRefs == 0) { ++ /* Release all WCD modules initialized in WCD_Init(). */ ++ COD_Exit(); ++ DEV_Exit(); ++ CHNL_Exit(); ++ MSG_Exit(); ++ IO_Exit(); ++ STRM_Exit(); ++ NTFY_Exit(); ++ DISP_Exit(); ++ NODE_Exit(); ++ PROC_Exit(); ++ MGR_Exit(); ++ RMM_exit(); ++ DRV_Exit(); ++ SERVICES_Exit(); ++ } ++ DBC_Ensure(WCD_cRefs >= 0); ++} ++ ++/* ++ * ======== WCD_Init ======== ++ * Purpose: ++ * Module initialization is done by SERVICES Init. ++ */ ++bool WCD_Init(void) ++{ ++ bool fInit = true; ++ bool fDRV, fDEV, fCOD, fSERVICES, fCHNL, fMSG, fIO; ++ bool fMGR, fPROC, fNODE, fDISP, fNTFY, fSTRM, fRMM; ++#ifdef DEBUG ++ /* runtime check of Device IOCtl array. */ ++ u32 i; ++ for (i = 1; i < (sizeof(WCD_cmdTable) / sizeof(struct WCD_Cmd)); i++) ++ DBC_Assert(WCD_cmdTable[i - 1].dwIndex == i); ++ ++#endif ++ if (WCD_cRefs == 0) { ++ /* initialize all SERVICES modules */ ++ fSERVICES = SERVICES_Init(); ++ /* initialize debugging module */ ++ DBC_Assert(!WCD_debugMask.flags); ++ GT_create(&WCD_debugMask, "CD"); /* CD for class driver */ ++ /* initialize class driver and other modules */ ++ fDRV = DRV_Init(); ++ fMGR = MGR_Init(); ++ fPROC = PROC_Init(); ++ fNODE = NODE_Init(); ++ fDISP = DISP_Init(); ++ fNTFY = NTFY_Init(); ++ fSTRM = STRM_Init(); ++ fRMM = RMM_init(); ++ fCHNL = CHNL_Init(); ++ fMSG = MSG_Init(); ++ fIO = IO_Init(); ++ fDEV = DEV_Init(); ++ fCOD = COD_Init(); ++ fInit = fSERVICES && fDRV && fDEV && fCHNL && fCOD && ++ fMSG && fIO; ++ fInit = fInit && fMGR && fPROC && fRMM; ++ if (!fInit) { ++ if (fSERVICES) ++ SERVICES_Exit(); ++ ++ if (fDRV) ++ DRV_Exit(); ++ ++ if (fMGR) ++ MGR_Exit(); ++ ++ if (fSTRM) ++ STRM_Exit(); ++ ++ if (fPROC) ++ PROC_Exit(); ++ ++ if (fNODE) ++ NODE_Exit(); ++ ++ if (fDISP) ++ DISP_Exit(); ++ ++ if (fNTFY) ++ NTFY_Exit(); ++ ++ if (fCHNL) ++ CHNL_Exit(); ++ ++ if (fMSG) ++ MSG_Exit(); ++ ++ if (fIO) ++ IO_Exit(); ++ ++ if (fDEV) ++ DEV_Exit(); ++ ++ if (fCOD) ++ COD_Exit(); ++ ++ if (fRMM) ++ RMM_exit(); ++ ++ } ++ } ++ if (fInit) ++ WCD_cRefs++; ++ ++ GT_1trace(WCD_debugMask, GT_5CLASS, ++ "Entered WCD_Init, ref count: 0x%x\n", WCD_cRefs); ++ return fInit; ++} ++ ++/* ++ * ======== WCD_InitComplete2 ======== ++ * Purpose: ++ * Perform any required WCD, and WMD initialization which ++ * cannot not be performed in WCD_Init() or DEV_StartDevice() due ++ * to the fact that some services are not yet ++ * completely initialized. ++ * Parameters: ++ * Returns: ++ * DSP_SOK: Allow this device to load ++ * DSP_EFAIL: Failure. ++ * Requires: ++ * WCD initialized. ++ * Ensures: ++ */ ++DSP_STATUS WCD_InitComplete2(void) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct CFG_DEVNODE *DevNode; ++ struct DEV_OBJECT *hDevObject; ++ u32 devType; ++ ++ DBC_Require(WCD_cRefs > 0); ++ GT_0trace(WCD_debugMask, GT_ENTER, "Entered WCD_InitComplete\n"); ++ /* Walk the list of DevObjects, get each devnode, and attempting to ++ * autostart the board. Note that this requires COF loading, which ++ * requires KFILE. */ ++ for (hDevObject = DEV_GetFirst(); hDevObject != NULL; ++ hDevObject = DEV_GetNext(hDevObject)) { ++ if (DSP_FAILED(DEV_GetDevNode(hDevObject, &DevNode))) ++ continue; ++ ++ if (DSP_FAILED(DEV_GetDevType(hDevObject, &devType))) ++ continue; ++ ++ if ((devType == DSP_UNIT) || (devType == IVA_UNIT)) { ++ if (DSP_FAILED(PROC_AutoStart(DevNode, hDevObject))) { ++ GT_0trace(WCD_debugMask, GT_1CLASS, ++ "WCD_InitComplete2 Failed\n"); ++ status = DSP_EFAIL; ++ /* break; */ ++ } ++ } else ++ GT_1trace(WCD_debugMask, GT_ENTER, ++ "Ignoring PROC_AutoStart " ++ "for Device Type = 0x%x \n", devType); ++ } /* End For Loop */ ++ GT_1trace(WCD_debugMask, GT_ENTER, ++ "Exiting WCD_InitComplete status 0x%x\n", status); ++ return status; ++} ++ ++/* ++ * ======== MGRWRAP_EnumNode_Info ======== ++ */ ++u32 MGRWRAP_EnumNode_Info(union Trapped_Args *args) ++{ ++ u8 *pNDBProps; ++ u32 uNumNodes; ++ DSP_STATUS status = DSP_SOK; ++ u32 size = args->ARGS_MGR_ENUMNODE_INFO.uNDBPropsSize; ++ ++ GT_4trace(WCD_debugMask, GT_ENTER, ++ "MGR_EnumNodeInfo: entered args:\n0x%x" ++ " uNode: 0x%x\tpNDBProps: 0x%x\tuNDBPropsSize: " ++ "0x%x\tpuNumNodes\n", args->ARGS_MGR_ENUMNODE_INFO.uNode, ++ args->ARGS_MGR_ENUMNODE_INFO.pNDBProps, ++ args->ARGS_MGR_ENUMNODE_INFO.uNDBPropsSize, ++ args->ARGS_MGR_ENUMNODE_INFO.puNumNodes); ++ pNDBProps = MEM_Alloc(size, MEM_NONPAGED); ++ if (pNDBProps == NULL) ++ status = DSP_EMEMORY; ++ ++ if (DSP_SUCCEEDED(status)) { ++ status = MGR_EnumNodeInfo(args->ARGS_MGR_ENUMNODE_INFO.uNode, ++ (struct DSP_NDBPROPS *)pNDBProps, ++ size, &uNumNodes); ++ } ++ cp_to_usr(args->ARGS_MGR_ENUMNODE_INFO.pNDBProps, pNDBProps, status, ++ size); ++ cp_to_usr(args->ARGS_MGR_ENUMNODE_INFO.puNumNodes, &uNumNodes, status, ++ 1); ++ if (pNDBProps) ++ MEM_Free(pNDBProps); ++ ++ return status; ++} ++ ++/* ++ * ======== MGRWRAP_EnumProc_Info ======== ++ */ ++u32 MGRWRAP_EnumProc_Info(union Trapped_Args *args) ++{ ++ u8 *pProcessorInfo; ++ u32 uNumProcs; ++ DSP_STATUS status = DSP_SOK; ++ u32 size = args->ARGS_MGR_ENUMPROC_INFO.uProcessorInfoSize; ++ ++ GT_4trace(WCD_debugMask, GT_ENTER, ++ "MGRWRAP_EnumProc_Info: entered args:\n" ++ "0x%x uProcessor: 0x%x\tpProcessorInfo: 0x%x\t" ++ "uProcessorInfoSize: 0x%x\tpuNumProcs \n", ++ args->ARGS_MGR_ENUMPROC_INFO.uProcessor, ++ args->ARGS_MGR_ENUMPROC_INFO.pProcessorInfo, ++ args->ARGS_MGR_ENUMPROC_INFO.uProcessorInfoSize, ++ args->ARGS_MGR_ENUMPROC_INFO.puNumProcs); ++ pProcessorInfo = MEM_Alloc(size, MEM_NONPAGED); ++ if (pProcessorInfo == NULL) ++ status = DSP_EMEMORY; ++ ++ if (DSP_SUCCEEDED(status)) { ++ status = MGR_EnumProcessorInfo(args-> ++ ARGS_MGR_ENUMPROC_INFO.uProcessor, ++ (struct DSP_PROCESSORINFO *)pProcessorInfo, ++ size, &uNumProcs); ++ } ++ cp_to_usr(args->ARGS_MGR_ENUMPROC_INFO.pProcessorInfo, pProcessorInfo, ++ status, size); ++ cp_to_usr(args->ARGS_MGR_ENUMPROC_INFO.puNumProcs, &uNumProcs, ++ status, 1); ++ if (pProcessorInfo) ++ MEM_Free(pProcessorInfo); ++ ++ return status; ++} ++ ++#define WRAP_MAP2CALLER(x) x ++/* ++ * ======== MGRWRAP_RegisterObject ======== ++ */ ++u32 MGRWRAP_RegisterObject(union Trapped_Args *args) ++{ ++ u32 retVal; ++ ++ GT_1trace(WCD_debugMask, GT_ENTER, ++ "MGRWRAP_RegisterObject: entered pg2hMsg " ++ "0x%x\n", args->ARGS_MGR_REGISTEROBJECT.pUuid); ++ retVal = DCD_RegisterObject(WRAP_MAP2CALLER ++ (args->ARGS_MGR_REGISTEROBJECT.pUuid), ++ args->ARGS_MGR_REGISTEROBJECT.objType, ++ WRAP_MAP2CALLER(args->ARGS_MGR_REGISTEROBJECT.pszPathName)); ++ return retVal; ++} ++ ++/* ++ * ======== MGRWRAP_UnregisterObject ======== ++ */ ++u32 MGRWRAP_UnregisterObject(union Trapped_Args *args) ++{ ++ u32 retVal; ++ ++ GT_1trace(WCD_debugMask, GT_ENTER, ++ "MGRWRAP_UnregisterObject: entered pg2hMsg" ++ " 0x%x\n", args->ARGS_MGR_UNREGISTEROBJECT.pUuid); ++ retVal = DCD_UnregisterObject(WRAP_MAP2CALLER ++ (args->ARGS_MGR_UNREGISTEROBJECT.pUuid), ++ args->ARGS_MGR_UNREGISTEROBJECT.objType); ++ ++ return retVal; ++} ++ ++/* ++ * ======== MGRWRAP_WaitForBridgeEvents ======== ++ */ ++u32 MGRWRAP_WaitForBridgeEvents(union Trapped_Args *args) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DSP_NOTIFICATION *aNotifications[MAX_EVENTS]; ++ struct DSP_NOTIFICATION notifications[MAX_EVENTS]; ++ u32 uIndex, i; ++ u32 uCount = args->ARGS_MGR_WAIT.uCount; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, ++ "MGRWRAP_WaitForBridgeEvents: entered\n"); ++ ++ if (uCount > MAX_EVENTS) ++ status = DSP_EINVALIDARG; ++ ++ /* get the array of pointers to user structures */ ++ cp_fm_usr(aNotifications, args->ARGS_MGR_WAIT.aNotifications, ++ status, uCount); ++ /* get the events */ ++ for (i = 0; i < uCount; i++) { ++ cp_fm_usr(¬ifications[i], aNotifications[i], status, 1); ++ if (DSP_SUCCEEDED(status)) { ++ /* set the array of pointers to kernel structures*/ ++ aNotifications[i] = ¬ifications[i]; ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ status = MGR_WaitForBridgeEvents(aNotifications, uCount, ++ &uIndex, args->ARGS_MGR_WAIT.uTimeout); ++ } ++ cp_to_usr(args->ARGS_MGR_WAIT.puIndex, &uIndex, status, 1); ++ return status; ++} ++ ++ ++#ifndef RES_CLEANUP_DISABLE ++/* ++ * ======== MGRWRAP_GetProcessResourceInfo ======== ++ */ ++u32 MGRWRAP_GetProcessResourcesInfo(union Trapped_Args *args) ++{ ++ DSP_STATUS status = DSP_SOK; ++ u32 uSize = 0; ++ u8 *pBuf = MEM_Alloc(8092, MEM_NONPAGED); ++ status = DRV_ProcDisplayResInfo(pBuf, &uSize); ++ GT_1trace(WCD_debugMask, GT_ENTER, ++ "MGRWRAP_GetProcessResourcesInfo:uSize=%d :\n", uSize); ++ cp_to_usr(args->ARGS_PROC_GETTRACE.pBuf, pBuf, status, uSize); ++ GT_0trace(WCD_debugMask, GT_ENTER, "\n***********" ++ "123MGRWRAP_GetProcessResourcesInfo:**************\n"); ++ GT_0trace(WCD_debugMask, GT_ENTER, "\n***********" ++ "456MGRWRAP_GetProcessResourcesInfo:**************\n"); ++ cp_to_usr(args->ARGS_PROC_GETTRACE.pSize, &uSize, status, 1); ++ MEM_Free(pBuf); ++ return status; ++} ++#endif ++ ++ ++/* ++ * ======== PROCWRAP_Attach ======== ++ */ ++u32 PROCWRAP_Attach(union Trapped_Args *args) ++{ ++ DSP_HPROCESSOR processor; ++ DSP_STATUS status = DSP_SOK; ++ struct DSP_PROCESSORATTRIN attrIn, *pAttrIn = NULL; ++ ++ GT_3trace(WCD_debugMask, GT_ENTER, ++ "PROCWRAP_Attach: entered args:\n" "0x%x" ++ " uProcessor: 0x%x\tpAttrIn: 0x%x\tphProcessor \n", ++ args->ARGS_PROC_ATTACH.uProcessor, ++ args->ARGS_PROC_ATTACH.pAttrIn, ++ args->ARGS_PROC_ATTACH.phProcessor); ++ /* Optional argument */ ++ if (args->ARGS_PROC_ATTACH.pAttrIn) { ++ cp_fm_usr(&attrIn, args->ARGS_PROC_ATTACH.pAttrIn, status, 1); ++ if (DSP_SUCCEEDED(status)) ++ pAttrIn = &attrIn; ++ ++ } ++ status = PROC_Attach(args->ARGS_PROC_ATTACH.uProcessor, pAttrIn, ++ &processor); ++ cp_to_usr(args->ARGS_PROC_ATTACH.phProcessor, &processor, status, 1); ++ return status; ++} ++ ++/* ++ * ======== PROCWRAP_Ctrl ======== ++ */ ++u32 PROCWRAP_Ctrl(union Trapped_Args *args) ++{ ++ u32 cbDataSize, __user *pSize = (u32 __user *) ++ args->ARGS_PROC_CTRL.pArgs; ++ u8 *pArgs = NULL; ++ DSP_STATUS status = DSP_SOK; ++ ++ GT_3trace(WCD_debugMask, GT_ENTER, ++ "PROCWRAP_Ctrl: entered args:\n 0x%x" ++ " uProcessor: 0x%x\tdwCmd: 0x%x\tpArgs \n", ++ args->ARGS_PROC_CTRL.hProcessor, ++ args->ARGS_PROC_CTRL.dwCmd, ++ args->ARGS_PROC_CTRL.pArgs); ++ if (pSize) { ++ if (get_user(cbDataSize, pSize)) ++ status = DSP_EFAIL; ++ ++ cbDataSize += sizeof(u32); ++ if (DSP_SUCCEEDED(status)) { ++ pArgs = MEM_Alloc(cbDataSize, MEM_NONPAGED); ++ if (pArgs == NULL) ++ status = DSP_EMEMORY; ++ ++ } ++ cp_fm_usr(pArgs, args->ARGS_PROC_CTRL.pArgs, status, ++ cbDataSize); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ status = PROC_Ctrl(args->ARGS_PROC_CTRL.hProcessor, ++ args->ARGS_PROC_CTRL.dwCmd, ++ (struct DSP_CBDATA *)pArgs); ++ } ++ ++ /* cp_to_usr(args->ARGS_PROC_CTRL.pArgs, pArgs, status, 1);*/ ++ if (pArgs) ++ MEM_Free(pArgs); ++ ++ return status; ++} ++ ++/* ++ * ======== PROCWRAP_Detach ======== ++ */ ++u32 PROCWRAP_Detach(union Trapped_Args *args) ++{ ++ u32 retVal; ++ ++ GT_1trace(WCD_debugMask, GT_ENTER, ++ "PROCWRAP_Detach: entered args\n0x%x " ++ "hProceesor \n", args->ARGS_PROC_DETACH.hProcessor); ++ retVal = PROC_Detach(args->ARGS_PROC_DETACH.hProcessor); ++ ++ return retVal; ++} ++ ++/* ++ * ======== PROCWRAP_EnumNode_Info ======== ++ */ ++u32 PROCWRAP_EnumNode_Info(union Trapped_Args *args) ++{ ++ DSP_STATUS status; ++ DSP_HNODE aNodeTab[MAX_NODES]; ++ u32 uNumNodes; ++ u32 uAllocated; ++ ++ GT_5trace(WCD_debugMask, GT_ENTER, ++ "PROCWRAP_EnumNode_Info:entered args:\n0x" ++ "%xhProcessor:0x%x\taNodeTab:0x%x\tuNodeTabSize:" ++ "%0x%x\tpuNumNodes%\n0x%x puAllocated: \n", ++ args->ARGS_PROC_ENUMNODE_INFO.hProcessor, ++ args->ARGS_PROC_ENUMNODE_INFO.aNodeTab, ++ args->ARGS_PROC_ENUMNODE_INFO.uNodeTabSize, ++ args->ARGS_PROC_ENUMNODE_INFO.puNumNodes, ++ args->ARGS_PROC_ENUMNODE_INFO.puAllocated); ++ DBC_Require(args->ARGS_PROC_ENUMNODE_INFO.uNodeTabSize <= MAX_NODES); ++ status = PROC_EnumNodes(args->ARGS_PROC_ENUMNODE_INFO.hProcessor, ++ aNodeTab, ++ args->ARGS_PROC_ENUMNODE_INFO.uNodeTabSize, ++ &uNumNodes, &uAllocated); ++ cp_to_usr(args->ARGS_PROC_ENUMNODE_INFO.aNodeTab, aNodeTab, status, ++ uNumNodes); ++ cp_to_usr(args->ARGS_PROC_ENUMNODE_INFO.puNumNodes, &uNumNodes, ++ status, 1); ++ cp_to_usr(args->ARGS_PROC_ENUMNODE_INFO.puAllocated, &uAllocated, ++ status, 1); ++ return status; ++} ++ ++/* ++ * ======== PROCWRAP_FlushMemory ======== ++ */ ++u32 PROCWRAP_FlushMemory(union Trapped_Args *args) ++{ ++ DSP_STATUS status; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_FlushMemory: entered\n"); ++ ++ status = PROC_FlushMemory(args->ARGS_PROC_FLUSHMEMORY.hProcessor, ++ args->ARGS_PROC_FLUSHMEMORY.pMpuAddr, ++ args->ARGS_PROC_FLUSHMEMORY.ulSize, ++ args->ARGS_PROC_FLUSHMEMORY.ulFlags); ++ return status; ++} ++ ++ ++/* ++ * ======== PROCWRAP_InvalidateMemory ======== ++ */ ++u32 PROCWRAP_InvalidateMemory(union Trapped_Args *args) ++{ ++ DSP_STATUS status; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, ++ "PROCWRAP_InvalidateMemory:entered\n"); ++ ++ status = PROC_InvalidateMemory( ++ args->ARGS_PROC_INVALIDATEMEMORY.hProcessor, ++ args->ARGS_PROC_INVALIDATEMEMORY.pMpuAddr, ++ args->ARGS_PROC_INVALIDATEMEMORY.ulSize); ++ return status; ++} ++ ++ ++/* ++ * ======== PROCWRAP_EnumResources ======== ++ */ ++u32 PROCWRAP_EnumResources(union Trapped_Args *args) ++{ ++ u32 retVal; ++ ++ GT_4trace(WCD_debugMask, GT_ENTER, ++ "PROCWRAP_EnumResources: entered args:\n" ++ "0x%x hProcessor: 0x%x\tuResourceMask: 0x%x\tpResourceInfo" ++ " 0x%x\tuResourceInfoSixe \n", ++ args->ARGS_PROC_ENUMRESOURCES.hProcessor, ++ args->ARGS_PROC_ENUMRESOURCES.uResourceType, ++ args->ARGS_PROC_ENUMRESOURCES.pResourceInfo, ++ args->ARGS_PROC_ENUMRESOURCES.uResourceInfoSize); ++ retVal = PROC_GetResourceInfo(args->ARGS_PROC_ENUMRESOURCES.hProcessor, ++ args->ARGS_PROC_ENUMRESOURCES.uResourceType, ++ WRAP_MAP2CALLER(args->ARGS_PROC_ENUMRESOURCES. ++ pResourceInfo), args->ARGS_PROC_ENUMRESOURCES. ++ uResourceInfoSize); ++ ++ return retVal; ++} ++ ++/* ++ * ======== PROCWRAP_GetState ======== ++ */ ++u32 PROCWRAP_GetState(union Trapped_Args *args) ++{ ++ DSP_STATUS status; ++ struct DSP_PROCESSORSTATE procStatus; ++ GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_GetState: entered\n"); ++ status = PROC_GetState(args->ARGS_PROC_GETSTATE.hProcessor, &procStatus, ++ args->ARGS_PROC_GETSTATE.uStateInfoSize); ++ cp_to_usr(args->ARGS_PROC_GETSTATE.pProcStatus, &procStatus, status, 1); ++ return status; ++ ++} ++ ++/* ++ * ======== PROCWRAP_GetTrace ======== ++ */ ++u32 PROCWRAP_GetTrace(union Trapped_Args *args) ++{ ++ DSP_STATUS status; ++ u8 *pBuf; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_GetTrace: entered\n"); ++ ++ DBC_Require(args->ARGS_PROC_GETTRACE.uMaxSize <= MAX_TRACEBUFLEN); ++ ++ pBuf = MEM_Calloc(args->ARGS_PROC_GETTRACE.uMaxSize, MEM_NONPAGED); ++ if (pBuf != NULL) { ++ status = PROC_GetTrace(args->ARGS_PROC_GETTRACE.hProcessor, ++ pBuf, args->ARGS_PROC_GETTRACE.uMaxSize); ++ } else { ++ status = DSP_EMEMORY; ++ } ++ cp_to_usr(args->ARGS_PROC_GETTRACE.pBuf, pBuf, status, ++ args->ARGS_PROC_GETTRACE.uMaxSize); ++ if (pBuf) ++ MEM_Free(pBuf); ++ ++ return status; ++} ++ ++/* ++ * ======== PROCWRAP_Load ======== ++ */ ++u32 PROCWRAP_Load(union Trapped_Args *args) ++{ ++ s32 i, len; ++ DSP_STATUS status = DSP_SOK; ++ char *temp; ++ s32 argc = args->ARGS_PROC_LOAD.iArgc; ++ u8 **argv, **envp = NULL; ++ ++ ++ DBC_Require(argc > 0); ++ DBC_Require(argc <= MAX_LOADARGS); ++ ++ argv = MEM_Alloc(argc * sizeof(u8 *), MEM_NONPAGED); ++ if (argv == NULL) ++ status = DSP_EMEMORY; ++ ++ cp_fm_usr(argv, args->ARGS_PROC_LOAD.aArgv, status, argc); ++ for (i = 0; DSP_SUCCEEDED(status) && (i < argc); i++) { ++ if (argv[i] != NULL) { ++ /* User space pointer to argument */ ++ temp = (char *) argv[i]; ++ len = strlen_user((char *)temp); ++ /* Kernel space pointer to argument */ ++ argv[i] = MEM_Alloc(len, MEM_NONPAGED); ++ if (argv[i] == NULL) { ++ status = DSP_EMEMORY; ++ break; ++ } ++ cp_fm_usr(argv[i], temp, status, len); ++ } ++ } ++ /* TODO: validate this */ ++ if (args->ARGS_PROC_LOAD.aEnvp != NULL) { ++ /* number of elements in the envp array including NULL */ ++ len = 0; ++ do { ++ len++; ++ get_user(temp, args->ARGS_PROC_LOAD.aEnvp); ++ } while (temp); ++ envp = MEM_Alloc(len * sizeof(u8 *), MEM_NONPAGED); ++ if (envp == NULL) ++ status = DSP_EMEMORY; ++ ++ cp_fm_usr(envp, args->ARGS_PROC_LOAD.aEnvp, status, len); ++ for (i = 0; DSP_SUCCEEDED(status) && (envp[i] != NULL); i++) { ++ /* User space pointer to argument */ ++ temp = (char *)envp[i]; ++ len = strlen_user((char *)temp); ++ /* Kernel space pointer to argument */ ++ envp[i] = MEM_Alloc(len, MEM_NONPAGED); ++ if (envp[i] == NULL) { ++ status = DSP_EMEMORY; ++ break; ++ } ++ cp_fm_usr(envp[i], temp, status, len); ++ } ++ } ++ GT_5trace(WCD_debugMask, GT_ENTER, ++ "PROCWRAP_Load, hProcessor: 0x%x\n\tiArgc:" ++ "0x%x\n\taArgv: 0x%x\n\taArgv[0]: %s\n\taEnvp: 0x%0x\n", ++ args->ARGS_PROC_LOAD.hProcessor, ++ args->ARGS_PROC_LOAD.iArgc, args->ARGS_PROC_LOAD.aArgv, ++ argv[0], args->ARGS_PROC_LOAD.aEnvp); ++ if (DSP_SUCCEEDED(status)) { ++ status = PROC_Load(args->ARGS_PROC_LOAD.hProcessor, ++ args->ARGS_PROC_LOAD.iArgc, ++ (CONST char **)argv, (CONST char **)envp); ++ } ++ if (envp != NULL) { ++ i = 0; ++ while (envp[i] != NULL) ++ MEM_Free(envp[i++]); ++ ++ MEM_Free(envp); ++ } ++ if (argv != NULL) { ++ for (i = 0; i < argc; i++) { ++ if (argv[i] != NULL) ++ MEM_Free(argv[i]); ++ ++ } ++ MEM_Free(argv); ++ } ++ return status; ++} ++ ++/* ++ * ======== PROCWRAP_Map ======== ++ */ ++u32 PROCWRAP_Map(union Trapped_Args *args) ++{ ++ DSP_STATUS status; ++ void *pMapAddr; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_Map: entered\n"); ++ status = PROC_Map(args->ARGS_PROC_MAPMEM.hProcessor, ++ args->ARGS_PROC_MAPMEM.pMpuAddr, ++ args->ARGS_PROC_MAPMEM.ulSize, ++ args->ARGS_PROC_MAPMEM.pReqAddr, &pMapAddr, ++ args->ARGS_PROC_MAPMEM.ulMapAttr); ++ if (DSP_SUCCEEDED(status)) { ++ if (put_user(pMapAddr, args->ARGS_PROC_MAPMEM.ppMapAddr)) ++ status = DSP_EINVALIDARG; ++ ++ } ++ return status; ++} ++ ++/* ++ * ======== PROCWRAP_RegisterNotify ======== ++ */ ++u32 PROCWRAP_RegisterNotify(union Trapped_Args *args) ++{ ++ DSP_STATUS status; ++ struct DSP_NOTIFICATION notification; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, ++ "PROCWRAP_RegisterNotify: entered\n"); ++ ++ /* Initialize the notification data structure */ ++ notification.psName = NULL; ++ notification.handle = NULL; ++ ++ status = PROC_RegisterNotify(args->ARGS_PROC_REGISTER_NOTIFY.hProcessor, ++ args->ARGS_PROC_REGISTER_NOTIFY.uEventMask, ++ args->ARGS_PROC_REGISTER_NOTIFY.uNotifyType, ++ ¬ification); ++ cp_to_usr(args->ARGS_PROC_REGISTER_NOTIFY.hNotification, ¬ification, ++ status, 1); ++ return status; ++} ++ ++/* ++ * ======== PROCWRAP_ReserveMemory ======== ++ */ ++u32 PROCWRAP_ReserveMemory(union Trapped_Args *args) ++{ ++ DSP_STATUS status; ++ void *pRsvAddr; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_ReserveMemory: entered\n"); ++ status = PROC_ReserveMemory(args->ARGS_PROC_RSVMEM.hProcessor, ++ args->ARGS_PROC_RSVMEM.ulSize, &pRsvAddr); ++ if (put_user(pRsvAddr, args->ARGS_PROC_RSVMEM.ppRsvAddr)) ++ status = DSP_EINVALIDARG; ++ ++ return status; ++} ++ ++/* ++ * ======== PROCWRAP_Start ======== ++ */ ++u32 PROCWRAP_Start(union Trapped_Args *args) ++{ ++ u32 retVal; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_Start: entered\n"); ++ retVal = PROC_Start(args->ARGS_PROC_START.hProcessor); ++ return retVal; ++} ++ ++/* ++ * ======== PROCWRAP_UnMap ======== ++ */ ++u32 PROCWRAP_UnMap(union Trapped_Args *args) ++{ ++ DSP_STATUS status; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_UnMap: entered\n"); ++ status = PROC_UnMap(args->ARGS_PROC_UNMAPMEM.hProcessor, ++ args->ARGS_PROC_UNMAPMEM.pMapAddr); ++ return status; ++} ++ ++/* ++ * ======== PROCWRAP_UnReserveMemory ======== ++ */ ++u32 PROCWRAP_UnReserveMemory(union Trapped_Args *args) ++{ ++ DSP_STATUS status; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, ++ "PROCWRAP_UnReserveMemory: entered\n"); ++ status = PROC_UnReserveMemory(args->ARGS_PROC_UNRSVMEM.hProcessor, ++ args->ARGS_PROC_UNRSVMEM.pRsvAddr); ++ return status; ++} ++ ++/* ++ * ======== PROCWRAP_Stop ======== ++ */ ++u32 PROCWRAP_Stop(union Trapped_Args *args) ++{ ++ u32 retVal; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_Stop: entered\n"); ++ retVal = PROC_Stop(args->ARGS_PROC_STOP.hProcessor); ++ ++ return retVal; ++} ++ ++/* ++ * ======== NODEWRAP_Allocate ======== ++ */ ++u32 NODEWRAP_Allocate(union Trapped_Args *args) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DSP_UUID nodeId; ++ u32 cbDataSize; ++ u32 __user *pSize = (u32 __user *)args->ARGS_NODE_ALLOCATE.pArgs; ++ u8 *pArgs = NULL; ++ struct DSP_NODEATTRIN attrIn, *pAttrIn = NULL; ++ struct NODE_OBJECT *hNode; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Allocate: entered\n"); ++ ++ /* Optional argument */ ++ if (pSize) { ++ if (get_user(cbDataSize, pSize)) ++ status = DSP_EFAIL; ++ ++ cbDataSize += sizeof(u32); ++ if (DSP_SUCCEEDED(status)) { ++ pArgs = MEM_Alloc(cbDataSize, MEM_NONPAGED); ++ if (pArgs == NULL) ++ status = DSP_EMEMORY; ++ ++ } ++ cp_fm_usr(pArgs, args->ARGS_NODE_ALLOCATE.pArgs, status, ++ cbDataSize); ++ } ++ cp_fm_usr(&nodeId, args->ARGS_NODE_ALLOCATE.pNodeID, status, 1); ++ /* Optional argument */ ++ if (args->ARGS_NODE_ALLOCATE.pAttrIn) { ++ cp_fm_usr(&attrIn, args->ARGS_NODE_ALLOCATE.pAttrIn, status, 1); ++ if (DSP_SUCCEEDED(status)) ++ pAttrIn = &attrIn; ++ ++ } ++ if (DSP_SUCCEEDED(status)) { ++ status = NODE_Allocate(args->ARGS_NODE_ALLOCATE.hProcessor, ++ &nodeId, (struct DSP_CBDATA *)pArgs, ++ pAttrIn, &hNode); ++ } ++ cp_to_usr(args->ARGS_NODE_ALLOCATE.phNode, &hNode, status, 1); ++ if (pArgs) ++ MEM_Free(pArgs); ++ ++ return status; ++} ++ ++/* ++ * ======== NODEWRAP_AllocMsgBuf ======== ++ */ ++u32 NODEWRAP_AllocMsgBuf(union Trapped_Args *args) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DSP_BUFFERATTR *pAttr = NULL; ++ struct DSP_BUFFERATTR attr; ++ u8 *pBuffer = NULL; ++ ++ if (args->ARGS_NODE_ALLOCMSGBUF.pAttr) { /* Optional argument */ ++ cp_fm_usr(&attr, args->ARGS_NODE_ALLOCMSGBUF.pAttr, status, 1); ++ if (DSP_SUCCEEDED(status)) ++ pAttr = &attr; ++ ++ } ++ /* IN OUT argument */ ++ cp_fm_usr(&pBuffer, args->ARGS_NODE_ALLOCMSGBUF.pBuffer, status, 1); ++ if (DSP_SUCCEEDED(status)) { ++ status = NODE_AllocMsgBuf(args->ARGS_NODE_ALLOCMSGBUF.hNode, ++ args->ARGS_NODE_ALLOCMSGBUF.uSize, ++ pAttr, &pBuffer); ++ } ++ cp_to_usr(args->ARGS_NODE_ALLOCMSGBUF.pBuffer, &pBuffer, status, 1) ++ return status; ++} ++ ++/* ++ * ======== NODEWRAP_ChangePriority ======== ++ */ ++u32 NODEWRAP_ChangePriority(union Trapped_Args *args) ++{ ++ u32 retVal; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, ++ "NODEWRAP_ChangePriority: entered\n"); ++ retVal = NODE_ChangePriority(args->ARGS_NODE_CHANGEPRIORITY.hNode, ++ args->ARGS_NODE_CHANGEPRIORITY.iPriority); ++ ++ return retVal; ++} ++ ++/* ++ * ======== NODEWRAP_Connect ======== ++ */ ++u32 NODEWRAP_Connect(union Trapped_Args *args) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DSP_STRMATTR attrs; ++ struct DSP_STRMATTR *pAttrs = NULL; ++ u32 cbDataSize; ++ u32 __user *pSize = (u32 __user *)args->ARGS_NODE_CONNECT.pConnParam; ++ u8 *pArgs = NULL; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Connect: entered\n"); ++ ++ /* Optional argument */ ++ if (pSize) { ++ if (get_user(cbDataSize, pSize)) ++ status = DSP_EFAIL; ++ ++ cbDataSize += sizeof(u32); ++ if (DSP_SUCCEEDED(status)) { ++ pArgs = MEM_Alloc(cbDataSize, MEM_NONPAGED); ++ if (pArgs == NULL) ++ status = DSP_EMEMORY; ++ ++ } ++ cp_fm_usr(pArgs, args->ARGS_NODE_CONNECT.pConnParam, status, ++ cbDataSize); ++ } ++ if (args->ARGS_NODE_CONNECT.pAttrs) { /* Optional argument */ ++ cp_fm_usr(&attrs, args->ARGS_NODE_CONNECT.pAttrs, status, 1); ++ if (DSP_SUCCEEDED(status)) ++ pAttrs = &attrs; ++ ++ } ++ if (DSP_SUCCEEDED(status)) { ++ status = NODE_Connect(args->ARGS_NODE_CONNECT.hNode, ++ args->ARGS_NODE_CONNECT.uStream, ++ args->ARGS_NODE_CONNECT.hOtherNode, ++ args->ARGS_NODE_CONNECT.uOtherStream, ++ pAttrs, (struct DSP_CBDATA *)pArgs); ++ } ++ if (pArgs) ++ MEM_Free(pArgs); ++ ++ return status; ++} ++ ++/* ++ * ======== NODEWRAP_Create ======== ++ */ ++u32 NODEWRAP_Create(union Trapped_Args *args) ++{ ++ u32 retVal; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Create: entered\n"); ++ retVal = NODE_Create(args->ARGS_NODE_CREATE.hNode); ++ ++ return retVal; ++} ++ ++/* ++ * ======== NODEWRAP_Delete ======== ++ */ ++u32 NODEWRAP_Delete(union Trapped_Args *args) ++{ ++ u32 retVal; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Delete: entered\n"); ++ retVal = NODE_Delete(args->ARGS_NODE_DELETE.hNode); ++ ++ return retVal; ++} ++ ++/* ++ * ======== NODEWRAP_FreeMsgBuf ======== ++ */ ++u32 NODEWRAP_FreeMsgBuf(union Trapped_Args *args) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DSP_BUFFERATTR *pAttr = NULL; ++ struct DSP_BUFFERATTR attr; ++ if (args->ARGS_NODE_FREEMSGBUF.pAttr) { /* Optional argument */ ++ cp_fm_usr(&attr, args->ARGS_NODE_FREEMSGBUF.pAttr, status, 1); ++ if (DSP_SUCCEEDED(status)) ++ pAttr = &attr; ++ ++ } ++ if (DSP_SUCCEEDED(status)) { ++ status = NODE_FreeMsgBuf(args->ARGS_NODE_FREEMSGBUF.hNode, ++ args->ARGS_NODE_FREEMSGBUF.pBuffer, ++ pAttr); ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== NODEWRAP_GetAttr ======== ++ */ ++u32 NODEWRAP_GetAttr(union Trapped_Args *args) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DSP_NODEATTR attr; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_GetAttr: entered\n"); ++ ++ status = NODE_GetAttr(args->ARGS_NODE_GETATTR.hNode, &attr, ++ args->ARGS_NODE_GETATTR.uAttrSize); ++ cp_to_usr(args->ARGS_NODE_GETATTR.pAttr, &attr, status, 1); ++ ++ return status; ++} ++ ++/* ++ * ======== NODEWRAP_GetMessage ======== ++ */ ++u32 NODEWRAP_GetMessage(union Trapped_Args *args) ++{ ++ DSP_STATUS status; ++ struct DSP_MSG msg; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_GetMessage: entered\n"); ++ ++ status = NODE_GetMessage(args->ARGS_NODE_GETMESSAGE.hNode, &msg, ++ args->ARGS_NODE_GETMESSAGE.uTimeout); ++ ++ cp_to_usr(args->ARGS_NODE_GETMESSAGE.pMessage, &msg, status, 1); ++ ++ return status; ++} ++ ++/* ++ * ======== NODEWRAP_Pause ======== ++ */ ++u32 NODEWRAP_Pause(union Trapped_Args *args) ++{ ++ u32 retVal; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Pause: entered\n"); ++ retVal = NODE_Pause(args->ARGS_NODE_PAUSE.hNode); ++ ++ return retVal; ++} ++ ++/* ++ * ======== NODEWRAP_PutMessage ======== ++ */ ++u32 NODEWRAP_PutMessage(union Trapped_Args *args) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DSP_MSG msg; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_PutMessage: entered\n"); ++ ++ cp_fm_usr(&msg, args->ARGS_NODE_PUTMESSAGE.pMessage, status, 1); ++ ++ if (DSP_SUCCEEDED(status)) { ++ status = NODE_PutMessage(args->ARGS_NODE_PUTMESSAGE.hNode, &msg, ++ args->ARGS_NODE_PUTMESSAGE.uTimeout); ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== NODEWRAP_RegisterNotify ======== ++ */ ++u32 NODEWRAP_RegisterNotify(union Trapped_Args *args) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DSP_NOTIFICATION notification; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, ++ "NODEWRAP_RegisterNotify: entered\n"); ++ ++ /* Initialize the notification data structure */ ++ notification.psName = NULL; ++ notification.handle = NULL; ++ ++ status = NODE_RegisterNotify(args->ARGS_NODE_REGISTERNOTIFY.hNode, ++ args->ARGS_NODE_REGISTERNOTIFY.uEventMask, ++ args->ARGS_NODE_REGISTERNOTIFY.uNotifyType, ++ ¬ification); ++ cp_to_usr(args->ARGS_NODE_REGISTERNOTIFY.hNotification, ¬ification, ++ status, 1); ++ return status; ++} ++ ++/* ++ * ======== NODEWRAP_Run ======== ++ */ ++u32 NODEWRAP_Run(union Trapped_Args *args) ++{ ++ u32 retVal; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Run: entered\n"); ++ retVal = NODE_Run(args->ARGS_NODE_RUN.hNode); ++ ++ return retVal; ++} ++ ++/* ++ * ======== NODEWRAP_Terminate ======== ++ */ ++u32 NODEWRAP_Terminate(union Trapped_Args *args) ++{ ++ DSP_STATUS status; ++ DSP_STATUS tempstatus; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Terminate: entered\n"); ++ ++ status = NODE_Terminate(args->ARGS_NODE_TERMINATE.hNode, &tempstatus); ++ ++ cp_to_usr(args->ARGS_NODE_TERMINATE.pStatus, &tempstatus, status, 1); ++ ++ return status; ++} ++ ++ ++/* ++ * ======== NODEWRAP_GetUUIDProps ======== ++ */ ++u32 NODEWRAP_GetUUIDProps(union Trapped_Args *args) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DSP_UUID nodeId; ++ struct DSP_NDBPROPS *pnodeProps = NULL; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, ++ "NODEWRAP_GetUUIDPropste: entered\n"); ++ ++ ++ cp_fm_usr(&nodeId, args->ARGS_NODE_GETUUIDPROPS.pNodeID, status, 1); ++ pnodeProps = MEM_Alloc(sizeof(struct DSP_NDBPROPS), MEM_NONPAGED); ++ if (pnodeProps != NULL) { ++ status = NODE_GetUUIDProps(args-> ++ ARGS_NODE_GETUUIDPROPS.hProcessor, ++ &nodeId, pnodeProps); ++ cp_to_usr(args->ARGS_NODE_GETUUIDPROPS.pNodeProps, pnodeProps, ++ status, 1); ++ } else ++ status = DSP_EMEMORY; ++ if (pnodeProps) ++ MEM_Free(pnodeProps); ++ return status; ++} ++ ++/* ++ * ======== STRMWRAP_AllocateBuffer ======== ++ */ ++u32 STRMWRAP_AllocateBuffer(union Trapped_Args *args) ++{ ++ DSP_STATUS status; ++ u8 **apBuffer = NULL; ++ u32 uNumBufs = args->ARGS_STRM_ALLOCATEBUFFER.uNumBufs; ++ ++ DBC_Require(uNumBufs <= MAX_BUFS); ++ ++ apBuffer = MEM_Alloc((uNumBufs * sizeof(u8 *)), MEM_NONPAGED); ++ ++ status = STRM_AllocateBuffer(args->ARGS_STRM_ALLOCATEBUFFER.hStream, ++ args->ARGS_STRM_ALLOCATEBUFFER.uSize, ++ apBuffer, uNumBufs); ++ cp_to_usr(args->ARGS_STRM_ALLOCATEBUFFER.apBuffer, apBuffer, status, ++ uNumBufs); ++ if (apBuffer) ++ MEM_Free(apBuffer); ++ ++ return status; ++} ++ ++/* ++ * ======== STRMWRAP_Close ======== ++ */ ++u32 STRMWRAP_Close(union Trapped_Args *args) ++{ ++ u32 retVal; ++ ++ retVal = STRM_Close(args->ARGS_STRM_CLOSE.hStream); ++ ++ return retVal; ++} ++ ++/* ++ * ======== STRMWRAP_FreeBuffer ======== ++ */ ++u32 STRMWRAP_FreeBuffer(union Trapped_Args *args) ++{ ++ DSP_STATUS status = DSP_SOK; ++ u8 **apBuffer = NULL; ++ u32 uNumBufs = args->ARGS_STRM_FREEBUFFER.uNumBufs; ++ ++ DBC_Require(uNumBufs <= MAX_BUFS); ++ ++ apBuffer = MEM_Alloc((uNumBufs * sizeof(u8 *)), MEM_NONPAGED); ++ ++ cp_fm_usr(apBuffer, args->ARGS_STRM_FREEBUFFER.apBuffer, status, ++ uNumBufs); ++ ++ if (DSP_SUCCEEDED(status)) { ++ status = STRM_FreeBuffer(args->ARGS_STRM_FREEBUFFER.hStream, ++ apBuffer, uNumBufs); ++ } ++ cp_to_usr(args->ARGS_STRM_FREEBUFFER.apBuffer, apBuffer, status, ++ uNumBufs); ++ if (apBuffer) ++ MEM_Free(apBuffer); ++ ++ return status; ++} ++ ++/* ++ * ======== STRMWRAP_GetEventHandle ======== ++ */ ++u32 STRMWRAP_GetEventHandle(union Trapped_Args *args) ++{ ++ return DSP_ENOTIMPL; ++} ++ ++/* ++ * ======== STRMWRAP_GetInfo ======== ++ */ ++u32 STRMWRAP_GetInfo(union Trapped_Args *args) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct STRM_INFO strmInfo; ++ struct DSP_STREAMINFO user; ++ struct DSP_STREAMINFO *temp; ++ ++ cp_fm_usr(&strmInfo, args->ARGS_STRM_GETINFO.pStreamInfo, status, 1); ++ temp = strmInfo.pUser; ++ ++ strmInfo.pUser = &user; ++ ++ if (DSP_SUCCEEDED(status)) { ++ status = STRM_GetInfo(args->ARGS_STRM_GETINFO.hStream, ++ &strmInfo, args->ARGS_STRM_GETINFO.uStreamInfoSize); ++ } ++ cp_to_usr(temp, strmInfo.pUser, status, 1); ++ strmInfo.pUser = temp; ++ cp_to_usr(args->ARGS_STRM_GETINFO.pStreamInfo, &strmInfo, status, 1); ++ return status; ++} ++ ++/* ++ * ======== STRMWRAP_Idle ======== ++ */ ++u32 STRMWRAP_Idle(union Trapped_Args *args) ++{ ++ u32 retVal; ++ ++ retVal = STRM_Idle(args->ARGS_STRM_IDLE.hStream, ++ args->ARGS_STRM_IDLE.bFlush); ++ ++ return retVal; ++} ++ ++/* ++ * ======== STRMWRAP_Issue ======== ++ */ ++u32 STRMWRAP_Issue(union Trapped_Args *args) ++{ ++ u32 retVal; ++ ++ retVal = STRM_Issue(args->ARGS_STRM_ISSUE.hStream, ++ args->ARGS_STRM_ISSUE.pBuffer, ++ args->ARGS_STRM_ISSUE.dwBytes, ++ args->ARGS_STRM_ISSUE.dwBufSize, ++ args->ARGS_STRM_ISSUE.dwArg); ++ ++ /* This is a user space pointer */ ++ return retVal; ++} ++ ++/* ++ * ======== STRMWRAP_Open ======== ++ */ ++u32 STRMWRAP_Open(union Trapped_Args *args) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct STRM_ATTR attr; ++ struct STRM_OBJECT *pStrm; ++ struct DSP_STREAMATTRIN strmAttrIn; ++ ++ cp_fm_usr(&attr, args->ARGS_STRM_OPEN.pAttrIn, status, 1); ++ ++ if (attr.pStreamAttrIn != NULL) { /* Optional argument */ ++ cp_fm_usr(&strmAttrIn, attr.pStreamAttrIn, status, 1); ++ if (DSP_SUCCEEDED(status)) ++ attr.pStreamAttrIn = &strmAttrIn; ++ ++ } ++ status = STRM_Open(args->ARGS_STRM_OPEN.hNode, ++ args->ARGS_STRM_OPEN.uDirection, ++ args->ARGS_STRM_OPEN.uIndex, &attr, &pStrm); ++ cp_to_usr(args->ARGS_STRM_OPEN.phStream, &pStrm, status, 1); ++ return status; ++} ++ ++/* ++ * ======== STRMWRAP_Reclaim ======== ++ */ ++u32 STRMWRAP_Reclaim(union Trapped_Args *args) ++{ ++ DSP_STATUS status = DSP_SOK; ++ u8 *pBufPtr; ++ u32 ulBytes; ++ u32 dwArg; ++ u32 ulBufSize; ++ ++ status = STRM_Reclaim(args->ARGS_STRM_RECLAIM.hStream, &pBufPtr, ++ &ulBytes, &ulBufSize, &dwArg); ++ cp_to_usr(args->ARGS_STRM_RECLAIM.pBufPtr, &pBufPtr, status, 1); ++ cp_to_usr(args->ARGS_STRM_RECLAIM.pBytes, &ulBytes, status, 1); ++ cp_to_usr(args->ARGS_STRM_RECLAIM.pdwArg, &dwArg, status, 1); ++ ++ if (args->ARGS_STRM_RECLAIM.pBufSize != NULL) { ++ cp_to_usr(args->ARGS_STRM_RECLAIM.pBufSize, &ulBufSize, ++ status, 1); ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== STRMWRAP_RegisterNotify ======== ++ */ ++u32 STRMWRAP_RegisterNotify(union Trapped_Args *args) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DSP_NOTIFICATION notification; ++ ++ GT_0trace(WCD_debugMask, GT_ENTER, ++ "NODEWRAP_RegisterNotify: entered\n"); ++ ++ /* Initialize the notification data structure */ ++ notification.psName = NULL; ++ notification.handle = NULL; ++ ++ status = STRM_RegisterNotify(args->ARGS_STRM_REGISTERNOTIFY.hStream, ++ args->ARGS_STRM_REGISTERNOTIFY.uEventMask, ++ args->ARGS_STRM_REGISTERNOTIFY.uNotifyType, ++ ¬ification); ++ cp_to_usr(args->ARGS_STRM_REGISTERNOTIFY.hNotification, ¬ification, ++ status, 1); ++ ++ return status; ++} ++ ++/* ++ * ======== STRMWRAP_Select ======== ++ */ ++u32 STRMWRAP_Select(union Trapped_Args *args) ++{ ++ u32 mask; ++ struct STRM_OBJECT *aStrmTab[MAX_STREAMS]; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(args->ARGS_STRM_SELECT.nStreams <= MAX_STREAMS); ++ ++ cp_fm_usr(aStrmTab, args->ARGS_STRM_SELECT.aStreamTab, status, ++ args->ARGS_STRM_SELECT.nStreams); ++ if (DSP_SUCCEEDED(status)) { ++ status = STRM_Select(aStrmTab, args->ARGS_STRM_SELECT.nStreams, ++ &mask, args->ARGS_STRM_SELECT.uTimeout); ++ } ++ cp_to_usr(args->ARGS_STRM_SELECT.pMask, &mask, status, 1); ++ return status; ++} ++ ++/* CMM */ ++ ++/* ++ * ======== CMMWRAP_CallocBuf ======== ++ */ ++u32 CMMWRAP_CallocBuf(union Trapped_Args *args) ++{ ++ /* This operation is done in kernel */ ++ return DSP_ENOTIMPL; ++} ++ ++/* ++ * ======== CMMWRAP_FreeBuf ======== ++ */ ++u32 CMMWRAP_FreeBuf(union Trapped_Args *args) ++{ ++ /* This operation is done in kernel */ ++ return DSP_ENOTIMPL; ++} ++ ++/* ++ * ======== CMMWRAP_GetHandle ======== ++ */ ++u32 CMMWRAP_GetHandle(union Trapped_Args *args) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct CMM_OBJECT *hCmmMgr; ++ ++ status = CMM_GetHandle(args->ARGS_CMM_GETHANDLE.hProcessor, &hCmmMgr); ++ ++ cp_to_usr(args->ARGS_CMM_GETHANDLE.phCmmMgr, &hCmmMgr, status, 1); ++ ++ return status; ++} ++ ++/* ++ * ======== CMMWRAP_GetInfo ======== ++ */ ++u32 CMMWRAP_GetInfo(union Trapped_Args *args) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct CMM_INFO cmmInfo; ++ ++ status = CMM_GetInfo(args->ARGS_CMM_GETINFO.hCmmMgr, &cmmInfo); ++ ++ cp_to_usr(args->ARGS_CMM_GETINFO.pCmmInfo, &cmmInfo, status, 1); ++ ++ return status; ++} +diff --git a/drivers/dsp/bridge/rmgr/dbdcd.c b/drivers/dsp/bridge/rmgr/dbdcd.c +new file mode 100644 +index 0000000..c5ec8f9 +--- /dev/null ++++ b/drivers/dsp/bridge/rmgr/dbdcd.c +@@ -0,0 +1,1573 @@ ++/* ++ * dbdcd.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== dbdcd.c ======== ++ * Description: ++ * This file contains the implementation of the DSP/BIOS Bridge ++ * Configuration Database (DCD). ++ * ++ * Notes: ++ * The fxn DCD_GetObjects can apply a callback fxn to each DCD object ++ * that is located in a specified COFF file. At the moment, ++ * DCD_AutoRegister, DCD_AutoUnregister, and NLDR module all use ++ * DCD_GetObjects. ++ * ++ *! Revision History ++ *! ================ ++ *! 03-Dec-2003 map Changed DCD_OBJTYPE to DSP_DCDOBJTYPE ++ *! 17-Dec-2002 map Modified DCD_GetDepLibs, DCD_GetNumDepLibs, GetDepLibInfo ++ *! to include phase information ++ *! 02-Dec-2002 map Modified DCD_GetLibraryName for phases in different ++ *! libraries ++ *! 26-Feb-2003 kc Updated DCD_AutoUnregister and DCD_GetObjects to simplify ++ *! DCD implementation. ++ *! 17-Jul-2002 jeh Call COD_Open() instead of COD_OpenBase(), call COD_Close() ++ *! 11-Jul-2002 jeh Added DCD_GetDepLibs(), DCD_GetNumDepLibs(). ++ *! 18-Feb-2003 vp Code review updates ++ *! 18-Oct-2002 vp Ported to Linux platform ++ *! 15-Mar-2002 jeh Read dynamic loading memory requirements into node object ++ *! data. Added DCD_GetLibraryName(). ++ *! 13-Feb-2002 jeh Get system stack size in GetAttrsFromBuf(). ++ *! 01-Aug-2001 ag: Added check for PROC "extended" attributes used for ++ *! DSP-MMU setup. These are private attributes. ++ *! 18-Apr-2001 jeh Use COD_OpenBase instead of COD_LoadBase. ++ *! 03-Apr-2001 sg: Changed error names to DSP_EDCD* format. ++ *! 11-Jan-2001 jeh Changes to DCD_GetObjectDef to match node.cdb, proc.cdb. ++ *! 12-Dec-2000 kc: Added DCD_AutoUnregister. MSGNODE, DAISNODE added in ++ *! GetAttrsFromBuf ++ *! 22-Nov-2000 kc: Replaced sprintf() calls with strncat. ++ *! 09-Nov-2000 kc: Optimized DCD module. ++ *! 30-Oct-2000 kc: Added DCD_AutoRegister function; changed local var. names. ++ *! 29-Sep-2000 kc: Added code review changes (src/reviews/dcd_reviews.txt). ++ *! 06-Sep-2000 jeh Get message segid, message notification type. Added Atoi() ++ *! to replace atoi(), until cdb generation can output in ++ *! decimal format. ++ *! 26-Jul-2000 kc: Created. ++ *! ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++ ++/* ----------------------------------- Others */ ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++/* ----------------------------------- Global defines. */ ++#define SIGNATURE 0x5f444344 /* "DCD_" (in reverse). */ ++ ++#define IsValidHandle(h) (((h) != NULL) && (h->dwSignature == SIGNATURE)) ++ ++#define MAX_INT2CHAR_LENGTH 16 /* Maximum int2char len of 32 bit int. */ ++ ++/* Name of section containing dependent libraries */ ++#define DEPLIBSECT ".dspbridge_deplibs" ++ ++/* DCD specific structures. */ ++struct DCD_MANAGER { ++ u32 dwSignature; /* Used for object validation. */ ++ struct COD_MANAGER *hCodMgr; /* Handle to COD manager object. */ ++}; ++ ++/* Global reference variables. */ ++static u32 cRefs; ++static u32 cEnumRefs; ++ ++extern struct GT_Mask curTrace; ++ ++/* helper function prototypes. */ ++static s32 Atoi(char *pszBuf); ++ ++static DSP_STATUS GetAttrsFromBuf(char *pszBuf, u32 ulBufSize, ++ enum DSP_DCDOBJTYPE objType, ++ struct DCD_GENERICOBJ *pGenObj); ++ ++static void CompressBuf(char *pszBuf, u32 ulBufSize, s32 cCharSize); ++ ++static char DspChar2GppChar(char *pWord, s32 cDspCharSize); ++ ++static DSP_STATUS GetDepLibInfo(IN struct DCD_MANAGER *hDcdMgr, ++ IN struct DSP_UUID *pUuid, ++ IN OUT u16 *pNumLibs, ++ OPTIONAL OUT u16 *pNumPersLibs, ++ OPTIONAL OUT struct DSP_UUID *pDepLibUuids, ++ OPTIONAL OUT bool *pPersistentDepLibs, ++ IN enum NLDR_PHASE phase); ++ ++/* ++ * ======== DCD_AutoRegister ======== ++ * Purpose: ++ * Parses the supplied image and resigsters with DCD. ++ */ ++ ++DSP_STATUS DCD_AutoRegister(IN struct DCD_MANAGER *hDcdMgr, ++ IN char *pszCoffPath) ++{ ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ ++ GT_1trace(curTrace, GT_ENTER, "DCD_AutoRegister: hDcdMgr 0x%x\n", ++ hDcdMgr); ++ ++ if (IsValidHandle(hDcdMgr)) { ++ status = DCD_GetObjects(hDcdMgr, pszCoffPath, ++ (DCD_REGISTERFXN)DCD_RegisterObject, ++ (void *)pszCoffPath); ++ } else { ++ status = DSP_EHANDLE; ++ GT_0trace(curTrace, GT_6CLASS, ++ "DCD_AutoRegister: invalid DCD manager handle.\n"); ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== DCD_AutoUnregister ======== ++ * Purpose: ++ * Parses the supplied DSP image and unresiters from DCD. ++ */ ++DSP_STATUS DCD_AutoUnregister(IN struct DCD_MANAGER *hDcdMgr, ++ IN char *pszCoffPath) ++{ ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ ++ GT_1trace(curTrace, GT_ENTER, "DCD_AutoUnregister: hDcdMgr 0x%x\n", ++ hDcdMgr); ++ ++ if (IsValidHandle(hDcdMgr)) { ++ status = DCD_GetObjects(hDcdMgr, pszCoffPath, ++ (DCD_REGISTERFXN)DCD_RegisterObject, ++ NULL); ++ } else { ++ status = DSP_EHANDLE; ++ GT_0trace(curTrace, GT_6CLASS, ++ "DCD_AutoUnregister: invalid DCD manager" ++ " handle.\n"); ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== DCD_CreateManager ======== ++ * Purpose: ++ * Creates DCD manager. ++ */ ++DSP_STATUS DCD_CreateManager(IN char *pszZlDllName, ++ OUT struct DCD_MANAGER **phDcdMgr) ++{ ++ struct COD_MANAGER *hCodMgr; /* COD manager handle */ ++ struct DCD_MANAGER *pDcdMgr = NULL; /* DCD Manager pointer */ ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs >= 0); ++ DBC_Require(phDcdMgr); ++ ++ GT_1trace(curTrace, GT_ENTER, "DCD_CreateManager: phDcdMgr 0x%x\n", ++ phDcdMgr); ++ ++ status = COD_Create(&hCodMgr, pszZlDllName, NULL); ++ if (DSP_SUCCEEDED(status)) { ++ ++ /* Create a DCD object. */ ++ MEM_AllocObject(pDcdMgr, struct DCD_MANAGER, SIGNATURE); ++ if (pDcdMgr != NULL) { ++ ++ /* Fill out the object. */ ++ pDcdMgr->hCodMgr = hCodMgr; ++ ++ /* Return handle to this DCD interface. */ ++ *phDcdMgr = pDcdMgr; ++ ++ GT_2trace(curTrace, GT_5CLASS, ++ "DCD_CreateManager: pDcdMgr 0x%x, " ++ " hCodMgr 0x%x", pDcdMgr, hCodMgr); ++ } else { ++ status = DSP_EMEMORY; ++ ++ /* ++ * If allocation of DcdManager object failed, delete the ++ * COD manager. ++ */ ++ COD_Delete(hCodMgr); ++ ++ GT_0trace(curTrace, GT_6CLASS, ++ "DCD_CreateManager: MEM_AllocObject failed\n"); ++ } ++ } else { ++ status = DSP_EFAIL; ++ GT_0trace(curTrace, GT_6CLASS, ++ "DCD_CreateManager: COD_Create failed\n"); ++ } ++ ++ DBC_Ensure((DSP_SUCCEEDED(status)) || ((hCodMgr == NULL) && ++ (status == DSP_EFAIL)) || ((pDcdMgr == NULL) && ++ (status == DSP_EMEMORY))); ++ ++ return status; ++} ++ ++/* ++ * ======== DCD_DestroyManager ======== ++ * Purpose: ++ * Frees DCD Manager object. ++ */ ++DSP_STATUS DCD_DestroyManager(IN struct DCD_MANAGER *hDcdMgr) ++{ ++ struct DCD_MANAGER *pDcdMgr = hDcdMgr; ++ DSP_STATUS status = DSP_EHANDLE; ++ ++ DBC_Require(cRefs >= 0); ++ ++ GT_1trace(curTrace, GT_ENTER, "DCD_DestroyManager: hDcdMgr 0x%x\n", ++ hDcdMgr); ++ ++ if (IsValidHandle(hDcdMgr)) { ++ ++ /* Delete the COD manager. */ ++ COD_Delete(pDcdMgr->hCodMgr); ++ ++ /* Deallocate a DCD manager object. */ ++ MEM_FreeObject(pDcdMgr); ++ ++ status = DSP_SOK; ++ } else { ++ GT_0trace(curTrace, GT_6CLASS, ++ "DCD_DestroyManager: invalid DCD manager handle.\n"); ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== DCD_EnumerateObject ======== ++ * Purpose: ++ * Enumerates objects in the DCD. ++ */ ++DSP_STATUS DCD_EnumerateObject(IN s32 cIndex, IN enum DSP_DCDOBJTYPE objType, ++ OUT struct DSP_UUID *pUuid) ++{ ++ DSP_STATUS status = DSP_SOK; ++ char szRegKey[REG_MAXREGPATHLENGTH]; ++ char szValue[REG_MAXREGPATHLENGTH]; ++ char szData[REG_MAXREGPATHLENGTH]; ++ u32 dwValueSize; ++ u32 dwDataSize; ++ struct DSP_UUID dspUuid; ++ char szObjType[MAX_INT2CHAR_LENGTH]; /* str. rep. of objType. */ ++ u32 dwKeyLen = 0; ++ ++ DBC_Require(cRefs >= 0); ++ DBC_Require(cIndex >= 0); ++ DBC_Require(pUuid != NULL); ++ ++ GT_3trace(curTrace, GT_ENTER, ++ "DCD_EnumerateObject: cIndex %d, objType %d, " ++ " pUuid 0x%x\n", cIndex, objType, pUuid); ++ ++ if ((cIndex != 0) && (cEnumRefs == 0)) { ++ /* ++ * If an enumeration is being performed on an index greater ++ * than zero, then the current cEnumRefs must have been ++ * incremented to greater than zero. ++ */ ++ status = DSP_ECHANGEDURINGENUM; ++ } else { ++ /* Enumerate a specific key in the registry by index. */ ++ dwValueSize = REG_MAXREGPATHLENGTH; ++ dwDataSize = REG_MAXREGPATHLENGTH; ++ ++ /* ++ * Pre-determine final key length. It's length of DCD_REGKEY + ++ * "_\0" + length of szObjType string + terminating NULL. ++ */ ++ dwKeyLen = strlen(DCD_REGKEY) + 1 + sizeof(szObjType) + 1; ++ DBC_Assert(dwKeyLen < REG_MAXREGPATHLENGTH); ++ ++ /* Create proper REG key; concatenate DCD_REGKEY with ++ * objType. */ ++ strncpy(szRegKey, DCD_REGKEY, strlen(DCD_REGKEY) + 1); ++ if ((strlen(szRegKey) + strlen("_\0")) < ++ REG_MAXREGPATHLENGTH) { ++ strncat(szRegKey, "_\0", 2); ++ } else { ++ status = DSP_EFAIL; ++ } ++ ++ /* This snprintf is guaranteed not to exceed max size of an ++ * integer. */ ++ status = snprintf(szObjType, MAX_INT2CHAR_LENGTH, "%d", ++ objType); ++ ++ if (status == -1) { ++ status = DSP_EFAIL; ++ } else { ++ status = DSP_SOK; ++ if ((strlen(szRegKey) + strlen(szObjType)) < ++ REG_MAXREGPATHLENGTH) { ++ strncat(szRegKey, szObjType, ++ strlen(szObjType) + 1); ++ } else { ++ status = DSP_EFAIL; ++ } ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ status = REG_EnumValue(NULL, cIndex, szRegKey, szValue, ++ &dwValueSize, szData, ++ &dwDataSize); ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* Create UUID value using string retrieved from ++ * registry. */ ++ UUID_UuidFromString(szValue, &dspUuid); ++ ++ *pUuid = dspUuid; ++ ++ /* Increment cEnumRefs to update reference count. */ ++ cEnumRefs++; ++ ++ status = DSP_SOK; ++ } else if (status == REG_E_NOMOREITEMS) { ++ /* At the end of enumeration. Reset cEnumRefs. */ ++ cEnumRefs = 0; ++ ++ status = DSP_SENUMCOMPLETE; ++ } else { ++ status = DSP_EFAIL; ++ GT_1trace(curTrace, GT_6CLASS, ++ "DCD_EnumerateObject: REG_EnumValue" ++ " failed, status = 0x%x\n", status); ++ } ++ } ++ ++ DBC_Ensure(pUuid || (status == DSP_EFAIL)); ++ ++ return status; ++} ++ ++/* ++ * ======== DCD_Exit ======== ++ * Purpose: ++ * Discontinue usage of the DCD module. ++ */ ++void DCD_Exit(void) ++{ ++ DBC_Require(cRefs > 0); ++ ++ GT_1trace(curTrace, GT_5CLASS, "DCD_Exit: cRefs 0x%x\n", cRefs); ++ ++ cRefs--; ++ if (cRefs == 0) { ++ REG_Exit(); ++ COD_Exit(); ++ MEM_Exit(); ++ } ++ ++ DBC_Ensure(cRefs >= 0); ++} ++ ++/* ++ * ======== DCD_GetDepLibs ======== ++ */ ++DSP_STATUS DCD_GetDepLibs(IN struct DCD_MANAGER *hDcdMgr, ++ IN struct DSP_UUID *pUuid, ++ u16 numLibs, OUT struct DSP_UUID *pDepLibUuids, ++ OUT bool *pPersistentDepLibs, IN enum NLDR_PHASE phase) ++{ ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(IsValidHandle(hDcdMgr)); ++ DBC_Require(pUuid != NULL); ++ DBC_Require(pDepLibUuids != NULL); ++ DBC_Require(pPersistentDepLibs != NULL); ++ ++ GT_1trace(curTrace, GT_ENTER, "DCD_GetDepLibs: hDcdMgr 0x%x\n", ++ hDcdMgr); ++ ++ status = GetDepLibInfo(hDcdMgr, pUuid, &numLibs, NULL, pDepLibUuids, ++ pPersistentDepLibs, phase); ++ ++ return status; ++} ++ ++/* ++ * ======== DCD_GetNumDepLibs ======== ++ */ ++DSP_STATUS DCD_GetNumDepLibs(IN struct DCD_MANAGER *hDcdMgr, ++ IN struct DSP_UUID *pUuid, OUT u16 *pNumLibs, ++ OUT u16 *pNumPersLibs, IN enum NLDR_PHASE phase) ++{ ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(IsValidHandle(hDcdMgr)); ++ DBC_Require(pNumLibs != NULL); ++ DBC_Require(pNumPersLibs != NULL); ++ DBC_Require(pUuid != NULL); ++ ++ GT_1trace(curTrace, GT_ENTER, "DCD_GetNumDepLibs: hDcdMgr 0x%x\n", ++ hDcdMgr); ++ ++ status = GetDepLibInfo(hDcdMgr, pUuid, pNumLibs, pNumPersLibs, ++ NULL, NULL, phase); ++ ++ return status; ++} ++ ++/* ++ * ======== DCD_GetObjectDef ======== ++ * Purpose: ++ * Retrieves the properties of a node or processor based on the UUID and ++ * object type. ++ */ ++DSP_STATUS DCD_GetObjectDef(IN struct DCD_MANAGER *hDcdMgr, ++ IN struct DSP_UUID *pObjUuid, ++ IN enum DSP_DCDOBJTYPE objType, ++ OUT struct DCD_GENERICOBJ *pObjDef) ++{ ++ struct DCD_MANAGER *pDcdMgr = hDcdMgr; /* pointer to DCD manager */ ++ struct COD_LIBRARYOBJ *lib = NULL; ++ DSP_STATUS status = DSP_SOK; ++ u32 ulAddr = 0; /* Used by COD_GetSection */ ++ u32 ulLen = 0; /* Used by COD_GetSection */ ++ u32 dwBufSize; /* Used by REG functions */ ++ char szRegKey[REG_MAXREGPATHLENGTH]; ++ char *szUuid; /*[MAXUUIDLEN];*/ ++ char szRegData[REG_MAXREGPATHLENGTH]; ++ char szSectName[MAXUUIDLEN + 2]; /* ".[UUID]\0" */ ++ char *pszCoffBuf; ++ u32 dwKeyLen; /* Len of REG key. */ ++ char szObjType[MAX_INT2CHAR_LENGTH]; /* str. rep. of objType. */ ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pObjDef != NULL); ++ DBC_Require(pObjUuid != NULL); ++ ++ GT_4trace(curTrace, GT_ENTER, ++ "DCD_GetObjectDef: hDcdMgr 0x%x, " "objUuid" ++ " 0x%x, objType 0x%x, pObjDef 0x%x\n", hDcdMgr, pObjUuid, ++ objType, pObjDef); ++ szUuid = (char *)MEM_Calloc(MAXUUIDLEN, MEM_PAGED); ++ if (!szUuid) ++ return status = DSP_EMEMORY; ++ ++ if (!IsValidHandle(hDcdMgr)) { ++ status = DSP_EHANDLE; ++ GT_0trace(curTrace, GT_6CLASS, "DCD_GetObjectDef: invalid " ++ "DCD manager handle.\n"); ++ goto func_end; ++ } ++ /* Pre-determine final key length. It's length of DCD_REGKEY + ++ * "_\0" + length of szObjType string + terminating NULL */ ++ dwKeyLen = strlen(DCD_REGKEY) + 1 + sizeof(szObjType) + 1; ++ DBC_Assert(dwKeyLen < REG_MAXREGPATHLENGTH); ++ /* Create proper REG key; concatenate DCD_REGKEY with objType. */ ++ strncpy(szRegKey, DCD_REGKEY, strlen(DCD_REGKEY) + 1); ++ ++ if ((strlen(szRegKey) + strlen("_\0")) < REG_MAXREGPATHLENGTH) ++ strncat(szRegKey, "_\0", 2); ++ else ++ status = DSP_EFAIL; ++ ++ status = snprintf(szObjType, MAX_INT2CHAR_LENGTH, "%d", objType); ++ if (status == -1) { ++ status = DSP_EFAIL; ++ } else { ++ status = DSP_SOK; ++ ++ if ((strlen(szRegKey) + strlen(szObjType)) < ++ REG_MAXREGPATHLENGTH) { ++ strncat(szRegKey, szObjType, strlen(szObjType) + 1); ++ } else { ++ status = DSP_EFAIL; ++ } ++ /* Create UUID value to set in registry. */ ++ UUID_UuidToString(pObjUuid, szUuid, MAXUUIDLEN); ++ ++ if ((strlen(szRegKey) + MAXUUIDLEN) < REG_MAXREGPATHLENGTH) ++ strncat(szRegKey, szUuid, MAXUUIDLEN); ++ else ++ status = DSP_EFAIL; ++ ++ /* Retrieve paths from the registry based on struct DSP_UUID */ ++ dwBufSize = REG_MAXREGPATHLENGTH; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ status = REG_GetValue(NULL, szRegKey, szRegKey, (u8 *)szRegData, ++ &dwBufSize); ++ } ++ if (DSP_FAILED(status)) { ++ status = DSP_EUUID; ++ GT_0trace(curTrace, GT_6CLASS, "DCD_GetObjectDef: " ++ "REG_GetValue() failed\n"); ++ goto func_end; ++ } ++ /* Open COFF file. */ ++ status = COD_Open(pDcdMgr->hCodMgr, szRegData, COD_NOLOAD, &lib); ++ if (DSP_FAILED(status)) { ++ status = DSP_EDCDLOADBASE; ++ GT_0trace(curTrace, GT_6CLASS, "DCD_GetObjectDef: " ++ "COD_OpenBase() failed\n"); ++ goto func_end; ++ } ++ /* Ensure szUuid + 1 is not greater than sizeof szSectName. */ ++ DBC_Assert((strlen(szUuid) + 1) < sizeof(szSectName)); ++ /* Create section name based on node UUID. A period is ++ * pre-pended to the UUID string to form the section name. ++ * I.e. ".24BC8D90_BB45_11d4_B756_006008BDB66F" */ ++ strncpy(szSectName, ".", 2); ++ strncat(szSectName, szUuid, strlen(szUuid)); ++ /* Get section information. */ ++ status = COD_GetSection(lib, szSectName, &ulAddr, &ulLen); ++ if (DSP_FAILED(status)) { ++ status = DSP_EDCDGETSECT; ++ GT_0trace(curTrace, GT_6CLASS, "DCD_GetObjectDef:" ++ " COD_GetSection() failed\n"); ++ goto func_end; ++ } ++ /* Allocate zeroed buffer. */ ++ pszCoffBuf = MEM_Calloc(ulLen + 4, MEM_PAGED); ++#ifdef _DB_TIOMAP ++ if (strstr(szRegData, "iva") == NULL) { ++ /* Locate section by objectID and read its content. */ ++ status = COD_ReadSection(lib, szSectName, pszCoffBuf, ulLen); ++ } else { ++ status = COD_ReadSection(lib, szSectName, pszCoffBuf, ulLen); ++ GT_0trace(curTrace, GT_4CLASS, ++ "Skipped Byte swap for IVA !!\n"); ++ } ++#else ++ status = COD_ReadSection(lib, szSectName, pszCoffBuf, ulLen); ++#endif ++ if (DSP_SUCCEEDED(status)) { ++ /* Compres DSP buffer to conform to PC format. */ ++ if (strstr(szRegData, "iva") == NULL) { ++ CompressBuf(pszCoffBuf, ulLen, DSPWORDSIZE); ++ } else { ++ CompressBuf(pszCoffBuf, ulLen, 1); ++ GT_0trace(curTrace, GT_4CLASS, "Compressing IVA " ++ "COFF buffer by 1 for IVA !!\n"); ++ } ++ /* Parse the content of the COFF buffer. */ ++ status = GetAttrsFromBuf(pszCoffBuf, ulLen, objType, pObjDef); ++ if (DSP_FAILED(status)) { ++ status = DSP_EDCDPARSESECT; ++ GT_0trace(curTrace, GT_6CLASS, "DCD_GetObjectDef: " ++ "GetAttrsFromBuf() failed\n"); ++ } ++ } else { ++ status = DSP_EDCDREADSECT; ++ GT_0trace(curTrace, GT_6CLASS, "DCD_GetObjectDef: " ++ "COD_ReadSection() failed\n"); ++ } ++ /* Free the previously allocated dynamic buffer. */ ++ MEM_Free(pszCoffBuf); ++func_end: ++ if (lib) ++ COD_Close(lib); ++ ++ if (szUuid) ++ MEM_Free(szUuid); ++ return status; ++} ++ ++/* ++ * ======== DCD_GetObjects ======== ++ */ ++DSP_STATUS DCD_GetObjects(IN struct DCD_MANAGER *hDcdMgr, IN char *pszCoffPath, ++ DCD_REGISTERFXN registerFxn, void *handle) ++{ ++ struct DCD_MANAGER *pDcdMgr = hDcdMgr; /* pointer to DCD manager */ ++ DSP_STATUS status = DSP_SOK; ++ char *pszCoffBuf; ++ char *pszCur; ++ struct COD_LIBRARYOBJ *lib = NULL; ++ u32 ulAddr = 0; /* Used by COD_GetSection */ ++ u32 ulLen = 0; /* Used by COD_GetSection */ ++ char seps[] = ":, "; ++ char *pToken = NULL; ++ struct DSP_UUID dspUuid; ++ s32 cObjectType; ++ ++ DBC_Require(cRefs > 0); ++ GT_1trace(curTrace, GT_ENTER, ++ "DCD_GetObjects: hDcdMgr 0x%x\n", hDcdMgr); ++ if (!IsValidHandle(hDcdMgr)) { ++ status = DSP_EHANDLE; ++ GT_0trace(curTrace, GT_6CLASS, ++ "DCD_GetObjects: invalid DCD manager handle.\n"); ++ goto func_end; ++ } ++ /* Open DSP coff file, don't load symbols. */ ++ status = COD_Open(pDcdMgr->hCodMgr, pszCoffPath, COD_NOLOAD, &lib); ++ if (DSP_FAILED(status)) { ++ status = DSP_EDCDLOADBASE; ++ GT_0trace(curTrace, GT_6CLASS, ++ "DCD_AutoRegister: COD_Open() failed\n"); ++ goto func_cont; ++ } ++ /* Get DCD_RESIGER_SECTION section information. */ ++ status = COD_GetSection(lib, DCD_REGISTER_SECTION, &ulAddr, &ulLen); ++ if (DSP_FAILED(status) || !(ulLen > 0)) { ++ status = DSP_EDCDNOAUTOREGISTER; ++ GT_0trace(curTrace, GT_6CLASS, ++ "DCD_GetObjects: COD_GetSection() " ++ "- no auto register section\n"); ++ goto func_cont; ++ } ++ /* Allocate zeroed buffer. */ ++ pszCoffBuf = MEM_Calloc(ulLen + 4, MEM_PAGED); ++#ifdef _DB_TIOMAP ++ if (strstr(pszCoffPath, "iva") == NULL) { ++ /* Locate section by objectID and read its content. */ ++ status = COD_ReadSection(lib, DCD_REGISTER_SECTION, ++ pszCoffBuf, ulLen); ++ } else { ++ GT_0trace(curTrace, GT_4CLASS, "Skipped Byte swap for IVA!!\n"); ++ status = COD_ReadSection(lib, DCD_REGISTER_SECTION, ++ pszCoffBuf, ulLen); ++ } ++#else ++ status = COD_ReadSection(lib, DCD_REGISTER_SECTION, pszCoffBuf, ulLen); ++#endif ++ if (DSP_SUCCEEDED(status)) { ++ /* Compress DSP buffer to conform to PC format. */ ++ GT_0trace(curTrace, GT_4CLASS, ++ "Successfully read section !!\n"); ++ if (strstr(pszCoffPath, "iva") == NULL) { ++ CompressBuf(pszCoffBuf, ulLen, DSPWORDSIZE); ++ } else { ++ CompressBuf(pszCoffBuf, ulLen, 1); ++ GT_0trace(curTrace, GT_4CLASS, "Compress COFF buffer " ++ "with 1 word for IVA !!\n"); ++ } ++ /* Read from buffer and register object in buffer. */ ++ pszCur = pszCoffBuf; ++ while ((pToken = strsep(&pszCur, seps)) && *pToken != '\0') { ++ /* Retrieve UUID string. */ ++ UUID_UuidFromString(pToken, &dspUuid); ++ /* Retrieve object type */ ++ pToken = strsep(&pszCur, seps); ++ /* Retrieve object type */ ++ cObjectType = Atoi(pToken); ++ /* ++ * Apply registerFxn to the found DCD object. ++ * Possible actions include: ++ * ++ * 1) Register found DCD object. ++ * 2) Unregister found DCD object (when handle == NULL) ++ * 3) Add overlay node. ++ */ ++ GT_1trace(curTrace, GT_4CLASS, "Registering objtype " ++ "%d \n", cObjectType); ++ status = registerFxn(&dspUuid, cObjectType, handle); ++ if (DSP_SUCCEEDED(status)) { ++ GT_1trace(curTrace, GT_5CLASS, ++ "DCD_GetObjects: status 0x%x\n", ++ status); ++ } else { ++ GT_0trace(curTrace, GT_6CLASS, ++ "DCD_GetObjects: " ++ "registration() failed\n"); ++ /* if error occurs, break from while loop. */ ++ break; ++ } ++ } ++ } else { ++ status = DSP_EDCDREADSECT; ++ GT_0trace(curTrace, GT_6CLASS, "DCD_GetObjects: " ++ "COD_ReadSection() failed\n"); ++ } ++ /* Free the previously allocated dynamic buffer. */ ++ MEM_Free(pszCoffBuf); ++func_cont: ++ if (lib) ++ COD_Close(lib); ++ ++func_end: ++ return status; ++} ++ ++/* ++ * ======== DCD_GetLibraryName ======== ++ * Purpose: ++ * Retrieves the library name for the given UUID. ++ * ++ */ ++DSP_STATUS DCD_GetLibraryName(IN struct DCD_MANAGER *hDcdMgr, ++ IN struct DSP_UUID *pUuid, ++ IN OUT char *pstrLibName, IN OUT u32 *pdwSize, ++ enum NLDR_PHASE phase, OUT bool *fPhaseSplit) ++{ ++ char szRegKey[REG_MAXREGPATHLENGTH]; ++ char szUuid[MAXUUIDLEN]; ++ u32 dwKeyLen; /* Len of REG key. */ ++ char szObjType[MAX_INT2CHAR_LENGTH]; /* str. rep. of objType. */ ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(pUuid != NULL); ++ DBC_Require(pstrLibName != NULL); ++ DBC_Require(pdwSize != NULL); ++ DBC_Require(IsValidHandle(hDcdMgr)); ++ ++ GT_4trace(curTrace, GT_ENTER, ++ "DCD_GetLibraryName: hDcdMgr 0x%x, pUuid 0x%x, " ++ " pstrLibName 0x%x, pdwSize 0x%x\n", hDcdMgr, pUuid, ++ pstrLibName, pdwSize); ++ /* ++ * Pre-determine final key length. It's length of DCD_REGKEY + ++ * "_\0" + length of szObjType string + terminating NULL. ++ */ ++ dwKeyLen = strlen(DCD_REGKEY) + 1 + sizeof(szObjType) + 1; ++ DBC_Assert(dwKeyLen < REG_MAXREGPATHLENGTH); ++ /* Create proper REG key; concatenate DCD_REGKEY with objType. */ ++ strncpy(szRegKey, DCD_REGKEY, strlen(DCD_REGKEY) + 1); ++ if ((strlen(szRegKey) + strlen("_\0")) < REG_MAXREGPATHLENGTH) ++ strncat(szRegKey, "_\0", 2); ++ else ++ status = DSP_EFAIL; ++ ++ switch (phase) { ++ case NLDR_CREATE: ++ /* create phase type */ ++ sprintf(szObjType, "%d", DSP_DCDCREATELIBTYPE); ++ break; ++ case NLDR_EXECUTE: ++ /* execute phase type */ ++ sprintf(szObjType, "%d", DSP_DCDEXECUTELIBTYPE); ++ break; ++ case NLDR_DELETE: ++ /* delete phase type */ ++ sprintf(szObjType, "%d", DSP_DCDDELETELIBTYPE); ++ break; ++ case NLDR_NOPHASE: ++ /* known to be a dependent library */ ++ sprintf(szObjType, "%d", DSP_DCDLIBRARYTYPE); ++ break; ++ default: ++ status = -1; ++ DBC_Assert(false); ++ } ++ if (status == -1) { ++ status = DSP_EFAIL; ++ } else { ++ status = DSP_SOK; ++ if ((strlen(szRegKey) + strlen(szObjType)) ++ < REG_MAXREGPATHLENGTH) { ++ strncat(szRegKey, szObjType, strlen(szObjType) + 1); ++ } else { ++ status = DSP_EFAIL; ++ } ++ /* Create UUID value to find match in registry. */ ++ UUID_UuidToString(pUuid, szUuid, MAXUUIDLEN); ++ if ((strlen(szRegKey) + MAXUUIDLEN) < ++ REG_MAXREGPATHLENGTH) { ++ strncat(szRegKey, szUuid, MAXUUIDLEN); ++ } else { ++ status = DSP_EFAIL; ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Retrieve path from the registry based on DSP_UUID */ ++ status = REG_GetValue(NULL, szRegKey, szRegKey, ++ (u8 *)pstrLibName, pdwSize); ++ } ++ /* If can't find, phases might be registered as generic LIBRARYTYPE */ ++ if (DSP_FAILED(status) && phase != NLDR_NOPHASE) { ++ if (fPhaseSplit) ++ *fPhaseSplit = false; ++ ++ strncpy(szRegKey, DCD_REGKEY, strlen(DCD_REGKEY) + 1); ++ if ((strlen(szRegKey) + strlen("_\0")) < ++ REG_MAXREGPATHLENGTH) { ++ strncat(szRegKey, "_\0", 2); ++ } else { ++ status = DSP_EFAIL; ++ } ++ sprintf(szObjType, "%d", DSP_DCDLIBRARYTYPE); ++ if ((strlen(szRegKey) + strlen(szObjType)) ++ < REG_MAXREGPATHLENGTH) { ++ strncat(szRegKey, szObjType, strlen(szObjType) + 1); ++ } else { ++ status = DSP_EFAIL; ++ } ++ UUID_UuidToString(pUuid, szUuid, MAXUUIDLEN); ++ if ((strlen(szRegKey) + MAXUUIDLEN) < REG_MAXREGPATHLENGTH) ++ strncat(szRegKey, szUuid, MAXUUIDLEN); ++ else ++ status = DSP_EFAIL; ++ ++ status = REG_GetValue(NULL, szRegKey, szRegKey, ++ (u8 *)pstrLibName, pdwSize); ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== DCD_Init ======== ++ * Purpose: ++ * Initialize the DCD module. ++ */ ++bool DCD_Init(void) ++{ ++ bool fInitMEM; ++ bool fInitREG; ++ bool fInitCOD; ++ bool fInit = true; ++ ++ DBC_Require(cRefs >= 0); ++ ++ GT_1trace(curTrace, GT_ENTER, "DCD_Init: (on enter) cRefs = 0x%x\n", ++ cRefs); ++ ++ if (cRefs == 0) { ++ ++ /* Initialize required modules. */ ++ fInitMEM = MEM_Init(); ++ fInitCOD = COD_Init(); ++ fInitREG = REG_Init(); ++ if (!fInitMEM || !fInitCOD || !fInitREG) { ++ fInit = false; ++ GT_0trace(curTrace, GT_6CLASS, "DCD_Init failed\n"); ++ /* Exit initialized modules. */ ++ if (fInitMEM) ++ MEM_Exit(); ++ ++ if (fInitCOD) ++ COD_Exit(); ++ ++ if (fInitREG) ++ REG_Exit(); ++ ++ } ++ } ++ ++ if (fInit) ++ cRefs++; ++ ++ ++ GT_1trace(curTrace, GT_5CLASS, "DCD_Init: (on exit) cRefs = 0x%x\n", ++ cRefs); ++ ++ DBC_Ensure((fInit && (cRefs > 0)) || (!fInit && (cRefs == 0))); ++ ++ return fInit; ++} ++ ++/* ++ * ======== DCD_RegisterObject ======== ++ * Purpose: ++ * Registers a node or a processor with the DCD. ++ * If pszPathName == NULL, unregister the specified DCD object. ++ */ ++DSP_STATUS DCD_RegisterObject(IN struct DSP_UUID *pUuid, ++ IN enum DSP_DCDOBJTYPE objType, ++ IN char *pszPathName) ++{ ++ DSP_STATUS status = DSP_SOK; ++ char szRegKey[REG_MAXREGPATHLENGTH]; ++ char szUuid[MAXUUIDLEN + 1]; ++ u32 dwPathSize = 0; ++ u32 dwKeyLen; /* Len of REG key. */ ++ char szObjType[MAX_INT2CHAR_LENGTH]; /* str. rep. of objType. */ ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pUuid != NULL); ++ DBC_Require((objType == DSP_DCDNODETYPE) || ++ (objType == DSP_DCDPROCESSORTYPE) || ++ (objType == DSP_DCDLIBRARYTYPE) || ++ (objType == DSP_DCDCREATELIBTYPE) || ++ (objType == DSP_DCDEXECUTELIBTYPE) || ++ (objType == DSP_DCDDELETELIBTYPE)); ++ ++ GT_3trace(curTrace, GT_ENTER, "DCD_RegisterObject: object UUID 0x%x, " ++ "objType %d, szPathName %s\n", pUuid, objType, pszPathName); ++ /* ++ * Pre-determine final key length. It's length of DCD_REGKEY + ++ * "_\0" + length of szObjType string + terminating NULL. ++ */ ++ dwKeyLen = strlen(DCD_REGKEY) + 1 + sizeof(szObjType) + 1; ++ DBC_Assert(dwKeyLen < REG_MAXREGPATHLENGTH); ++ /* Create proper REG key; concatenate DCD_REGKEY with objType. */ ++ strncpy(szRegKey, DCD_REGKEY, strlen(DCD_REGKEY) + 1); ++ if ((strlen(szRegKey) + strlen("_\0")) < REG_MAXREGPATHLENGTH) ++ strncat(szRegKey, "_\0", 2); ++ else ++ status = DSP_EFAIL; ++ ++ status = snprintf(szObjType, MAX_INT2CHAR_LENGTH, "%d", objType); ++ if (status == -1) { ++ status = DSP_EFAIL; ++ } else { ++ status = DSP_SOK; ++ if ((strlen(szRegKey) + strlen(szObjType)) < ++ REG_MAXREGPATHLENGTH) { ++ strncat(szRegKey, szObjType, strlen(szObjType) + 1); ++ } else { ++ status = DSP_EFAIL; ++ } ++ /* Create UUID value to set in registry. */ ++ UUID_UuidToString(pUuid, szUuid, MAXUUIDLEN); ++ if ((strlen(szRegKey) + MAXUUIDLEN) < REG_MAXREGPATHLENGTH) ++ strncat(szRegKey, szUuid, MAXUUIDLEN); ++ else ++ status = DSP_EFAIL; ++ ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* ++ * If pszPathName != NULL, perform registration, otherwise, ++ * perform unregistration. ++ */ ++ if (pszPathName) { ++ /* Add new reg value (UUID+objType) with COFF path ++ * info. */ ++ dwPathSize = strlen(pszPathName) + 1; ++ status = REG_SetValue(NULL, szRegKey, szRegKey, REG_SZ, ++ (u8 *)pszPathName, dwPathSize); ++ GT_3trace(curTrace, GT_6CLASS, ++ "REG_SetValue REG_SZ=%d, " ++ "(u8 *)pszPathName=%s, dwPathSize=%d\n", ++ REG_SZ, pszPathName, dwPathSize); ++ if (DSP_FAILED(status)) { ++ status = DSP_EFAIL; ++ GT_0trace(curTrace, GT_6CLASS, ++ "DCD_RegisterObject: REG_SetValue failed!\n"); ++ } ++ } else { ++ /* Deregister an existing object. */ ++ status = REG_DeleteValue(NULL, szRegKey, szRegKey); ++ if (DSP_FAILED(status)) { ++ status = DSP_EFAIL; ++ GT_0trace(curTrace, GT_6CLASS, ++ "DCD_UnregisterObject: " ++ "REG_DeleteValue failed!\n"); ++ } ++ } ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* ++ * Because the node database has been updated through a ++ * successful object registration/de-registration operation, ++ * we need to reset the object enumeration counter to allow ++ * current enumerations to reflect this update in the node ++ * database. ++ */ ++ ++ cEnumRefs = 0; ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== DCD_UnregisterObject ======== ++ * Call DCD_Register object with pszPathName set to NULL to ++ * perform actual object de-registration. ++ */ ++DSP_STATUS DCD_UnregisterObject(IN struct DSP_UUID *pUuid, ++ IN enum DSP_DCDOBJTYPE objType) ++{ ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pUuid != NULL); ++ DBC_Require((objType == DSP_DCDNODETYPE) || ++ (objType == DSP_DCDPROCESSORTYPE) || ++ (objType == DSP_DCDLIBRARYTYPE) || ++ (objType == DSP_DCDCREATELIBTYPE) || ++ (objType == DSP_DCDEXECUTELIBTYPE) || ++ (objType == DSP_DCDDELETELIBTYPE)); ++ ++ GT_2trace(curTrace, GT_ENTER, ++ "DCD_UnregisterObject: object UUID 0x%x, " ++ "objType %d\n", pUuid, objType); ++ ++ /* ++ * When DCD_RegisterObject is called with NULL as pathname, ++ * it indicates an unregister object operation. ++ */ ++ status = DCD_RegisterObject(pUuid, objType, NULL); ++ ++ return status; ++} ++ ++/* ++ ********************************************************************** ++ * DCD Helper Functions ++ ********************************************************************** ++ */ ++ ++/* ++ * ======== Atoi ======== ++ * Purpose: ++ * This function converts strings in decimal or hex format to integers. ++ */ ++static s32 Atoi(char *pszBuf) ++{ ++ s32 result = 0; ++ char *pch = pszBuf; ++ char c; ++ char first; ++ s32 base = 10; ++ s32 len; ++ ++ while (isspace(*pch)) ++ pch++; ++ ++ first = *pch; ++ if (first == '-' || first == '+') { ++ pch++; ++ } else { ++ /* Determine if base 10 or base 16 */ ++ len = strlen(pch); ++ if (len > 1) { ++ c = pch[1]; ++ if ((*pch == '0' && (c == 'x' || c == 'X'))) { ++ base = 16; ++ pch += 2; ++ } ++ c = pch[len - 1]; ++ if (c == 'h' || c == 'H') ++ base = 16; ++ ++ } ++ } ++ ++ while (isdigit(c = *pch) || ((base == 16) && isxdigit(c))) { ++ result *= base; ++ if ('A' <= c && c <= 'F') { ++ c = c - 'A' + 10; ++ } else { ++ if ('a' <= c && c <= 'f') ++ c = c - 'a' + 10; ++ else ++ c -= '0'; ++ ++ } ++ result += c; ++ ++pch; ++ } ++ ++ return result; ++} ++ ++/* ++ * ======== GetAttrsFromBuf ======== ++ * Purpose: ++ * Parse the content of a buffer filled with DSP-side data and ++ * retrieve an object's attributes from it. IMPORTANT: Assume the ++ * buffer has been converted from DSP format to GPP format. ++ */ ++static DSP_STATUS GetAttrsFromBuf(char *pszBuf, u32 ulBufSize, ++ enum DSP_DCDOBJTYPE objType, ++ struct DCD_GENERICOBJ *pGenObj) ++{ ++ DSP_STATUS status = DSP_SOK; ++ char seps[] = ", "; ++ char *pszCur; ++ char *token; ++ s32 cLen = 0; ++ u32 i = 0; ++#ifdef _DB_TIOMAP ++ s32 iEntry; ++#endif ++ ++ DBC_Require(pszBuf != NULL); ++ DBC_Require(ulBufSize != 0); ++ DBC_Require((objType == DSP_DCDNODETYPE) ++ || (objType == DSP_DCDPROCESSORTYPE)); ++ DBC_Require(pGenObj != NULL); ++ ++ ++ switch (objType) { ++ case DSP_DCDNODETYPE: ++ /* ++ * Parse COFF sect buffer to retrieve individual tokens used ++ * to fill in object attrs. ++ */ ++ pszCur = pszBuf; ++ token = strsep(&pszCur, seps); ++ ++ /* u32 cbStruct */ ++ pGenObj->objData.nodeObj.ndbProps.cbStruct = ++ (u32) Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ /* DSP_UUID uiNodeID */ ++ UUID_UuidFromString(token, ++ &pGenObj->objData.nodeObj.ndbProps.uiNodeID); ++ token = strsep(&pszCur, seps); ++ ++ /* acName */ ++ DBC_Require(token); ++ cLen = strlen(token); ++ if (cLen > DSP_MAXNAMELEN - 1) ++ cLen = DSP_MAXNAMELEN - 1; ++ ++ strncpy(pGenObj->objData.nodeObj.ndbProps.acName, ++ token, cLen); ++ pGenObj->objData.nodeObj.ndbProps.acName[cLen] = '\0'; ++ token = strsep(&pszCur, seps); ++ /* u32 uNodeType */ ++ pGenObj->objData.nodeObj.ndbProps.uNodeType = Atoi(token); ++ token = strsep(&pszCur, seps); ++ /* u32 bCacheOnGPP */ ++ pGenObj->objData.nodeObj.ndbProps.bCacheOnGPP = Atoi(token); ++ token = strsep(&pszCur, seps); ++ /* DSP_RESOURCEREQMTS dspResourceReqmts */ ++ pGenObj->objData.nodeObj.ndbProps.dspResourceReqmts.cbStruct = ++ (u32) Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ pGenObj->objData.nodeObj.ndbProps.dspResourceReqmts. ++ uStaticDataSize = Atoi(token); ++ token = strsep(&pszCur, seps); ++ pGenObj->objData.nodeObj.ndbProps.dspResourceReqmts. ++ uGlobalDataSize = Atoi(token); ++ token = strsep(&pszCur, seps); ++ pGenObj->objData.nodeObj.ndbProps.dspResourceReqmts. ++ uProgramMemSize = Atoi(token); ++ token = strsep(&pszCur, seps); ++ pGenObj->objData.nodeObj.ndbProps.dspResourceReqmts. ++ uWCExecutionTime = Atoi(token); ++ token = strsep(&pszCur, seps); ++ pGenObj->objData.nodeObj.ndbProps.dspResourceReqmts. ++ uWCPeriod = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ pGenObj->objData.nodeObj.ndbProps.dspResourceReqmts. ++ uWCDeadline = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ pGenObj->objData.nodeObj.ndbProps.dspResourceReqmts. ++ uAvgExectionTime = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ pGenObj->objData.nodeObj.ndbProps.dspResourceReqmts. ++ uMinimumPeriod = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ /* s32 iPriority */ ++ pGenObj->objData.nodeObj.ndbProps.iPriority = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ /* u32 uStackSize */ ++ pGenObj->objData.nodeObj.ndbProps.uStackSize = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ /* u32 uSysStackSize */ ++ pGenObj->objData.nodeObj.ndbProps.uSysStackSize = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ /* u32 uStackSeg */ ++ pGenObj->objData.nodeObj.ndbProps.uStackSeg = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ /* u32 uMessageDepth */ ++ pGenObj->objData.nodeObj.ndbProps.uMessageDepth = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ /* u32 uNumInputStreams */ ++ pGenObj->objData.nodeObj.ndbProps.uNumInputStreams = ++ Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ /* u32 uNumOutputStreams */ ++ pGenObj->objData.nodeObj.ndbProps.uNumOutputStreams = ++ Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ /* u32 uTimeout */ ++ pGenObj->objData.nodeObj.ndbProps.uTimeout = ++ Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ /* char * pstrCreatePhaseFxn */ ++ DBC_Require(token); ++ cLen = strlen(token); ++ pGenObj->objData.nodeObj.pstrCreatePhaseFxn = ++ MEM_Calloc(cLen + 1, MEM_PAGED); ++ strncpy(pGenObj->objData.nodeObj.pstrCreatePhaseFxn, ++ token, cLen); ++ pGenObj->objData.nodeObj.pstrCreatePhaseFxn[cLen] = '\0'; ++ token = strsep(&pszCur, seps); ++ ++ /* char * pstrExecutePhaseFxn */ ++ DBC_Require(token); ++ cLen = strlen(token); ++ pGenObj->objData.nodeObj.pstrExecutePhaseFxn = ++ MEM_Calloc(cLen + 1, MEM_PAGED); ++ strncpy(pGenObj->objData.nodeObj.pstrExecutePhaseFxn, ++ token, cLen); ++ pGenObj->objData.nodeObj.pstrExecutePhaseFxn[cLen] = '\0'; ++ token = strsep(&pszCur, seps); ++ ++ /* char * pstrDeletePhaseFxn */ ++ DBC_Require(token); ++ cLen = strlen(token); ++ pGenObj->objData.nodeObj.pstrDeletePhaseFxn = ++ MEM_Calloc(cLen + 1, MEM_PAGED); ++ strncpy(pGenObj->objData.nodeObj.pstrDeletePhaseFxn, ++ token, cLen); ++ pGenObj->objData.nodeObj.pstrDeletePhaseFxn[cLen] = '\0'; ++ token = strsep(&pszCur, seps); ++ ++ /* Segment id for message buffers */ ++ pGenObj->objData.nodeObj.uMsgSegid = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ /* Message notification type */ ++ pGenObj->objData.nodeObj.uMsgNotifyType = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ /* char * pstrIAlgName */ ++ if (token) { ++ cLen = strlen(token); ++ pGenObj->objData.nodeObj.pstrIAlgName = ++ MEM_Calloc(cLen + 1, MEM_PAGED); ++ strncpy(pGenObj->objData.nodeObj.pstrIAlgName, ++ token, cLen); ++ pGenObj->objData.nodeObj.pstrIAlgName[cLen] = '\0'; ++ token = strsep(&pszCur, seps); ++ } ++ ++ /* Load type (static, dynamic, or overlay) */ ++ if (token) { ++ pGenObj->objData.nodeObj.usLoadType = Atoi(token); ++ token = strsep(&pszCur, seps); ++ } ++ ++ /* Dynamic load data requirements */ ++ if (token) { ++ pGenObj->objData.nodeObj.ulDataMemSegMask = Atoi(token); ++ token = strsep(&pszCur, seps); ++ } ++ ++ /* Dynamic load code requirements */ ++ if (token) { ++ pGenObj->objData.nodeObj.ulCodeMemSegMask = Atoi(token); ++ token = strsep(&pszCur, seps); ++ } ++ ++ /* Extract node profiles into node properties */ ++ if (token) { ++ ++ pGenObj->objData.nodeObj.ndbProps.uCountProfiles = ++ Atoi(token); ++ for (i = 0; i < pGenObj->objData.nodeObj.ndbProps. ++ uCountProfiles; i++) { ++ token = strsep(&pszCur, seps); ++ if (token) { ++ /* Heap Size for the node */ ++ pGenObj->objData.nodeObj.ndbProps. ++ aProfiles[i].ulHeapSize = ++ Atoi(token); ++ } ++ } ++ } ++ token = strsep(&pszCur, seps); ++ if (token) { ++ pGenObj->objData.nodeObj.ndbProps.uStackSegName = ++ (u32)(token); ++ } ++ ++ break; ++ ++ case DSP_DCDPROCESSORTYPE: ++ /* ++ * Parse COFF sect buffer to retrieve individual tokens used ++ * to fill in object attrs. ++ */ ++ pszCur = pszBuf; ++ token = strsep(&pszCur, seps); ++ ++ pGenObj->objData.procObj.cbStruct = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ pGenObj->objData.procObj.uProcessorFamily = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ pGenObj->objData.procObj.uProcessorType = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ pGenObj->objData.procObj.uClockRate = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ pGenObj->objData.procObj.ulInternalMemSize = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ pGenObj->objData.procObj.ulExternalMemSize = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ pGenObj->objData.procObj.uProcessorID = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ pGenObj->objData.procObj.tyRunningRTOS = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ pGenObj->objData.procObj.nNodeMinPriority = Atoi(token); ++ token = strsep(&pszCur, seps); ++ ++ pGenObj->objData.procObj.nNodeMaxPriority = Atoi(token); ++ ++#ifdef _DB_TIOMAP ++ /* Proc object may contain additional(extended) attributes. */ ++ /* attr must match proc.hxx */ ++ for (iEntry = 0; iEntry < 7; iEntry++) { ++ token = strsep(&pszCur, seps); ++ pGenObj->objData.extProcObj.tyTlb[iEntry].ulGppPhys = ++ Atoi(token); ++ ++ token = strsep(&pszCur, seps); ++ pGenObj->objData.extProcObj.tyTlb[iEntry].ulDspVirt = ++ Atoi(token); ++ } ++#endif ++ ++ break; ++ ++ default: ++ status = DSP_EFAIL; ++ break; ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== CompressBuffer ======== ++ * Purpose: ++ * Compress the DSP buffer, if necessary, to conform to PC format. ++ */ ++static void CompressBuf(char *pszBuf, u32 ulBufSize, s32 cCharSize) ++{ ++ char *p; ++ char ch; ++ char *q; ++ ++ p = pszBuf; ++ if (p == NULL) ++ return; ++ ++ for (q = pszBuf; q < (pszBuf + ulBufSize);) { ++ ++ ch = DspChar2GppChar(q, cCharSize); ++ if (ch == '\\') { ++ q += cCharSize; ++ ch = DspChar2GppChar(q, cCharSize); ++ switch (ch) { ++ case 't': ++ *p = '\t'; ++ break; ++ ++ case 'n': ++ *p = '\n'; ++ break; ++ ++ case 'r': ++ *p = '\r'; ++ break; ++ ++ case '0': ++ *p = '\0'; ++ break; ++ ++ default: ++ *p = ch; ++ break; ++ } ++ } else { ++ *p = ch; ++ } ++ p++; ++ q += cCharSize; ++ } ++ ++ /* NULL out remainder of buffer. */ ++ while (p < q) ++ *p++ = '\0'; ++ ++} ++ ++/* ++ * ======== DspChar2GppChar ======== ++ * Purpose: ++ * Convert DSP char to host GPP char in a portable manner ++ */ ++static char DspChar2GppChar(char *pWord, s32 cDspCharSize) ++{ ++ char ch = '\0'; ++ char *chSrc; ++ s32 i; ++ ++ for (chSrc = pWord, i = cDspCharSize; i > 0; i--) ++ ch |= *chSrc++; ++ ++ return ch; ++} ++ ++/* ++ * ======== GetDepLibInfo ======== ++ */ ++static DSP_STATUS GetDepLibInfo(IN struct DCD_MANAGER *hDcdMgr, ++ IN struct DSP_UUID *pUuid, ++ IN OUT u16 *pNumLibs, ++ OPTIONAL OUT u16 *pNumPersLibs, ++ OPTIONAL OUT struct DSP_UUID *pDepLibUuids, ++ OPTIONAL OUT bool *pPersistentDepLibs, ++ enum NLDR_PHASE phase) ++{ ++ struct DCD_MANAGER *pDcdMgr = hDcdMgr; /* pointer to DCD manager */ ++ char *pszCoffBuf = NULL; ++ char *pszCur; ++ char *pszFileName = NULL; ++ struct COD_LIBRARYOBJ *lib = NULL; ++ u32 ulAddr = 0; /* Used by COD_GetSection */ ++ u32 ulLen = 0; /* Used by COD_GetSection */ ++ u32 dwDataSize = COD_MAXPATHLENGTH; ++ char seps[] = ", "; ++ char *pToken = NULL; ++ bool fGetUuids = (pDepLibUuids != NULL); ++ u16 nDepLibs = 0; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ ++ DBC_Require(IsValidHandle(hDcdMgr)); ++ DBC_Require(pNumLibs != NULL); ++ DBC_Require(pUuid != NULL); ++ ++ GT_1trace(curTrace, GT_ENTER, "DCD_GetNumDepLibs: hDcdMgr 0x%x\n", ++ hDcdMgr); ++ ++ /* Initialize to 0 dependent libraries, if only counting number of ++ * dependent libraries */ ++ if (!fGetUuids) { ++ *pNumLibs = 0; ++ *pNumPersLibs = 0; ++ } ++ ++ /* Allocate a buffer for file name */ ++ pszFileName = MEM_Calloc(dwDataSize, MEM_PAGED); ++ if (pszFileName == NULL) { ++ status = DSP_EMEMORY; ++ } else { ++ /* Get the name of the library */ ++ status = DCD_GetLibraryName(hDcdMgr, pUuid, pszFileName, ++ &dwDataSize, phase, NULL); ++ } ++ /* Open the library */ ++ if (DSP_SUCCEEDED(status)) { ++ status = COD_Open(pDcdMgr->hCodMgr, pszFileName, ++ COD_NOLOAD, &lib); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Get dependent library section information. */ ++ status = COD_GetSection(lib, DEPLIBSECT, &ulAddr, &ulLen); ++ ++ if (DSP_FAILED(status)) { ++ /* Ok, no dependent libraries */ ++ ulLen = 0; ++ status = DSP_SNODEPENDENTLIBS; ++ } ++ } ++ ++ if (DSP_FAILED(status) || !(ulLen > 0)) ++ goto func_cont; ++ ++ /* Allocate zeroed buffer. */ ++ pszCoffBuf = MEM_Calloc(ulLen, MEM_PAGED); ++ if (pszCoffBuf == NULL) ++ status = DSP_EMEMORY; ++ ++ /* Read section contents. */ ++ status = COD_ReadSection(lib, DEPLIBSECT, pszCoffBuf, ulLen); ++ if (DSP_FAILED(status)) ++ goto func_cont; ++ ++ /* Compress and format DSP buffer to conform to PC format. */ ++ CompressBuf(pszCoffBuf, ulLen, DSPWORDSIZE); ++ /* Read from buffer */ ++ pszCur = pszCoffBuf; ++ while ((pToken = strsep(&pszCur, seps)) && *pToken != '\0') { ++ if (fGetUuids) { ++ if (nDepLibs >= *pNumLibs) { ++ /* Gone beyond the limit */ ++ break; ++ } else { ++ /* Retrieve UUID string. */ ++ UUID_UuidFromString(pToken, ++ &(pDepLibUuids[nDepLibs])); ++ /* Is this library persistent? */ ++ pToken = strsep(&pszCur, seps); ++ pPersistentDepLibs[nDepLibs] = Atoi(pToken); ++ nDepLibs++; ++ } ++ } else { ++ /* Advanc to next token */ ++ pToken = strsep(&pszCur, seps); ++ if (Atoi(pToken)) ++ (*pNumPersLibs)++; ++ ++ /* Just counting number of dependent libraries */ ++ (*pNumLibs)++; ++ } ++ } ++func_cont: ++ if (lib) ++ COD_Close(lib); ++ ++ /* Free previously allocated dynamic buffers. */ ++ if (pszFileName) ++ MEM_Free(pszFileName); ++ ++ if (pszCoffBuf) ++ MEM_Free(pszCoffBuf); ++ ++ return status; ++} ++ +diff --git a/drivers/dsp/bridge/rmgr/disp.c b/drivers/dsp/bridge/rmgr/disp.c +new file mode 100644 +index 0000000..3fbbf01 +--- /dev/null ++++ b/drivers/dsp/bridge/rmgr/disp.c +@@ -0,0 +1,916 @@ ++/* ++ * disp.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== disp.c ======== ++ * ++ * Description: ++ * Node Dispatcher interface. Communicates with Resource Manager Server ++ * (RMS) on DSP. Access to RMS is synchronized in NODE. ++ * ++ * Public Functions: ++ * DISP_Create ++ * DISP_Delete ++ * DISP_Exit ++ * DISP_Init ++ * DISP_NodeChangePriority ++ * DISP_NodeCreate ++ * DISP_NodeDelete ++ * DISP_NodePause ++ * DISP_NodeRun ++ * ++ *! Revision History: ++ *! ================= ++ *! 18-Feb-2003 vp Code review updates ++ *! 18-Oct-2002 vp Ported to Linux platform ++ *! 16-May-2002 jeh Added DISP_DoCinit(). ++ *! 24-Apr-2002 jeh Added DISP_MemWrite(). ++ *! 13-Feb-2002 jeh Pass system stack size to RMS. ++ *! 16-Jan-2002 ag Added bufsize param to _ChnlAddIOReq() fxn ++ *! 10-May-2001 jeh Code Review cleanup. ++ *! 26-Sep-2000 jeh Fixed status values in SendMessage(). ++ *! 19-Jun-2000 jeh Created. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Link Driver */ ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++#include ++ ++/* ----------------------------------- Resource Manager */ ++#include ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++#define DISP_SIGNATURE 0x50534944 /* "PSID" */ ++ ++/* Size of a reply from RMS */ ++#define REPLYSIZE (3 * sizeof(RMS_WORD)) ++ ++/* Reserved channel offsets for communication with RMS */ ++#define CHNLTORMSOFFSET 0 ++#define CHNLFROMRMSOFFSET 1 ++ ++#define CHNLIOREQS 1 ++ ++#define SwapWord(x) (((u32)(x) >> 16) | ((u32)(x) << 16)) ++ ++/* ++ * ======== DISP_OBJECT ======== ++ */ ++struct DISP_OBJECT { ++ u32 dwSignature; /* Used for object validation */ ++ struct DEV_OBJECT *hDevObject; /* Device for this processor */ ++ struct WMD_DRV_INTERFACE *pIntfFxns; /* Function interface to WMD */ ++ struct CHNL_MGR *hChnlMgr; /* Channel manager */ ++ struct CHNL_OBJECT *hChnlToDsp; /* Channel for commands to RMS */ ++ struct CHNL_OBJECT *hChnlFromDsp; /* Channel for replies from RMS */ ++ u8 *pBuf; /* Buffer for commands, replies */ ++ u32 ulBufsize; /* pBuf size in bytes */ ++ u32 ulBufsizeRMS; /* pBuf size in RMS words */ ++ u32 uCharSize; /* Size of DSP character */ ++ u32 uWordSize; /* Size of DSP word */ ++ u32 uDataMauSize; /* Size of DSP Data MAU */ ++}; ++ ++static u32 cRefs; ++ ++/* Debug msgs: */ ++#if GT_TRACE ++static struct GT_Mask DISP_DebugMask = { NULL, NULL }; ++#endif ++ ++static void DeleteDisp(struct DISP_OBJECT *hDisp); ++static DSP_STATUS FillStreamDef(RMS_WORD *pdwBuf, u32 *ptotal, u32 offset, ++ struct NODE_STRMDEF strmDef, u32 max, ++ u32 uCharsInRMSWord); ++static DSP_STATUS SendMessage(struct DISP_OBJECT *hDisp, u32 dwTimeout, ++ u32 ulBytes, OUT u32 *pdwArg); ++ ++/* ++ * ======== DISP_Create ======== ++ * Create a NODE Dispatcher object. ++ */ ++DSP_STATUS DISP_Create(OUT struct DISP_OBJECT **phDispObject, ++ struct DEV_OBJECT *hDevObject, ++ IN CONST struct DISP_ATTRS *pDispAttrs) ++{ ++ struct DISP_OBJECT *pDisp; ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ u32 ulChnlId; ++ struct CHNL_ATTRS chnlAttrs; ++ DSP_STATUS status = DSP_SOK; ++ u32 devType; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phDispObject != NULL); ++ DBC_Require(pDispAttrs != NULL); ++ DBC_Require(hDevObject != NULL); ++ ++ GT_3trace(DISP_DebugMask, GT_ENTER, "DISP_Create: phDispObject: 0x%x\t" ++ "hDevObject: 0x%x\tpDispAttrs: 0x%x\n", phDispObject, ++ hDevObject, pDispAttrs); ++ ++ *phDispObject = NULL; ++ ++ /* Allocate Node Dispatcher object */ ++ MEM_AllocObject(pDisp, struct DISP_OBJECT, DISP_SIGNATURE); ++ if (pDisp == NULL) { ++ status = DSP_EMEMORY; ++ GT_0trace(DISP_DebugMask, GT_6CLASS, ++ "DISP_Create: MEM_AllocObject() failed!\n"); ++ } else { ++ pDisp->hDevObject = hDevObject; ++ } ++ ++ /* Get Channel manager and WMD function interface */ ++ if (DSP_SUCCEEDED(status)) { ++ status = DEV_GetChnlMgr(hDevObject, &(pDisp->hChnlMgr)); ++ if (DSP_SUCCEEDED(status)) { ++ (void) DEV_GetIntfFxns(hDevObject, &pIntfFxns); ++ pDisp->pIntfFxns = pIntfFxns; ++ } else { ++ GT_1trace(DISP_DebugMask, GT_6CLASS, ++ "DISP_Create: Failed to get " ++ "channel manager! status = 0x%x\n", status); ++ } ++ } ++ ++ /* check device type and decide if streams or messag'ing is used for ++ * RMS/EDS */ ++ if (DSP_FAILED(status)) ++ goto func_cont; ++ ++ status = DEV_GetDevType(hDevObject, &devType); ++ GT_1trace(DISP_DebugMask, GT_6CLASS, "DISP_Create: Creating DISP for " ++ "device = 0x%x\n", devType); ++ if (DSP_FAILED(status)) ++ goto func_cont; ++ ++ if (devType != DSP_UNIT) { ++ GT_0trace(DISP_DebugMask, GT_6CLASS, ++ "DISP_Create: Unkown device " ++ "type in Device object !! \n"); ++ status = DSP_EFAIL; ++ goto func_cont; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ pDisp->uCharSize = DSPWORDSIZE; ++ pDisp->uWordSize = DSPWORDSIZE; ++ pDisp->uDataMauSize = DSPWORDSIZE; ++ /* Open channels for communicating with the RMS */ ++ chnlAttrs.uIOReqs = CHNLIOREQS; ++ chnlAttrs.hEvent = NULL; ++ ulChnlId = pDispAttrs->ulChnlOffset + CHNLTORMSOFFSET; ++ status = (*pIntfFxns->pfnChnlOpen)(&(pDisp->hChnlToDsp), ++ pDisp->hChnlMgr, CHNL_MODETODSP, ulChnlId, &chnlAttrs); ++ if (DSP_FAILED(status)) { ++ GT_2trace(DISP_DebugMask, GT_6CLASS, ++ "DISP_Create: Channel to RMS " ++ "open failed, chnl id = %d, status = 0x%x\n", ++ ulChnlId, status); ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ ulChnlId = pDispAttrs->ulChnlOffset + CHNLFROMRMSOFFSET; ++ status = (*pIntfFxns->pfnChnlOpen)(&(pDisp->hChnlFromDsp), ++ pDisp->hChnlMgr, CHNL_MODEFROMDSP, ulChnlId, ++ &chnlAttrs); ++ if (DSP_FAILED(status)) { ++ GT_2trace(DISP_DebugMask, GT_6CLASS, ++ "DISP_Create: Channel from RMS " ++ "open failed, chnl id = %d, status = 0x%x\n", ++ ulChnlId, status); ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Allocate buffer for commands, replies */ ++ pDisp->ulBufsize = pDispAttrs->ulChnlBufSize; ++ pDisp->ulBufsizeRMS = RMS_COMMANDBUFSIZE; ++ pDisp->pBuf = MEM_Calloc(pDisp->ulBufsize, MEM_PAGED); ++ if (pDisp->pBuf == NULL) { ++ status = DSP_EMEMORY; ++ GT_0trace(DISP_DebugMask, GT_6CLASS, ++ "DISP_Create: Failed " ++ "to allocate channel buffer!\n"); ++ } ++ } ++func_cont: ++ if (DSP_SUCCEEDED(status)) ++ *phDispObject = pDisp; ++ else ++ DeleteDisp(pDisp); ++ ++ DBC_Ensure(((DSP_FAILED(status)) && ((*phDispObject == NULL))) || ++ ((DSP_SUCCEEDED(status)) && ++ (MEM_IsValidHandle((*phDispObject), DISP_SIGNATURE)))); ++ return status; ++} ++ ++/* ++ * ======== DISP_Delete ======== ++ * Delete the NODE Dispatcher. ++ */ ++void DISP_Delete(struct DISP_OBJECT *hDisp) ++{ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(hDisp, DISP_SIGNATURE)); ++ ++ GT_1trace(DISP_DebugMask, GT_ENTER, ++ "DISP_Delete: hDisp: 0x%x\n", hDisp); ++ ++ DeleteDisp(hDisp); ++ ++ DBC_Ensure(!MEM_IsValidHandle(hDisp, DISP_SIGNATURE)); ++} ++ ++/* ++ * ======== DISP_Exit ======== ++ * Discontinue usage of DISP module. ++ */ ++void DISP_Exit(void) ++{ ++ DBC_Require(cRefs > 0); ++ ++ cRefs--; ++ ++ GT_1trace(DISP_DebugMask, GT_5CLASS, ++ "Entered DISP_Exit, ref count: 0x%x\n", cRefs); ++ ++ DBC_Ensure(cRefs >= 0); ++} ++ ++/* ++ * ======== DISP_Init ======== ++ * Initialize the DISP module. ++ */ ++bool DISP_Init(void) ++{ ++ bool fRetVal = true; ++ ++ DBC_Require(cRefs >= 0); ++ ++ if (cRefs == 0) { ++ DBC_Assert(!DISP_DebugMask.flags); ++ GT_create(&DISP_DebugMask, "DI"); /* "DI" for DIspatcher */ ++ } ++ ++ if (fRetVal) ++ cRefs++; ++ ++ GT_1trace(DISP_DebugMask, GT_5CLASS, ++ "DISP_Init(), ref count: 0x%x\n", cRefs); ++ ++ DBC_Ensure((fRetVal && (cRefs > 0)) || (!fRetVal && (cRefs >= 0))); ++ return fRetVal; ++} ++ ++/* ++ * ======== DISP_NodeChangePriority ======== ++ * Change the priority of a node currently running on the target. ++ */ ++DSP_STATUS DISP_NodeChangePriority(struct DISP_OBJECT *hDisp, ++ struct NODE_OBJECT *hNode, ++ u32 ulRMSFxn, NODE_ENV nodeEnv, ++ s32 nPriority) ++{ ++ u32 dwArg; ++ struct RMS_Command *pCommand; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(hDisp, DISP_SIGNATURE)); ++ DBC_Require(hNode != NULL); ++ ++ GT_5trace(DISP_DebugMask, GT_ENTER, "DISP_NodeChangePriority: hDisp: " ++ "0x%x\thNode: 0x%x\tulRMSFxn: 0x%x\tnodeEnv: 0x%x\tnPriority\n", ++ hDisp, hNode, ulRMSFxn, nodeEnv, nPriority); ++ ++ /* Send message to RMS to change priority */ ++ pCommand = (struct RMS_Command *)(hDisp->pBuf); ++ pCommand->fxn = (RMS_WORD)(ulRMSFxn); ++ pCommand->arg1 = (RMS_WORD)nodeEnv; ++ pCommand->arg2 = nPriority; ++ status = SendMessage(hDisp, NODE_GetTimeout(hNode), ++ sizeof(struct RMS_Command), &dwArg); ++ if (DSP_FAILED(status)) { ++ GT_1trace(DISP_DebugMask, GT_6CLASS, ++ "DISP_NodeChangePriority failed! " ++ "status = 0x%x\n", status); ++ } ++ return status; ++} ++ ++/* ++ * ======== DISP_NodeCreate ======== ++ * Create a node on the DSP by remotely calling the node's create function. ++ */ ++DSP_STATUS DISP_NodeCreate(struct DISP_OBJECT *hDisp, struct NODE_OBJECT *hNode, ++ u32 ulRMSFxn, u32 ulCreateFxn, ++ IN CONST struct NODE_CREATEARGS *pArgs, ++ OUT NODE_ENV *pNodeEnv) ++{ ++ struct NODE_MSGARGS msgArgs; ++ struct NODE_TASKARGS taskArgs; ++ struct RMS_Command *pCommand; ++ struct RMS_MsgArgs *pMsgArgs; ++ struct RMS_MoreTaskArgs *pMoreTaskArgs; ++ enum NODE_TYPE nodeType; ++ u32 dwLength; ++ RMS_WORD *pdwBuf = NULL; ++ u32 ulBytes; ++ u32 i; ++ u32 total; ++ u32 uCharsInRMSWord; ++ s32 taskArgsOffset; ++ s32 sioInDefOffset; ++ s32 sioOutDefOffset; ++ s32 sioDefsOffset; ++ s32 argsOffset = -1; ++ s32 offset; ++ struct NODE_STRMDEF strmDef; ++ u32 max; ++ DSP_STATUS status = DSP_SOK; ++ struct DSP_NODEINFO nodeInfo; ++ u32 devType; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(hDisp, DISP_SIGNATURE)); ++ DBC_Require(hNode != NULL); ++ DBC_Require(NODE_GetType(hNode) != NODE_DEVICE); ++ DBC_Require(pNodeEnv != NULL); ++ ++ GT_6trace(DISP_DebugMask, GT_ENTER, ++ "DISP_NodeCreate: hDisp: 0x%x\thNode:" ++ " 0x%x\tulRMSFxn: 0x%x\tulCreateFxn: 0x%x\tpArgs: 0x%x\tpNodeEnv:" ++ " 0x%x\n", hDisp, hNode, ulRMSFxn, ulCreateFxn, pArgs, pNodeEnv); ++ ++ status = DEV_GetDevType(hDisp->hDevObject, &devType); ++ ++ GT_1trace(DISP_DebugMask, GT_6CLASS, "DISP_Create: Creating DISP " ++ "for device = 0x%x\n", devType); ++ ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ if (devType != DSP_UNIT) { ++ GT_1trace(DISP_DebugMask, GT_7CLASS, ++ "DISP_NodeCreate unknown device " ++ "type = 0x%x\n", devType); ++ goto func_end; ++ } ++ DBC_Require(pArgs != NULL); ++ nodeType = NODE_GetType(hNode); ++ msgArgs = pArgs->asa.msgArgs; ++ max = hDisp->ulBufsizeRMS; /*Max # of RMS words that can be sent */ ++ DBC_Assert(max == RMS_COMMANDBUFSIZE); ++ uCharsInRMSWord = sizeof(RMS_WORD) / hDisp->uCharSize; ++ /* Number of RMS words needed to hold arg data */ ++ dwLength = (msgArgs.uArgLength + uCharsInRMSWord - 1) / uCharsInRMSWord; ++ /* Make sure msg args and command fit in buffer */ ++ total = sizeof(struct RMS_Command) / sizeof(RMS_WORD) + ++ sizeof(struct RMS_MsgArgs) ++ / sizeof(RMS_WORD) - 1 + dwLength; ++ if (total >= max) { ++ status = DSP_EFAIL; ++ GT_2trace(DISP_DebugMask, GT_6CLASS, ++ "DISP_NodeCreate: Message args too" ++ " large for buffer! Message args size = %d, max = %d\n", ++ total, max); ++ } ++ /* ++ * Fill in buffer to send to RMS. ++ * The buffer will have the following format: ++ * ++ * RMS command: ++ * Address of RMS_CreateNode() ++ * Address of node's create function ++ * dummy argument ++ * node type ++ * ++ * Message Args: ++ * max number of messages ++ * segid for message buffer allocation ++ * notification type to use when message is received ++ * length of message arg data ++ * message args data ++ * ++ * Task Args (if task or socket node): ++ * priority ++ * stack size ++ * system stack size ++ * stack segment ++ * misc ++ * number of input streams ++ * pSTRMInDef[] - offsets of STRM definitions for input streams ++ * number of output streams ++ * pSTRMOutDef[] - offsets of STRM definitions for output ++ * streams ++ * STRMInDef[] - array of STRM definitions for input streams ++ * STRMOutDef[] - array of STRM definitions for output streams ++ * ++ * Socket Args (if DAIS socket node): ++ * ++ */ ++ if (DSP_SUCCEEDED(status)) { ++ total = 0; /* Total number of words in buffer so far */ ++ pdwBuf = (RMS_WORD *)hDisp->pBuf; ++ pCommand = (struct RMS_Command *)pdwBuf; ++ pCommand->fxn = (RMS_WORD)(ulRMSFxn); ++ pCommand->arg1 = (RMS_WORD)(ulCreateFxn); ++ if (NODE_GetLoadType(hNode) == NLDR_DYNAMICLOAD) { ++ /* Flush ICACHE on Load */ ++ pCommand->arg2 = 1; /* dummy argument */ ++ } else { ++ /* Do not flush ICACHE */ ++ pCommand->arg2 = 0; /* dummy argument */ ++ } ++ pCommand->data = NODE_GetType(hNode); ++ /* ++ * argsOffset is the offset of the data field in struct ++ * RMS_Command structure. We need this to calculate stream ++ * definition offsets. ++ */ ++ argsOffset = 3; ++ total += sizeof(struct RMS_Command) / sizeof(RMS_WORD); ++ /* Message args */ ++ pMsgArgs = (struct RMS_MsgArgs *) (pdwBuf + total); ++ pMsgArgs->maxMessages = msgArgs.uMaxMessages; ++ pMsgArgs->segid = msgArgs.uSegid; ++ pMsgArgs->notifyType = msgArgs.uNotifyType; ++ pMsgArgs->argLength = msgArgs.uArgLength; ++ total += sizeof(struct RMS_MsgArgs) / sizeof(RMS_WORD) - 1; ++ memcpy(pdwBuf + total, msgArgs.pData, msgArgs.uArgLength); ++ total += dwLength; ++ } ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ /* If node is a task node, copy task create arguments into buffer */ ++ if (nodeType == NODE_TASK || nodeType == NODE_DAISSOCKET) { ++ taskArgs = pArgs->asa.taskArgs; ++ taskArgsOffset = total; ++ total += sizeof(struct RMS_MoreTaskArgs) / sizeof(RMS_WORD) + ++ 1 + taskArgs.uNumInputs + taskArgs.uNumOutputs; ++ /* Copy task arguments */ ++ if (total < max) { ++ total = taskArgsOffset; ++ pMoreTaskArgs = (struct RMS_MoreTaskArgs *)(pdwBuf + ++ total); ++ /* ++ * Get some important info about the node. Note that we ++ * don't just reach into the hNode struct because ++ * that would break the node object's abstraction. ++ */ ++ GetNodeInfo(hNode, &nodeInfo); ++ GT_2trace(DISP_DebugMask, GT_ENTER, ++ "uExecutionPriority %x, nPriority %x\n", ++ nodeInfo.uExecutionPriority, ++ taskArgs.nPriority); ++ pMoreTaskArgs->priority = nodeInfo.uExecutionPriority; ++ pMoreTaskArgs->stackSize = taskArgs.uStackSize; ++ pMoreTaskArgs->sysstackSize = taskArgs.uSysStackSize; ++ pMoreTaskArgs->stackSeg = taskArgs.uStackSeg; ++ pMoreTaskArgs->heapAddr = taskArgs.uDSPHeapAddr; ++ pMoreTaskArgs->heapSize = taskArgs.uHeapSize; ++ pMoreTaskArgs->misc = taskArgs.ulDaisArg; ++ pMoreTaskArgs->numInputStreams = taskArgs.uNumInputs; ++ total += ++ sizeof(struct RMS_MoreTaskArgs) / sizeof(RMS_WORD); ++ GT_2trace(DISP_DebugMask, GT_7CLASS, ++ "DISP::::uDSPHeapAddr %x, " ++ "uHeapSize %x\n", taskArgs.uDSPHeapAddr, ++ taskArgs.uHeapSize); ++ /* Keep track of pSIOInDef[] and pSIOOutDef[] ++ * positions in the buffer, since this needs to be ++ * filled in later. */ ++ sioInDefOffset = total; ++ total += taskArgs.uNumInputs; ++ pdwBuf[total++] = taskArgs.uNumOutputs; ++ sioOutDefOffset = total; ++ total += taskArgs.uNumOutputs; ++ sioDefsOffset = total; ++ /* Fill SIO defs and offsets */ ++ offset = sioDefsOffset; ++ for (i = 0; i < taskArgs.uNumInputs; i++) { ++ if (DSP_FAILED(status)) ++ break; ++ ++ pdwBuf[sioInDefOffset + i] = ++ (offset - argsOffset) ++ * (sizeof(RMS_WORD) / DSPWORDSIZE); ++ strmDef = taskArgs.strmInDef[i]; ++ status = FillStreamDef(pdwBuf, &total, offset, ++ strmDef, max, uCharsInRMSWord); ++ offset = total; ++ } ++ for (i = 0; (i < taskArgs.uNumOutputs) && ++ (DSP_SUCCEEDED(status)); i++) { ++ pdwBuf[sioOutDefOffset + i] = ++ (offset - argsOffset) ++ * (sizeof(RMS_WORD) / DSPWORDSIZE); ++ strmDef = taskArgs.strmOutDef[i]; ++ status = FillStreamDef(pdwBuf, &total, offset, ++ strmDef, max, uCharsInRMSWord); ++ offset = total; ++ } ++ if (DSP_FAILED(status)) { ++ GT_2trace(DISP_DebugMask, GT_6CLASS, ++ "DISP_NodeCreate: Message" ++ " args to large for buffer! Message args" ++ " size = %d, max = %d\n", total, max); ++ } ++ } else { ++ /* Args won't fit */ ++ status = DSP_EFAIL; ++ GT_2trace(DISP_DebugMask, GT_6CLASS, ++ "DISP_NodeCreate: Message args " ++ " too large for buffer! Message args size = %d" ++ ", max = %d\n", total, max); ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ ulBytes = total * sizeof(RMS_WORD); ++ DBC_Assert(ulBytes < (RMS_COMMANDBUFSIZE * sizeof(RMS_WORD))); ++ status = SendMessage(hDisp, NODE_GetTimeout(hNode), ++ ulBytes, pNodeEnv); ++ if (DSP_FAILED(status)) { ++ GT_1trace(DISP_DebugMask, GT_6CLASS, ++ "DISP_NodeCreate failed! " ++ "status = 0x%x\n", status); ++ } else { ++ /* ++ * Message successfully received from RMS. ++ * Return the status of the Node's create function ++ * on the DSP-side ++ */ ++ status = (((RMS_WORD *)(hDisp->pBuf))[0]); ++ if (DSP_FAILED(status)) { ++ GT_1trace(DISP_DebugMask, GT_6CLASS, ++ "DISP_NodeCreate, " ++ "DSP-side Node Create failed: 0x%x\n", ++ status); ++ } ++ ++ } ++ } ++func_end: ++ return status; ++} ++ ++/* ++ * ======== DISP_NodeDelete ======== ++ * purpose: ++ * Delete a node on the DSP by remotely calling the node's delete function. ++ * ++ */ ++DSP_STATUS DISP_NodeDelete(struct DISP_OBJECT *hDisp, struct NODE_OBJECT *hNode, ++ u32 ulRMSFxn, u32 ulDeleteFxn, NODE_ENV nodeEnv) ++{ ++ u32 dwArg; ++ struct RMS_Command *pCommand; ++ DSP_STATUS status = DSP_SOK; ++ u32 devType; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(hDisp, DISP_SIGNATURE)); ++ DBC_Require(hNode != NULL); ++ ++ GT_5trace(DISP_DebugMask, GT_ENTER, ++ "DISP_NodeDelete: hDisp: 0x%xthNode: " ++ "0x%x\tulRMSFxn: 0x%x\tulDeleteFxn: 0x%x\tnodeEnv: 0x%x\n", ++ hDisp, hNode, ulRMSFxn, ulDeleteFxn, nodeEnv); ++ ++ status = DEV_GetDevType(hDisp->hDevObject, &devType); ++ ++ if (DSP_SUCCEEDED(status)) { ++ ++ if (devType == DSP_UNIT) { ++ ++ /* ++ * Fill in buffer to send to RMS ++ */ ++ pCommand = (struct RMS_Command *)hDisp->pBuf; ++ pCommand->fxn = (RMS_WORD)(ulRMSFxn); ++ pCommand->arg1 = (RMS_WORD)nodeEnv; ++ pCommand->arg2 = (RMS_WORD)(ulDeleteFxn); ++ pCommand->data = NODE_GetType(hNode); ++ ++ status = SendMessage(hDisp, NODE_GetTimeout(hNode), ++ sizeof(struct RMS_Command), &dwArg); ++ if (DSP_FAILED(status)) { ++ GT_1trace(DISP_DebugMask, GT_6CLASS, ++ "DISP_NodeDelete failed!" ++ "status = 0x%x\n", status); ++ } else { ++ /* ++ * Message successfully received from RMS. ++ * Return the status of the Node's delete ++ * function on the DSP-side ++ */ ++ status = (((RMS_WORD *)(hDisp->pBuf))[0]); ++ if (DSP_FAILED(status)) { ++ GT_1trace(DISP_DebugMask, GT_6CLASS, ++ "DISP_NodeDelete, " ++ "DSP-side Node Delete failed: 0x%x\n", ++ status); ++ } ++ } ++ ++ ++ } ++ } ++ return status; ++} ++ ++/* ++ * ======== DISP_NodeRun ======== ++ * purpose: ++ * Start execution of a node's execute phase, or resume execution of a node ++ * that has been suspended (via DISP_NodePause()) on the DSP. ++ */ ++DSP_STATUS DISP_NodeRun(struct DISP_OBJECT *hDisp, struct NODE_OBJECT *hNode, ++ u32 ulRMSFxn, u32 ulExecuteFxn, NODE_ENV nodeEnv) ++{ ++ u32 dwArg; ++ struct RMS_Command *pCommand; ++ DSP_STATUS status = DSP_SOK; ++ u32 devType; ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(hDisp, DISP_SIGNATURE)); ++ DBC_Require(hNode != NULL); ++ ++ GT_5trace(DISP_DebugMask, GT_ENTER, "DISP_NodeRun: hDisp: 0x%xthNode: \ ++ 0x%x\tulRMSFxn: 0x%x\tulExecuteFxn: 0x%x\tnodeEnv: 0x%x\n", \ ++ hDisp, hNode, ulRMSFxn, ulExecuteFxn, nodeEnv); ++ ++ status = DEV_GetDevType(hDisp->hDevObject, &devType); ++ ++ if (DSP_SUCCEEDED(status)) { ++ ++ if (devType == DSP_UNIT) { ++ ++ /* ++ * Fill in buffer to send to RMS. ++ */ ++ pCommand = (struct RMS_Command *) hDisp->pBuf; ++ pCommand->fxn = (RMS_WORD) (ulRMSFxn); ++ pCommand->arg1 = (RMS_WORD) nodeEnv; ++ pCommand->arg2 = (RMS_WORD) (ulExecuteFxn); ++ pCommand->data = NODE_GetType(hNode); ++ ++ status = SendMessage(hDisp, NODE_GetTimeout(hNode), ++ sizeof(struct RMS_Command), &dwArg); ++ if (DSP_FAILED(status)) { ++ GT_1trace(DISP_DebugMask, GT_6CLASS, ++ "DISP_NodeRun failed!" ++ "status = 0x%x\n", status); ++ } else { ++ /* ++ * Message successfully received from RMS. ++ * Return the status of the Node's execute ++ * function on the DSP-side ++ */ ++ status = (((RMS_WORD *)(hDisp->pBuf))[0]); ++ if (DSP_FAILED(status)) { ++ GT_1trace(DISP_DebugMask, GT_6CLASS, ++ "DISP_NodeRun, DSP-side Node " ++ "Execute failed: 0x%x\n", ++ status); ++ } ++ } ++ ++ } ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== DeleteDisp ======== ++ * purpose: ++ * Frees the resources allocated for the dispatcher. ++ */ ++static void DeleteDisp(struct DISP_OBJECT *hDisp) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ ++ if (MEM_IsValidHandle(hDisp, DISP_SIGNATURE)) { ++ pIntfFxns = hDisp->pIntfFxns; ++ ++ /* Free Node Dispatcher resources */ ++ if (hDisp->hChnlFromDsp) { ++ /* Channel close can fail only if the channel handle ++ * is invalid. */ ++ status = (*pIntfFxns->pfnChnlClose) ++ (hDisp->hChnlFromDsp); ++ if (DSP_FAILED(status)) { ++ GT_1trace(DISP_DebugMask, GT_6CLASS, ++ "DISP_Delete: Failed to " ++ "close channel from RMS: 0x%x\n", ++ status); ++ } ++ } ++ if (hDisp->hChnlToDsp) { ++ status = (*pIntfFxns->pfnChnlClose)(hDisp->hChnlToDsp); ++ if (DSP_FAILED(status)) { ++ GT_1trace(DISP_DebugMask, GT_6CLASS, ++ "DISP_Delete: Failed to " ++ "close channel to RMS: 0x%x\n", ++ status); ++ } ++ } ++ if (hDisp->pBuf) ++ MEM_Free(hDisp->pBuf); ++ ++ MEM_FreeObject(hDisp); ++ } ++} ++ ++/* ++ * ======== FillStreamDef ======== ++ * purpose: ++ * Fills stream definitions. ++ */ ++static DSP_STATUS FillStreamDef(RMS_WORD *pdwBuf, u32 *ptotal, u32 offset, ++ struct NODE_STRMDEF strmDef, u32 max, ++ u32 uCharsInRMSWord) ++{ ++ struct RMS_StrmDef *pStrmDef; ++ u32 total = *ptotal; ++ u32 uNameLen; ++ u32 dwLength; ++ DSP_STATUS status = DSP_SOK; ++ ++ if (total + sizeof(struct RMS_StrmDef) / sizeof(RMS_WORD) >= max) { ++ status = DSP_EFAIL; ++ } else { ++ pStrmDef = (struct RMS_StrmDef *)(pdwBuf + total); ++ pStrmDef->bufsize = strmDef.uBufsize; ++ pStrmDef->nbufs = strmDef.uNumBufs; ++ pStrmDef->segid = strmDef.uSegid; ++ pStrmDef->align = strmDef.uAlignment; ++ pStrmDef->timeout = strmDef.uTimeout; ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* ++ * Since we haven't added the device name yet, subtract ++ * 1 from total. ++ */ ++ total += sizeof(struct RMS_StrmDef) / sizeof(RMS_WORD) - 1; ++ DBC_Require(strmDef.szDevice); ++ dwLength = strlen(strmDef.szDevice) + 1; ++ ++ /* Number of RMS_WORDS needed to hold device name */ ++ uNameLen = (dwLength + uCharsInRMSWord - 1) / uCharsInRMSWord; ++ ++ if (total + uNameLen >= max) { ++ status = DSP_EFAIL; ++ } else { ++ /* ++ * Zero out last word, since the device name may not ++ * extend to completely fill this word. ++ */ ++ pdwBuf[total + uNameLen - 1] = 0; ++ /** TODO USE SERVICES **/ ++ memcpy(pdwBuf + total, strmDef.szDevice, dwLength); ++ total += uNameLen; ++ *ptotal = total; ++ } ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== SendMessage ====== ++ * Send command message to RMS, get reply from RMS. ++ */ ++static DSP_STATUS SendMessage(struct DISP_OBJECT *hDisp, u32 dwTimeout, ++ u32 ulBytes, u32 *pdwArg) ++{ ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ struct CHNL_OBJECT *hChnl; ++ u32 dwArg = 0; ++ u8 *pBuf; ++ struct CHNL_IOC chnlIOC; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(pdwArg != NULL); ++ ++ *pdwArg = (u32) NULL; ++ pIntfFxns = hDisp->pIntfFxns; ++ hChnl = hDisp->hChnlToDsp; ++ pBuf = hDisp->pBuf; ++ ++ /* Send the command */ ++ status = (*pIntfFxns->pfnChnlAddIOReq) (hChnl, pBuf, ulBytes, 0, ++ 0L, dwArg); ++ ++ if (DSP_FAILED(status)) { ++ GT_1trace(DISP_DebugMask, GT_6CLASS, ++ "SendMessage: Channel AddIOReq to" ++ " RMS failed! Status = 0x%x\n", status); ++ goto func_cont; ++ } ++ status = (*pIntfFxns->pfnChnlGetIOC) (hChnl, dwTimeout, &chnlIOC); ++ if (DSP_SUCCEEDED(status)) { ++ if (!CHNL_IsIOComplete(chnlIOC)) { ++ if (CHNL_IsTimedOut(chnlIOC)) { ++ status = DSP_ETIMEOUT; ++ } else { ++ GT_1trace(DISP_DebugMask, GT_6CLASS, ++ "SendMessage failed! " ++ "Channel IOC status = 0x%x\n", ++ chnlIOC.status); ++ status = DSP_EFAIL; ++ } ++ } ++ } else { ++ GT_1trace(DISP_DebugMask, GT_6CLASS, ++ "SendMessage: Channel GetIOC to" ++ " RMS failed! Status = 0x%x\n", status); ++ } ++func_cont: ++ /* Get the reply */ ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ hChnl = hDisp->hChnlFromDsp; ++ ulBytes = REPLYSIZE; ++ status = (*pIntfFxns->pfnChnlAddIOReq)(hChnl, pBuf, ulBytes, ++ 0, 0L, dwArg); ++ if (DSP_FAILED(status)) { ++ GT_1trace(DISP_DebugMask, GT_6CLASS, ++ "SendMessage: Channel AddIOReq " ++ "from RMS failed! Status = 0x%x\n", status); ++ goto func_end; ++ } ++ status = (*pIntfFxns->pfnChnlGetIOC) (hChnl, dwTimeout, &chnlIOC); ++ if (DSP_SUCCEEDED(status)) { ++ if (CHNL_IsTimedOut(chnlIOC)) { ++ status = DSP_ETIMEOUT; ++ } else if (chnlIOC.cBytes < ulBytes) { ++ /* Did not get all of the reply from the RMS */ ++ GT_1trace(DISP_DebugMask, GT_6CLASS, ++ "SendMessage: Did not get all" ++ "of reply from RMS! Bytes received: %d\n", ++ chnlIOC.cBytes); ++ status = DSP_EFAIL; ++ } else { ++ if (CHNL_IsIOComplete(chnlIOC)) { ++ DBC_Assert(chnlIOC.pBuf == pBuf); ++ status = (*((RMS_WORD *)chnlIOC.pBuf)); ++ *pdwArg = (((RMS_WORD *)(chnlIOC.pBuf))[1]); ++ } else { ++ status = DSP_EFAIL; ++ } ++ } ++ } else { ++ /* GetIOC failed */ ++ GT_1trace(DISP_DebugMask, GT_6CLASS, ++ "SendMessage: Failed to get " ++ "reply from RMS! Status = 0x%x\n", status); ++ } ++func_end: ++ return status; ++} +diff --git a/drivers/dsp/bridge/rmgr/drv.c b/drivers/dsp/bridge/rmgr/drv.c +new file mode 100644 +index 0000000..256ce12 +--- /dev/null ++++ b/drivers/dsp/bridge/rmgr/drv.c +@@ -0,0 +1,1893 @@ ++/* ++ * drv.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== drv.c ======== ++ * Description: ++ * DSP/BIOS Bridge resource allocation module. ++ * ++ * Public Functions: ++ * DRV_Create ++ * DRV_Destroy ++ * DRV_Exit ++ * DRV_GetDevObject ++ * DRV_GetDevExtension ++ * DRV_GetFirstDevObject ++ * DRV_GetNextDevObject ++ * DRV_GetNextDevExtension ++ * DRV_Init ++ * DRV_InsertDevObject ++ * DRV_RemoveDevObject ++ * DRV_RequestResources ++ * DRV_ReleaseResources ++ * ++ *! Revision History ++ *! ======== ======== ++ *! 19-Apr-2004 sb: Replaced OS specific APIs with MEM_AllocPhysMem and ++ MEM_FreePhysMem. Fixed warnings. Cosmetic updates. ++ *! 12-Apr-2004 hp: IVA clean up during bridge-uninstall ++ *! 05-Jan-2004 vp: Updated for 24xx platform ++ *! 21-Mar-2003 sb: Get SHM size from registry ++ *! 10-Feb-2003 vp: Code review updates ++ *! 18-Oct-2002 vp: Ported to Linux platform ++ *! 30-Oct-2000 kc: Modified usage of REG_SetValue. ++ *! 06-Sep-2000 jeh Read channel info into struct CFG_HOSTRES in ++ *! RequestISAResources() ++ *! 21-Sep-2000 rr: numwindows is calculated instead of default value in ++ *! RequestISAResources. ++ *! 07-Aug-2000 rr: static list of dev objects removed. ++ *! 27-Jul-2000 rr: RequestResources split into two(Request and Release) ++ *! Device extension created to hold the DevNodeString. ++ *! 17-Jul-2000 rr: Driver Object holds the list of Device Objects. ++ *! Added DRV_Create, DRV_Destroy, DRV_GetDevObject, ++ *! DRV_GetFirst/NextDevObject, DRV_Insert/RemoveDevObject. ++ *! 09-May-2000 rr: PCI Support is not L301 specific.Use of MEM_Calloc ++ *! instead of MEM_Alloc. ++ *! 28-Mar-2000 rr: PCI Support added. L301 Specific. TBD. ++ *! 03-Feb-2000 rr: GT and Module Init/exit Changes. Merged with kc. ++ *! 19-Jan-2000 rr: DBC_Ensure in RequestPCMCIA moved within PCCARD ifdef ++ *! 29-Dec-1999 rr: PCCard support for any slot.Bus type stored in the ++ *! struct CFG_HOSTRES Structure. ++ *! 17-Dec-1999 rr: if PCCARD_Init fails we return DSP_EFAIL. ++ *! DBC_Ensure checks for sucess and pDevice != NULL ++ *! 11-Dec-1999 ag: #define "Isa" renamed to "IsaBus". ++ *! 09-Dec-1999 rr: windows.h included to remove warnings. ++ *! 02-Dec-1999 rr: struct GT_Mask is with in if DEBUG. Request resources checks ++ *! status while making call to Reg functions. ++ *! 23-Nov-1999 rr: windows.h included ++ *! 19-Nov-1999 rr: DRV_RELEASE bug while setting the registry to zero. ++ *! fixed. ++ *! 12-Nov-1999 rr: RequestResources() reads values from the registry. ++ *! Hardcoded bIRQRegister define removed. ++ *! 05-Nov-1999 rr: Added hardcoded device interrupt. ++ *! 25-Oct-1999 rr: Resource structure removed. Now it uses the Host ++ *! Resource structure directly. ++ *! 15-Oct-1999 rr: Resource Structure modified. See drv.h ++ *! dwBusType taken from the registry.Hard coded ++ *! registry entries removed. ++ *! 05-Oct-1999 rr: Calling DEV_StartDevice moved to wcdce.c. DRV_Register ++ *! MiniDriver has been renamed to DRV_RequestResources. ++ *! DRV_UnRegisterMiniDriver fxn removed. ++ *! 24-Sep-1999 rr: Significant changes to the RegisterMiniDriver fxns. ++ *! Now it is simpler. IT stores the dev node in the ++ *! registry, assign resources and calls the DEV_Start. ++ *! 10-Sep-1999 rr: Register Minidriver modified. ++ *! - Resource structure follows the NT model ++ *! 08-Aug-1999 rr: Adopted for WinCE. Exports Fxns removed. Hull Created. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Others */ ++#include ++ ++/* ----------------------------------- This */ ++#include ++#include ++ ++#ifndef RES_CLEANUP_DISABLE ++#include ++#include ++#include ++#include ++#include ++#include ++#endif ++ ++/* ----------------------------------- Defines, Data Structures, Typedefs */ ++#define SIGNATURE 0x5f52474d /* "DRV_" (in reverse) */ ++ ++struct DRV_OBJECT { ++ u32 dwSignature; ++ struct LST_LIST *devList; ++ struct LST_LIST *devNodeString; ++#ifndef RES_CLEANUP_DISABLE ++ struct PROCESS_CONTEXT *procCtxtList; ++#endif ++}; ++ ++/* ++ * This is the Device Extension. Named with the Prefix ++ * DRV_ since it is living in this module ++ */ ++struct DRV_EXT { ++ struct LST_ELEM link; ++ char szString[MAXREGPATHLENGTH]; ++}; ++ ++/* ----------------------------------- Globals */ ++static s32 cRefs; ++ ++#if GT_TRACE ++extern struct GT_Mask curTrace; ++#endif ++ ++/* ----------------------------------- Function Prototypes */ ++static DSP_STATUS RequestBridgeResources(u32 dwContext, s32 fRequest); ++static DSP_STATUS RequestBridgeResourcesDSP(u32 dwContext, s32 fRequest); ++ ++#ifndef RES_CLEANUP_DISABLE ++/* GPP PROCESS CLEANUP CODE */ ++ ++static DSP_STATUS PrintProcessInformation(void); ++static DSP_STATUS DRV_ProcFreeNodeRes(HANDLE hPCtxt); ++static DSP_STATUS DRV_ProcFreeSTRMRes(HANDLE hPCtxt); ++extern enum NODE_STATE NODE_GetState(HANDLE hNode); ++ ++/* Get the process context list from driver object */ ++ ++/* Set the Process ID */ ++DSP_STATUS DRV_ProcSetPID(HANDLE hPCtxt, s32 hProcess) ++{ ++ struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Assert(hPCtxt != NULL); ++ ++ pCtxt->pid = hProcess; ++ return status; ++} ++ ++ ++/* Getting the head of the process context list */ ++DSP_STATUS DRV_GetProcCtxtList(struct PROCESS_CONTEXT **pPctxt, ++ struct DRV_OBJECT *hDrvObject) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DRV_OBJECT *pDrvObject = (struct DRV_OBJECT *)hDrvObject; ++ ++ DBC_Assert(hDrvObject != NULL); ++ GT_2trace(curTrace, GT_ENTER, ++ "DRV_GetProcCtxtList: 2 *pPctxt:%x, pDrvObject" ++ ":%x", *pPctxt, pDrvObject); ++ *pPctxt = pDrvObject->procCtxtList; ++ GT_2trace(curTrace, GT_ENTER, ++ "DRV_GetProcCtxtList: 3 *pPctxt:%x, pDrvObject" ++ ":%x", *pPctxt, pDrvObject); ++ return status; ++} ++ ++ ++ ++/* Get a particular process context based on process handle (phProcess) */ ++DSP_STATUS DRV_GetProcContext(u32 phProcess, ++ struct DRV_OBJECT *hDrvObject, ++ HANDLE hPCtxt, DSP_HNODE hNode, ++ u32 pMapAddr) ++{ ++ struct PROCESS_CONTEXT **pCtxt = (struct PROCESS_CONTEXT **)hPCtxt; ++ DSP_STATUS status = DSP_SOK; ++ struct PROCESS_CONTEXT *pCtxtList = NULL; ++ struct DRV_OBJECT *pDrvObject = (struct DRV_OBJECT *)hDrvObject; ++ struct NODE_RES_OBJECT *pTempNode2 = NULL; ++ struct NODE_RES_OBJECT *pTempNode = NULL; ++ struct DMM_RES_OBJECT *pTempDMM2 = NULL; ++ struct DMM_RES_OBJECT *pTempDMM = NULL; ++ s32 pCtxtFound = 0; ++ ++ DBC_Assert(pDrvObject != NULL); ++ pCtxtList = pDrvObject->procCtxtList; ++ GT_0trace(curTrace, GT_ENTER, "2DRV_GetProcContext: 2"); ++ while ((pCtxtList != NULL) && (pCtxtList->pid != phProcess)) { ++ pCtxtList = pCtxtList->next; ++ GT_0trace(curTrace, GT_ENTER, "2DRV_GetProcContext: 3"); ++ } ++ if (pCtxtList == NULL) { ++ if (hNode != NULL) { ++ pCtxtList = pDrvObject->procCtxtList; ++ while ((pCtxtList != NULL) && (pCtxtFound == 0)) { ++ pTempNode = pCtxtList->pNodeList; ++ while ((pTempNode != NULL) && ++ (pTempNode->hNode != hNode)) { ++ pTempNode2 = pTempNode; ++ pTempNode = pTempNode->next; ++ } ++ if (pTempNode != NULL) { ++ pCtxtFound = 1; ++ status = DSP_SOK; ++ } else { ++ pCtxtList = pCtxtList->next; ++ } ++ } ++ } else if ((pMapAddr != 0) && (pCtxtFound == 0)) { ++ pCtxtList = pDrvObject->procCtxtList; ++ while ((pCtxtList != NULL) && (pCtxtFound == 0)) { ++ pTempDMM = pCtxtList->pDMMList; ++ while ((pTempDMM != NULL) && ++ (pTempDMM->ulDSPAddr != pMapAddr)) { ++ pTempDMM2 = pTempDMM; ++ pTempDMM = pTempDMM->next; ++ } ++ if (pTempDMM != NULL) { ++ pCtxtFound = 1; ++ status = DSP_SOK; ++ } else { ++ pCtxtList = pCtxtList->next; ++ } ++ } ++ if (pCtxtList == NULL) ++ status = DSP_ENOTFOUND; ++ ++ } ++ } else{ ++ status = DSP_SOK; ++ } ++ GT_0trace(curTrace, GT_ENTER, "2DRV_GetProcContext: 4"); ++ *pCtxt = pCtxtList; ++ return status; ++} ++ ++ ++/* Add a new process context to process context list */ ++DSP_STATUS DRV_InsertProcContext(struct DRV_OBJECT *hDrVObject, HANDLE hPCtxt) ++{ ++ struct PROCESS_CONTEXT **pCtxt = (struct PROCESS_CONTEXT **)hPCtxt; ++ DSP_STATUS status = DSP_SOK; ++ struct PROCESS_CONTEXT *pCtxtList = NULL; ++ struct DRV_OBJECT *hDRVObject; ++ ++ GT_0trace(curTrace, GT_ENTER, "\n In DRV_InsertProcContext\n"); ++ status = CFG_GetObject((u32 *)&hDRVObject, REG_DRV_OBJECT); ++ DBC_Assert(hDRVObject != NULL); ++ *pCtxt = MEM_Calloc(1 * sizeof(struct PROCESS_CONTEXT), MEM_PAGED); ++ GT_0trace(curTrace, GT_ENTER, ++ "\n In DRV_InsertProcContext Calling " ++ "DRV_GetProcCtxtList\n"); ++ DRV_GetProcCtxtList(&pCtxtList, hDRVObject); ++ GT_0trace(curTrace, GT_ENTER, ++ "\n In DRV_InsertProcContext After Calling " ++ "DRV_GetProcCtxtList\n"); ++ if (pCtxtList != NULL) { ++ GT_0trace(curTrace, GT_ENTER, ++ "\n In DRV_InsertProcContext and pCtxt is " ++ "not Null\n"); ++ while (pCtxtList->next != NULL) ++ pCtxtList = pCtxtList->next; ++ ++ pCtxtList->next = *pCtxt; ++ } else { ++ GT_0trace(curTrace, GT_ENTER, ++ "\n In DRV_InsertProcContext and " ++ "pCtxt is Null\n"); ++ hDRVObject->procCtxtList = *pCtxt; ++ } ++ return status; ++} ++ ++/* Delete a process context from process resource context list */ ++DSP_STATUS DRV_RemoveProcContext(struct DRV_OBJECT *hDRVObject, ++ HANDLE hPCtxt, HANDLE hProcess) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct PROCESS_CONTEXT *pCtxt2 = NULL; ++ struct PROCESS_CONTEXT *pTmp = NULL; ++ struct PROCESS_CONTEXT *pCtxtList = NULL; ++ ++ DBC_Assert(hDRVObject != NULL); ++ DRV_GetProcContext((u32)hProcess, hDRVObject, &pCtxt2, NULL, 0); ++ ++ GT_0trace(curTrace, GT_ENTER, "DRV_RemoveProcContext: 12"); ++ DRV_GetProcCtxtList(&pCtxtList, hDRVObject); ++ GT_0trace(curTrace, GT_ENTER, "DRV_RemoveProcContext: 13"); ++ pTmp = pCtxtList; ++ while ((pCtxtList != NULL) && (pCtxtList != pCtxt2)) { ++ pTmp = pCtxtList; ++ pCtxtList = pCtxtList->next; ++ GT_0trace(curTrace, GT_ENTER, ++ "DRV_RemoveProcContext: 2"); ++ } ++ GT_0trace(curTrace, GT_ENTER, "DRV_RemoveProcContext: 3"); ++ if (hDRVObject->procCtxtList == pCtxt2) ++ hDRVObject->procCtxtList = pCtxt2->next; ++ ++ if (pCtxtList == NULL) ++ return DSP_ENOTFOUND; ++ else if (pTmp->next != NULL) ++ pTmp->next = pTmp->next->next; ++ ++ MEM_Free(pCtxt2); ++ GT_0trace(curTrace, GT_ENTER, "DRV_RemoveProcContext: 7"); ++ ++ return status; ++} ++ ++/* Update the state of process context */ ++DSP_STATUS DRV_ProcUpdatestate(HANDLE hPCtxt, enum GPP_PROC_RES_STATE status) ++{ ++ struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; ++ DSP_STATUS status1 = DSP_SOK; ++ if (pCtxt != NULL) { ++ pCtxt->resState = status; ++ } else { ++ GT_0trace(curTrace, GT_ENTER, ++ "DRV_ProcUpdatestate: Failed to update " ++ "process state"); ++ } ++ return status1; ++} ++ ++/* Allocate and add a node resource element ++* This function is called from .Node_Allocate. */ ++DSP_STATUS DRV_InsertNodeResElement(HANDLE hNode, HANDLE hNodeRes, ++ HANDLE hPCtxt) ++{ ++ struct NODE_RES_OBJECT **pNodeRes = (struct NODE_RES_OBJECT **)hNodeRes; ++ struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; ++ DSP_STATUS status = DSP_SOK; ++ struct NODE_RES_OBJECT *pTempNodeRes = NULL; ++ GT_0trace(curTrace, GT_ENTER, "DRV_InsertNodeResElement: 1"); ++ *pNodeRes = (struct NODE_RES_OBJECT *)MEM_Calloc ++ (1 * sizeof(struct NODE_RES_OBJECT), MEM_PAGED); ++ DBC_Assert(hPCtxt != NULL); ++ if ((*pNodeRes == NULL) || (hPCtxt == NULL)) { ++ GT_0trace(curTrace, GT_ENTER, "DRV_InsertNodeResElement: 12"); ++ status = DSP_EHANDLE; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ (*pNodeRes)->hNode = hNode; ++ if (pCtxt->pNodeList != NULL) { ++ pTempNodeRes = pCtxt->pNodeList; ++ while (pTempNodeRes->next != NULL) ++ pTempNodeRes = pTempNodeRes->next; ++ ++ pTempNodeRes->next = *pNodeRes; ++ GT_0trace(curTrace, GT_ENTER, ++ "DRV_InsertNodeResElement: 2"); ++ } else { ++ pCtxt->pNodeList = *pNodeRes; ++ GT_0trace(curTrace, GT_ENTER, ++ "DRV_InsertNodeResElement: 3"); ++ } ++ } ++ GT_0trace(curTrace, GT_ENTER, "DRV_InsertNodeResElement: 4"); ++ return status; ++} ++ ++/* Release all Node resources and its context ++* This is called from .Node_Delete. */ ++DSP_STATUS DRV_RemoveNodeResElement(HANDLE hNodeRes, HANDLE hPCtxt) ++{ ++ struct NODE_RES_OBJECT *pNodeRes = (struct NODE_RES_OBJECT *)hNodeRes; ++ struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; ++ DSP_STATUS status = DSP_SOK; ++ struct NODE_RES_OBJECT *pTempNode2 = pCtxt->pNodeList; ++ struct NODE_RES_OBJECT *pTempNode = pCtxt->pNodeList; ++ ++ DBC_Assert(hPCtxt != NULL); ++ GT_0trace(curTrace, GT_ENTER, "\nDRV_RemoveNodeResElement: 1\n"); ++ while ((pTempNode != NULL) && (pTempNode != pNodeRes)) { ++ pTempNode2 = pTempNode; ++ pTempNode = pTempNode->next; ++ } ++ if (pCtxt->pNodeList == pNodeRes) ++ pCtxt->pNodeList = pNodeRes->next; ++ ++ if (pTempNode == NULL) ++ return DSP_ENOTFOUND; ++ else if (pTempNode2->next != NULL) ++ pTempNode2->next = pTempNode2->next->next; ++ ++ MEM_Free(pTempNode); ++ return status; ++} ++ ++/* Actual Node De-Allocation */ ++static DSP_STATUS DRV_ProcFreeNodeRes(HANDLE hPCtxt) ++{ ++ struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; ++ DSP_STATUS status = DSP_SOK; ++ struct NODE_RES_OBJECT *pNodeList = NULL; ++ struct NODE_RES_OBJECT *pNodeRes = NULL; ++ u32 nState; ++ ++ DBC_Assert(hPCtxt != NULL); ++ pNodeList = pCtxt->pNodeList; ++ while (pNodeList != NULL) { ++ GT_0trace(curTrace, GT_ENTER, "DRV_ProcFreeNodeRes: 1"); ++ pNodeRes = pNodeList; ++ pNodeList = pNodeList->next; ++ if (pNodeRes->nodeAllocated) { ++ nState = NODE_GetState(pNodeRes->hNode) ; ++ GT_1trace(curTrace, GT_5CLASS, ++ "DRV_ProcFreeNodeRes: Node state %x\n", nState); ++ if (nState <= NODE_DELETING) { ++ if ((nState == NODE_RUNNING) || ++ (nState == NODE_PAUSED) || ++ (nState == NODE_TERMINATING)) { ++ GT_1trace(curTrace, GT_5CLASS, ++ "Calling Node_Terminate for Node:" ++ " 0x%x\n", pNodeRes->hNode); ++ status = NODE_Terminate ++ (pNodeRes->hNode, &status); ++ GT_1trace(curTrace, GT_5CLASS, ++ "Calling Node_Delete for Node:" ++ " 0x%x\n", pNodeRes->hNode); ++ status = NODE_Delete(pNodeRes->hNode); ++ GT_1trace(curTrace, GT_5CLASS, ++ "the status after the NodeDelete %x\n", ++ status); ++ } else if ((nState == NODE_ALLOCATED) ++ || (nState == NODE_CREATED)) ++ status = NODE_Delete(pNodeRes->hNode); ++ } ++ } ++ pNodeRes->nodeAllocated = 0; ++ } ++ return status; ++} ++ ++/* Allocate the DMM resource element ++* This is called from Proc_Map. after the actual resource is allocated */ ++DSP_STATUS DRV_InsertDMMResElement(HANDLE hDMMRes, HANDLE hPCtxt) ++{ ++ struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; ++ struct DMM_RES_OBJECT **pDMMRes = (struct DMM_RES_OBJECT **)hDMMRes; ++ DSP_STATUS status = DSP_SOK; ++ struct DMM_RES_OBJECT *pTempDMMRes = NULL; ++ ++ *pDMMRes = (struct DMM_RES_OBJECT *) ++ MEM_Calloc(1 * sizeof(struct DMM_RES_OBJECT), MEM_PAGED); ++ DBC_Assert(hPCtxt != NULL); ++ GT_0trace(curTrace, GT_ENTER, "DRV_InsertDMMResElement: 1"); ++ if ((*pDMMRes == NULL) || (hPCtxt == NULL)) { ++ GT_0trace(curTrace, GT_5CLASS, "DRV_InsertDMMResElement: 2"); ++ status = DSP_EHANDLE; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ if (pCtxt->pDMMList != NULL) { ++ GT_0trace(curTrace, GT_5CLASS, ++ "DRV_InsertDMMResElement: 3"); ++ pTempDMMRes = pCtxt->pDMMList; ++ while (pTempDMMRes->next != NULL) ++ pTempDMMRes = pTempDMMRes->next; ++ ++ pTempDMMRes->next = *pDMMRes; ++ } else { ++ pCtxt->pDMMList = *pDMMRes; ++ GT_0trace(curTrace, GT_5CLASS, ++ "DRV_InsertDMMResElement: 4"); ++ } ++ } ++ GT_0trace(curTrace, GT_ENTER, "DRV_InsertDMMResElement: 5"); ++ return status; ++} ++ ++ ++ ++/* Release DMM resource element context ++* This is called from Proc_UnMap. after the actual resource is freed */ ++DSP_STATUS DRV_RemoveDMMResElement(HANDLE hDMMRes, HANDLE hPCtxt) ++{ ++ struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; ++ struct DMM_RES_OBJECT *pDMMRes = (struct DMM_RES_OBJECT *)hDMMRes; ++ DSP_STATUS status = DSP_SOK; ++ struct DMM_RES_OBJECT *pTempDMMRes2 = NULL; ++ struct DMM_RES_OBJECT *pTempDMMRes = NULL; ++ ++ DBC_Assert(hPCtxt != NULL); ++ pTempDMMRes2 = pCtxt->pDMMList; ++ pTempDMMRes = pCtxt->pDMMList; ++ GT_0trace(curTrace, GT_ENTER, "DRV_RemoveDMMResElement: 1"); ++ while ((pTempDMMRes != NULL) && (pTempDMMRes != pDMMRes)) { ++ GT_0trace(curTrace, GT_ENTER, "DRV_RemoveDMMResElement: 2"); ++ pTempDMMRes2 = pTempDMMRes; ++ pTempDMMRes = pTempDMMRes->next; ++ } ++ GT_0trace(curTrace, GT_ENTER, "DRV_RemoveDMMResElement: 3"); ++ if (pCtxt->pDMMList == pTempDMMRes) ++ pCtxt->pDMMList = pTempDMMRes->next; ++ ++ if (pTempDMMRes == NULL) ++ return DSP_ENOTFOUND; ++ else if (pTempDMMRes2->next != NULL) ++ pTempDMMRes2->next = pTempDMMRes2->next->next; ++ ++ MEM_Free(pDMMRes); ++ GT_0trace(curTrace, GT_ENTER, "DRV_RemoveDMMResElement: 4"); ++ return status; ++} ++ ++/* Update DMM resource status */ ++DSP_STATUS DRV_UpdateDMMResElement(HANDLE hDMMRes, u32 pMpuAddr, u32 ulSize, ++ u32 pReqAddr, u32 pMapAddr, ++ HANDLE hProcessor) ++{ ++ struct DMM_RES_OBJECT *pDMMRes = (struct DMM_RES_OBJECT *)hDMMRes; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Assert(hDMMRes != NULL); ++ pDMMRes->ulMpuAddr = pMpuAddr; ++ pDMMRes->ulDSPAddr = pMapAddr; ++ pDMMRes->ulDSPResAddr = pReqAddr; ++ pDMMRes->dmmSize = ulSize; ++ pDMMRes->hProcessor = hProcessor; ++ pDMMRes->dmmAllocated = 1; ++ ++ return status; ++} ++ ++/* Actual DMM De-Allocation */ ++DSP_STATUS DRV_ProcFreeDMMRes(HANDLE hPCtxt) ++{ ++ struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; ++ DSP_STATUS status = DSP_SOK; ++ struct DMM_RES_OBJECT *pDMMList = pCtxt->pDMMList; ++ struct DMM_RES_OBJECT *pDMMRes = NULL; ++ ++ DBC_Assert(hPCtxt != NULL); ++ GT_0trace(curTrace, GT_ENTER, "\nDRV_ProcFreeDMMRes: 1\n"); ++ while (pDMMList != NULL) { ++ pDMMRes = pDMMList; ++ pDMMList = pDMMList->next; ++ if (pDMMRes->dmmAllocated) { ++ status = PROC_UnMap(pDMMRes->hProcessor, ++ (void *)pDMMRes->ulDSPResAddr); ++ status = PROC_UnReserveMemory(pDMMRes->hProcessor, ++ (void *)pDMMRes->ulDSPResAddr); ++ pDMMRes->dmmAllocated = 0; ++ } ++ } ++ return status; ++} ++ ++ ++/* Release all DMM resources and its context ++* This is called from .bridge_release. */ ++DSP_STATUS DRV_RemoveAllDMMResElements(HANDLE hPCtxt) ++{ ++ struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; ++ DSP_STATUS status = DSP_SOK; ++ struct DMM_RES_OBJECT *pTempDMMRes2 = NULL; ++ struct DMM_RES_OBJECT *pTempDMMRes = NULL; ++ ++ DBC_Assert(pCtxt != NULL); ++ DRV_ProcFreeDMMRes(pCtxt); ++ pTempDMMRes = pCtxt->pDMMList; ++ while (pTempDMMRes != NULL) { ++ pTempDMMRes2 = pTempDMMRes; ++ pTempDMMRes = pTempDMMRes->next; ++ MEM_Free(pTempDMMRes2); ++ } ++ pCtxt->pDMMList = NULL; ++ return status; ++} ++ ++DSP_STATUS DRV_GetDMMResElement(u32 pMapAddr, HANDLE hDMMRes, HANDLE hPCtxt) ++{ ++ struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; ++ struct DMM_RES_OBJECT **pDMMRes = (struct DMM_RES_OBJECT **)hDMMRes; ++ DSP_STATUS status = DSP_SOK; ++ struct DMM_RES_OBJECT *pTempDMM2 = NULL; ++ struct DMM_RES_OBJECT *pTempDMM = NULL; ++ ++ DBC_Assert(hPCtxt != NULL); ++ pTempDMM = pCtxt->pDMMList; ++ while ((pTempDMM != NULL) && (pTempDMM->ulDSPAddr != pMapAddr)) { ++ GT_3trace(curTrace, GT_ENTER, ++ "DRV_GetDMMResElement: 2 pTempDMM:%x " ++ "pTempDMM->ulDSPAddr:%x pMapAddr:%x\n", pTempDMM, ++ pTempDMM->ulDSPAddr, pMapAddr); ++ pTempDMM2 = pTempDMM; ++ pTempDMM = pTempDMM->next; ++ } ++ if (pTempDMM != NULL) { ++ GT_0trace(curTrace, GT_ENTER, "DRV_GetDMMResElement: 3"); ++ *pDMMRes = pTempDMM; ++ } else { ++ status = DSP_ENOTFOUND; ++ } GT_0trace(curTrace, GT_ENTER, "DRV_GetDMMResElement: 4"); ++ return status; ++} ++ ++/* Update Node allocation status */ ++void DRV_ProcNodeUpdateStatus(HANDLE hNodeRes, s32 status) ++{ ++ struct NODE_RES_OBJECT *pNodeRes = (struct NODE_RES_OBJECT *)hNodeRes; ++ DBC_Assert(hNodeRes != NULL); ++ pNodeRes->nodeAllocated = status; ++} ++ ++/* Update Node Heap status */ ++void DRV_ProcNodeUpdateHeapStatus(HANDLE hNodeRes, s32 status) ++{ ++ struct NODE_RES_OBJECT *pNodeRes = (struct NODE_RES_OBJECT *)hNodeRes; ++ DBC_Assert(hNodeRes != NULL); ++ pNodeRes->heapAllocated = status; ++} ++ ++/* Release all Node resources and its context ++* This is called from .bridge_release. ++*/ ++DSP_STATUS DRV_RemoveAllNodeResElements(HANDLE hPCtxt) ++{ ++ struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; ++ DSP_STATUS status = DSP_SOK; ++ struct NODE_RES_OBJECT *pTempNode2 = NULL; ++ struct NODE_RES_OBJECT *pTempNode = NULL; ++ ++ DBC_Assert(hPCtxt != NULL); ++ DRV_ProcFreeNodeRes(pCtxt); ++ pTempNode = pCtxt->pNodeList; ++ while (pTempNode != NULL) { ++ pTempNode2 = pTempNode; ++ pTempNode = pTempNode->next; ++ MEM_Free(pTempNode2); ++ } ++ pCtxt->pNodeList = NULL; ++ return status; ++} ++ ++/* Getting the node resource element */ ++ ++DSP_STATUS DRV_GetNodeResElement(HANDLE hNode, HANDLE hNodeRes, HANDLE hPCtxt) ++{ ++ struct NODE_RES_OBJECT **nodeRes = (struct NODE_RES_OBJECT **)hNodeRes; ++ struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; ++ DSP_STATUS status = DSP_SOK; ++ struct NODE_RES_OBJECT *pTempNode2 = NULL; ++ struct NODE_RES_OBJECT *pTempNode = NULL; ++ ++ DBC_Assert(hPCtxt != NULL); ++ pTempNode = pCtxt->pNodeList; ++ GT_0trace(curTrace, GT_ENTER, "DRV_GetNodeResElement: 1"); ++ while ((pTempNode != NULL) && (pTempNode->hNode != hNode)) { ++ pTempNode2 = pTempNode; ++ pTempNode = pTempNode->next; ++ } ++ if (pTempNode != NULL) ++ *nodeRes = pTempNode; ++ else ++ status = DSP_ENOTFOUND; ++ ++ return status; ++} ++ ++ ++ ++/* Allocate the STRM resource element ++* This is called after the actual resource is allocated ++*/ ++DSP_STATUS DRV_ProcInsertSTRMResElement(HANDLE hStreamHandle, HANDLE hSTRMRes, ++ HANDLE hPCtxt) ++{ ++ struct STRM_RES_OBJECT **pSTRMRes = (struct STRM_RES_OBJECT **)hSTRMRes; ++ struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; ++ DSP_STATUS status = DSP_SOK; ++ struct STRM_RES_OBJECT *pTempSTRMRes = NULL; ++ DBC_Assert(hPCtxt != NULL); ++ ++ *pSTRMRes = (struct STRM_RES_OBJECT *) ++ MEM_Calloc(1 * sizeof(struct STRM_RES_OBJECT), MEM_PAGED); ++ if ((*pSTRMRes == NULL) || (hPCtxt == NULL)) { ++ GT_0trace(curTrace, GT_ENTER, "DRV_InsertSTRMResElement: 2"); ++ status = DSP_EHANDLE; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ (*pSTRMRes)->hStream = hStreamHandle; ++ if (pCtxt->pSTRMList != NULL) { ++ GT_0trace(curTrace, GT_ENTER, ++ "DRV_InsertiSTRMResElement: 3"); ++ pTempSTRMRes = pCtxt->pSTRMList; ++ while (pTempSTRMRes->next != NULL) ++ pTempSTRMRes = pTempSTRMRes->next; ++ ++ pTempSTRMRes->next = *pSTRMRes; ++ } else { ++ pCtxt->pSTRMList = *pSTRMRes; ++ GT_0trace(curTrace, GT_ENTER, ++ "DRV_InsertSTRMResElement: 4"); ++ } ++ } ++ return status; ++} ++ ++ ++ ++/* Release Stream resource element context ++* This function called after the actual resource is freed ++*/ ++DSP_STATUS DRV_ProcRemoveSTRMResElement(HANDLE hSTRMRes, HANDLE hPCtxt) ++{ ++ struct STRM_RES_OBJECT *pSTRMRes = (struct STRM_RES_OBJECT *)hSTRMRes; ++ struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; ++ DSP_STATUS status = DSP_SOK; ++ struct STRM_RES_OBJECT *pTempSTRMRes2 = pCtxt->pSTRMList; ++ struct STRM_RES_OBJECT *pTempSTRMRes = pCtxt->pSTRMList; ++ ++ DBC_Assert(hPCtxt != NULL); ++ while ((pTempSTRMRes != NULL) && (pTempSTRMRes != pSTRMRes)) { ++ pTempSTRMRes2 = pTempSTRMRes; ++ pTempSTRMRes = pTempSTRMRes->next; ++ } ++ if (pCtxt->pSTRMList == pTempSTRMRes) ++ pCtxt->pSTRMList = pTempSTRMRes->next; ++ ++ if (pTempSTRMRes == NULL) ++ status = DSP_ENOTFOUND; ++ else if (pTempSTRMRes2->next != NULL) ++ pTempSTRMRes2->next = pTempSTRMRes2->next->next; ++ ++ MEM_Free(pSTRMRes); ++ return status; ++} ++ ++ ++/* Actual Stream De-Allocation */ ++static DSP_STATUS DRV_ProcFreeSTRMRes(HANDLE hPCtxt) ++{ ++ struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; ++ DSP_STATUS status = DSP_SOK; ++ DSP_STATUS status1 = DSP_SOK; ++ u8 **apBuffer = NULL; ++ struct STRM_RES_OBJECT *pSTRMList = NULL; ++ struct STRM_RES_OBJECT *pSTRMRes = NULL; ++ u8 *pBufPtr; ++ u32 ulBytes; ++ u32 dwArg; ++ s32 ulBufSize; ++ ++ ++ DBC_Assert(hPCtxt != NULL); ++ pSTRMList = pCtxt->pSTRMList; ++ while (pSTRMList != NULL) { ++ pSTRMRes = pSTRMList; ++ pSTRMList = pSTRMList->next; ++ if (pSTRMRes->uNumBufs != 0) { ++ apBuffer = MEM_Alloc((pSTRMRes->uNumBufs * ++ sizeof(u8 *)), MEM_NONPAGED); ++ status = STRM_FreeBuffer(pSTRMRes->hStream, apBuffer, ++ pSTRMRes->uNumBufs); ++ MEM_Free(apBuffer); ++ } ++ status = STRM_Close(pSTRMRes->hStream); ++ if (DSP_FAILED(status)) { ++ if (status == DSP_EPENDING) { ++ status = STRM_Reclaim(pSTRMRes->hStream, ++ &pBufPtr, &ulBytes, ++ (u32 *)&ulBufSize, &dwArg); ++ if (DSP_SUCCEEDED(status)) ++ status = STRM_Close(pSTRMRes->hStream); ++ ++ } ++ } ++ } ++ return status1; ++} ++ ++/* Release all Stream resources and its context ++* This is called from .bridge_release. ++*/ ++DSP_STATUS DRV_RemoveAllSTRMResElements(HANDLE hPCtxt) ++{ ++ struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; ++ DSP_STATUS status = DSP_SOK; ++ struct STRM_RES_OBJECT *pTempSTRMRes2 = NULL; ++ struct STRM_RES_OBJECT *pTempSTRMRes = NULL; ++ ++ DBC_Assert(hPCtxt != NULL); ++ DRV_ProcFreeSTRMRes(pCtxt); ++ pTempSTRMRes = pCtxt->pSTRMList; ++ while (pTempSTRMRes != NULL) { ++ pTempSTRMRes2 = pTempSTRMRes; ++ pTempSTRMRes = pTempSTRMRes->next; ++ MEM_Free(pTempSTRMRes2); ++ } ++ pCtxt->pSTRMList = NULL; ++ return status; ++} ++ ++ ++/* Getting the stream resource element */ ++DSP_STATUS DRV_GetSTRMResElement(HANDLE hStrm, HANDLE hSTRMRes, HANDLE hPCtxt) ++{ ++ struct STRM_RES_OBJECT **STRMRes = (struct STRM_RES_OBJECT **)hSTRMRes; ++ struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; ++ DSP_STATUS status = DSP_SOK; ++ struct STRM_RES_OBJECT *pTempSTRM2 = NULL; ++ struct STRM_RES_OBJECT *pTempSTRM = pCtxt->pSTRMList; ++ ++ DBC_Assert(hPCtxt != NULL); ++ while ((pTempSTRM != NULL) && (pTempSTRM->hStream != hStrm)) { ++ GT_0trace(curTrace, GT_ENTER, "DRV_GetSTRMResElement: 2"); ++ pTempSTRM2 = pTempSTRM; ++ pTempSTRM = pTempSTRM->next; ++ } ++ if (pTempSTRM != NULL) { ++ GT_0trace(curTrace, GT_ENTER, "DRV_GetSTRMResElement: 3"); ++ *STRMRes = pTempSTRM; ++ } else { ++ GT_0trace(curTrace, GT_ENTER, "DRV_GetSTRMResElement: 4"); ++ status = DSP_ENOTFOUND; ++ } ++ GT_0trace(curTrace, GT_ENTER, "DRV_GetSTRMResElement: 5"); ++ return status; ++} ++ ++/* Updating the stream resource element */ ++DSP_STATUS DRV_ProcUpdateSTRMRes(u32 uNumBufs, HANDLE hSTRMRes, HANDLE hPCtxt) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct STRM_RES_OBJECT **STRMRes = (struct STRM_RES_OBJECT **)hSTRMRes; ++ ++ DBC_Assert(hPCtxt != NULL); ++ (*STRMRes)->uNumBufs = uNumBufs; ++ return status; ++} ++ ++/* Displaying the resources allocated by a process */ ++DSP_STATUS DRV_ProcDisplayResInfo(u8 *pBuf1, u32 *pSize) ++{ ++ struct PROCESS_CONTEXT *pCtxt = NULL; ++ struct NODE_RES_OBJECT *pNodeRes = NULL; ++ struct DMM_RES_OBJECT *pDMMRes = NULL; ++ struct STRM_RES_OBJECT *pSTRMRes = NULL; ++ struct DSPHEAP_RES_OBJECT *pDSPHEAPRes = NULL; ++ u32 tempCount = 1; ++ HANDLE hDrvObject = NULL; ++ void *pBuf = pBuf1; ++ u8 pTempBuf[250]; ++ u32 tempStrLen = 0, tempStrLen2 = 0; ++ DSP_STATUS status = DSP_SOK; ++ ++ CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT); ++ DRV_GetProcCtxtList(&pCtxt, (struct DRV_OBJECT *)hDrvObject); ++ GT_0trace(curTrace, GT_ENTER, "*********************" ++ "DRV_ProcDisplayResourceInfo:*\n"); ++ while (pCtxt != NULL) { ++ tempStrLen2 = sprintf((char *)pTempBuf, ++ "-------------------------------------" ++ "-----------------------------------\n"); ++ tempStrLen2 += 2; ++ memmove(pBuf+tempStrLen, pTempBuf, tempStrLen2); ++ tempStrLen += tempStrLen2; ++ if (pCtxt->resState == PROC_RES_ALLOCATED) { ++ tempStrLen2 = sprintf((char *)pTempBuf, ++ "GPP Process Resource State: " ++ "pCtxt->resState = PROC_RES_ALLOCATED, " ++ " Process ID: %d\n", pCtxt->pid); ++ tempStrLen2 += 2; ++ memmove(pBuf+tempStrLen, pTempBuf, tempStrLen2); ++ tempStrLen += tempStrLen2; ++ } else { ++ tempStrLen2 = sprintf((char *)pTempBuf, ++ "GPP Resource State: pCtxt->resState" ++ " = PROC_RES_DEALLOCATED, Process ID:%d\n", ++ pCtxt->pid); ++ tempStrLen2 += 2; ++ memmove(pBuf+tempStrLen, pTempBuf, tempStrLen2); ++ tempStrLen += tempStrLen2; ++ } ++ pNodeRes = pCtxt->pNodeList; ++ tempCount = 1; ++ while (pNodeRes != NULL) { ++ GT_2trace(curTrace, GT_ENTER, ++ "DRV_ProcDisplayResourceInfo: #:%d " ++ "pCtxt->pNodeList->hNode:%x\n", ++ tempCount, pNodeRes->hNode); ++ tempStrLen2 = sprintf((char *)pTempBuf, ++ "Node Resource Information: Node #" ++ " %d Node Handle hNode:0X%x\n", ++ tempCount, (u32)pNodeRes->hNode); ++ pNodeRes = pNodeRes->next; ++ tempStrLen2 += 2; ++ memmove(pBuf+tempStrLen, pTempBuf, tempStrLen2); ++ tempStrLen += tempStrLen2; ++ tempCount++; ++ } ++ tempCount = 1; ++ pDSPHEAPRes = pCtxt->pDSPHEAPList; ++ while (pDSPHEAPRes != NULL) { ++ GT_2trace(curTrace, GT_ENTER, ++ "DRV_ProcDisplayResourceInfo: #:%d " ++ "pCtxt->pDSPHEAPRList->ulMpuAddr:%x\n", ++ tempCount, pDSPHEAPRes->ulMpuAddr); ++ tempStrLen2 = sprintf((char *)pTempBuf, ++ "DSP Heap Resource Info: HEAP # %d" ++ " Mapped GPP Address: 0x%x, size: 0x%x\n", ++ tempCount, (u32)pDSPHEAPRes->ulMpuAddr, ++ (u32)pDSPHEAPRes->heapSize); ++ pDSPHEAPRes = pDSPHEAPRes->next; ++ tempStrLen2 += 2; ++ memmove(pBuf+tempStrLen, pTempBuf, tempStrLen2); ++ tempStrLen += tempStrLen2; ++ tempCount++; ++ } ++ tempCount = 1; ++ pDMMRes = pCtxt->pDMMList; ++ while (pDMMRes != NULL) { ++ GT_2trace(curTrace, GT_ENTER, ++ "DRV_ProcDisplayResourceInfo: #:%d " ++ " pCtxt->pDMMList->ulMpuAddr:%x\n", ++ tempCount, ++ pDMMRes->ulMpuAddr); ++ tempStrLen2 = sprintf((char *)pTempBuf, ++ "DMM Resource Info: DMM # %d Mapped" ++ " GPP Address: 0x%x, size: 0x%x\n", ++ tempCount, (u32)pDMMRes->ulMpuAddr, ++ (u32)pDMMRes->dmmSize); ++ pDMMRes = pDMMRes->next; ++ tempStrLen2 += 2; ++ memmove(pBuf+tempStrLen, pTempBuf, tempStrLen2); ++ tempStrLen += tempStrLen2; ++ tempCount++; ++ } ++ tempCount = 1; ++ pSTRMRes = pCtxt->pSTRMList; ++ while (pSTRMRes != NULL) { ++ GT_2trace(curTrace, GT_ENTER, ++ "DRV_ProcDisplayResourceInfo: #:%d " ++ "pCtxt->pSTRMList->hStream:%x\n", tempCount, ++ pSTRMRes->hStream); ++ tempStrLen2 = sprintf((char *)pTempBuf, ++ "Stream Resource info: STRM # %d " ++ "Stream Handle: 0x%x \n", ++ tempCount, (u32)pSTRMRes->hStream); ++ pSTRMRes = pSTRMRes->next; ++ tempStrLen2 += 2; ++ memmove(pBuf+tempStrLen, pTempBuf, tempStrLen2); ++ tempStrLen += tempStrLen2; ++ tempCount++; ++ } ++ pCtxt = pCtxt->next; ++ } ++ *pSize = tempStrLen; ++ status = PrintProcessInformation(); ++ GT_0trace(curTrace, GT_ENTER, "*********************" ++ "DRV_ProcDisplayResourceInfo:**\n"); ++ return status; ++} ++ ++/* ++ * ======== PrintProcessInformation ======== ++ * Purpose: ++ * This function prints the Process's information stored in ++ * the process context list. Some of the information that ++ * it displays is Process's state, Node, Stream, DMM, and ++ * Heap information. ++ */ ++static DSP_STATUS PrintProcessInformation(void) ++{ ++ struct DRV_OBJECT *hDrvObject = NULL; ++ struct PROCESS_CONTEXT *pCtxtList = NULL; ++ struct NODE_RES_OBJECT *pNodeRes = NULL; ++ struct DMM_RES_OBJECT *pDMMRes = NULL; ++ struct STRM_RES_OBJECT *pSTRMRes = NULL; ++ struct DSPHEAP_RES_OBJECT *pDSPHEAPRes = NULL; ++ DSP_STATUS status = DSP_SOK; ++ u32 tempCount; ++ u32 procID; ++ ++ /* Get the Process context list */ ++ CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT); ++ DRV_GetProcCtxtList(&pCtxtList, hDrvObject); ++ GT_0trace(curTrace, GT_4CLASS, "\n### Debug information" ++ " for DSP bridge ##\n"); ++ GT_0trace(curTrace, GT_4CLASS, " \n ###The processes" ++ " information is as follows ### \n") ; ++ GT_0trace(curTrace, GT_4CLASS, " =====================" ++ "============ \n"); ++ /* Go through the entries in the Process context list */ ++ while (pCtxtList != NULL) { ++ GT_1trace(curTrace, GT_4CLASS, "\nThe process" ++ " id is %d\n", pCtxtList->pid); ++ GT_0trace(curTrace, GT_4CLASS, " -------------------" ++ "---------\n"); ++ if (pCtxtList->resState == PROC_RES_ALLOCATED) { ++ GT_0trace(curTrace, GT_4CLASS, " \nThe Process" ++ " is in Allocated state\n"); ++ } else { ++ GT_0trace(curTrace, GT_4CLASS, "\nThe Process" ++ " is in DeAllocated state\n"); ++ } ++ GT_1trace(curTrace, GT_4CLASS, "\nThe hProcessor" ++ " handle is: 0X%x\n", ++ (u32)pCtxtList->hProcessor); ++ if (pCtxtList->hProcessor != NULL) { ++ PROC_GetProcessorId(pCtxtList->hProcessor, &procID); ++ if (procID == DSP_UNIT) { ++ GT_0trace(curTrace, GT_4CLASS, ++ "\nProcess connected to" ++ " DSP Processor\n"); ++ } else if (procID == IVA_UNIT) { ++ GT_0trace(curTrace, GT_4CLASS, ++ "\nProcess connected to" ++ " IVA Processor\n"); ++ } else { ++ GT_0trace(curTrace, GT_7CLASS, ++ "\n***ERROR:Invalid Processor Id***\n"); ++ } ++ } ++ pNodeRes = pCtxtList->pNodeList; ++ tempCount = 1; ++ while (pNodeRes != NULL) { ++ if (tempCount == 1) ++ GT_0trace(curTrace, GT_4CLASS, ++ "\n***The Nodes allocated by" ++ " this Process are***\n"); ++ GT_2trace(curTrace, GT_4CLASS, ++ "Node # %d Node Handle hNode:0x%x\n", ++ tempCount, (u32)pNodeRes->hNode); ++ pNodeRes = pNodeRes->next; ++ tempCount++; ++ } ++ if (tempCount == 1) ++ GT_0trace(curTrace, GT_4CLASS, ++ "\n ***There are no Nodes" ++ " allocated by this Process***\n"); ++ tempCount = 1; ++ pDSPHEAPRes = pCtxtList->pDSPHEAPList; ++ while (pDSPHEAPRes != NULL) { ++ if (tempCount == 1) ++ GT_0trace(curTrace, GT_4CLASS, ++ "\n***The Heaps allocated by" ++ " this Process are***\n"); ++ GT_3trace(curTrace, GT_4CLASS, ++ "DSP Heap Resource Info: HEAP # %d " ++ "Mapped GPP Address:0x%x, Size: 0x%lx\n", ++ tempCount, (u32)pDSPHEAPRes->ulMpuAddr, ++ pDSPHEAPRes->heapSize); ++ pDSPHEAPRes = pDSPHEAPRes->next; ++ tempCount++; ++ } ++ if (tempCount == 1) ++ GT_0trace(curTrace, GT_4CLASS, ++ "\n ***There are no Heaps allocated" ++ " by this Process***\n"); ++ tempCount = 1; ++ pDMMRes = pCtxtList->pDMMList; ++ while (pDMMRes != NULL) { ++ if (tempCount == 1) ++ GT_0trace(curTrace, GT_4CLASS, ++ "\n ***The DMM resources allocated by" ++ " this Process are***\n"); ++ GT_3trace(curTrace, GT_4CLASS, ++ "DMM Resource Info: DMM # %d " ++ "Mapped GPP Address:0X%lx, Size: 0X%lx\n", ++ tempCount, pDMMRes->ulMpuAddr, ++ pDMMRes->dmmSize); ++ pDMMRes = pDMMRes->next; ++ tempCount++; ++ } ++ if (tempCount == 1) ++ GT_0trace(curTrace, GT_4CLASS, ++ "\n ***There are no DMM resources" ++ " allocated by this Process***\n"); ++ tempCount = 1; ++ pSTRMRes = pCtxtList->pSTRMList; ++ while (pSTRMRes != NULL) { ++ if (tempCount == 1) ++ GT_0trace(curTrace, GT_4CLASS, ++ "\n***The Stream resources allocated by" ++ " this Process are***\n"); ++ GT_2trace(curTrace, GT_4CLASS, ++ "Stream Resource info: STRM # %d" ++ "Stream Handle:0X%x\n", tempCount, ++ (u32)pSTRMRes->hStream); ++ pSTRMRes = pSTRMRes->next; ++ tempCount++; ++ } ++ if (tempCount == 1) ++ GT_0trace(curTrace, GT_4CLASS, ++ "\n ***There are no Stream resources" ++ "allocated by this Process***\n"); ++ pCtxtList = pCtxtList->next; ++ } ++ return status; ++} ++ ++/* GPP PROCESS CLEANUP CODE END */ ++#endif ++ ++/* ++ * ======== = DRV_Create ======== = ++ * Purpose: ++ * DRV Object gets created only once during Driver Loading. ++ */ ++DSP_STATUS DRV_Create(OUT struct DRV_OBJECT **phDRVObject) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DRV_OBJECT *pDRVObject = NULL; ++ ++ DBC_Require(phDRVObject != NULL); ++ DBC_Require(cRefs > 0); ++ GT_1trace(curTrace, GT_ENTER, "Entering DRV_Create" ++ " phDRVObject 0x%x\n", phDRVObject); ++ MEM_AllocObject(pDRVObject, struct DRV_OBJECT, SIGNATURE); ++ if (pDRVObject) { ++ /* Create and Initialize List of device objects */ ++ pDRVObject->devList = LST_Create(); ++ if (pDRVObject->devList) { ++ /* Create and Initialize List of device Extension */ ++ pDRVObject->devNodeString = LST_Create(); ++ if (!(pDRVObject->devNodeString)) { ++ status = DSP_EFAIL; ++ GT_0trace(curTrace, GT_7CLASS, ++ "Failed to Create DRV_EXT list "); ++ MEM_FreeObject(pDRVObject); ++ } ++ } else { ++ status = DSP_EFAIL; ++ GT_0trace(curTrace, GT_7CLASS, ++ "Failed to Create Dev List "); ++ MEM_FreeObject(pDRVObject); ++ } ++ } else { ++ status = DSP_EFAIL; ++ GT_0trace(curTrace, GT_7CLASS, ++ "Failed to Allocate Memory for DRV Obj"); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Store the DRV Object in the Registry */ ++ if (DSP_SUCCEEDED ++ (CFG_SetObject((u32) pDRVObject, REG_DRV_OBJECT))) { ++ GT_1trace(curTrace, GT_1CLASS, ++ "DRV Obj Created pDrvObject 0x%x\n ", ++ pDRVObject); ++ *phDRVObject = pDRVObject; ++ } else { ++ /* Free the DRV Object */ ++ status = DSP_EFAIL; ++ MEM_Free(pDRVObject); ++ GT_0trace(curTrace, GT_7CLASS, ++ "Failed to update the Registry with " ++ "DRV Object "); ++ } ++ } ++ GT_2trace(curTrace, GT_ENTER, ++ "Exiting DRV_Create: phDRVObject: 0x%x\tstatus:" ++ "0x%x\n", phDRVObject, status); ++ DBC_Ensure(DSP_FAILED(status) || ++ MEM_IsValidHandle(pDRVObject, SIGNATURE)); ++ return status; ++} ++ ++/* ++ * ======== DRV_Exit ======== ++ * Purpose: ++ * Discontinue usage of the DRV module. ++ */ ++void DRV_Exit(void) ++{ ++ DBC_Require(cRefs > 0); ++ ++ GT_0trace(curTrace, GT_5CLASS, "Entering DRV_Exit \n"); ++ ++ cRefs--; ++ ++ DBC_Ensure(cRefs >= 0); ++} ++ ++/* ++ * ======== = DRV_Destroy ======== = ++ * purpose: ++ * Invoked during bridge de-initialization ++ */ ++DSP_STATUS DRV_Destroy(struct DRV_OBJECT *hDRVObject) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DRV_OBJECT *pDRVObject = (struct DRV_OBJECT *)hDRVObject; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(pDRVObject, SIGNATURE)); ++ ++ GT_1trace(curTrace, GT_ENTER, "Entering DRV_Destroy" ++ " hDRVObject 0x%x\n", hDRVObject); ++ /* ++ * Delete the List if it exists.Should not come here ++ * as the DRV_RemoveDevObject and the Last DRV_RequestResources ++ * removes the list if the lists are empty. ++ */ ++ if (pDRVObject->devList) { ++ /* Could assert if the list is not empty */ ++ LST_Delete(pDRVObject->devList); ++ } ++ if (pDRVObject->devNodeString) { ++ /* Could assert if the list is not empty */ ++ LST_Delete(pDRVObject->devNodeString); ++ } ++ MEM_FreeObject(pDRVObject); ++ /* Update the DRV Object in Registry to be 0 */ ++ (void)CFG_SetObject(0, REG_DRV_OBJECT); ++ GT_2trace(curTrace, GT_ENTER, ++ "Exiting DRV_Destroy: hDRVObject: 0x%x\tstatus:" ++ "0x%x\n", hDRVObject, status); ++ DBC_Ensure(!MEM_IsValidHandle(pDRVObject, SIGNATURE)); ++ return status; ++} ++ ++/* ++ * ======== DRV_GetDevObject ======== ++ * Purpose: ++ * Given a index, returns a handle to DevObject from the list. ++ */ ++DSP_STATUS DRV_GetDevObject(u32 uIndex, struct DRV_OBJECT *hDrvObject, ++ struct DEV_OBJECT **phDevObject) ++{ ++ DSP_STATUS status = DSP_SOK; ++#if GT_TRACE /* pDrvObject is used only for Assertions and debug messages.*/ ++ struct DRV_OBJECT *pDrvObject = (struct DRV_OBJECT *)hDrvObject; ++#endif ++ struct DEV_OBJECT *pDevObject; ++ u32 i; ++ DBC_Require(MEM_IsValidHandle(pDrvObject, SIGNATURE)); ++ DBC_Require(phDevObject != NULL); ++ DBC_Require(uIndex >= 0); ++ DBC_Require(cRefs > 0); ++ DBC_Assert(!(LST_IsEmpty(pDrvObject->devList))); ++ GT_3trace(curTrace, GT_ENTER, ++ "Entered DRV_GetDevObject, args:\n\tuIndex: " ++ "0x%x\n\thDrvObject: 0x%x\n\tphDevObject: 0x%x\n", ++ uIndex, hDrvObject, phDevObject); ++ pDevObject = (struct DEV_OBJECT *)DRV_GetFirstDevObject(); ++ for (i = 0; i < uIndex; i++) { ++ pDevObject = ++ (struct DEV_OBJECT *)DRV_GetNextDevObject((u32)pDevObject); ++ } ++ if (pDevObject) { ++ *phDevObject = (struct DEV_OBJECT *) pDevObject; ++ status = DSP_SOK; ++ } else { ++ *phDevObject = NULL; ++ status = DSP_EFAIL; ++ GT_0trace(curTrace, GT_7CLASS, ++ "DRV: Could not get the DevObject\n"); ++ } ++ GT_2trace(curTrace, GT_ENTER, ++ "Exiting Drv_GetDevObject\n\tstatus: 0x%x\n\t" ++ "hDevObject: 0x%x\n", status, *phDevObject); ++ return status; ++} ++ ++/* ++ * ======== DRV_GetFirstDevObject ======== ++ * Purpose: ++ * Retrieve the first Device Object handle from an internal linked list of ++ * of DEV_OBJECTs maintained by DRV. ++ */ ++u32 DRV_GetFirstDevObject(void) ++{ ++ u32 dwDevObject = 0; ++ struct DRV_OBJECT *pDrvObject; ++ ++ if (DSP_SUCCEEDED ++ (CFG_GetObject((u32 *)&pDrvObject, REG_DRV_OBJECT))) { ++ if ((pDrvObject->devList != NULL) && ++ !LST_IsEmpty(pDrvObject->devList)) ++ dwDevObject = (u32) LST_First(pDrvObject->devList); ++ } ++ ++ return dwDevObject; ++} ++ ++/* ++ * ======== DRV_GetFirstDevNodeString ======== ++ * Purpose: ++ * Retrieve the first Device Extension from an internal linked list of ++ * of Pointer to DevNode Strings maintained by DRV. ++ */ ++u32 DRV_GetFirstDevExtension(void) ++{ ++ u32 dwDevExtension = 0; ++ struct DRV_OBJECT *pDrvObject; ++ ++ if (DSP_SUCCEEDED ++ (CFG_GetObject((u32 *)&pDrvObject, REG_DRV_OBJECT))) { ++ ++ if ((pDrvObject->devNodeString != NULL) && ++ !LST_IsEmpty(pDrvObject->devNodeString)) { ++ dwDevExtension = (u32)LST_First(pDrvObject-> ++ devNodeString); ++ } ++ } ++ ++ return dwDevExtension; ++} ++ ++/* ++ * ======== DRV_GetNextDevObject ======== ++ * Purpose: ++ * Retrieve the next Device Object handle from an internal linked list of ++ * of DEV_OBJECTs maintained by DRV, after having previously called ++ * DRV_GetFirstDevObject() and zero or more DRV_GetNext. ++ */ ++u32 DRV_GetNextDevObject(u32 hDevObject) ++{ ++ u32 dwNextDevObject = 0; ++ struct DRV_OBJECT *pDrvObject; ++ ++ DBC_Require(hDevObject != 0); ++ ++ if (DSP_SUCCEEDED ++ (CFG_GetObject((u32 *)&pDrvObject, REG_DRV_OBJECT))) { ++ ++ if ((pDrvObject->devList != NULL) && ++ !LST_IsEmpty(pDrvObject->devList)) { ++ dwNextDevObject = (u32)LST_Next(pDrvObject->devList, ++ (struct LST_ELEM *)hDevObject); ++ } ++ } ++ return dwNextDevObject; ++} ++ ++/* ++ * ======== DRV_GetNextDevExtension ======== ++ * Purpose: ++ * Retrieve the next Device Extension from an internal linked list of ++ * of pointer to DevNodeString maintained by DRV, after having previously ++ * called DRV_GetFirstDevExtension() and zero or more ++ * DRV_GetNextDevExtension(). ++ */ ++u32 DRV_GetNextDevExtension(u32 hDevExtension) ++{ ++ u32 dwDevExtension = 0; ++ struct DRV_OBJECT *pDrvObject; ++ ++ DBC_Require(hDevExtension != 0); ++ ++ if (DSP_SUCCEEDED(CFG_GetObject((u32 *)&pDrvObject, ++ REG_DRV_OBJECT))) { ++ if ((pDrvObject->devNodeString != NULL) && ++ !LST_IsEmpty(pDrvObject->devNodeString)) { ++ dwDevExtension = (u32)LST_Next(pDrvObject-> ++ devNodeString, ++ (struct LST_ELEM *)hDevExtension); ++ } ++ } ++ ++ return dwDevExtension; ++} ++ ++/* ++ * ======== DRV_Init ======== ++ * Purpose: ++ * Initialize DRV module private state. ++ */ ++DSP_STATUS DRV_Init(void) ++{ ++ s32 fRetval = 1; /* function return value */ ++ ++ DBC_Require(cRefs >= 0); ++ ++ if (fRetval) ++ cRefs++; ++ ++ GT_1trace(curTrace, GT_5CLASS, "Entering DRV_Entry crefs 0x%x \n", ++ cRefs); ++ ++ DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0))); ++ ++ return fRetval; ++} ++ ++/* ++ * ======== DRV_InsertDevObject ======== ++ * Purpose: ++ * Insert a DevObject into the list of Manager object. ++ */ ++DSP_STATUS DRV_InsertDevObject(struct DRV_OBJECT *hDRVObject, ++ struct DEV_OBJECT *hDevObject) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DRV_OBJECT *pDRVObject = (struct DRV_OBJECT *)hDRVObject; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(hDevObject != NULL); ++ DBC_Require(MEM_IsValidHandle(pDRVObject, SIGNATURE)); ++ DBC_Assert(pDRVObject->devList); ++ ++ GT_2trace(curTrace, GT_ENTER, ++ "Entering DRV_InsertProcObject hDRVObject " ++ "0x%x\n, hDevObject 0x%x\n", hDRVObject, hDevObject); ++ ++ LST_PutTail(pDRVObject->devList, (struct LST_ELEM *)hDevObject); ++ ++ GT_1trace(curTrace, GT_ENTER, ++ "Exiting InsertDevObject status 0x%x\n", status); ++ ++ DBC_Ensure(DSP_SUCCEEDED(status) && !LST_IsEmpty(pDRVObject->devList)); ++ ++ return status; ++} ++ ++/* ++ * ======== DRV_RemoveDevObject ======== ++ * Purpose: ++ * Search for and remove a DeviceObject from the given list of DRV ++ * objects. ++ */ ++DSP_STATUS DRV_RemoveDevObject(struct DRV_OBJECT *hDRVObject, ++ struct DEV_OBJECT *hDevObject) ++{ ++ DSP_STATUS status = DSP_EFAIL; ++ struct DRV_OBJECT *pDRVObject = (struct DRV_OBJECT *)hDRVObject; ++ struct LST_ELEM *pCurElem; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(pDRVObject, SIGNATURE)); ++ DBC_Require(hDevObject != NULL); ++ ++ DBC_Require(pDRVObject->devList != NULL); ++ DBC_Require(!LST_IsEmpty(pDRVObject->devList)); ++ ++ GT_2trace(curTrace, GT_ENTER, ++ "Entering DRV_RemoveDevObject hDevObject " ++ "0x%x\n, hDRVObject 0x%x\n", hDevObject, hDRVObject); ++ /* Search list for pProcObject: */ ++ for (pCurElem = LST_First(pDRVObject->devList); pCurElem != NULL; ++ pCurElem = LST_Next(pDRVObject->devList, pCurElem)) { ++ /* If found, remove it. */ ++ if ((struct DEV_OBJECT *) pCurElem == hDevObject) { ++ LST_RemoveElem(pDRVObject->devList, pCurElem); ++ status = DSP_SOK; ++ break; ++ } ++ } ++ /* Remove list if empty. */ ++ if (LST_IsEmpty(pDRVObject->devList)) { ++ LST_Delete(pDRVObject->devList); ++ pDRVObject->devList = NULL; ++ } ++ DBC_Ensure((pDRVObject->devList == NULL) || ++ !LST_IsEmpty(pDRVObject->devList)); ++ GT_1trace(curTrace, GT_ENTER, ++ "DRV_RemoveDevObject returning 0x%x\n", status); ++ return status; ++} ++ ++/* ++ * ======== DRV_RequestResources ======== ++ * Purpose: ++ * Requests resources from the OS. ++ */ ++DSP_STATUS DRV_RequestResources(u32 dwContext, u32 *pDevNodeString) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DRV_OBJECT *pDRVObject; ++ struct DRV_EXT *pszdevNode; ++ ++ DBC_Require(dwContext != 0); ++ DBC_Require(pDevNodeString != NULL); ++ GT_0trace(curTrace, GT_ENTER, "Entering DRV_RequestResources\n"); ++ /* ++ * Allocate memory to hold the string. This will live untill ++ * it is freed in the Release resources. Update the driver object ++ * list. ++ */ ++ if (DSP_SUCCEEDED(CFG_GetObject((u32 *)&pDRVObject, ++ REG_DRV_OBJECT))) { ++ pszdevNode = MEM_Calloc(sizeof(struct DRV_EXT), MEM_NONPAGED); ++ if (pszdevNode) { ++ LST_InitElem(&pszdevNode->link); ++ strncpy((char *) pszdevNode->szString, ++ (char *)dwContext, MAXREGPATHLENGTH); ++ /* Update the Driver Object List */ ++ *pDevNodeString = (u32)pszdevNode->szString; ++ LST_PutTail(pDRVObject->devNodeString, ++ (struct LST_ELEM *)pszdevNode); ++ } else { ++ GT_0trace(curTrace, GT_7CLASS, ++ "Failed to Allocate Memory devNodeString "); ++ status = DSP_EFAIL; ++ *pDevNodeString = 0; ++ } ++ } else { ++ status = DSP_EFAIL; ++ GT_0trace(curTrace, GT_7CLASS, ++ "Failed to get Driver Object from Registry"); ++ *pDevNodeString = 0; ++ } ++ ++ if (!(strcmp((char *) dwContext, "TIOMAP1510"))) { ++ GT_0trace(curTrace, GT_1CLASS, ++ " Allocating resources for UMA \n"); ++ status = RequestBridgeResourcesDSP(dwContext, DRV_ASSIGN); ++ } else { ++ status = DSP_EFAIL; ++ GT_0trace(curTrace, GT_7CLASS, "Unknown Device "); ++ } ++ ++ if (DSP_FAILED(status)) { ++ GT_0trace(curTrace, GT_7CLASS, ++ "Failed to reserve bridge resources "); ++ } ++ DBC_Ensure((DSP_SUCCEEDED(status) && pDevNodeString != NULL && ++ !LST_IsEmpty(pDRVObject->devNodeString)) || ++ (DSP_FAILED(status) && *pDevNodeString == 0)); ++ ++ return status; ++} ++ ++/* ++ * ======== DRV_ReleaseResources ======== ++ * Purpose: ++ * Releases resources from the OS. ++ */ ++DSP_STATUS DRV_ReleaseResources(u32 dwContext, struct DRV_OBJECT *hDrvObject) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DRV_OBJECT *pDRVObject = (struct DRV_OBJECT *)hDrvObject; ++ struct DRV_EXT *pszdevNode; ++ ++ GT_0trace(curTrace, GT_ENTER, "Entering DRV_Release Resources\n"); ++ ++ if (!(strcmp((char *)((struct DRV_EXT *)dwContext)->szString, ++ "TIOMAP1510"))) { ++ GT_0trace(curTrace, GT_1CLASS, ++ " Releasing DSP-Bridge resources \n"); ++ status = RequestBridgeResources(dwContext, DRV_RELEASE); ++ } else { ++ GT_0trace(curTrace, GT_1CLASS, " Unknown device\n"); ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ GT_0trace(curTrace, GT_1CLASS, ++ "Failed to relese bridge resources\n"); ++ } ++ ++ /* ++ * Irrespective of the status go ahead and clean it ++ * The following will over write the status. ++ */ ++ for (pszdevNode = (struct DRV_EXT *)DRV_GetFirstDevExtension(); ++ pszdevNode != NULL; pszdevNode = (struct DRV_EXT *) ++ DRV_GetNextDevExtension((u32)pszdevNode)) { ++ if ((u32)pszdevNode == dwContext) { ++ /* Found it */ ++ /* Delete from the Driver object list */ ++ LST_RemoveElem(pDRVObject->devNodeString, ++ (struct LST_ELEM *)pszdevNode); ++ MEM_Free((void *) pszdevNode); ++ break; ++ } ++ /* Delete the List if it is empty */ ++ if (LST_IsEmpty(pDRVObject->devNodeString)) { ++ LST_Delete(pDRVObject->devNodeString); ++ pDRVObject->devNodeString = NULL; ++ } ++ } ++ return status; ++} ++ ++/* ++ * ======== RequestBridgeResources ======== ++ * Purpose: ++ * Reserves shared memory for bridge. ++ */ ++static DSP_STATUS RequestBridgeResources(u32 dwContext, s32 bRequest) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct CFG_HOSTRES *pResources; ++ u32 dwBuffSize; ++ ++ struct DRV_EXT *driverExt; ++ u32 shm_size; ++ ++ DBC_Require(dwContext != 0); ++ ++ GT_0trace(curTrace, GT_ENTER, "->RequestBridgeResources \n"); ++ ++ if (!bRequest) { ++ driverExt = (struct DRV_EXT *)dwContext; ++ /* Releasing resources by deleting the registry key */ ++ dwBuffSize = sizeof(struct CFG_HOSTRES); ++ pResources = MEM_Calloc(dwBuffSize, MEM_NONPAGED); ++ if (DSP_FAILED(REG_GetValue(NULL, (char *)driverExt->szString, ++ CURRENTCONFIG, (u8 *)pResources, &dwBuffSize))) { ++ status = CFG_E_RESOURCENOTAVAIL; ++ GT_0trace(curTrace, GT_1CLASS, ++ "REG_GetValue Failed \n"); ++ } else { ++ GT_0trace(curTrace, GT_1CLASS, ++ "REG_GetValue Succeeded \n"); ++ } ++ ++ if (pResources != NULL) { ++ dwBuffSize = sizeof(shm_size); ++ status = REG_GetValue(NULL, CURRENTCONFIG, SHMSIZE, ++ (u8 *)&shm_size, &dwBuffSize); ++ if (DSP_SUCCEEDED(status)) { ++ if ((pResources->dwMemBase[1]) && ++ (pResources->dwMemPhys[1])) { ++ MEM_FreePhysMem((void *)pResources-> ++ dwMemBase[1], pResources->dwMemPhys[1], ++ shm_size); ++ } ++ } else { ++ GT_1trace(curTrace, GT_7CLASS, ++ "Error getting SHM size from registry: " ++ "%x. Not calling MEM_FreePhysMem\n", ++ status); ++ } ++ pResources->dwMemBase[1] = 0; ++ pResources->dwMemPhys[1] = 0; ++ ++ if (pResources->dwPrmBase) ++ iounmap((void *)pResources->dwPrmBase); ++ if (pResources->dwCmBase) ++ iounmap((void *)pResources->dwCmBase); ++ if (pResources->dwMboxBase) ++ iounmap((void *)pResources->dwMboxBase); ++ if (pResources->dwMemBase[0]) ++ iounmap((void *)pResources->dwMemBase[0]); ++ if (pResources->dwMemBase[2]) ++ iounmap((void *)pResources->dwMemBase[2]); ++ if (pResources->dwMemBase[3]) ++ iounmap((void *)pResources->dwMemBase[3]); ++ if (pResources->dwMemBase[4]) ++ iounmap((void *)pResources->dwMemBase[4]); ++ if (pResources->dwWdTimerDspBase) ++ iounmap((void *)pResources->dwWdTimerDspBase); ++ if (pResources->dwDmmuBase) ++ iounmap((void *)pResources->dwDmmuBase); ++ if (pResources->dwPerBase) ++ iounmap((void *)pResources->dwPerBase); ++ if (pResources->dwPerPmBase) ++ iounmap((void *)pResources->dwPerPmBase); ++ if (pResources->dwCorePmBase) ++ iounmap((void *)pResources->dwCorePmBase); ++ if (pResources->dwSysCtrlBase) { ++ iounmap((void *)pResources->dwSysCtrlBase); ++ /* don't set pResources->dwSysCtrlBase to null ++ * as it is used in BOARD_Stop */ ++ } ++ pResources->dwPrmBase = (u32) NULL; ++ pResources->dwCmBase = (u32) NULL; ++ pResources->dwMboxBase = (u32) NULL; ++ pResources->dwMemBase[0] = (u32) NULL; ++ pResources->dwMemBase[2] = (u32) NULL; ++ pResources->dwMemBase[3] = (u32) NULL; ++ pResources->dwMemBase[4] = (u32) NULL; ++ pResources->dwWdTimerDspBase = (u32) NULL; ++ pResources->dwDmmuBase = (u32) NULL; ++ ++ dwBuffSize = sizeof(struct CFG_HOSTRES); ++ status = REG_SetValue(NULL, (char *)driverExt->szString, ++ CURRENTCONFIG, REG_BINARY, (u8 *)pResources, ++ (u32)dwBuffSize); ++ /* Set all the other entries to NULL */ ++ MEM_Free(pResources); ++ } ++ GT_0trace(curTrace, GT_ENTER, " <- RequestBridgeResources \n"); ++ return status; ++ } ++ dwBuffSize = sizeof(struct CFG_HOSTRES); ++ pResources = MEM_Calloc(dwBuffSize, MEM_NONPAGED); ++ if (pResources != NULL) { ++ /* wNumMemWindows must not be more than CFG_MAXMEMREGISTERS */ ++ pResources->wNumMemWindows = 2; ++ /* First window is for DSP internal memory */ ++ ++ pResources->dwPrmBase = (u32)ioremap(OMAP_IVA2_PRM_BASE, ++ OMAP_IVA2_PRM_SIZE); ++ pResources->dwCmBase = (u32)ioremap(OMAP_IVA2_CM_BASE, ++ OMAP_IVA2_CM_SIZE); ++ pResources->dwMboxBase = (u32)ioremap(OMAP_MBOX_BASE, ++ OMAP_MBOX_SIZE); ++ pResources->dwSysCtrlBase = (u32)ioremap(OMAP_SYSC_BASE, ++ OMAP_SYSC_SIZE); ++ GT_1trace(curTrace, GT_2CLASS, "dwMemBase[0] 0x%x\n", ++ pResources->dwMemBase[0]); ++ GT_1trace(curTrace, GT_2CLASS, "dwMemBase[3] 0x%x\n", ++ pResources->dwMemBase[3]); ++ GT_1trace(curTrace, GT_2CLASS, "dwPrmBase 0x%x\n", ++ pResources->dwPrmBase); ++ GT_1trace(curTrace, GT_2CLASS, "dwCmBase 0x%x\n", ++ pResources->dwCmBase); ++ GT_1trace(curTrace, GT_2CLASS, "dwWdTimerDspBase 0x%x\n", ++ pResources->dwWdTimerDspBase); ++ GT_1trace(curTrace, GT_2CLASS, "dwMboxBase 0x%x\n", ++ pResources->dwMboxBase); ++ GT_1trace(curTrace, GT_2CLASS, "dwDmmuBase 0x%x\n", ++ pResources->dwDmmuBase); ++ ++ /* for 24xx base port is not mapping the mamory for DSP ++ * internal memory TODO Do a ioremap here */ ++ /* Second window is for DSP external memory shared with MPU */ ++ if (DSP_SUCCEEDED(status)) { ++ /* for Linux, these are hard-coded values */ ++ pResources->dwBusType = 0; ++ pResources->bIRQRegisters = 0; ++ pResources->bIRQAttrib = 0; ++ pResources->dwOffsetForMonitor = 0; ++ pResources->dwChnlOffset = 0; ++ /* CHNL_MAXCHANNELS */ ++ pResources->dwNumChnls = CHNL_MAXCHANNELS; ++ pResources->dwChnlBufSize = 0x400; ++ dwBuffSize = sizeof(struct CFG_HOSTRES); ++ status = REG_SetValue(NULL, (char *) dwContext, ++ CURRENTCONFIG, REG_BINARY, ++ (u8 *)pResources, ++ sizeof(struct CFG_HOSTRES)); ++ if (DSP_SUCCEEDED(status)) { ++ GT_0trace(curTrace, GT_1CLASS, ++ " Successfully set the registry " ++ "value for CURRENTCONFIG\n"); ++ } else { ++ GT_0trace(curTrace, GT_7CLASS, ++ " Failed to set the registry " ++ "value for CURRENTCONFIG\n"); ++ } ++ } ++ MEM_Free(pResources); ++ } ++ /* End Mem alloc */ ++ return status; ++} ++ ++/* ++ * ======== RequestBridgeResourcesDSP ======== ++ * Purpose: ++ * Reserves shared memory for bridge. ++ */ ++static DSP_STATUS RequestBridgeResourcesDSP(u32 dwContext, s32 bRequest) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct CFG_HOSTRES *pResources; ++ u32 dwBuffSize; ++ u32 dmaAddr; ++ u32 shm_size; ++ ++ DBC_Require(dwContext != 0); ++ ++ GT_0trace(curTrace, GT_ENTER, "->RequestBridgeResourcesDSP \n"); ++ ++ dwBuffSize = sizeof(struct CFG_HOSTRES); ++ ++ pResources = MEM_Calloc(dwBuffSize, MEM_NONPAGED); ++ ++ if (pResources != NULL) { ++ if (DSP_FAILED(CFG_GetHostResources((struct CFG_DEVNODE *) ++ dwContext, pResources))) { ++ /* Call CFG_GetHostResources to get reserve resouces */ ++ status = RequestBridgeResources(dwContext, bRequest); ++ if (DSP_SUCCEEDED(status)) { ++ status = CFG_GetHostResources ++ ((struct CFG_DEVNODE *) dwContext, ++ pResources); ++ } ++ } ++ /* wNumMemWindows must not be more than CFG_MAXMEMREGISTERS */ ++ pResources->wNumMemWindows = 4; ++ ++ pResources->dwMemBase[0] = 0; ++ pResources->dwMemBase[2] = (u32)ioremap(OMAP_DSP_MEM1_BASE, ++ OMAP_DSP_MEM1_SIZE); ++ pResources->dwMemBase[3] = (u32)ioremap(OMAP_DSP_MEM2_BASE, ++ OMAP_DSP_MEM2_SIZE); ++ pResources->dwMemBase[4] = (u32)ioremap(OMAP_DSP_MEM3_BASE, ++ OMAP_DSP_MEM3_SIZE); ++ pResources->dwPerBase = (u32)ioremap(OMAP_PER_CM_BASE, ++ OMAP_PER_CM_SIZE); ++ pResources->dwPerPmBase = (u32)ioremap(OMAP_PER_PRM_BASE, ++ OMAP_PER_PRM_SIZE); ++ pResources->dwCorePmBase = (u32)ioremap(OMAP_CORE_PRM_BASE, ++ OMAP_CORE_PRM_SIZE); ++ pResources->dwDmmuBase = (u32)ioremap(OMAP_DMMU_BASE, ++ OMAP_DMMU_SIZE); ++ pResources->dwWdTimerDspBase = 0; ++ ++ GT_1trace(curTrace, GT_2CLASS, "dwMemBase[0] 0x%x\n", ++ pResources->dwMemBase[0]); ++ GT_1trace(curTrace, GT_2CLASS, "dwMemBase[1] 0x%x\n", ++ pResources->dwMemBase[1]); ++ GT_1trace(curTrace, GT_2CLASS, "dwMemBase[2] 0x%x\n", ++ pResources->dwMemBase[2]); ++ GT_1trace(curTrace, GT_2CLASS, "dwMemBase[3] 0x%x\n", ++ pResources->dwMemBase[3]); ++ GT_1trace(curTrace, GT_2CLASS, "dwMemBase[4] 0x%x\n", ++ pResources->dwMemBase[4]); ++ GT_1trace(curTrace, GT_2CLASS, "dwPrmBase 0x%x\n", ++ pResources->dwPrmBase); ++ GT_1trace(curTrace, GT_2CLASS, "dwCmBase 0x%x\n", ++ pResources->dwCmBase); ++ GT_1trace(curTrace, GT_2CLASS, "dwWdTimerDspBase 0x%x\n", ++ pResources->dwWdTimerDspBase); ++ GT_1trace(curTrace, GT_2CLASS, "dwMboxBase 0x%x\n", ++ pResources->dwMboxBase); ++ GT_1trace(curTrace, GT_2CLASS, "dwDmmuBase 0x%x\n", ++ pResources->dwDmmuBase); ++ dwBuffSize = sizeof(shm_size); ++ status = REG_GetValue(NULL, CURRENTCONFIG, SHMSIZE, ++ (u8 *)&shm_size, &dwBuffSize); ++ if (DSP_SUCCEEDED(status)) { ++ /* Allocate Physically contiguous, ++ * non-cacheable memory */ ++ pResources->dwMemBase[1] = ++ (u32)MEM_AllocPhysMem(shm_size, 0x100000, ++ &dmaAddr); ++ if (pResources->dwMemBase[1] == 0) { ++ status = DSP_EMEMORY; ++ GT_0trace(curTrace, GT_7CLASS, ++ "SHM reservation Failed\n"); ++ } else { ++ pResources->dwMemLength[1] = shm_size; ++ pResources->dwMemPhys[1] = dmaAddr; ++ ++ GT_3trace(curTrace, GT_1CLASS, ++ "Bridge SHM address 0x%x dmaAddr" ++ " %x size %x\n", ++ pResources->dwMemBase[1], ++ dmaAddr, shm_size); ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* for Linux, these are hard-coded values */ ++ pResources->dwBusType = 0; ++ pResources->bIRQRegisters = 0; ++ pResources->bIRQAttrib = 0; ++ pResources->dwOffsetForMonitor = 0; ++ pResources->dwChnlOffset = 0; ++ /* CHNL_MAXCHANNELS */ ++ pResources->dwNumChnls = CHNL_MAXCHANNELS; ++ pResources->dwChnlBufSize = 0x400; ++ dwBuffSize = sizeof(struct CFG_HOSTRES); ++ status = REG_SetValue(NULL, (char *)dwContext, ++ CURRENTCONFIG, REG_BINARY, ++ (u8 *)pResources, ++ sizeof(struct CFG_HOSTRES)); ++ if (DSP_SUCCEEDED(status)) { ++ GT_0trace(curTrace, GT_1CLASS, ++ " Successfully set the registry" ++ " value for CURRENTCONFIG\n"); ++ } else { ++ GT_0trace(curTrace, GT_7CLASS, ++ " Failed to set the registry value" ++ " for CURRENTCONFIG\n"); ++ } ++ } ++ MEM_Free(pResources); ++ } ++ /* End Mem alloc */ ++ return status; ++} +diff --git a/drivers/dsp/bridge/rmgr/drv_interface.c b/drivers/dsp/bridge/rmgr/drv_interface.c +new file mode 100644 +index 0000000..4aa7de6 +--- /dev/null ++++ b/drivers/dsp/bridge/rmgr/drv_interface.c +@@ -0,0 +1,777 @@ ++/* ++ * drv_interface.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== linux_driver.c ======== ++ * Description: ++ * DSP/BIOS Bridge driver interface. ++ * ++ * Public Functions: ++ * driver_init ++ * driver_exit ++ * driver_open ++ * driver_release ++ * driver_ioctl ++ * driver_mmap ++ * ++ *! Revision History ++ *! ================ ++ *! 21-Apr-2004 map Deprecated use of MODULE_PARM for kernel versions ++ *! greater than 2.5, use module_param. ++ *! 08-Mar-2004 sb Added the dsp_debug argument, which keeps the DSP in self ++ *! loop after image load and waits in a loop for DSP to start ++ *! 16-Feb-2004 vp Deprecated the usage of MOD_INC_USE_COUNT and ++ *! MOD_DEC_USE_COUNT ++ *! for kernel versions greater than 2.5 ++ *! 20-May-2003 vp Added unregister functions for the DPM. ++ *! 24-Mar-2003 sb Pass pid instead of driverContext to DSP_Close ++ *! 24-Mar-2003 vp Added Power Management support. ++ *! 21-Mar-2003 sb Configure SHM size using insmod argument shm_size ++ *! 10-Feb-2003 vp Updated based on code review comments ++ *! 18-Oct-2002 sb Created initial version ++ */ ++ ++/* ----------------------------------- Host OS */ ++ ++#include ++#include ++#include ++ ++#ifdef MODULE ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Resource Manager */ ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++#ifndef RES_CLEANUP_DISABLE ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#endif ++ ++#ifdef CONFIG_BRIDGE_DVFS ++#include ++#include ++#endif ++ ++#define BRIDGE_NAME "C6410" ++/* ----------------------------------- Globals */ ++#define DRIVER_NAME "DspBridge" ++#define DRIVER_MAJOR 0 /* Linux assigns our Major device number */ ++#define DRIVER_MINOR 0 /* Linux assigns our Major device number */ ++s32 dsp_debug; ++ ++struct platform_device *omap_dspbridge_dev; ++ ++struct bridge_dev { ++ struct cdev cdev; ++}; ++ ++static struct bridge_dev *bridge_device; ++ ++static struct class *bridge_class; ++ ++static u32 driverContext; ++#ifdef CONFIG_BRIDGE_DEBUG ++static char *GT_str; ++#endif /* CONFIG_BRIDGE_DEBUG */ ++static s32 driver_major = DRIVER_MAJOR; ++static s32 driver_minor = DRIVER_MINOR; ++static char *base_img; ++char *iva_img; ++static char *num_procs = "C55=1"; ++static s32 shm_size = 0x400000; /* 4 MB */ ++static u32 phys_mempool_base; ++static u32 phys_mempool_size; ++static int tc_wordswapon; /* Default value is always false */ ++ ++#ifdef CONFIG_PM ++struct omap34xx_bridge_suspend_data { ++ int suspended; ++ wait_queue_head_t suspend_wq; ++}; ++ ++static struct omap34xx_bridge_suspend_data bridge_suspend_data; ++ ++static int omap34xxbridge_suspend_lockout( ++ struct omap34xx_bridge_suspend_data *s, struct file *f) ++{ ++ if ((s)->suspended) { ++ if ((f)->f_flags & O_NONBLOCK) ++ return DSP_EDPMSUSPEND; ++ wait_event_interruptible((s)->suspend_wq, (s)->suspended == 0); ++ } ++ return 0; ++} ++ ++#endif ++ ++#ifdef DEBUG ++module_param(GT_str, charp, 0); ++MODULE_PARM_DESC(GT_str, "GT string, default = NULL"); ++ ++module_param(dsp_debug, int, 0); ++MODULE_PARM_DESC(dsp_debug, "Wait after loading DSP image. default = false"); ++#endif ++ ++module_param(driver_major, int, 0); /* Driver's major number */ ++MODULE_PARM_DESC(driver_major, "Major device number, default = 0 (auto)"); ++ ++module_param(driver_minor, int, 0); /* Driver's major number */ ++MODULE_PARM_DESC(driver_minor, "Minor device number, default = 0 (auto)"); ++ ++module_param(base_img, charp, 0); ++MODULE_PARM_DESC(base_img, "DSP base image, default = NULL"); ++ ++module_param(shm_size, int, 0); ++MODULE_PARM_DESC(shm_size, "SHM size, default = 4 MB, minimum = 64 KB"); ++ ++module_param(phys_mempool_base, uint, 0); ++MODULE_PARM_DESC(phys_mempool_base, ++ "Physical memory pool base passed to driver"); ++ ++module_param(phys_mempool_size, uint, 0); ++MODULE_PARM_DESC(phys_mempool_size, ++ "Physical memory pool size passed to driver"); ++module_param(tc_wordswapon, int, 0); ++MODULE_PARM_DESC(tc_wordswapon, "TC Word Swap Option. default = 0"); ++ ++MODULE_AUTHOR("Texas Instruments"); ++MODULE_LICENSE("GPL"); ++ ++static char *driver_name = DRIVER_NAME; ++ ++#ifdef CONFIG_BRIDGE_DEBUG ++static struct GT_Mask driverTrace; ++#endif /* CONFIG_BRIDGE_DEBUG */ ++ ++static struct file_operations bridge_fops = { ++ .open = bridge_open, ++ .release = bridge_release, ++ .ioctl = bridge_ioctl, ++ .mmap = bridge_mmap, ++}; ++ ++#ifdef CONFIG_PM ++static u32 timeOut = 1000; ++#ifdef CONFIG_BRIDGE_DVFS ++static struct clk *clk_handle; ++s32 dsp_max_opps = VDD1_OPP3; ++#endif ++ ++/* Maximum Opps that can be requested by IVA*/ ++/*vdd1 rate table*/ ++#ifdef CONFIG_BRIDGE_DVFS ++const struct omap_opp vdd1_rate_table_bridge[] = { ++ {0, 0, 0}, ++ /*OPP1*/ ++ {S125M, VDD1_OPP1, 0}, ++ /*OPP2*/ ++ {S250M, VDD1_OPP2, 0}, ++ /*OPP3*/ ++ {S500M, VDD1_OPP3, 0}, ++ /*OPP4*/ ++ {S550M, VDD1_OPP4, 0}, ++ /*OPP5*/ ++ {S600M, VDD1_OPP5, 0}, ++}; ++#endif ++#endif ++ ++struct dspbridge_platform_data *omap_dspbridge_pdata; ++ ++u32 vdd1_dsp_freq[6][4] = { ++ {0, 0, 0, 0}, ++ /*OPP1*/ ++ {0, 90000, 0, 86000}, ++ /*OPP2*/ ++ {0, 180000, 80000, 170000}, ++ /*OPP3*/ ++ {0, 360000, 160000, 340000}, ++ /*OPP4*/ ++ {0, 396000, 325000, 376000}, ++ /*OPP5*/ ++ {0, 430000, 355000, 430000}, ++}; ++ ++#ifdef CONFIG_BRIDGE_DVFS ++static int dspbridge_post_scale(struct notifier_block *op, unsigned long level, ++ void *ptr) ++{ ++ PWR_PM_PostScale(PRCM_VDD1, level); ++ return 0; ++} ++ ++static struct notifier_block iva_clk_notifier = { ++ .notifier_call = dspbridge_post_scale, ++ NULL, ++}; ++#endif ++ ++static int __devinit omap34xx_bridge_probe(struct platform_device *pdev) ++{ ++ int status; ++ u32 initStatus; ++ u32 temp; ++ dev_t dev = 0 ; ++ int result; ++#ifdef CONFIG_BRIDGE_DVFS ++ int i = 0; ++#endif ++ struct dspbridge_platform_data *pdata = pdev->dev.platform_data; ++ ++ omap_dspbridge_dev = pdev; ++ ++ /* use 2.6 device model */ ++ if (driver_major) { ++ dev = MKDEV(driver_major, driver_minor); ++ result = register_chrdev_region(dev, 1, driver_name); ++ } else { ++ result = alloc_chrdev_region(&dev, driver_minor, 1, ++ driver_name); ++ driver_major = MAJOR(dev); ++ } ++ ++ if (result < 0) { ++ GT_1trace(driverTrace, GT_7CLASS, "bridge_init: " ++ "Can't get Major %d \n", driver_major); ++ return result; ++ } ++ ++ bridge_device = kmalloc(sizeof(struct bridge_dev), GFP_KERNEL); ++ if (!bridge_device) { ++ result = -ENOMEM; ++ unregister_chrdev_region(dev, 1); ++ return result; ++ } ++ memset(bridge_device, 0, sizeof(struct bridge_dev)); ++ cdev_init(&bridge_device->cdev, &bridge_fops); ++ bridge_device->cdev.owner = THIS_MODULE; ++ bridge_device->cdev.ops = &bridge_fops; ++ ++ status = cdev_add(&bridge_device->cdev, dev, 1); ++ ++ if (status) { ++ GT_0trace(driverTrace, GT_7CLASS, ++ "Failed to add the bridge device \n"); ++ return status; ++ } ++ ++ /* udev support */ ++ bridge_class = class_create(THIS_MODULE, "ti_bridge"); ++ ++ if (IS_ERR(bridge_class)) ++ GT_0trace(driverTrace, GT_7CLASS, ++ "Error creating bridge class \n"); ++ ++ device_create(bridge_class, NULL, MKDEV(driver_major, driver_minor), ++ NULL, "DspBridge"); ++ ++ GT_init(); ++ GT_create(&driverTrace, "LD"); ++ ++#ifdef DEBUG ++ if (GT_str) ++ GT_set(GT_str); ++#elif defined(DDSP_DEBUG_PRODUCT) && GT_TRACE ++ GT_set("**=67"); ++#endif ++ ++ GT_0trace(driverTrace, GT_ENTER, "-> driver_init\n"); ++ ++#ifdef CONFIG_PM ++ /* Initialize the wait queue */ ++ if (!status) { ++ bridge_suspend_data.suspended = 0; ++ init_waitqueue_head(&bridge_suspend_data.suspend_wq); ++ } ++#endif ++ ++ SERVICES_Init(); ++ ++ /* Autostart flag. This should be set to true if the DSP image should ++ * be loaded and run during bridge module initialization */ ++ ++ if (base_img) { ++ temp = true; ++ REG_SetValue(NULL, NULL, AUTOSTART, REG_DWORD, (u8 *)&temp, ++ sizeof(temp)); ++ REG_SetValue(NULL, NULL, DEFEXEC, REG_SZ, (u8 *)base_img, ++ strlen(base_img) + 1); ++ } else { ++ temp = false; ++ REG_SetValue(NULL, NULL, AUTOSTART, REG_DWORD, (u8 *)&temp, ++ sizeof(temp)); ++ REG_SetValue(NULL, NULL, DEFEXEC, REG_SZ, (u8 *) "\0", (u32)2); ++ } ++ REG_SetValue(NULL, NULL, NUMPROCS, REG_SZ, (u8 *) num_procs, ++ strlen(num_procs) + 1); ++ ++ if (shm_size >= 0x10000) { /* 64 KB */ ++ initStatus = REG_SetValue(NULL, NULL, SHMSIZE, REG_DWORD, ++ (u8 *)&shm_size, sizeof(shm_size)); ++ } else { ++ initStatus = DSP_EINVALIDARG; ++ status = -1; ++ GT_0trace(driverTrace, GT_7CLASS, ++ "SHM size must be at least 64 KB\n"); ++ } ++ GT_1trace(driverTrace, GT_7CLASS, ++ "requested shm_size = 0x%x\n", shm_size); ++ ++ if (pdata->phys_mempool_base && pdata->phys_mempool_size) { ++ phys_mempool_base = pdata->phys_mempool_base; ++ phys_mempool_size = pdata->phys_mempool_size; ++ } ++ ++ if (phys_mempool_base > 0x0) { ++ initStatus = REG_SetValue(NULL, NULL, PHYSMEMPOOLBASE, ++ REG_DWORD, (u8 *)&phys_mempool_base, ++ sizeof(phys_mempool_base)); ++ } ++ GT_1trace(driverTrace, GT_7CLASS, "phys_mempool_base = 0x%x \n", ++ phys_mempool_base); ++ ++ if (phys_mempool_size > 0x0) { ++ initStatus = REG_SetValue(NULL, NULL, PHYSMEMPOOLSIZE, ++ REG_DWORD, (u8 *)&phys_mempool_size, ++ sizeof(phys_mempool_size)); ++ } ++ GT_1trace(driverTrace, GT_7CLASS, "phys_mempool_size = 0x%x\n", ++ phys_mempool_base); ++ if ((phys_mempool_base > 0x0) && (phys_mempool_size > 0x0)) ++ MEM_ExtPhysPoolInit(phys_mempool_base, phys_mempool_size); ++ if (tc_wordswapon) { ++ GT_0trace(driverTrace, GT_7CLASS, "TC Word Swap is enabled\n"); ++ REG_SetValue(NULL, NULL, TCWORDSWAP, REG_DWORD, ++ (u8 *)&tc_wordswapon, sizeof(tc_wordswapon)); ++ } else { ++ GT_0trace(driverTrace, GT_7CLASS, "TC Word Swap is disabled\n"); ++ REG_SetValue(NULL, NULL, TCWORDSWAP, ++ REG_DWORD, (u8 *)&tc_wordswapon, ++ sizeof(tc_wordswapon)); ++ } ++ if (DSP_SUCCEEDED(initStatus)) { ++#ifdef CONFIG_BRIDGE_DVFS ++ for (i = 0; i < 6; i++) ++ pdata->mpu_speed[i] = vdd1_rate_table_bridge[i].rate; ++ ++ clk_handle = clk_get(NULL, "iva2_ck"); ++ if (!clk_handle) { ++ GT_0trace(driverTrace, GT_7CLASS, ++ "clk_get failed to get iva2_ck \n"); ++ } else { ++ GT_0trace(driverTrace, GT_7CLASS, ++ "clk_get PASS to get iva2_ck \n"); ++ } ++ if (!clk_notifier_register(clk_handle, &iva_clk_notifier)) { ++ GT_0trace(driverTrace, GT_7CLASS, ++ "clk_notifier_register PASS for iva2_ck \n"); ++ } else { ++ GT_0trace(driverTrace, GT_7CLASS, ++ "clk_notifier_register FAIL for iva2_ck \n"); ++ } ++#endif ++ driverContext = DSP_Init(&initStatus); ++ if (DSP_FAILED(initStatus)) { ++ status = -1; ++ GT_0trace(driverTrace, GT_7CLASS, ++ "DSP/BIOS Bridge initialization Failed\n"); ++ } else { ++ GT_0trace(driverTrace, GT_5CLASS, ++ "DSP/BIOS Bridge driver loaded\n"); ++ } ++ } ++ ++ DBC_Assert(status == 0); ++ DBC_Assert(DSP_SUCCEEDED(initStatus)); ++ GT_0trace(driverTrace, GT_ENTER, " <- driver_init\n"); ++ return status; ++} ++ ++static int __devexit omap34xx_bridge_remove(struct platform_device *pdev) ++{ ++ dev_t devno; ++ bool ret; ++ DSP_STATUS dsp_status = DSP_SOK; ++ HANDLE hDrvObject = NULL; ++ struct PROCESS_CONTEXT *pTmp = NULL; ++ struct PROCESS_CONTEXT *pCtxtclosed = NULL; ++ struct PROCESS_CONTEXT *pCtxttraverse = NULL; ++ ++ GT_0trace(driverTrace, GT_ENTER, "-> driver_exit\n"); ++ ++ dsp_status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT); ++ DRV_GetProcCtxtList(&pCtxtclosed, (struct DRV_OBJECT *)hDrvObject); ++ while (pCtxtclosed != NULL) { ++ DRV_RemoveAllResources(pCtxtclosed); ++ if (pCtxtclosed->hProcessor != NULL) { ++ DRV_GetProcCtxtList(&pCtxttraverse, ++ (struct DRV_OBJECT *)hDrvObject); ++ if (pCtxttraverse->next == NULL) { ++ PROC_Detach(pCtxtclosed->hProcessor); ++ goto func_cont; ++ } ++ if ((pCtxtclosed->pid == pCtxttraverse->pid) && ++ (pCtxttraverse->next != NULL)) { ++ pCtxttraverse = pCtxttraverse->next; ++ } ++ while ((pCtxttraverse != NULL) && ++ (pCtxtclosed->hProcessor ++ != pCtxttraverse->hProcessor)) { ++ pCtxttraverse = pCtxttraverse->next; ++ if ((pCtxttraverse != NULL) && ++ (pCtxtclosed->pid == pCtxttraverse->pid)) { ++ pCtxttraverse = pCtxttraverse->next; ++ } ++ } ++ if (pCtxttraverse == NULL) ++ PROC_Detach(pCtxtclosed->hProcessor); ++ } ++func_cont: ++ pTmp = pCtxtclosed->next; ++ DRV_RemoveProcContext((struct DRV_OBJECT *)hDrvObject, ++ pCtxtclosed, (void *)pCtxtclosed->pid); ++ pCtxtclosed = pTmp; ++ } ++ ++ /* unregister the clock notifier */ ++#ifdef CONFIG_BRIDGE_DVFS ++ if (!clk_notifier_unregister(clk_handle, &iva_clk_notifier)) { ++ GT_0trace(driverTrace, GT_7CLASS, ++ "clk_notifier_unregister PASS for iva2_ck \n"); ++ } else { ++ GT_0trace(driverTrace, GT_7CLASS, ++ "clk_notifier_unregister PASS for iva2_ck \n"); ++ } ++ ++ clk_put(clk_handle); ++ clk_handle = NULL; ++#endif /* #ifdef CONFIG_BRIDGE_DVFS */ ++ ++ if (driverContext) { ++ ret = DSP_Deinit(driverContext); ++ driverContext = 0; ++ ++ DBC_Assert(ret == true); ++ } ++ SERVICES_Exit(); ++ GT_exit(); ++ ++ devno = MKDEV(driver_major, driver_minor); ++ if (bridge_device) { ++ cdev_del(&bridge_device->cdev); ++ kfree(bridge_device); ++ } ++ unregister_chrdev_region(devno, 1); ++ if (bridge_class) { ++ /* remove the device from sysfs */ ++ device_destroy(bridge_class, MKDEV(driver_major, driver_minor)); ++ class_destroy(bridge_class); ++ ++ } ++ return 0; ++} ++ ++ ++#ifdef CONFIG_PM ++static int bridge_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ u32 status; ++ u32 command = PWR_EMERGENCYDEEPSLEEP; ++ ++ status = PWR_SleepDSP(command, timeOut); ++ if (DSP_FAILED(status)) ++ return -1; ++ ++ bridge_suspend_data.suspended = 1; ++ return 0; ++} ++ ++static int bridge_resume(struct platform_device *pdev) ++{ ++ u32 status; ++ ++ status = PWR_WakeDSP(timeOut); ++ if (DSP_FAILED(status)) ++ return -1; ++ ++ bridge_suspend_data.suspended = 0; ++ wake_up(&bridge_suspend_data.suspend_wq); ++ return 0; ++} ++#else ++#define bridge_suspend NULL ++#define bridge_resume NULL ++#endif ++ ++static struct platform_driver bridge_driver = { ++ .driver = { ++ .name = BRIDGE_NAME, ++ }, ++ .probe = omap34xx_bridge_probe, ++ .remove = __devexit_p(omap34xx_bridge_remove), ++ .suspend = bridge_suspend, ++ .resume = bridge_resume, ++}; ++ ++static int __init bridge_init(void) ++{ ++ return platform_driver_register(&bridge_driver); ++} ++ ++static void __exit bridge_exit(void) ++{ ++ platform_driver_unregister(&bridge_driver); ++} ++ ++/* This function is called when an application opens handle to the ++ * bridge driver. */ ++ ++static int bridge_open(struct inode *ip, struct file *filp) ++{ ++ int status = 0; ++#ifndef RES_CLEANUP_DISABLE ++ u32 hProcess; ++ DSP_STATUS dsp_status = DSP_SOK; ++ HANDLE hDrvObject = NULL; ++ struct PROCESS_CONTEXT *pPctxt = NULL; ++ struct PROCESS_CONTEXT *next_node = NULL; ++ struct PROCESS_CONTEXT *pCtxtclosed = NULL; ++ struct PROCESS_CONTEXT *pCtxttraverse = NULL; ++ struct task_struct *tsk = NULL; ++ GT_0trace(driverTrace, GT_ENTER, "-> driver_open\n"); ++ dsp_status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT); ++ ++ /* Checking weather task structure for all process existing ++ * in the process context list If not removing those processes*/ ++ if (DSP_FAILED(dsp_status)) ++ goto func_cont; ++ ++ DRV_GetProcCtxtList(&pCtxtclosed, (struct DRV_OBJECT *)hDrvObject); ++ while (pCtxtclosed != NULL) { ++ tsk = find_task_by_vpid(pCtxtclosed->pid); ++ next_node = pCtxtclosed->next; ++ ++ if ((tsk == NULL) || (tsk->exit_state == EXIT_ZOMBIE)) { ++ ++ GT_1trace(driverTrace, GT_5CLASS, ++ "***Task structure not existing for " ++ "process***%d\n", pCtxtclosed->pid); ++ DRV_RemoveAllResources(pCtxtclosed); ++ if (pCtxtclosed->hProcessor != NULL) { ++ DRV_GetProcCtxtList(&pCtxttraverse, ++ (struct DRV_OBJECT *)hDrvObject); ++ if (pCtxttraverse->next == NULL) { ++ PROC_Detach(pCtxtclosed->hProcessor); ++ } else { ++ if ((pCtxtclosed->pid == ++ pCtxttraverse->pid) && ++ (pCtxttraverse->next != NULL)) { ++ pCtxttraverse = ++ pCtxttraverse->next; ++ } ++ while ((pCtxttraverse != NULL) && ++ (pCtxtclosed->hProcessor ++ != pCtxttraverse->hProcessor)) { ++ pCtxttraverse = ++ pCtxttraverse->next; ++ if ((pCtxttraverse != NULL) && ++ (pCtxtclosed->pid == ++ pCtxttraverse->pid)) { ++ pCtxttraverse = ++ pCtxttraverse->next; ++ } ++ } ++ if (pCtxttraverse == NULL) { ++ PROC_Detach ++ (pCtxtclosed->hProcessor); ++ } ++ } ++ } ++ DRV_RemoveProcContext((struct DRV_OBJECT *)hDrvObject, ++ pCtxtclosed, ++ (void *)pCtxtclosed->pid); ++ } ++ pCtxtclosed = next_node; ++ } ++func_cont: ++ dsp_status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT); ++ if (DSP_SUCCEEDED(dsp_status)) ++ dsp_status = DRV_InsertProcContext( ++ (struct DRV_OBJECT *)hDrvObject, &pPctxt); ++ ++ if (pPctxt != NULL) { ++ /* Return PID instead of process handle */ ++ hProcess = current->pid; ++ ++ DRV_ProcUpdatestate(pPctxt, PROC_RES_ALLOCATED); ++ DRV_ProcSetPID(pPctxt, hProcess); ++ } ++#endif ++ ++ GT_0trace(driverTrace, GT_ENTER, " <- driver_open\n"); ++ return status; ++} ++ ++/* This function is called when an application closes handle to the bridge ++ * driver. */ ++static int bridge_release(struct inode *ip, struct file *filp) ++{ ++ int status; ++ u32 pid; ++ ++ GT_0trace(driverTrace, GT_ENTER, "-> driver_release\n"); ++ ++ /* Return PID instead of process handle */ ++ pid = current->pid; ++ ++ status = DSP_Close(pid); ++ ++ ++ (status == true) ? (status = 0) : (status = -1); ++ ++ GT_0trace(driverTrace, GT_ENTER, " <- driver_release\n"); ++ ++ return status; ++} ++ ++/* This function provides IO interface to the bridge driver. */ ++static int bridge_ioctl(struct inode *ip, struct file *filp, unsigned int code, ++ unsigned long args) ++{ ++ int status; ++ u32 retval = DSP_SOK; ++ union Trapped_Args pBufIn; ++ ++ DBC_Require(filp != NULL); ++#ifdef CONFIG_PM ++ status = omap34xxbridge_suspend_lockout(&bridge_suspend_data, filp); ++ if (status != 0) ++ return status; ++#endif ++ ++ GT_0trace(driverTrace, GT_ENTER, " -> driver_ioctl\n"); ++ ++ /* Deduct one for the CMD_BASE. */ ++ code = (code - 1); ++ ++ status = copy_from_user(&pBufIn, (union Trapped_Args *)args, ++ sizeof(union Trapped_Args)); ++ ++ if (status >= 0) { ++ status = WCD_CallDevIOCtl(code, &pBufIn, &retval); ++ ++ if (DSP_SUCCEEDED(status)) { ++ status = retval; ++ } else { ++ GT_1trace(driverTrace, GT_7CLASS, ++ "IOCTL Failed, code : 0x%x\n", code); ++ status = -1; ++ } ++ ++ } ++ ++ GT_0trace(driverTrace, GT_ENTER, " <- driver_ioctl\n"); ++ ++ return status; ++} ++ ++/* This function maps kernel space memory to user space memory. */ ++static int bridge_mmap(struct file *filp, struct vm_area_struct *vma) ++{ ++#if GT_TRACE ++ u32 offset = vma->vm_pgoff << PAGE_SHIFT; ++#endif ++ u32 status; ++ ++ DBC_Assert(vma->vm_start < vma->vm_end); ++ ++ vma->vm_flags |= VM_RESERVED | VM_IO; ++ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); ++ ++ GT_6trace(driverTrace, GT_3CLASS, ++ "vm filp %p offset %lx start %lx end %lx" ++ " page_prot %lx flags %lx\n", filp, offset, vma->vm_start, ++ vma->vm_end, vma->vm_page_prot, vma->vm_flags); ++ ++ status = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, ++ vma->vm_end - vma->vm_start, vma->vm_page_prot); ++ if (status != 0) ++ status = -EAGAIN; ++ ++ return status; ++} ++ ++#ifndef RES_CLEANUP_DISABLE ++/* To remove all process resources before removing the process from the ++ * process context list*/ ++DSP_STATUS DRV_RemoveAllResources(HANDLE hPCtxt) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; ++ if (pCtxt != NULL) { ++ DRV_RemoveAllSTRMResElements(pCtxt); ++ DRV_RemoveAllNodeResElements(pCtxt); ++ DRV_RemoveAllDMMResElements(pCtxt); ++ DRV_ProcUpdatestate(pCtxt, PROC_RES_FREED); ++ } ++ return status; ++} ++#endif ++ ++/* Bridge driver initialization and de-initialization functions */ ++module_init(bridge_init); ++module_exit(bridge_exit); ++ +diff --git a/drivers/dsp/bridge/rmgr/drv_interface.h b/drivers/dsp/bridge/rmgr/drv_interface.h +new file mode 100644 +index 0000000..f5b068e +--- /dev/null ++++ b/drivers/dsp/bridge/rmgr/drv_interface.h +@@ -0,0 +1,40 @@ ++/* ++ * drv_interface.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== drv_interface.h ======== ++ * ++ *! Revision History ++ *! ================ ++ *! 24-Mar-2003 vp Added hooks for Power Management Test ++ *! 18-Feb-2003 vp Code review updates ++ *! 18-Oct-2002 sb Created initial version ++ ++ */ ++ ++#ifndef _DRV_INTERFACE_H_ ++#define _DRV_INTERFACE_H_ ++ ++/* Prototypes for all functions in this bridge */ ++static int __init bridge_init(void); /* Initialize bridge */ ++static void __exit bridge_exit(void); /* Opposite of initialize */ ++static int bridge_open(struct inode *, struct file *); /* Open */ ++static int bridge_release(struct inode *, struct file *); /* Release */ ++static int bridge_ioctl(struct inode *, struct file *, unsigned int, ++ unsigned long); ++static int bridge_mmap(struct file *filp, struct vm_area_struct *vma); ++#endif /* ifndef _DRV_INTERFACE_H_ */ +diff --git a/drivers/dsp/bridge/rmgr/dspdrv.c b/drivers/dsp/bridge/rmgr/dspdrv.c +new file mode 100644 +index 0000000..a7a74fc +--- /dev/null ++++ b/drivers/dsp/bridge/rmgr/dspdrv.c +@@ -0,0 +1,276 @@ ++/* ++ * dspdrv.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== dspdrv.c ======== ++ * Description: ++ * Interface to allocate and free bridge resources. ++ * ++ *! Revision History ++ *! ================ ++ *! 12-Apr-2004 hp: Compile IVA only for 24xx. ++ *! 09-Feb-2004 vp: Updated to support IVA. ++ *! 10-Feb-2003 vp: Code review updates. ++ *! 18-oct-2002 vp: Ported to the Linux platform. ++ *! 03-Mar-2002 rr: DSP_Deinit bug fixed (gets the Mgrhandle from registry ++ *! before calling MGR_Destroy. ++ *! 11-Jul-2001 jeh Moved MGR_Create() from DSP_Init() to DEV_StartDevice(). ++ *! 02-Apr-2001 rr: WCD_InitComplete2 return value is not checked thus ++ *! sllowing the class driver to load irrespective of ++ *! the image load. ++ *! 30-Oct-2000 kc: Made changes w.r.t. usage of REG_SetValue. ++ *! 05-Oct-2000 rr: WCD_InitComplete2 return value checked for RM. ++ *! Failure in WCD_InitComplete2 will cause the ++ *! DSP_Init to fail. ++ *! 12-Aug-2000 kc: Changed REG_EnumValue to REG_EnumKey. ++ *! 07-Aug-2000 rr: MGR_Create does the job of loading the DCD Dll. ++ *! 26-Jul-2000 rr: Driver Object holds the DevNodeStrings for each ++ *! DevObjects. Static variables removed. Returns ++ *! the Driver Object in DSP_Init. ++ *! 17-Jul-2000 rr: Driver Object is created in DSP_Init and that holds ++ *! the list of Device objects. ++ *! 07-Jul-2000 rr: RM implementaion started. ++ *! 24-May-2000 ag: Cleaned up debug msgs. ++ *! 02-May-2000 rr: DSP_Open returns GetCallerProcess as dwOpenContext. ++ *! 03-Feb-2000 rr: GT Changes. ++ *! 28-Jan-2000 rr: Code Cleaned up.Type void changed to void. ++ *! DSP_Deinit checks return values.dwCode in ++ *! DSP_IO_CONTROL is decoded(not hard coded) ++ *! 27-Jan-2000 rr: REG_EnumValue Used .EnumerateKey fxn removed. ++ *! 13-Jan-2000 rr: CFG_GetPrivateDword renamed to CFG_GetDevObject. ++ *! 29-Dec-1999 rr: Code Cleaned up ++ *! 09-Dec-1999 rr: EnumerateKey changed for retail build. ++ *! 06-Dec-1999 rr: ArrayofInstalledNode, index and ArrayofInstalledDev ++ *! is Global.DevObject stores this pointer as hDevNode. ++ *! 02-Dec-1999 rr: DBG_SetGT and RetailMSG conditionally included. ++ *! Comments changed.Deinit handled.Code cleaned up. ++ *! DSP_IOControl, Close, Deinit returns bool values. ++ *! Calls WCD_InitComplete2 for Board AutoStart. ++ *! 29-Nov-1999 rr: DSP_IOControl returns the result through pBufOut. ++ *! Global Arrays keeps track of installed devices. ++ *! 19-Nov-1999 rr: DSP_Init handles multiple drivers. ++ *! 12-Nov-1999 rr: GetDriverKey and EnumerateKey functions added. ++ *! for multiple mini driver support.PCCARD flag ++ *! checking to include PCMCIA related stuff. ++ *! 25-Oct-1999 rr: GT_Init is called within the Process Attach. ++ *! return value initalized to S_OK upfront in the ++ *! Process Attach. ++ *! 15-Oct-1999 rr: DSP_DeInit handles the return values ++ *! 05-Oct-1999 rr: All the PCMCIA related functions are now in PCCARD.c ++ *! DRV_Request Resources is used instead of the ++ *! RegisterMiniDriver as it sounds close to what we are doing. ++ *! 24-Sep-1999 rr: DRV_RegisterMiniDriver is being called from here. Only ++ *! neccessaryPCMCIA fxns are here. Soon they will move out ++ *! either to a seperate file for bus specific inits. ++ *! 10-Sep-1999 rr: GT Enabled. Considerably changed the driver structure as ++ *! - This is the Class driver. After successfully initialized ++ *! the Class driver will attempt to load the Mini driver. ++ *! - Need to seperate the PCMCIA stuff based on bus type. ++ *! - Changed the name of the file to wcdce.c ++ *! - Made the Media Handle as Global again ++ *! ++ *! 19-Aug-1999 rr: Removed the Global hbhMediaHandle. Included the MemTest. ++ *! Modified the DSP_Init, now three windows are opened. ++ *! Split the driver into PDD so that hardware dependent ++ *! functions will reside in PDD. ++ *! 16-Jul-1999 ag Adapted from rkw's CAC Bullet card driver. ++ *! ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Resource Manager */ ++#include ++ ++/* ----------------------------------- Others */ ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++/* ----------------------------------- Globals */ ++struct GT_Mask curTrace; ++ ++/* ++ * ======== DSP_Init ======== ++ * Allocates bridge resources. Loads a base image onto DSP, if specified. ++ */ ++u32 DSP_Init(OUT u32 *initStatus) ++{ ++ char devNode[MAXREGPATHLENGTH] = "TIOMAP1510"; ++ DSP_STATUS status = DSP_EFAIL; ++ struct DRV_OBJECT *drvObject = NULL; ++ u32 index = 0; ++ u32 deviceNode; ++ u32 deviceNodeString; ++ ++ GT_create(&curTrace, "DD"); ++ ++ GT_0trace(curTrace, GT_ENTER, "Entering DSP_Init \r\n"); ++ ++ if (DSP_FAILED(WCD_Init())) { ++ GT_0trace(curTrace, GT_7CLASS, "DSP_Init Failed \n"); ++ goto func_cont; ++ } /* End WCD_Exit */ ++ if (DSP_FAILED(DRV_Create(&drvObject))) { ++ GT_0trace(curTrace, GT_7CLASS, "DSP_Init:DRV_Create Failed \n"); ++ WCD_Exit(); ++ goto func_cont; ++ } /* End DRV_Create */ ++ GT_0trace(curTrace, GT_5CLASS, "DSP_Init:DRV Created \r\n"); ++ ++ /* Request Resources */ ++ if (DSP_SUCCEEDED(DRV_RequestResources((u32)&devNode, ++ &deviceNodeString))) { ++ /* Attempt to Start the Device */ ++ if (DSP_SUCCEEDED(DEV_StartDevice( ++ (struct CFG_DEVNODE *)deviceNodeString))) { ++ /* Retreive the DevObject from the Registry */ ++ GT_2trace(curTrace, GT_1CLASS, ++ "DSP_Init Succeeded for Device1:" ++ "%d: value: %x\n", index, deviceNodeString); ++ status = DSP_SOK; ++ } else { ++ GT_0trace(curTrace, GT_7CLASS, ++ "DSP_Init:DEV_StartDevice Failed\n"); ++ (void)DRV_ReleaseResources ++ ((u32) deviceNodeString, drvObject); ++ status = DSP_EFAIL; ++ } ++ } else { ++ GT_0trace(curTrace, GT_7CLASS, ++ "DSP_Init:DRV_RequestResources Failed \r\n"); ++ status = DSP_EFAIL; ++ } /* DRV_RequestResources */ ++ index++; ++ ++ /* Unwind whatever was loaded */ ++ if (DSP_FAILED(status)) { ++ /* irrespective of the status of DEV_RemoveDevice we conitinue ++ * unloading. Get the Driver Object iterate through and remove. ++ * Reset the status to E_FAIL to avoid going through ++ * WCD_InitComplete2. */ ++ status = DSP_EFAIL; ++ for (deviceNode = DRV_GetFirstDevExtension(); deviceNode != 0; ++ deviceNode = DRV_GetNextDevExtension(deviceNode)) { ++ (void)DEV_RemoveDevice ++ ((struct CFG_DEVNODE *)deviceNode); ++ (void)DRV_ReleaseResources((u32)deviceNode, ++ drvObject); ++ } ++ /* Remove the Driver Object */ ++ (void)DRV_Destroy(drvObject); ++ drvObject = NULL; ++ WCD_Exit(); ++ GT_0trace(curTrace, GT_7CLASS, ++ "DSP_Init:Logical device Failed to Load\n"); ++ } /* Unwinding the loaded drivers */ ++func_cont: ++ /* Attempt to Start the Board */ ++ if (DSP_SUCCEEDED(status)) { ++ /* BRD_AutoStart could fail if the dsp execuetable is not the ++ * correct one. We should not propagate that error ++ * into the device loader. */ ++ (void)WCD_InitComplete2(); ++ GT_0trace(curTrace, GT_1CLASS, "DSP_Init Succeeded\n"); ++ } else { ++ GT_0trace(curTrace, GT_7CLASS, "DSP_Init Failed\n"); ++ } /* End WCD_InitComplete2 */ ++ DBC_Ensure((DSP_SUCCEEDED(status) && drvObject != NULL) || ++ (DSP_FAILED(status) && drvObject == NULL)); ++ *initStatus = status; ++ /* Return the Driver Object */ ++ return (u32)drvObject; ++} ++ ++/* ++ * ======== DSP_Deinit ======== ++ * Frees the resources allocated for bridge. ++ */ ++bool DSP_Deinit(u32 deviceContext) ++{ ++ bool retVal = true; ++ u32 deviceNode; ++ struct MGR_OBJECT *mgrObject = NULL; ++ ++ GT_0trace(curTrace, GT_ENTER, "Entering DSP_Deinit \r\n"); ++ ++ while ((deviceNode = DRV_GetFirstDevExtension()) != 0) { ++ (void)DEV_RemoveDevice((struct CFG_DEVNODE *)deviceNode); ++ ++ (void)DRV_ReleaseResources((u32)deviceNode, ++ (struct DRV_OBJECT *)deviceContext); ++ } ++ ++ (void) DRV_Destroy((struct DRV_OBJECT *) deviceContext); ++ ++ /* Get the Manager Object from Registry ++ * MGR Destroy will unload the DCD dll */ ++ if (DSP_SUCCEEDED(CFG_GetObject((u32 *)&mgrObject, REG_MGR_OBJECT))) ++ (void)MGR_Destroy(mgrObject); ++ ++ WCD_Exit(); ++ ++ return retVal; ++} ++ ++/* ++ * ======== DSP_Close ======== ++ * The Calling Process handle is passed to DEV_CleanupProcesState ++ * for cleaning up of any resources used by the application ++ */ ++bool DSP_Close(u32 dwOpenContext) ++{ ++ bool retVal = false; ++ ++ DBC_Require(dwOpenContext != 0); ++ ++ GT_0trace(curTrace, GT_ENTER, "Entering DSP_Close\n"); ++ ++#ifdef RES_CLEANUP_DISABLE ++ ++ if (DSP_SUCCEEDED(DEV_CleanupProcessState((HANDLE) dwOpenContext))) { ++ GT_0trace(curTrace, GT_1CLASS, "DSP_Close Succeeded \r\n"); ++ retVal = true; ++ } else { ++ GT_0trace(curTrace, GT_7CLASS, "DSP_Close failed \r\n"); ++ } ++#endif ++ ++ return retVal; ++} +diff --git a/drivers/dsp/bridge/rmgr/mgr.c b/drivers/dsp/bridge/rmgr/mgr.c +new file mode 100644 +index 0000000..943cf93 +--- /dev/null ++++ b/drivers/dsp/bridge/rmgr/mgr.c +@@ -0,0 +1,491 @@ ++/* ++ * mgr.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== mgr.c ======== ++ * Description: ++ * Implementation of Manager interface to the device object at the ++ * driver level. This queries the NDB data base and retrieves the ++ * data about Node and Processor. ++ * ++ * ++ *! Revision History: ++ *! ================ ++ *! 12-Feb-2003 vp: Code review updates. ++ *! 18-Oct-2002 vp: Ported to Linux platform ++ *! 01-Aug-2001 ag: Added extended info for DSP-MMU setup support. ++ *! 13-Feb-2001 kc: DSP/BIOS Bridge name updates. ++ *! 22-Nov-2000 kc: Added MGR_GetPerfData. ++ *! 03-Nov-2000 rr: Updated after code review. ++ *! 25-Sep-2000 rr: Updated to Version 0.9 ++ *! 10-Aug-2000 rr: dwSignature is not specifically inserted in MGR Obj ++ *! as it is taken care by MEM_AllocObject. stdwin.h added ++ *! for retail build to succeed. ++ *! 07-Aug-2000 rr: MGR_Create does the job of Loading DCD Dll. ++ *! 26-Jul-2000 rr: MGR_Destroy releases the hNDBDll. ++ *! 20-Jun-2000 rr: Created. ++ */ ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Others */ ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++/* ----------------------------------- Defines, Data Structures, Typedefs */ ++#define ZLDLLNAME "" ++#define SIGNATURE 0x5f52474d /* "MGR_" (in reverse) */ ++ ++struct MGR_OBJECT { ++ u32 dwSignature; ++ struct DCD_MANAGER *hDcdMgr; /* Proc/Node data manager */ ++}; ++ ++/* ----------------------------------- Globals */ ++#if GT_TRACE ++static struct GT_Mask MGR_DebugMask = { NULL, NULL }; ++#endif ++ ++static u32 cRefs; ++ ++/* ++ * ========= MGR_Create ========= ++ * Purpose: ++ * MGR Object gets created only once during driver Loading. ++ */ ++DSP_STATUS MGR_Create(OUT struct MGR_OBJECT **phMgrObject, ++ struct CFG_DEVNODE *hDevNode) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct MGR_OBJECT *pMgrObject = NULL; ++ ++ DBC_Require(phMgrObject != NULL); ++ DBC_Require(cRefs > 0); ++ GT_1trace(MGR_DebugMask, GT_ENTER, ++ "Entering MGR_Create phMgrObject 0x%x\n ", ++ phMgrObject); ++ MEM_AllocObject(pMgrObject, struct MGR_OBJECT, SIGNATURE); ++ if (pMgrObject) { ++ if (DSP_SUCCEEDED(DCD_CreateManager(ZLDLLNAME, ++ &pMgrObject->hDcdMgr))) { ++ /* If succeeded store the handle in the MGR Object */ ++ if (DSP_SUCCEEDED(CFG_SetObject((u32)pMgrObject, ++ REG_MGR_OBJECT))) { ++ *phMgrObject = pMgrObject; ++ GT_0trace(MGR_DebugMask, GT_1CLASS, ++ "MGR_Create:MGR Created\r\n"); ++ } else { ++ status = DSP_EFAIL; ++ GT_0trace(MGR_DebugMask, GT_7CLASS, ++ "MGR_Create:CFG_SetObject " ++ "Failed\r\n"); ++ DCD_DestroyManager(pMgrObject->hDcdMgr); ++ MEM_FreeObject(pMgrObject); ++ } ++ } else { ++ /* failed to Create DCD Manager */ ++ status = DSP_EFAIL; ++ GT_0trace(MGR_DebugMask, GT_7CLASS, ++ "MGR_Create:DCD_ManagerCreate Failed\r\n"); ++ MEM_FreeObject(pMgrObject); ++ } ++ } else { ++ status = DSP_EMEMORY; ++ GT_0trace(MGR_DebugMask, GT_7CLASS, ++ "MGR_Create DSP_FAILED to allocate memory \n"); ++ } ++ GT_2trace(MGR_DebugMask, GT_ENTER, ++ "Exiting MGR_Create: phMgrObject: 0x%x\t" ++ "status: 0x%x\n", phMgrObject, status); ++ DBC_Ensure(DSP_FAILED(status) || ++ MEM_IsValidHandle(pMgrObject, SIGNATURE)); ++ return status; ++} ++ ++/* ++ * ========= MGR_Destroy ========= ++ * This function is invoked during bridge driver unloading.Frees MGR object. ++ */ ++DSP_STATUS MGR_Destroy(struct MGR_OBJECT *hMgrObject) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct MGR_OBJECT *pMgrObject = (struct MGR_OBJECT *)hMgrObject; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(hMgrObject, SIGNATURE)); ++ ++ GT_1trace(MGR_DebugMask, GT_ENTER, ++ "Entering MGR_Destroy hMgrObject 0x%x\n", hMgrObject); ++ /* Free resources */ ++ if (hMgrObject->hDcdMgr) ++ DCD_DestroyManager(hMgrObject->hDcdMgr); ++ ++ MEM_FreeObject(pMgrObject); ++ /* Update the Registry with NULL for MGR Object */ ++ (void)CFG_SetObject(0, REG_MGR_OBJECT); ++ ++ GT_2trace(MGR_DebugMask, GT_ENTER, ++ "Exiting MGR_Destroy: hMgrObject: 0x%x\t" ++ "status: 0x%x\n", hMgrObject, status); ++ ++ DBC_Ensure(DSP_FAILED(status) || ++ !MEM_IsValidHandle(hMgrObject, SIGNATURE)); ++ ++ return status; ++} ++ ++/* ++ * ======== MGR_EnumNodeInfo ======== ++ * Enumerate and get configuration information about nodes configured ++ * in the node database. ++ */ ++DSP_STATUS MGR_EnumNodeInfo(u32 uNode, OUT struct DSP_NDBPROPS *pNDBProps, ++ u32 uNDBPropsSize, OUT u32 *puNumNodes) ++{ ++ DSP_STATUS status = DSP_SOK; ++ DSP_STATUS status1 = DSP_SOK; ++ struct DSP_UUID Uuid, uTempUuid; ++ u32 uTempIndex = 0; ++ u32 uNodeIndex = 0; ++ struct DCD_GENERICOBJ GenObj; ++ struct MGR_OBJECT *pMgrObject = NULL; ++ ++ DBC_Require(pNDBProps != NULL); ++ DBC_Require(puNumNodes != NULL); ++ DBC_Require(uNDBPropsSize >= sizeof(struct DSP_NDBPROPS)); ++ DBC_Require(cRefs > 0); ++ ++ GT_4trace(MGR_DebugMask, GT_ENTER, "Entered Manager_EnumNodeInfo, " ++ "args:\n\t uNode: 0x%x\n\tpNDBProps: 0x%x\n\tuNDBPropsSize:" ++ "0x%x\tpuNumNodes: 0x%x\n", uNode, pNDBProps, ++ uNDBPropsSize, puNumNodes); ++ *puNumNodes = 0; ++ /* Get The Manager Object from the Registry */ ++ if (DSP_FAILED(CFG_GetObject((u32 *)&pMgrObject, ++ REG_MGR_OBJECT))) { ++ GT_0trace(MGR_DebugMask, GT_7CLASS, ++ "Manager_EnumNodeInfo:Failed To Get" ++ " MGR Object from Registry\r\n"); ++ goto func_cont; ++ } ++ DBC_Assert(MEM_IsValidHandle(pMgrObject, SIGNATURE)); ++ /* Forever loop till we hit failed or no more items in the ++ * Enumeration. We will exit the loop other than DSP_SOK; */ ++ while (status == DSP_SOK) { ++ status = DCD_EnumerateObject(uTempIndex++, DSP_DCDNODETYPE, ++ &uTempUuid); ++ if (status == DSP_SOK) { ++ uNodeIndex++; ++ if (uNode == (uNodeIndex - 1)) ++ Uuid = uTempUuid; ++ ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ if (uNode > (uNodeIndex - 1)) { ++ status = DSP_EINVALIDARG; ++ GT_0trace(MGR_DebugMask, GT_7CLASS, ++ "Manager_EnumNodeInfo: uNode" ++ " is Invalid \r\n"); ++ } else { ++ status1 = DCD_GetObjectDef(pMgrObject->hDcdMgr, ++ (struct DSP_UUID *)&Uuid, ++ DSP_DCDNODETYPE, &GenObj); ++ if (DSP_SUCCEEDED(status1)) { ++ /* Get the Obj def */ ++ *pNDBProps = GenObj.objData.nodeObj.ndbProps; ++ *puNumNodes = uNodeIndex; ++ status = DSP_SOK; ++ } else { ++ GT_0trace(MGR_DebugMask, GT_7CLASS, ++ "Manager_EnumNodeInfo: " ++ "Failed to Get Node Info \r\n"); ++ status = DSP_EFAIL; ++ } ++ } ++ } else { ++ /* This could be changed during enum, EFAIL ... */ ++ GT_0trace(MGR_DebugMask, GT_7CLASS, "Manager_EnumNodeInfo: " ++ "Enumeration failure\r\n"); ++ status = DSP_EFAIL; ++ } ++func_cont: ++ GT_4trace(MGR_DebugMask, GT_ENTER, ++ "Exiting Manager_EnumNodeInfo, args:\n\t" ++ "uNode: 0x%x\n\tpNDBProps: 0x%x\n\tuNDBPropsSize:" ++ " 0x%x\tuNumNodes: 0x%x\n", uNode, pNDBProps, ++ uNDBPropsSize, *puNumNodes); ++ DBC_Ensure((DSP_SUCCEEDED(status) && *puNumNodes > 0) || ++ (DSP_FAILED(status) && *puNumNodes == 0)); ++ ++ return status; ++} ++ ++/* ++ * ======== MGR_EnumProcessorInfo ======== ++ * Enumerate and get configuration information about available ++ * DSP processors. ++ */ ++DSP_STATUS MGR_EnumProcessorInfo(u32 uProcessor, ++ OUT struct DSP_PROCESSORINFO *pProcessorInfo, ++ u32 uProcessorInfoSize, OUT u32 *puNumProcs) ++{ ++ DSP_STATUS status = DSP_SOK; ++ DSP_STATUS status1 = DSP_SOK; ++ DSP_STATUS status2 = DSP_SOK; ++ struct DSP_UUID uTempUuid; ++ u32 uTempIndex = 0; ++ u32 uProcIndex = 0; ++ struct DCD_GENERICOBJ GenObj; ++ struct MGR_OBJECT *pMgrObject = NULL; ++ struct MGR_PROCESSOREXTINFO *pExtInfo; ++ struct DEV_OBJECT *hDevObject; ++ struct DRV_OBJECT *hDrvObject; ++ s32 devType; ++ struct CFG_DEVNODE *devNode; ++ struct CFG_DSPRES chipResources; ++ bool procDetect = false; ++ ++ DBC_Require(pProcessorInfo != NULL); ++ DBC_Require(puNumProcs != NULL); ++ DBC_Require(uProcessorInfoSize >= sizeof(struct DSP_PROCESSORINFO)); ++ DBC_Require(cRefs > 0); ++ ++ GT_4trace(MGR_DebugMask, GT_ENTER, ++ "Entered Manager_EnumProcessorInfo, " ++ "args:\n\tuProcessor: 0x%x\n\tpProcessorInfo: 0x%x\n\t" ++ "uProcessorInfoSize: 0x%x\tpuNumProcs: 0x%x\n", uProcessor, ++ pProcessorInfo, uProcessorInfoSize, puNumProcs); ++ *puNumProcs = 0; ++ status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT); ++ if (DSP_SUCCEEDED(status)) { ++ status = DRV_GetDevObject(uProcessor, hDrvObject, &hDevObject); ++ if (DSP_SUCCEEDED(status)) { ++ status = DEV_GetDevType(hDevObject, (u32 *) &devType); ++ status = DEV_GetDevNode(hDevObject, &devNode); ++ if (devType == DSP_UNIT) { ++ status = CFG_GetDSPResources(devNode, ++ &chipResources); ++ } else { ++ status = DSP_EFAIL; ++ GT_1trace(MGR_DebugMask, GT_7CLASS, ++ "Unsupported dev type gotten" ++ "from device object %d\n", devType); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ pProcessorInfo->uProcessorType = ++ chipResources.uChipType; ++ } ++ } ++ } ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ /* Get The Manager Object from the Registry */ ++ if (DSP_FAILED(CFG_GetObject((u32 *)&pMgrObject, ++ REG_MGR_OBJECT))) { ++ GT_0trace(MGR_DebugMask, GT_7CLASS, ++ "Manager_EnumProcessorInfo: " ++ "Failed To Get MGR Object from Registry\r\n"); ++ goto func_end; ++ } ++ DBC_Assert(MEM_IsValidHandle(pMgrObject, SIGNATURE)); ++ /* Forever loop till we hit no more items in the ++ * Enumeration. We will exit the loop other than DSP_SOK; */ ++ while (status1 == DSP_SOK) { ++ status1 = DCD_EnumerateObject(uTempIndex++, ++ DSP_DCDPROCESSORTYPE, ++ &uTempUuid); ++ if (status1 != DSP_SOK) ++ break; ++ ++ uProcIndex++; ++ /* Get the Object properties to find the Device/Processor ++ * Type */ ++ if (procDetect != false) ++ continue; ++ ++ status2 = DCD_GetObjectDef(pMgrObject->hDcdMgr, ++ (struct DSP_UUID *)&uTempUuid, ++ DSP_DCDPROCESSORTYPE, ++ &GenObj); ++ if (DSP_SUCCEEDED(status2)) { ++ /* Get the Obj def */ ++ if (uProcessorInfoSize < ++ sizeof(struct MGR_PROCESSOREXTINFO)) { ++ *pProcessorInfo = GenObj.objData.procObj; ++ } else { ++ /* extended info */ ++ pExtInfo = (struct MGR_PROCESSOREXTINFO *) ++ pProcessorInfo; ++ *pExtInfo = GenObj.objData.extProcObj; ++ } ++ GT_1trace(MGR_DebugMask, GT_7CLASS, ++ "Manager_EnumProcessorInfo: Got" ++ " Proctype from DCD %x \r\n", ++ pProcessorInfo->uProcessorType); ++ /* See if we got the needed processor */ ++ if (devType == DSP_UNIT) { ++ if (pProcessorInfo->uProcessorType == ++ DSPPROCTYPE_C64) ++ procDetect = true; ++ } else if (devType == IVA_UNIT) { ++ if (pProcessorInfo->uProcessorType == ++ IVAPROCTYPE_ARM7) ++ procDetect = true; ++ } ++ /* User applciatiuons aonly check for chip type, so ++ * this clumsy overwrite */ ++ pProcessorInfo->uProcessorType = ++ chipResources.uChipType; ++ } else { ++ GT_1trace(MGR_DebugMask, GT_7CLASS, ++ "Manager_EnumProcessorInfo: " ++ "Failed to Get DCD Processor Info %x \r\n", ++ status2); ++ status = DSP_EFAIL; ++ } ++ } ++ *puNumProcs = uProcIndex; ++ if (procDetect == false) { ++ GT_0trace(MGR_DebugMask, GT_7CLASS, ++ "Manager_EnumProcessorInfo: Failed" ++ " to get Proc info from DCD , so use CFG registry\n"); ++ pProcessorInfo->uProcessorType = chipResources.uChipType; ++ } ++func_end: ++ return status; ++} ++ ++/* ++ * ======== MGR_Exit ======== ++ * Decrement reference count, and free resources when reference count is ++ * 0. ++ */ ++void MGR_Exit(void) ++{ ++ DBC_Require(cRefs > 0); ++ cRefs--; ++ if (cRefs == 0) ++ DCD_Exit(); ++ ++ GT_1trace(MGR_DebugMask, GT_5CLASS, ++ "Entered MGR_Exit, ref count: 0x%x\n", cRefs); ++ DBC_Ensure(cRefs >= 0); ++} ++ ++/* ++ * ======== MGR_GetDCDHandle ======== ++ * Retrieves the MGR handle. Accessor Function. ++ */ ++DSP_STATUS MGR_GetDCDHandle(struct MGR_OBJECT *hMGRHandle, ++ OUT u32 *phDCDHandle) ++{ ++ DSP_STATUS status = DSP_EFAIL; ++ struct MGR_OBJECT *pMgrObject = (struct MGR_OBJECT *)hMGRHandle; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phDCDHandle != NULL); ++ ++ *phDCDHandle = (u32)NULL; ++ if (MEM_IsValidHandle(pMgrObject, SIGNATURE)) { ++ *phDCDHandle = (u32) pMgrObject->hDcdMgr; ++ status = DSP_SOK; ++ } ++ DBC_Ensure((DSP_SUCCEEDED(status) && *phDCDHandle != (u32)NULL) || ++ (DSP_FAILED(status) && *phDCDHandle == (u32)NULL)); ++ ++ return status; ++} ++ ++/* ++ * ======== MGR_Init ======== ++ * Initialize MGR's private state, keeping a reference count on each call. ++ */ ++bool MGR_Init(void) ++{ ++ bool fRetval = true; ++ bool fInitDCD = false; ++ ++ DBC_Require(cRefs >= 0); ++ ++ if (cRefs == 0) { ++ ++ /* Set the Trace mask */ ++ DBC_Assert(!MGR_DebugMask.flags); ++ ++ GT_create(&MGR_DebugMask, "MG"); /* "MG" for Manager */ ++ fInitDCD = DCD_Init(); /* DCD Module */ ++ ++ if (!fInitDCD) { ++ fRetval = false; ++ GT_0trace(MGR_DebugMask, GT_6CLASS, ++ "MGR_Init failed\n"); ++ } ++ } ++ ++ if (fRetval) ++ cRefs++; ++ ++ ++ GT_1trace(MGR_DebugMask, GT_5CLASS, ++ "Entered MGR_Init, ref count: 0x%x\n", cRefs); ++ DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0))); ++ ++ return fRetval; ++} ++ ++/* ++ * ======== MGR_WaitForBridgeEvents ======== ++ * Block on any Bridge event(s) ++ */ ++DSP_STATUS MGR_WaitForBridgeEvents(struct DSP_NOTIFICATION **aNotifications, ++ u32 uCount, OUT u32 *puIndex, u32 uTimeout) ++{ ++ DSP_STATUS status; ++ struct SYNC_OBJECT *hSyncEvents[MAX_EVENTS]; ++ u32 i; ++ ++ DBC_Require(uCount < MAX_EVENTS); ++ ++ for (i = 0; i < uCount; i++) ++ hSyncEvents[i] = aNotifications[i]->handle; ++ ++ status = SYNC_WaitOnMultipleEvents(hSyncEvents, uCount, uTimeout, ++ puIndex); ++ ++ return status; ++ ++} ++ +diff --git a/drivers/dsp/bridge/rmgr/nldr.c b/drivers/dsp/bridge/rmgr/nldr.c +new file mode 100644 +index 0000000..f3c429c +--- /dev/null ++++ b/drivers/dsp/bridge/rmgr/nldr.c +@@ -0,0 +1,1967 @@ ++/* ++ * nldr.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== nldr.c ======== ++ * Description: ++ * DSP/BIOS Bridge dynamic + overlay Node loader. ++ * ++ * Public Functions: ++ * NLDR_Allocate ++ * NLDR_Create ++ * NLDR_Delete ++ * NLDR_Exit ++ * NLDR_Free ++ * NLDR_GetFxnAddr ++ * NLDR_Init ++ * NLDR_Load ++ * NLDR_Unload ++ * ++ * Notes: ++ * ++ *! Revision History ++ *! ================ ++ *! 07-Apr-2003 map Removed references to dead DLDR module ++ *! 23-Jan-2003 map Updated RemoteAlloc to support memory granularity ++ *! 20-Jan-2003 map Updated to maintain persistent dependent libraries ++ *! 15-Jan-2003 map Adapted for use with multiple dynamic phase libraries ++ *! 19-Dec-2002 map Fixed overlay bug in AddOvlySect for overlay ++ *! sections > 1024 bytes. ++ *! 13-Dec-2002 map Fixed NLDR_GetFxnAddr bug by searching dependent ++ *! libs for symbols ++ *! 27-Sep-2002 map Added RemoteFree to convert size to words for ++ *! correct deallocation ++ *! 16-Sep-2002 map Code Review Cleanup(from dldr.c) ++ *! 29-Aug-2002 map Adjusted for ARM-side overlay copy ++ *! 05-Aug-2002 jeh Created. ++ */ ++ ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++#ifdef DEBUG ++#include ++#endif ++ ++/* OS adaptation layer */ ++#include ++#include ++ ++/* Platform manager */ ++#include ++#include ++ ++/* Resource manager */ ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define NLDR_SIGNATURE 0x52444c4e /* "RDLN" */ ++#define NLDR_NODESIGNATURE 0x4e444c4e /* "NDLN" */ ++ ++/* Name of section containing dynamic load mem */ ++#define DYNMEMSECT ".dspbridge_mem" ++ ++/* Name of section containing dependent library information */ ++#define DEPLIBSECT ".dspbridge_deplibs" ++ ++/* Max depth of recursion for loading node's dependent libraries */ ++#define MAXDEPTH 5 ++ ++/* Max number of persistent libraries kept by a node */ ++#define MAXLIBS 5 ++ ++/* ++ * Defines for extracting packed dynamic load memory requirements from two ++ * masks. ++ * These defines must match node.cdb and dynm.cdb ++ * Format of data/code mask is: ++ * uuuuuuuu|fueeeeee|fudddddd|fucccccc| ++ * where ++ * u = unused ++ * cccccc = prefered/required dynamic mem segid for create phase data/code ++ * dddddd = prefered/required dynamic mem segid for delete phase data/code ++ * eeeeee = prefered/req. dynamic mem segid for execute phase data/code ++ * f = flag indicating if memory is preferred or required: ++ * f = 1 if required, f = 0 if preferred. ++ * ++ * The 6 bits of the segid are interpreted as follows: ++ * ++ * If the 6th bit (bit 5) is not set, then this specifies a memory segment ++ * between 0 and 31 (a maximum of 32 dynamic loading memory segments). ++ * If the 6th bit (bit 5) is set, segid has the following interpretation: ++ * segid = 32 - Any internal memory segment can be used. ++ * segid = 33 - Any external memory segment can be used. ++ * segid = 63 - Any memory segment can be used (in this case the ++ * required/preferred flag is irrelevant). ++ * ++ */ ++/* Maximum allowed dynamic loading memory segments */ ++#define MAXMEMSEGS 32 ++ ++#define MAXSEGID 3 /* Largest possible (real) segid */ ++#define MEMINTERNALID 32 /* Segid meaning use internal mem */ ++#define MEMEXTERNALID 33 /* Segid meaning use external mem */ ++#define NULLID 63 /* Segid meaning no memory req/pref */ ++#define FLAGBIT 7 /* 7th bit is pref./req. flag */ ++#define SEGMASK 0x3f /* Bits 0 - 5 */ ++ ++#define CREATEBIT 0 /* Create segid starts at bit 0 */ ++#define DELETEBIT 8 /* Delete segid starts at bit 8 */ ++#define EXECUTEBIT 16 /* Execute segid starts at bit 16 */ ++ ++/* ++ * Masks that define memory type. Must match defines in dynm.cdb. ++ */ ++#define DYNM_CODE 0x2 ++#define DYNM_DATA 0x4 ++#define DYNM_CODEDATA (DYNM_CODE | DYNM_DATA) ++#define DYNM_INTERNAL 0x8 ++#define DYNM_EXTERNAL 0x10 ++ ++/* ++ * Defines for packing memory requirement/preference flags for code and ++ * data of each of the node's phases into one mask. ++ * The bit is set if the segid is required for loading code/data of the ++ * given phase. The bit is not set, if the segid is preferred only. ++ * ++ * These defines are also used as indeces into a segid array for the node. ++ * eg node's segid[CREATEDATAFLAGBIT] is the memory segment id that the ++ * create phase data is required or preferred to be loaded into. ++ */ ++#define CREATEDATAFLAGBIT 0 ++#define CREATECODEFLAGBIT 1 ++#define EXECUTEDATAFLAGBIT 2 ++#define EXECUTECODEFLAGBIT 3 ++#define DELETEDATAFLAGBIT 4 ++#define DELETECODEFLAGBIT 5 ++#define MAXFLAGS 6 ++ ++#define IsInternal(hNldr, segid) (((segid) <= MAXSEGID && \ ++ hNldr->segTable[(segid)] & DYNM_INTERNAL) || \ ++ (segid) == MEMINTERNALID) ++ ++#define IsExternal(hNldr, segid) (((segid) <= MAXSEGID && \ ++ hNldr->segTable[(segid)] & DYNM_EXTERNAL) || \ ++ (segid) == MEMEXTERNALID) ++ ++#define SWAPLONG(x) ((((x) << 24) & 0xFF000000) | (((x) << 8) & 0xFF0000L) | \ ++ (((x) >> 8) & 0xFF00L) | (((x) >> 24) & 0xFF)) ++ ++#define SWAPWORD(x) ((((x) << 8) & 0xFF00) | (((x) >> 8) & 0xFF)) ++ ++ /* ++ * These names may be embedded in overlay sections to identify which ++ * node phase the section should be overlayed. ++ */ ++#define PCREATE "create" ++#define PDELETE "delete" ++#define PEXECUTE "execute" ++ ++#define IsEqualUUID(uuid1, uuid2) (\ ++ ((uuid1).ulData1 == (uuid2).ulData1) && \ ++ ((uuid1).usData2 == (uuid2).usData2) && \ ++ ((uuid1).usData3 == (uuid2).usData3) && \ ++ ((uuid1).ucData4 == (uuid2).ucData4) && \ ++ ((uuid1).ucData5 == (uuid2).ucData5) && \ ++ (strncmp((void *)(uuid1).ucData6, (void *)(uuid2).ucData6, 6)) == 0) ++ ++ /* ++ * ======== MemInfo ======== ++ * Format of dynamic loading memory segment info in coff file. ++ * Must match dynm.h55. ++ */ ++struct MemInfo { ++ u32 segid; /* Dynamic loading memory segment number */ ++ u32 base; ++ u32 len; ++ u32 type; /* Mask of DYNM_CODE, DYNM_INTERNAL, etc. */ ++}; ++ ++/* ++ * ======== LibNode ======== ++ * For maintaining a tree of library dependencies. ++ */ ++struct LibNode { ++ struct DBLL_LibraryObj *lib; /* The library */ ++ u16 nDepLibs; /* Number of dependent libraries */ ++ struct LibNode *pDepLibs; /* Dependent libraries of lib */ ++}; ++ ++/* ++ * ======== OvlySect ======== ++ * Information needed to overlay a section. ++ */ ++struct OvlySect { ++ struct OvlySect *pNextSect; ++ u32 loadAddr; /* Load address of section */ ++ u32 runAddr; /* Run address of section */ ++ u32 size; /* Size of section */ ++ u16 page; /* DBL_CODE, DBL_DATA */ ++}; ++ ++/* ++ * ======== OvlyNode ======== ++ * For maintaining a list of overlay nodes, with sections that need to be ++ * overlayed for each of the nodes phases. ++ */ ++struct OvlyNode { ++ struct DSP_UUID uuid; ++ char *pNodeName; ++ struct OvlySect *pCreateSects; ++ struct OvlySect *pDeleteSects; ++ struct OvlySect *pExecuteSects; ++ struct OvlySect *pOtherSects; ++ u16 nCreateSects; ++ u16 nDeleteSects; ++ u16 nExecuteSects; ++ u16 nOtherSects; ++ u16 createRef; ++ u16 deleteRef; ++ u16 executeRef; ++ u16 otherRef; ++}; ++ ++/* ++ * ======== NLDR_OBJECT ======== ++ * Overlay loader object. ++ */ ++struct NLDR_OBJECT { ++ u32 dwSignature; /* For object validation */ ++ struct DEV_OBJECT *hDevObject; /* Device object */ ++ struct DCD_MANAGER *hDcdMgr; /* Proc/Node data manager */ ++ struct DBLL_TarObj *dbll; /* The DBL loader */ ++ struct DBLL_LibraryObj *baseLib; /* Base image library */ ++ struct RMM_TargetObj *rmm; /* Remote memory manager for DSP */ ++ struct DBLL_Fxns dbllFxns; /* Loader function table */ ++ struct DBLL_Attrs dbllAttrs; /* attrs to pass to loader functions */ ++ NLDR_OVLYFXN ovlyFxn; /* "write" for overlay nodes */ ++ NLDR_WRITEFXN writeFxn; /* "write" for dynamic nodes */ ++ struct OvlyNode *ovlyTable; /* Table of overlay nodes */ ++ u16 nOvlyNodes; /* Number of overlay nodes in base */ ++ u16 nNode; /* Index for tracking overlay nodes */ ++ u16 nSegs; /* Number of dynamic load mem segs */ ++ u32 *segTable; /* memtypes of dynamic memory segs ++ * indexed by segid ++ */ ++ u16 usDSPMauSize; /* Size of DSP MAU */ ++ u16 usDSPWordSize; /* Size of DSP word */ ++}; ++ ++/* ++ * ======== NLDR_NODEOBJECT ======== ++ * Dynamic node object. This object is created when a node is allocated. ++ */ ++struct NLDR_NODEOBJECT { ++ u32 dwSignature; /* For object validation */ ++ struct NLDR_OBJECT *pNldr; /* Dynamic loader handle */ ++ void *pPrivRef; /* Handle to pass to DBL_WriteFxn */ ++ struct DSP_UUID uuid; /* Node's UUID */ ++ bool fDynamic; /* Dynamically loaded node? */ ++ bool fOverlay; /* Overlay node? */ ++ bool *pfPhaseSplit; /* Multiple phase libraries? */ ++ struct LibNode root; /* Library containing node phase */ ++ struct LibNode createLib; /* Library containing create phase lib */ ++ struct LibNode executeLib; /* Library containing execute phase lib */ ++ struct LibNode deleteLib; /* Library containing delete phase lib */ ++ struct LibNode persLib[MAXLIBS]; /* libs remain loaded until Delete */ ++ s32 nPersLib; /* Number of persistent libraries */ ++ /* Path in lib dependency tree */ ++ struct DBLL_LibraryObj *libPath[MAXDEPTH + 1]; ++ enum NLDR_PHASE phase; /* Node phase currently being loaded */ ++ ++ /* ++ * Dynamic loading memory segments for data and code of each phase. ++ */ ++ u16 segId[MAXFLAGS]; ++ ++ /* ++ * Mask indicating whether each mem segment specified in segId[] ++ * is preferred or required. ++ * For example if (codeDataFlagMask & (1 << EXECUTEDATAFLAGBIT)) != 0, ++ * then it is required to load execute phase data into the memory ++ * specified by segId[EXECUTEDATAFLAGBIT]. ++ */ ++ u32 codeDataFlagMask; ++}; ++ ++/* Dynamic loader function table */ ++static struct DBLL_Fxns dbllFxns = { ++ (DBLL_CloseFxn) DBLL_close, ++ (DBLL_CreateFxn) DBLL_create, ++ (DBLL_DeleteFxn) DBLL_delete, ++ (DBLL_ExitFxn) DBLL_exit, ++ (DBLL_GetAttrsFxn) DBLL_getAttrs, ++ (DBLL_GetAddrFxn) DBLL_getAddr, ++ (DBLL_GetCAddrFxn) DBLL_getCAddr, ++ (DBLL_GetSectFxn) DBLL_getSect, ++ (DBLL_InitFxn) DBLL_init, ++ (DBLL_LoadFxn) DBLL_load, ++ (DBLL_LoadSectFxn) DBLL_loadSect, ++ (DBLL_OpenFxn) DBLL_open, ++ (DBLL_ReadSectFxn) DBLL_readSect, ++ (DBLL_SetAttrsFxn) DBLL_setAttrs, ++ (DBLL_UnloadFxn) DBLL_unload, ++ (DBLL_UnloadSectFxn) DBLL_unloadSect, ++}; ++ ++static struct GT_Mask NLDR_debugMask = { NULL, NULL }; /* GT trace variable */ ++static u32 cRefs; /* module reference count */ ++ ++static DSP_STATUS AddOvlyInfo(void *handle, struct DBLL_SectInfo *sectInfo, ++ u32 addr, u32 nBytes); ++static DSP_STATUS AddOvlyNode(struct DSP_UUID *pUuid, ++ enum DSP_DCDOBJTYPE objType, ++ IN void *handle); ++static DSP_STATUS AddOvlySect(struct NLDR_OBJECT *hNldr, ++ struct OvlySect **pList, ++ struct DBLL_SectInfo *pSectInfo, bool *pExists, ++ u32 addr, u32 nBytes); ++static s32 fakeOvlyWrite(void *handle, u32 dspAddr, void *buf, u32 nBytes, ++ s32 mtype); ++static void FreeSects(struct NLDR_OBJECT *hNldr, struct OvlySect *pPhaseSects, ++ u16 nAlloc); ++static bool GetSymbolValue(void *handle, void *pArg, void *rmmHandle, ++ char *symName, struct DBLL_Symbol **sym); ++static DSP_STATUS LoadLib(struct NLDR_NODEOBJECT *hNldrNode, ++ struct LibNode *root, struct DSP_UUID uuid, ++ bool rootPersistent, struct DBLL_LibraryObj **libPath, ++ enum NLDR_PHASE phase, u16 depth); ++static DSP_STATUS LoadOvly(struct NLDR_NODEOBJECT *hNldrNode, ++ enum NLDR_PHASE phase); ++static DSP_STATUS RemoteAlloc(void **pRef, u16 memType, u32 size, ++ u32 align, u32 *dspAddr, ++ OPTIONAL s32 segmentId, OPTIONAL s32 req, ++ bool reserve); ++static DSP_STATUS RemoteFree(void **pRef, u16 space, u32 dspAddr, ++ u32 size, bool reserve); ++ ++static void UnloadLib(struct NLDR_NODEOBJECT *hNldrNode, struct LibNode *root); ++static void UnloadOvly(struct NLDR_NODEOBJECT *hNldrNode, ++ enum NLDR_PHASE phase); ++static bool findInPersistentLibArray(struct NLDR_NODEOBJECT *hNldrNode, ++ struct DBLL_LibraryObj *lib); ++static u32 findLcm(u32 a, u32 b); ++static u32 findGcf(u32 a, u32 b); ++ ++/* ++ * ======== NLDR_Allocate ======== ++ */ ++DSP_STATUS NLDR_Allocate(struct NLDR_OBJECT *hNldr, void *pPrivRef, ++ IN CONST struct DCD_NODEPROPS *pNodeProps, ++ OUT struct NLDR_NODEOBJECT **phNldrNode, ++ IN bool *pfPhaseSplit) ++{ ++ struct NLDR_NODEOBJECT *pNldrNode = NULL; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pNodeProps != NULL); ++ DBC_Require(phNldrNode != NULL); ++ DBC_Require(MEM_IsValidHandle(hNldr, NLDR_SIGNATURE)); ++ ++ GT_5trace(NLDR_debugMask, GT_ENTER, "NLDR_Allocate(0x%x, 0x%x, 0x%x, " ++ "0x%x, 0x%x)\n", hNldr, pPrivRef, pNodeProps, phNldrNode, ++ pfPhaseSplit); ++ ++ /* Initialize handle in case of failure */ ++ *phNldrNode = NULL; ++ /* Allocate node object */ ++ MEM_AllocObject(pNldrNode, struct NLDR_NODEOBJECT, NLDR_NODESIGNATURE); ++ ++ if (pNldrNode == NULL) { ++ GT_0trace(NLDR_debugMask, GT_6CLASS, "NLDR_Allocate: " ++ "Memory allocation failed\n"); ++ status = DSP_EMEMORY; ++ } else { ++ pNldrNode->pfPhaseSplit = pfPhaseSplit; ++ pNldrNode->nPersLib = 0; ++ pNldrNode->pNldr = hNldr; ++ pNldrNode->pPrivRef = pPrivRef; ++ /* Save node's UUID. */ ++ pNldrNode->uuid = pNodeProps->ndbProps.uiNodeID; ++ /* ++ * Determine if node is a dynamically loaded node from ++ * ndbProps. ++ */ ++ if (pNodeProps->usLoadType == NLDR_DYNAMICLOAD) { ++ /* Dynamic node */ ++ pNldrNode->fDynamic = true; ++ /* ++ * Extract memory requirements from ndbProps masks ++ */ ++ /* Create phase */ ++ pNldrNode->segId[CREATEDATAFLAGBIT] = (u16) ++ (pNodeProps->ulDataMemSegMask >> CREATEBIT) & ++ SEGMASK; ++ pNldrNode->codeDataFlagMask |= ++ ((pNodeProps->ulDataMemSegMask >> ++ (CREATEBIT + FLAGBIT)) & 1) << ++ CREATEDATAFLAGBIT; ++ pNldrNode->segId[CREATECODEFLAGBIT] = (u16) ++ (pNodeProps->ulCodeMemSegMask >> ++ CREATEBIT) & SEGMASK; ++ pNldrNode->codeDataFlagMask |= ++ ((pNodeProps->ulCodeMemSegMask >> ++ (CREATEBIT + FLAGBIT)) & 1) << ++ CREATECODEFLAGBIT; ++ /* Execute phase */ ++ pNldrNode->segId[EXECUTEDATAFLAGBIT] = (u16) ++ (pNodeProps->ulDataMemSegMask >> ++ EXECUTEBIT) & SEGMASK; ++ pNldrNode->codeDataFlagMask |= ++ ((pNodeProps->ulDataMemSegMask >> ++ (EXECUTEBIT + FLAGBIT)) & 1) << ++ EXECUTEDATAFLAGBIT; ++ pNldrNode->segId[EXECUTECODEFLAGBIT] = (u16) ++ (pNodeProps->ulCodeMemSegMask >> ++ EXECUTEBIT) & SEGMASK; ++ pNldrNode->codeDataFlagMask |= ++ ((pNodeProps->ulCodeMemSegMask >> ++ (EXECUTEBIT + FLAGBIT)) & 1) << ++ EXECUTECODEFLAGBIT; ++ /* Delete phase */ ++ pNldrNode->segId[DELETEDATAFLAGBIT] = (u16) ++ (pNodeProps->ulDataMemSegMask >> DELETEBIT) & ++ SEGMASK; ++ pNldrNode->codeDataFlagMask |= ++ ((pNodeProps->ulDataMemSegMask >> ++ (DELETEBIT + FLAGBIT)) & 1) << ++ DELETEDATAFLAGBIT; ++ pNldrNode->segId[DELETECODEFLAGBIT] = (u16) ++ (pNodeProps->ulCodeMemSegMask >> ++ DELETEBIT) & SEGMASK; ++ pNldrNode->codeDataFlagMask |= ++ ((pNodeProps->ulCodeMemSegMask >> ++ (DELETEBIT + FLAGBIT)) & 1) << ++ DELETECODEFLAGBIT; ++ } else { ++ /* Non-dynamically loaded nodes are part of the ++ * base image */ ++ pNldrNode->root.lib = hNldr->baseLib; ++ /* Check for overlay node */ ++ if (pNodeProps->usLoadType == NLDR_OVLYLOAD) ++ pNldrNode->fOverlay = true; ++ ++ } ++ *phNldrNode = (struct NLDR_NODEOBJECT *) pNldrNode; ++ } ++ /* Cleanup on failure */ ++ if (DSP_FAILED(status) && pNldrNode) ++ NLDR_Free((struct NLDR_NODEOBJECT *) pNldrNode); ++ ++ DBC_Ensure((DSP_SUCCEEDED(status) && ++ MEM_IsValidHandle(((struct NLDR_NODEOBJECT *)(*phNldrNode)), ++ NLDR_NODESIGNATURE)) || (DSP_FAILED(status) && ++ *phNldrNode == NULL)); ++ return status; ++} ++ ++/* ++ * ======== NLDR_Create ======== ++ */ ++DSP_STATUS NLDR_Create(OUT struct NLDR_OBJECT **phNldr, ++ struct DEV_OBJECT *hDevObject, ++ IN CONST struct NLDR_ATTRS *pAttrs) ++{ ++ struct COD_MANAGER *hCodMgr; /* COD manager */ ++ char *pszCoffBuf = NULL; ++ char szZLFile[COD_MAXPATHLENGTH]; ++ struct NLDR_OBJECT *pNldr = NULL; ++ struct DBLL_Attrs saveAttrs; ++ struct DBLL_Attrs newAttrs; ++ DBLL_Flags flags; ++ u32 ulEntry; ++ u16 nSegs = 0; ++ struct MemInfo *pMemInfo; ++ u32 ulLen = 0; ++ u32 ulAddr; ++ struct RMM_Segment *rmmSegs = NULL; ++ u16 i; ++ DSP_STATUS status = DSP_SOK; ++ DBC_Require(cRefs > 0); ++ DBC_Require(phNldr != NULL); ++ DBC_Require(hDevObject != NULL); ++ DBC_Require(pAttrs != NULL); ++ DBC_Require(pAttrs->pfnOvly != NULL); ++ DBC_Require(pAttrs->pfnWrite != NULL); ++ GT_3trace(NLDR_debugMask, GT_ENTER, "NLDR_Create(0x%x, 0x%x, 0x%x)\n", ++ phNldr, hDevObject, pAttrs); ++ /* Allocate dynamic loader object */ ++ MEM_AllocObject(pNldr, struct NLDR_OBJECT, NLDR_SIGNATURE); ++ if (pNldr) { ++ pNldr->hDevObject = hDevObject; ++ /* warning, lazy status checking alert! */ ++ status = DEV_GetCodMgr(hDevObject, &hCodMgr); ++ DBC_Assert(DSP_SUCCEEDED(status)); ++ status = COD_GetLoader(hCodMgr, &pNldr->dbll); ++ DBC_Assert(DSP_SUCCEEDED(status)); ++ status = COD_GetBaseLib(hCodMgr, &pNldr->baseLib); ++ DBC_Assert(DSP_SUCCEEDED(status)); ++ status = COD_GetBaseName(hCodMgr, szZLFile, COD_MAXPATHLENGTH); ++ DBC_Assert(DSP_SUCCEEDED(status)); ++ status = DSP_SOK; ++ /* end lazy status checking */ ++ pNldr->usDSPMauSize = pAttrs->usDSPMauSize; ++ pNldr->usDSPWordSize = pAttrs->usDSPWordSize; ++ pNldr->dbllFxns = dbllFxns; ++ if (!(pNldr->dbllFxns.initFxn())) ++ status = DSP_EMEMORY; ++ ++ } else { ++ GT_0trace(NLDR_debugMask, GT_6CLASS, "NLDR_Create: " ++ "Memory allocation failed\n"); ++ status = DSP_EMEMORY; ++ } ++ /* Create the DCD Manager */ ++ if (DSP_SUCCEEDED(status)) ++ status = DCD_CreateManager(NULL, &pNldr->hDcdMgr); ++ ++ /* Get dynamic loading memory sections from base lib */ ++ if (DSP_SUCCEEDED(status)) { ++ status = pNldr->dbllFxns.getSectFxn(pNldr->baseLib, DYNMEMSECT, ++ &ulAddr, &ulLen); ++ if (DSP_SUCCEEDED(status)) { ++ pszCoffBuf = MEM_Calloc(ulLen * pNldr->usDSPMauSize, ++ MEM_PAGED); ++ if (!pszCoffBuf) { ++ GT_0trace(NLDR_debugMask, GT_6CLASS, ++ "NLDR_Create: Memory " ++ "allocation failed\n"); ++ status = DSP_EMEMORY; ++ } ++ } else { ++ /* Ok to not have dynamic loading memory */ ++ status = DSP_SOK; ++ ulLen = 0; ++ GT_1trace(NLDR_debugMask, GT_6CLASS, ++ "NLDR_Create: DBLL_getSect " ++ "failed (no dynamic loading mem segments): " ++ "0x%lx\n", status); ++ } ++ } ++ if (DSP_SUCCEEDED(status) && ulLen > 0) { ++ /* Read section containing dynamic load mem segments */ ++ status = pNldr->dbllFxns.readSectFxn(pNldr->baseLib, DYNMEMSECT, ++ pszCoffBuf, ulLen); ++ if (DSP_FAILED(status)) { ++ GT_1trace(NLDR_debugMask, GT_6CLASS, ++ "NLDR_Create: DBLL_read Section" ++ "failed: 0x%lx\n", status); ++ } ++ } ++ if (DSP_SUCCEEDED(status) && ulLen > 0) { ++ /* Parse memory segment data */ ++ nSegs = (u16)(*((u32 *)pszCoffBuf)); ++ if (nSegs > MAXMEMSEGS) { ++ GT_1trace(NLDR_debugMask, GT_6CLASS, ++ "NLDR_Create: Invalid number of " ++ "dynamic load mem segments: 0x%lx\n", nSegs); ++ status = DSP_ECORRUPTFILE; ++ } ++ } ++ /* Parse dynamic load memory segments */ ++ if (DSP_SUCCEEDED(status) && nSegs > 0) { ++ rmmSegs = MEM_Calloc(sizeof(struct RMM_Segment) * nSegs, ++ MEM_PAGED); ++ pNldr->segTable = MEM_Calloc(sizeof(u32) * nSegs, MEM_PAGED); ++ if (rmmSegs == NULL || pNldr->segTable == NULL) { ++ status = DSP_EMEMORY; ++ } else { ++ pNldr->nSegs = nSegs; ++ pMemInfo = (struct MemInfo *)(pszCoffBuf + ++ sizeof(u32)); ++ for (i = 0; i < nSegs; i++) { ++ rmmSegs[i].base = (pMemInfo + i)->base; ++ rmmSegs[i].length = (pMemInfo + i)->len; ++ rmmSegs[i].space = 0; ++ pNldr->segTable[i] = (pMemInfo + i)->type; ++#ifdef DEBUG ++ DBG_Trace(DBG_LEVEL7, ++ "** (proc) DLL MEMSEGMENT: %d, Base: 0x%x, " ++ "Length: 0x%x\n", i, rmmSegs[i].base, ++ rmmSegs[i].length); ++#endif ++ } ++ } ++ } ++ /* Create Remote memory manager */ ++ if (DSP_SUCCEEDED(status)) ++ status = RMM_create(&pNldr->rmm, rmmSegs, nSegs); ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* set the alloc, free, write functions for loader */ ++ pNldr->dbllFxns.getAttrsFxn(pNldr->dbll, &saveAttrs); ++ newAttrs = saveAttrs; ++ newAttrs.alloc = (DBLL_AllocFxn) RemoteAlloc; ++ newAttrs.free = (DBLL_FreeFxn) RemoteFree; ++ newAttrs.symLookup = (DBLL_SymLookup) GetSymbolValue; ++ newAttrs.symHandle = pNldr; ++ newAttrs.write = (DBLL_WriteFxn) pAttrs->pfnWrite; ++ pNldr->ovlyFxn = pAttrs->pfnOvly; ++ pNldr->writeFxn = pAttrs->pfnWrite; ++ pNldr->dbllAttrs = newAttrs; ++ } ++ if (rmmSegs) ++ MEM_Free(rmmSegs); ++ ++ if (pszCoffBuf) ++ MEM_Free(pszCoffBuf); ++ ++ /* Get overlay nodes */ ++ if (DSP_SUCCEEDED(status)) { ++ status = COD_GetBaseName(hCodMgr, szZLFile, COD_MAXPATHLENGTH); ++ /* lazy check */ ++ DBC_Assert(DSP_SUCCEEDED(status)); ++ /* First count number of overlay nodes */ ++ status = DCD_GetObjects(pNldr->hDcdMgr, szZLFile, AddOvlyNode, ++ (void *) pNldr); ++ /* Now build table of overlay nodes */ ++ if (DSP_SUCCEEDED(status) && pNldr->nOvlyNodes > 0) { ++ /* Allocate table for overlay nodes */ ++ pNldr->ovlyTable = ++ MEM_Calloc(sizeof(struct OvlyNode) * pNldr->nOvlyNodes, ++ MEM_PAGED); ++ /* Put overlay nodes in the table */ ++ pNldr->nNode = 0; ++ status = DCD_GetObjects(pNldr->hDcdMgr, szZLFile, ++ AddOvlyNode, ++ (void *) pNldr); ++ } ++ } ++ /* Do a fake reload of the base image to get overlay section info */ ++ if (DSP_SUCCEEDED(status) && pNldr->nOvlyNodes > 0) { ++ saveAttrs.write = fakeOvlyWrite; ++ saveAttrs.logWrite = AddOvlyInfo; ++ saveAttrs.logWriteHandle = pNldr; ++ flags = DBLL_CODE | DBLL_DATA | DBLL_SYMB; ++ status = pNldr->dbllFxns.loadFxn(pNldr->baseLib, flags, ++ &saveAttrs, &ulEntry); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ *phNldr = (struct NLDR_OBJECT *) pNldr; ++ } else { ++ if (pNldr) ++ NLDR_Delete((struct NLDR_OBJECT *) pNldr); ++ ++ *phNldr = NULL; ++ } ++ /* FIXME:Temp. Fix. Must be removed */ ++ DBC_Ensure((DSP_SUCCEEDED(status) && ++ MEM_IsValidHandle(((struct NLDR_OBJECT *)*phNldr), ++ NLDR_SIGNATURE)) ++ || (DSP_FAILED(status) && (*phNldr == NULL))); ++ return status; ++} ++ ++/* ++ * ======== NLDR_Delete ======== ++ */ ++void NLDR_Delete(struct NLDR_OBJECT *hNldr) ++{ ++ struct OvlySect *pSect; ++ struct OvlySect *pNext; ++ u16 i; ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(hNldr, NLDR_SIGNATURE)); ++ GT_1trace(NLDR_debugMask, GT_ENTER, "NLDR_Delete(0x%x)\n", hNldr); ++ hNldr->dbllFxns.exitFxn(); ++ if (hNldr->rmm) ++ RMM_delete(hNldr->rmm); ++ ++ if (hNldr->segTable) ++ MEM_Free(hNldr->segTable); ++ ++ if (hNldr->hDcdMgr) ++ DCD_DestroyManager(hNldr->hDcdMgr); ++ ++ /* Free overlay node information */ ++ if (hNldr->ovlyTable) { ++ for (i = 0; i < hNldr->nOvlyNodes; i++) { ++ pSect = hNldr->ovlyTable[i].pCreateSects; ++ while (pSect) { ++ pNext = pSect->pNextSect; ++ MEM_Free(pSect); ++ pSect = pNext; ++ } ++ pSect = hNldr->ovlyTable[i].pDeleteSects; ++ while (pSect) { ++ pNext = pSect->pNextSect; ++ MEM_Free(pSect); ++ pSect = pNext; ++ } ++ pSect = hNldr->ovlyTable[i].pExecuteSects; ++ while (pSect) { ++ pNext = pSect->pNextSect; ++ MEM_Free(pSect); ++ pSect = pNext; ++ } ++ pSect = hNldr->ovlyTable[i].pOtherSects; ++ while (pSect) { ++ pNext = pSect->pNextSect; ++ MEM_Free(pSect); ++ pSect = pNext; ++ } ++ } ++ MEM_Free(hNldr->ovlyTable); ++ } ++ MEM_FreeObject(hNldr); ++ DBC_Ensure(!MEM_IsValidHandle(hNldr, NLDR_SIGNATURE)); ++} ++ ++/* ++ * ======== NLDR_Exit ======== ++ * Discontinue usage of NLDR module. ++ */ ++void NLDR_Exit(void) ++{ ++ DBC_Require(cRefs > 0); ++ ++ cRefs--; ++ ++ GT_1trace(NLDR_debugMask, GT_5CLASS, ++ "Entered NLDR_Exit, ref count: 0x%x\n", cRefs); ++ ++ if (cRefs == 0) { ++ RMM_exit(); ++ NLDR_debugMask.flags = NULL; ++ } ++ ++ DBC_Ensure(cRefs >= 0); ++} ++ ++/* ++ * ======== NLDR_Free ======== ++ */ ++void NLDR_Free(struct NLDR_NODEOBJECT *hNldrNode) ++{ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(hNldrNode, NLDR_NODESIGNATURE)); ++ ++ GT_1trace(NLDR_debugMask, GT_ENTER, "NLDR_Free(0x%x)\n", hNldrNode); ++ ++ MEM_FreeObject(hNldrNode); ++} ++ ++/* ++ * ======== NLDR_GetFxnAddr ======== ++ */ ++DSP_STATUS NLDR_GetFxnAddr(struct NLDR_NODEOBJECT *hNldrNode, char *pstrFxn, ++ u32 *pulAddr) ++{ ++ struct DBLL_Symbol *pSym; ++ struct NLDR_OBJECT *hNldr; ++ DSP_STATUS status = DSP_SOK; ++ bool status1 = false; ++ s32 i = 0; ++ struct LibNode root = { NULL, 0, NULL }; ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(hNldrNode, NLDR_NODESIGNATURE)); ++ DBC_Require(pulAddr != NULL); ++ DBC_Require(pstrFxn != NULL); ++ GT_3trace(NLDR_debugMask, GT_ENTER, "NLDR_GetFxnAddr(0x%x, %s, 0x%x)\n", ++ hNldrNode, pstrFxn, pulAddr); ++ ++ hNldr = hNldrNode->pNldr; ++ /* Called from NODE_Create(), NODE_Delete(), or NODE_Run(). */ ++ if (hNldrNode->fDynamic && *hNldrNode->pfPhaseSplit) { ++ switch (hNldrNode->phase) { ++ case NLDR_CREATE: ++ root = hNldrNode->createLib; ++ break; ++ case NLDR_EXECUTE: ++ root = hNldrNode->executeLib; ++ break; ++ case NLDR_DELETE: ++ root = hNldrNode->deleteLib; ++ break; ++ default: ++ DBC_Assert(false); ++ break; ++ } ++ } else { ++ /* for Overlay nodes or non-split Dynamic nodes */ ++ root = hNldrNode->root; ++ } ++ status1 = hNldr->dbllFxns.getCAddrFxn(root.lib, pstrFxn, &pSym); ++ if (!status1) ++ status1 = hNldr->dbllFxns.getAddrFxn(root.lib, pstrFxn, &pSym); ++ ++ /* If symbol not found, check dependent libraries */ ++ if (!status1) { ++ for (i = 0; i < root.nDepLibs; i++) { ++ status1 = hNldr->dbllFxns.getAddrFxn(root.pDepLibs[i]. ++ lib, pstrFxn, &pSym); ++ if (!status1) { ++ status1 = hNldr->dbllFxns.getCAddrFxn(root. ++ pDepLibs[i].lib, pstrFxn, &pSym); ++ } ++ if (status1) { ++ /* Symbol found */ ++ break; ++ } ++ } ++ } ++ /* Check persistent libraries */ ++ if (!status1) { ++ for (i = 0; i < hNldrNode->nPersLib; i++) { ++ status1 = hNldr->dbllFxns.getAddrFxn(hNldrNode-> ++ persLib[i].lib, pstrFxn, &pSym); ++ if (!status1) { ++ status1 = ++ hNldr->dbllFxns.getCAddrFxn(hNldrNode-> ++ persLib[i].lib, pstrFxn, &pSym); ++ } ++ if (status1) { ++ /* Symbol found */ ++ break; ++ } ++ } ++ } ++ ++ if (status1) { ++ *pulAddr = pSym->value; ++ } else { ++ GT_1trace(NLDR_debugMask, GT_6CLASS, ++ "NLDR_GetFxnAddr: Symbol not found: " ++ "%s\n", pstrFxn); ++ status = DSP_ESYMBOL; ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== NLDR_GetRmmManager ======== ++ * Given a NLDR object, retrieve RMM Manager Handle ++ */ ++DSP_STATUS NLDR_GetRmmManager(struct NLDR_OBJECT *hNldrObject, ++ OUT struct RMM_TargetObj **phRmmMgr) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct NLDR_OBJECT *pNldrObject = hNldrObject; ++ DBC_Require(phRmmMgr != NULL); ++ GT_2trace(NLDR_debugMask, GT_ENTER, "NLDR_GetRmmManager(0x%x, 0x%x)\n", ++ hNldrObject, phRmmMgr); ++ if (MEM_IsValidHandle(hNldrObject, NLDR_SIGNATURE)) { ++ *phRmmMgr = pNldrObject->rmm; ++ } else { ++ *phRmmMgr = NULL; ++ status = DSP_EHANDLE; ++ GT_0trace(NLDR_debugMask, GT_7CLASS, ++ "NLDR_GetRmmManager:Invalid handle"); ++ } ++ ++ GT_2trace(NLDR_debugMask, GT_ENTER, "Exit NLDR_GetRmmManager: status " ++ "0x%x\n\tphRmmMgr: 0x%x\n", status, *phRmmMgr); ++ ++ DBC_Ensure(DSP_SUCCEEDED(status) || ((phRmmMgr != NULL) && ++ (*phRmmMgr == NULL))); ++ ++ return status; ++} ++ ++/* ++ * ======== NLDR_Init ======== ++ * Initialize the NLDR module. ++ */ ++bool NLDR_Init(void) ++{ ++ DBC_Require(cRefs >= 0); ++ ++ if (cRefs == 0) { ++ DBC_Assert(!NLDR_debugMask.flags); ++ GT_create(&NLDR_debugMask, "DL"); /* "DL" for DLdr */ ++ ++ RMM_init(); ++ } ++ ++ cRefs++; ++ ++ GT_1trace(NLDR_debugMask, GT_5CLASS, "NLDR_Init(), ref count: 0x%x\n", ++ cRefs); ++ ++ DBC_Ensure(cRefs > 0); ++ return true; ++} ++ ++/* ++ * ======== NLDR_Load ======== ++ */ ++DSP_STATUS NLDR_Load(struct NLDR_NODEOBJECT *hNldrNode, enum NLDR_PHASE phase) ++{ ++ struct NLDR_OBJECT *hNldr; ++ struct DSP_UUID libUUID; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(hNldrNode, NLDR_NODESIGNATURE)); ++ ++ hNldr = hNldrNode->pNldr; ++ ++ GT_2trace(NLDR_debugMask, GT_ENTER, "NLDR_Load(0x%x, 0x%x)\n", ++ hNldrNode, phase); ++ ++ if (hNldrNode->fDynamic) { ++ hNldrNode->phase = phase; ++ ++ libUUID = hNldrNode->uuid; ++ ++ /* At this point, we may not know if node is split into ++ * different libraries. So we'll go ahead and load the ++ * library, and then save the pointer to the appropriate ++ * location after we know. */ ++ ++ status = LoadLib(hNldrNode, &hNldrNode->root, libUUID, false, ++ hNldrNode->libPath, phase, 0); ++ ++ if (DSP_SUCCEEDED(status)) { ++ if (*hNldrNode->pfPhaseSplit) { ++ switch (phase) { ++ case NLDR_CREATE: ++ hNldrNode->createLib = hNldrNode->root; ++ break; ++ ++ case NLDR_EXECUTE: ++ hNldrNode->executeLib = hNldrNode->root; ++ break; ++ ++ case NLDR_DELETE: ++ hNldrNode->deleteLib = hNldrNode->root; ++ break; ++ ++ default: ++ DBC_Assert(false); ++ break; ++ } ++ } ++ } ++ } else { ++ if (hNldrNode->fOverlay) ++ status = LoadOvly(hNldrNode, phase); ++ ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== NLDR_Unload ======== ++ */ ++DSP_STATUS NLDR_Unload(struct NLDR_NODEOBJECT *hNldrNode, enum NLDR_PHASE phase) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct LibNode *pRootLib = NULL; ++ s32 i = 0; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(hNldrNode, NLDR_NODESIGNATURE)); ++ GT_2trace(NLDR_debugMask, GT_ENTER, "NLDR_Unload(0x%x, 0x%x)\n", ++ hNldrNode, phase); ++ if (hNldrNode != NULL) { ++ if (hNldrNode->fDynamic) { ++ if (*hNldrNode->pfPhaseSplit) { ++ switch (phase) { ++ case NLDR_CREATE: ++ pRootLib = &hNldrNode->createLib; ++ break; ++ case NLDR_EXECUTE: ++ pRootLib = &hNldrNode->executeLib; ++ break; ++ case NLDR_DELETE: ++ pRootLib = &hNldrNode->deleteLib; ++ /* Unload persistent libraries */ ++ for (i = 0; i < hNldrNode->nPersLib; ++ i++) { ++ UnloadLib(hNldrNode, ++ &hNldrNode->persLib[i]); ++ } ++ hNldrNode->nPersLib = 0; ++ break; ++ default: ++ DBC_Assert(false); ++ break; ++ } ++ } else { ++ /* Unload main library */ ++ pRootLib = &hNldrNode->root; ++ } ++ UnloadLib(hNldrNode, pRootLib); ++ } else { ++ if (hNldrNode->fOverlay) ++ UnloadOvly(hNldrNode, phase); ++ ++ } ++ } ++ return status; ++} ++ ++/* ++ * ======== AddOvlyInfo ======== ++ */ ++static DSP_STATUS AddOvlyInfo(void *handle, struct DBLL_SectInfo *sectInfo, ++ u32 addr, u32 nBytes) ++{ ++ char *pNodeName; ++ char *pSectName = (char *)sectInfo->name; ++ bool fExists = false; ++ char seps = ':'; ++ char *pch; ++ u16 i; ++ struct NLDR_OBJECT *hNldr = (struct NLDR_OBJECT *)handle; ++ DSP_STATUS status = DSP_SOK; ++ ++ /* Is this an overlay section (load address != run address)? */ ++ if (sectInfo->loadAddr == sectInfo->runAddr) ++ goto func_end; ++ ++ /* Find the node it belongs to */ ++ for (i = 0; i < hNldr->nOvlyNodes; i++) { ++ pNodeName = hNldr->ovlyTable[i].pNodeName; ++ DBC_Require(pNodeName); ++ if (strncmp(pNodeName, pSectName + 1, ++ strlen(pNodeName)) == 0) { ++ /* Found the node */ ++ break; ++ } ++ } ++ if (!(i < hNldr->nOvlyNodes)) ++ goto func_end; ++ ++ /* Determine which phase this section belongs to */ ++ for (pch = pSectName + 1; *pch && *pch != seps; pch++) ++ ;; ++ ++ if (*pch) { ++ pch++; /* Skip over the ':' */ ++ if (strncmp(pch, PCREATE, strlen(PCREATE)) == 0) { ++ status = AddOvlySect(hNldr, &hNldr->ovlyTable[i]. ++ pCreateSects, sectInfo, &fExists, addr, nBytes); ++ if (DSP_SUCCEEDED(status) && !fExists) ++ hNldr->ovlyTable[i].nCreateSects++; ++ ++ } else ++ if (strncmp(pch, PDELETE, strlen(PDELETE)) == 0) { ++ status = AddOvlySect(hNldr, &hNldr->ovlyTable[i]. ++ pDeleteSects, sectInfo, &fExists, ++ addr, nBytes); ++ if (DSP_SUCCEEDED(status) && !fExists) ++ hNldr->ovlyTable[i].nDeleteSects++; ++ ++ } else ++ if (strncmp(pch, PEXECUTE, strlen(PEXECUTE)) == 0) { ++ status = AddOvlySect(hNldr, &hNldr->ovlyTable[i]. ++ pExecuteSects, sectInfo, &fExists, ++ addr, nBytes); ++ if (DSP_SUCCEEDED(status) && !fExists) ++ hNldr->ovlyTable[i].nExecuteSects++; ++ ++ } else { ++ /* Put in "other" sectins */ ++ status = AddOvlySect(hNldr, &hNldr->ovlyTable[i]. ++ pOtherSects, sectInfo, &fExists, ++ addr, nBytes); ++ if (DSP_SUCCEEDED(status) && !fExists) ++ hNldr->ovlyTable[i].nOtherSects++; ++ ++ } ++ } ++func_end: ++ return status; ++} ++ ++/* ++ * ======== AddOvlyNode ========= ++ * Callback function passed to DCD_GetObjects. ++ */ ++static DSP_STATUS AddOvlyNode(struct DSP_UUID *pUuid, ++ enum DSP_DCDOBJTYPE objType, ++ IN void *handle) ++{ ++ struct NLDR_OBJECT *hNldr = (struct NLDR_OBJECT *)handle; ++ char *pNodeName = NULL; ++ char *pBuf = NULL; ++ u32 uLen; ++ struct DCD_GENERICOBJ objDef; ++ DSP_STATUS status = DSP_SOK; ++ ++ if (objType != DSP_DCDNODETYPE) ++ goto func_end; ++ ++ status = DCD_GetObjectDef(hNldr->hDcdMgr, pUuid, objType, &objDef); ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ /* If overlay node, add to the list */ ++ if (objDef.objData.nodeObj.usLoadType == NLDR_OVLYLOAD) { ++ if (hNldr->ovlyTable == NULL) { ++ hNldr->nOvlyNodes++; ++ } else { ++ /* Add node to table */ ++ hNldr->ovlyTable[hNldr->nNode].uuid = *pUuid; ++ DBC_Require(objDef.objData.nodeObj.ndbProps.acName); ++ uLen = strlen(objDef.objData.nodeObj.ndbProps.acName); ++ pNodeName = objDef.objData.nodeObj.ndbProps.acName; ++ pBuf = MEM_Calloc(uLen + 1, MEM_PAGED); ++ if (pBuf == NULL) { ++ status = DSP_EMEMORY; ++ } else { ++ strncpy(pBuf, pNodeName, uLen); ++ hNldr->ovlyTable[hNldr->nNode].pNodeName = pBuf; ++ hNldr->nNode++; ++ } ++ } ++ } ++ /* These were allocated in DCD_GetObjectDef */ ++ if (objDef.objData.nodeObj.pstrCreatePhaseFxn) ++ MEM_Free(objDef.objData.nodeObj.pstrCreatePhaseFxn); ++ ++ if (objDef.objData.nodeObj.pstrExecutePhaseFxn) ++ MEM_Free(objDef.objData.nodeObj.pstrExecutePhaseFxn); ++ ++ if (objDef.objData.nodeObj.pstrDeletePhaseFxn) ++ MEM_Free(objDef.objData.nodeObj.pstrDeletePhaseFxn); ++ ++ if (objDef.objData.nodeObj.pstrIAlgName) ++ MEM_Free(objDef.objData.nodeObj.pstrIAlgName); ++ ++func_end: ++ return status; ++} ++ ++/* ++ * ======== AddOvlySect ======== ++ */ ++static DSP_STATUS AddOvlySect(struct NLDR_OBJECT *hNldr, ++ struct OvlySect **pList, ++ struct DBLL_SectInfo *pSectInfo, bool *pExists, ++ u32 addr, u32 nBytes) ++{ ++ struct OvlySect *pNewSect = NULL; ++ struct OvlySect *pLastSect; ++ struct OvlySect *pSect; ++ DSP_STATUS status = DSP_SOK; ++ ++ pSect = pLastSect = *pList; ++ *pExists = false; ++ while (pSect) { ++ /* ++ * Make sure section has not already been added. Multiple ++ * 'write' calls may be made to load the section. ++ */ ++ if (pSect->loadAddr == addr) { ++ /* Already added */ ++ *pExists = true; ++ break; ++ } ++ pLastSect = pSect; ++ pSect = pSect->pNextSect; ++ } ++ ++ if (!pSect) { ++ /* New section */ ++ pNewSect = MEM_Calloc(sizeof(struct OvlySect), MEM_PAGED); ++ if (pNewSect == NULL) { ++ status = DSP_EMEMORY; ++ } else { ++ pNewSect->loadAddr = addr; ++ pNewSect->runAddr = pSectInfo->runAddr + ++ (addr - pSectInfo->loadAddr); ++ pNewSect->size = nBytes; ++ pNewSect->page = pSectInfo->type; ++ } ++ ++ /* Add to the list */ ++ if (DSP_SUCCEEDED(status)) { ++ if (*pList == NULL) { ++ /* First in the list */ ++ *pList = pNewSect; ++ } else { ++ pLastSect->pNextSect = pNewSect; ++ } ++ } ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== fakeOvlyWrite ======== ++ */ ++static s32 fakeOvlyWrite(void *handle, u32 dspAddr, void *buf, u32 nBytes, ++ s32 mtype) ++{ ++ return (s32)nBytes; ++} ++ ++/* ++ * ======== FreeSects ======== ++ */ ++static void FreeSects(struct NLDR_OBJECT *hNldr, struct OvlySect *pPhaseSects, ++ u16 nAlloc) ++{ ++ struct OvlySect *pSect = pPhaseSects; ++ u16 i = 0; ++ bool fRet; ++ ++ while (pSect && i < nAlloc) { ++ /* 'Deallocate' */ ++ /* segid - page not supported yet */ ++ /* Reserved memory */ ++ fRet = RMM_free(hNldr->rmm, 0, pSect->runAddr, pSect->size, ++ true); ++ DBC_Assert(fRet); ++ pSect = pSect->pNextSect; ++ i++; ++ } ++} ++ ++/* ++ * ======== GetSymbolValue ======== ++ * Find symbol in library's base image. If not there, check dependent ++ * libraries. ++ */ ++static bool GetSymbolValue(void *handle, void *pArg, void *rmmHandle, ++ char *name, struct DBLL_Symbol **sym) ++{ ++ struct NLDR_OBJECT *hNldr = (struct NLDR_OBJECT *)handle; ++ struct NLDR_NODEOBJECT *hNldrNode = (struct NLDR_NODEOBJECT *)rmmHandle; ++ struct LibNode *root = (struct LibNode *)pArg; ++ u16 i; ++ bool status = false; ++ ++ /* check the base image */ ++ status = hNldr->dbllFxns.getAddrFxn(hNldr->baseLib, name, sym); ++ if (!status) ++ status = hNldr->dbllFxns.getCAddrFxn(hNldr->baseLib, name, sym); ++ ++ /* ++ * Check in root lib itself. If the library consists of ++ * multiple object files linked together, some symbols in the ++ * library may need to be resolved. ++ */ ++ if (!status) { ++ status = hNldr->dbllFxns.getAddrFxn(root->lib, name, sym); ++ if (!status) { ++ status = ++ hNldr->dbllFxns.getCAddrFxn(root->lib, name, sym); ++ } ++ } ++ ++ /* ++ * Check in root lib's dependent libraries, but not dependent ++ * libraries' dependents. ++ */ ++ if (!status) { ++ for (i = 0; i < root->nDepLibs; i++) { ++ status = hNldr->dbllFxns.getAddrFxn(root->pDepLibs[i]. ++ lib, name, sym); ++ if (!status) { ++ status = hNldr->dbllFxns.getCAddrFxn(root-> ++ pDepLibs[i].lib, name, sym); ++ } ++ if (status) { ++ /* Symbol found */ ++ break; ++ } ++ } ++ } ++ /* ++ * Check in persistent libraries ++ */ ++ if (!status) { ++ for (i = 0; i < hNldrNode->nPersLib; i++) { ++ status = hNldr->dbllFxns.getAddrFxn(hNldrNode-> ++ persLib[i].lib, name, sym); ++ if (!status) { ++ status = hNldr->dbllFxns.getCAddrFxn ++ (hNldrNode->persLib[i].lib, name, sym); ++ } ++ if (status) { ++ /* Symbol found */ ++ break; ++ } ++ } ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== LoadLib ======== ++ * Recursively load library and all its dependent libraries. The library ++ * we're loading is specified by a uuid. ++ */ ++static DSP_STATUS LoadLib(struct NLDR_NODEOBJECT *hNldrNode, ++ struct LibNode *root, struct DSP_UUID uuid, ++ bool rootPersistent, struct DBLL_LibraryObj **libPath, ++ enum NLDR_PHASE phase, u16 depth) ++{ ++ struct NLDR_OBJECT *hNldr = hNldrNode->pNldr; ++ u16 nLibs = 0; /* Number of dependent libraries */ ++ u16 nPLibs = 0; /* Number of persistent libraries */ ++ u16 nLoaded = 0; /* Number of dep. libraries loaded */ ++ u16 i; ++ u32 entry; ++ u32 dwBufSize = NLDR_MAXPATHLENGTH; ++ DBLL_Flags flags = DBLL_SYMB | DBLL_CODE | DBLL_DATA | DBLL_DYNAMIC; ++ struct DBLL_Attrs newAttrs; ++ char *pszFileName = NULL; ++ struct DSP_UUID *depLibUUIDs = NULL; ++ bool *persistentDepLibs = NULL; ++ DSP_STATUS status = DSP_SOK; ++ bool fStatus = false; ++ struct LibNode *pDepLib; ++ ++ if (depth > MAXDEPTH) { ++ /* Error */ ++ DBC_Assert(false); ++ } ++ root->lib = NULL; ++ /* Allocate a buffer for library file name of size DBL_MAXPATHLENGTH */ ++ pszFileName = MEM_Calloc(DBLL_MAXPATHLENGTH, MEM_PAGED); ++ if (pszFileName == NULL) ++ status = DSP_EMEMORY; ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* Get the name of the library */ ++ if (depth == 0) { ++ status = DCD_GetLibraryName(hNldrNode->pNldr->hDcdMgr, ++ &uuid, pszFileName, &dwBufSize, phase, ++ hNldrNode->pfPhaseSplit); ++ } else { ++ /* Dependent libraries are registered with a phase */ ++ status = DCD_GetLibraryName(hNldrNode->pNldr->hDcdMgr, ++ &uuid, pszFileName, &dwBufSize, NLDR_NOPHASE, ++ NULL); ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Open the library, don't load symbols */ ++ status = hNldr->dbllFxns.openFxn(hNldr->dbll, pszFileName, ++ DBLL_NOLOAD, &root->lib); ++ } ++ /* Done with file name */ ++ if (pszFileName) ++ MEM_Free(pszFileName); ++ ++ /* Check to see if library not already loaded */ ++ if (DSP_SUCCEEDED(status) && rootPersistent) { ++ fStatus = findInPersistentLibArray(hNldrNode, root->lib); ++ /* Close library */ ++ if (fStatus) { ++ hNldr->dbllFxns.closeFxn(root->lib); ++ return DSP_SALREADYLOADED; ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Check for circular dependencies. */ ++ for (i = 0; i < depth; i++) { ++ if (root->lib == libPath[i]) { ++ /* This condition could be checked by a ++ * tool at build time. */ ++ status = DSP_EDYNLOAD; ++ } ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Add library to current path in dependency tree */ ++ libPath[depth] = root->lib; ++ depth++; ++ /* Get number of dependent libraries */ ++ status = DCD_GetNumDepLibs(hNldrNode->pNldr->hDcdMgr, &uuid, ++ &nLibs, &nPLibs, phase); ++ } ++ DBC_Assert(nLibs >= nPLibs); ++ if (DSP_SUCCEEDED(status)) { ++ if (!(*hNldrNode->pfPhaseSplit)) ++ nPLibs = 0; ++ ++ /* nLibs = #of dependent libraries */ ++ root->nDepLibs = nLibs - nPLibs; ++ if (nLibs > 0) { ++ depLibUUIDs = MEM_Calloc(sizeof(struct DSP_UUID) * ++ nLibs, MEM_PAGED); ++ persistentDepLibs = ++ MEM_Calloc(sizeof(bool) * nLibs, MEM_PAGED); ++ if (!depLibUUIDs || !persistentDepLibs) ++ status = DSP_EMEMORY; ++ ++ if (root->nDepLibs > 0) { ++ /* Allocate arrays for dependent lib UUIDs, ++ * lib nodes */ ++ root->pDepLibs = MEM_Calloc ++ (sizeof(struct LibNode) * ++ (root->nDepLibs), MEM_PAGED); ++ if (!(root->pDepLibs)) ++ status = DSP_EMEMORY; ++ ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* Get the dependent library UUIDs */ ++ status = DCD_GetDepLibs(hNldrNode->pNldr-> ++ hDcdMgr, &uuid, nLibs, depLibUUIDs, ++ persistentDepLibs, phase); ++ } ++ } ++ } ++ ++ /* ++ * Recursively load dependent libraries. ++ */ ++ if (DSP_SUCCEEDED(status) && persistentDepLibs) { ++ for (i = 0; i < nLibs; i++) { ++ /* If root library is NOT persistent, and dep library ++ * is, then record it. If root library IS persistent, ++ * the deplib is already included */ ++ if (!rootPersistent && persistentDepLibs[i] && ++ *hNldrNode->pfPhaseSplit) { ++ if ((hNldrNode->nPersLib) > MAXLIBS) { ++ status = DSP_EDYNLOAD; ++ break; ++ } ++ ++ /* Allocate library outside of phase */ ++ pDepLib = &hNldrNode->persLib[hNldrNode-> ++ nPersLib]; ++ } else { ++ if (rootPersistent) ++ persistentDepLibs[i] = true; ++ ++ ++ /* Allocate library within phase */ ++ pDepLib = &root->pDepLibs[nLoaded]; ++ } ++ ++ if (depLibUUIDs) { ++ status = LoadLib(hNldrNode, pDepLib, ++ depLibUUIDs[i], ++ persistentDepLibs[i], libPath, ++ phase, ++ depth); ++ } else { ++ status = DSP_EMEMORY; ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ if ((status != DSP_SALREADYLOADED) && ++ !rootPersistent && persistentDepLibs[i] && ++ *hNldrNode->pfPhaseSplit) { ++ (hNldrNode->nPersLib)++; ++ } else { ++ if (!persistentDepLibs[i] || ++ !(*hNldrNode->pfPhaseSplit)) { ++ nLoaded++; ++ } ++ } ++ } else { ++ break; ++ } ++ } ++ } ++ ++ /* Now we can load the root library */ ++ if (DSP_SUCCEEDED(status)) { ++ newAttrs = hNldr->dbllAttrs; ++ newAttrs.symArg = root; ++ newAttrs.rmmHandle = hNldrNode; ++ newAttrs.wHandle = hNldrNode->pPrivRef; ++ newAttrs.baseImage = false; ++ ++ status = hNldr->dbllFxns.loadFxn(root->lib, flags, &newAttrs, ++ &entry); ++ } ++ ++ /* ++ * In case of failure, unload any dependent libraries that ++ * were loaded, and close the root library. ++ * (Persistent libraries are unloaded from the very top) ++ */ ++ if (DSP_FAILED(status)) { ++ if (phase != NLDR_EXECUTE) { ++ for (i = 0; i < hNldrNode->nPersLib; i++) ++ UnloadLib(hNldrNode, &hNldrNode->persLib[i]); ++ ++ hNldrNode->nPersLib = 0; ++ } ++ for (i = 0; i < nLoaded; i++) ++ UnloadLib(hNldrNode, &root->pDepLibs[i]); ++ ++ if (root->lib) ++ hNldr->dbllFxns.closeFxn(root->lib); ++ ++ } ++ ++ /* Going up one node in the dependency tree */ ++ depth--; ++ ++ if (depLibUUIDs) { ++ MEM_Free(depLibUUIDs); ++ depLibUUIDs = NULL; ++ } ++ ++ if (persistentDepLibs) { ++ MEM_Free(persistentDepLibs); ++ persistentDepLibs = NULL; ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== LoadOvly ======== ++ */ ++static DSP_STATUS LoadOvly(struct NLDR_NODEOBJECT *hNldrNode, ++ enum NLDR_PHASE phase) ++{ ++ struct NLDR_OBJECT *hNldr = hNldrNode->pNldr; ++ struct OvlyNode *pONode = NULL; ++ struct OvlySect *pPhaseSects = NULL; ++ struct OvlySect *pOtherSects = NULL; ++ u16 i; ++ u16 nAlloc = 0; ++ u16 nOtherAlloc = 0; ++ u16 *pRefCount = NULL; ++ u16 *pOtherRef = NULL; ++ u32 nBytes; ++ struct OvlySect *pSect; ++ DSP_STATUS status = DSP_SOK; ++ ++ /* Find the node in the table */ ++ for (i = 0; i < hNldr->nOvlyNodes; i++) { ++ if (IsEqualUUID(hNldrNode->uuid, hNldr->ovlyTable[i].uuid)) { ++ /* Found it */ ++ pONode = &(hNldr->ovlyTable[i]); ++ break; ++ } ++ } ++ ++ DBC_Assert(i < hNldr->nOvlyNodes); ++ switch (phase) { ++ case NLDR_CREATE: ++ pRefCount = &(pONode->createRef); ++ pOtherRef = &(pONode->otherRef); ++ pPhaseSects = pONode->pCreateSects; ++ pOtherSects = pONode->pOtherSects; ++ break; ++ ++ case NLDR_EXECUTE: ++ pRefCount = &(pONode->executeRef); ++ pPhaseSects = pONode->pExecuteSects; ++ break; ++ ++ case NLDR_DELETE: ++ pRefCount = &(pONode->deleteRef); ++ pPhaseSects = pONode->pDeleteSects; ++ break; ++ ++ default: ++ DBC_Assert(false); ++ break; ++ } ++ ++ DBC_Assert(pRefCount != NULL); ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ if (pRefCount == NULL) ++ goto func_end; ++ ++ if (*pRefCount != 0) ++ goto func_end; ++ ++ /* 'Allocate' memory for overlay sections of this phase */ ++ pSect = pPhaseSects; ++ while (pSect) { ++ /* allocate */ /* page not supported yet */ ++ /* reserve */ /* align */ ++ status = RMM_alloc(hNldr->rmm, 0, pSect->size, 0, ++ &(pSect->runAddr), true); ++ if (DSP_SUCCEEDED(status)) { ++ pSect = pSect->pNextSect; ++ nAlloc++; ++ } else { ++ break; ++ } ++ } ++ if (pOtherRef && *pOtherRef == 0) { ++ /* 'Allocate' memory for other overlay sections ++ * (create phase) */ ++ if (DSP_SUCCEEDED(status)) { ++ pSect = pOtherSects; ++ while (pSect) { ++ /* page not supported */ /* align */ ++ /* reserve */ ++ status = RMM_alloc(hNldr->rmm, 0, pSect->size, ++ 0, &(pSect->runAddr), true); ++ if (DSP_SUCCEEDED(status)) { ++ pSect = pSect->pNextSect; ++ nOtherAlloc++; ++ } else { ++ break; ++ } ++ } ++ } ++ } ++ if (*pRefCount == 0) { ++ if (DSP_SUCCEEDED(status)) { ++ /* Load sections for this phase */ ++ pSect = pPhaseSects; ++ while (pSect && DSP_SUCCEEDED(status)) { ++ nBytes = (*hNldr->ovlyFxn)(hNldrNode->pPrivRef, ++ pSect->runAddr, pSect->loadAddr, ++ pSect->size, pSect->page); ++ if (nBytes != pSect->size) ++ status = DSP_EFAIL; ++ ++ pSect = pSect->pNextSect; ++ } ++ } ++ } ++ if (pOtherRef && *pOtherRef == 0) { ++ if (DSP_SUCCEEDED(status)) { ++ /* Load other sections (create phase) */ ++ pSect = pOtherSects; ++ while (pSect && DSP_SUCCEEDED(status)) { ++ nBytes = (*hNldr->ovlyFxn)(hNldrNode->pPrivRef, ++ pSect->runAddr, pSect->loadAddr, ++ pSect->size, pSect->page); ++ if (nBytes != pSect->size) ++ status = DSP_EFAIL; ++ ++ pSect = pSect->pNextSect; ++ } ++ } ++ } ++ if (DSP_FAILED(status)) { ++ /* 'Deallocate' memory */ ++ FreeSects(hNldr, pPhaseSects, nAlloc); ++ FreeSects(hNldr, pOtherSects, nOtherAlloc); ++ } ++func_end: ++ if (DSP_SUCCEEDED(status) && (pRefCount != NULL)) { ++ *pRefCount += 1; ++ if (pOtherRef) ++ *pOtherRef += 1; ++ ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== RemoteAlloc ======== ++ */ ++static DSP_STATUS RemoteAlloc(void **pRef, u16 space, u32 size, ++ u32 align, u32 *dspAddr, ++ OPTIONAL s32 segmentId, OPTIONAL s32 req, ++ bool reserve) ++{ ++ struct NLDR_NODEOBJECT *hNode = (struct NLDR_NODEOBJECT *)pRef; ++ struct NLDR_OBJECT *hNldr; ++ struct RMM_TargetObj *rmm; ++ u16 memPhaseBit = MAXFLAGS; ++ u16 segid = 0; ++ u16 i; ++ u16 memType; ++ u32 nWords; ++ struct RMM_Addr *pRmmAddr = (struct RMM_Addr *)dspAddr; ++ bool fReq = false; ++ DSP_STATUS status = DSP_EMEMORY; /* Set to fail */ ++ DBC_Require(MEM_IsValidHandle(hNode, NLDR_NODESIGNATURE)); ++ DBC_Require(space == DBLL_CODE || space == DBLL_DATA || ++ space == DBLL_BSS); ++ hNldr = hNode->pNldr; ++ rmm = hNldr->rmm; ++ /* Convert size to DSP words */ ++ nWords = (size + hNldr->usDSPWordSize - 1) / hNldr->usDSPWordSize; ++ /* Modify memory 'align' to account for DSP cache line size */ ++ align = findLcm(GEM_CACHE_LINE_SIZE, align); ++ GT_1trace(NLDR_debugMask, GT_7CLASS, ++ "RemoteAlloc: memory align to 0x%x \n", align); ++ if (segmentId != -1) { ++ pRmmAddr->segid = segmentId; ++ segid = segmentId; ++ fReq = req; ++ } else { ++ switch (hNode->phase) { ++ case NLDR_CREATE: ++ memPhaseBit = CREATEDATAFLAGBIT; ++ break; ++ case NLDR_DELETE: ++ memPhaseBit = DELETEDATAFLAGBIT; ++ break; ++ case NLDR_EXECUTE: ++ memPhaseBit = EXECUTEDATAFLAGBIT; ++ break; ++ default: ++ DBC_Assert(false); ++ break; ++ } ++ if (space == DBLL_CODE) ++ memPhaseBit++; ++ ++ if (memPhaseBit < MAXFLAGS) ++ segid = hNode->segId[memPhaseBit]; ++ ++ /* Determine if there is a memory loading requirement */ ++ if ((hNode->codeDataFlagMask >> memPhaseBit) & 0x1) ++ fReq = true; ++ ++ } ++ memType = (space == DBLL_CODE) ? DYNM_CODE : DYNM_DATA; ++ ++ /* Find an appropriate segment based on space */ ++ if (segid == NULLID) { ++ /* No memory requirements of preferences */ ++ DBC_Assert(!fReq); ++ goto func_cont; ++ } ++ if (segid <= MAXSEGID) { ++ DBC_Assert(segid < hNldr->nSegs); ++ /* Attempt to allocate from segid first. */ ++ pRmmAddr->segid = segid; ++ status = RMM_alloc(rmm, segid, nWords, align, dspAddr, false); ++ if (DSP_FAILED(status)) { ++ GT_1trace(NLDR_debugMask, GT_6CLASS, ++ "RemoteAlloc:Unable allocate " ++ "from segment %d.\n", segid); ++ } ++ } else { ++ /* segid > MAXSEGID ==> Internal or external memory */ ++ DBC_Assert(segid == MEMINTERNALID || segid == MEMEXTERNALID); ++ /* Check for any internal or external memory segment, ++ * depending on segid.*/ ++ memType |= segid == MEMINTERNALID ? ++ DYNM_INTERNAL : DYNM_EXTERNAL; ++ for (i = 0; i < hNldr->nSegs; i++) { ++ if ((hNldr->segTable[i] & memType) != memType) ++ continue; ++ ++ status = RMM_alloc(rmm, i, nWords, align, dspAddr, ++ false); ++ if (DSP_SUCCEEDED(status)) { ++ /* Save segid for freeing later */ ++ pRmmAddr->segid = i; ++ break; ++ } ++ } ++ } ++func_cont: ++ /* Haven't found memory yet, attempt to find any segment that works */ ++ if (status == DSP_EMEMORY && !fReq) { ++ GT_0trace(NLDR_debugMask, GT_6CLASS, ++ "RemoteAlloc: Preferred segment " ++ "unavailable, trying another segment.\n"); ++ for (i = 0; i < hNldr->nSegs; i++) { ++ /* All bits of memType must be set */ ++ if ((hNldr->segTable[i] & memType) != memType) ++ continue; ++ ++ status = RMM_alloc(rmm, i, nWords, align, dspAddr, ++ false); ++ if (DSP_SUCCEEDED(status)) { ++ /* Save segid */ ++ pRmmAddr->segid = i; ++ break; ++ } ++ } ++ } ++ ++ return status; ++} ++ ++static DSP_STATUS RemoteFree(void **pRef, u16 space, u32 dspAddr, ++ u32 size, bool reserve) ++{ ++ struct NLDR_OBJECT *hNldr = (struct NLDR_OBJECT *)pRef; ++ struct RMM_TargetObj *rmm; ++ u32 nWords; ++ DSP_STATUS status = DSP_EMEMORY; /* Set to fail */ ++ ++ DBC_Require(MEM_IsValidHandle(hNldr, NLDR_SIGNATURE)); ++ ++ rmm = hNldr->rmm; ++ ++ /* Convert size to DSP words */ ++ nWords = (size + hNldr->usDSPWordSize - 1) / hNldr->usDSPWordSize; ++ ++ if (RMM_free(rmm, space, dspAddr, nWords, reserve)) ++ status = DSP_SOK; ++ ++ return status; ++} ++ ++/* ++ * ======== UnloadLib ======== ++ */ ++static void UnloadLib(struct NLDR_NODEOBJECT *hNldrNode, struct LibNode *root) ++{ ++ struct DBLL_Attrs newAttrs; ++ struct NLDR_OBJECT *hNldr = hNldrNode->pNldr; ++ u16 i; ++ ++ DBC_Assert(root != NULL); ++ ++ /* Unload dependent libraries */ ++ for (i = 0; i < root->nDepLibs; i++) ++ UnloadLib(hNldrNode, &root->pDepLibs[i]); ++ ++ root->nDepLibs = 0; ++ ++ newAttrs = hNldr->dbllAttrs; ++ newAttrs.rmmHandle = hNldr->rmm; ++ newAttrs.wHandle = hNldrNode->pPrivRef; ++ newAttrs.baseImage = false; ++ newAttrs.symArg = root; ++ ++ if (root->lib) { ++ /* Unload the root library */ ++ hNldr->dbllFxns.unloadFxn(root->lib, &newAttrs); ++ hNldr->dbllFxns.closeFxn(root->lib); ++ } ++ ++ /* Free dependent library list */ ++ if (root->pDepLibs) { ++ MEM_Free(root->pDepLibs); ++ root->pDepLibs = NULL; ++ } ++} ++ ++/* ++ * ======== UnloadOvly ======== ++ */ ++static void UnloadOvly(struct NLDR_NODEOBJECT *hNldrNode, enum NLDR_PHASE phase) ++{ ++ struct NLDR_OBJECT *hNldr = hNldrNode->pNldr; ++ struct OvlyNode *pONode = NULL; ++ struct OvlySect *pPhaseSects = NULL; ++ struct OvlySect *pOtherSects = NULL; ++ u16 i; ++ u16 nAlloc = 0; ++ u16 nOtherAlloc = 0; ++ u16 *pRefCount = NULL; ++ u16 *pOtherRef = NULL; ++ DSP_STATUS status = DSP_SOK; ++ ++ /* Find the node in the table */ ++ for (i = 0; i < hNldr->nOvlyNodes; i++) { ++ if (IsEqualUUID(hNldrNode->uuid, hNldr->ovlyTable[i].uuid)) { ++ /* Found it */ ++ pONode = &(hNldr->ovlyTable[i]); ++ break; ++ } ++ } ++ ++ DBC_Assert(i < hNldr->nOvlyNodes); ++ switch (phase) { ++ case NLDR_CREATE: ++ pRefCount = &(pONode->createRef); ++ pPhaseSects = pONode->pCreateSects; ++ nAlloc = pONode->nCreateSects; ++ break; ++ case NLDR_EXECUTE: ++ pRefCount = &(pONode->executeRef); ++ pPhaseSects = pONode->pExecuteSects; ++ nAlloc = pONode->nExecuteSects; ++ break; ++ case NLDR_DELETE: ++ pRefCount = &(pONode->deleteRef); ++ pOtherRef = &(pONode->otherRef); ++ pPhaseSects = pONode->pDeleteSects; ++ /* 'Other' overlay sections are unloaded in the delete phase */ ++ pOtherSects = pONode->pOtherSects; ++ nAlloc = pONode->nDeleteSects; ++ nOtherAlloc = pONode->nOtherSects; ++ break; ++ default: ++ DBC_Assert(false); ++ break; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ DBC_Assert(pRefCount && (*pRefCount > 0)); ++ if (pRefCount && (*pRefCount > 0)) { ++ *pRefCount -= 1; ++ if (pOtherRef) { ++ DBC_Assert(*pOtherRef > 0); ++ *pOtherRef -= 1; ++ } ++ } ++ } ++ if (pRefCount && (*pRefCount == 0)) { ++ /* 'Deallocate' memory */ ++ FreeSects(hNldr, pPhaseSects, nAlloc); ++ } ++ if (pOtherRef && *pOtherRef == 0) ++ FreeSects(hNldr, pOtherSects, nOtherAlloc); ++ ++} ++ ++/* ++ * ======== findInPersistentLibArray ======== ++ */ ++static bool findInPersistentLibArray(struct NLDR_NODEOBJECT *hNldrNode, ++ struct DBLL_LibraryObj *lib) ++{ ++ s32 i = 0; ++ ++ for (i = 0; i < hNldrNode->nPersLib; i++) { ++ if (lib == hNldrNode->persLib[i].lib) ++ return true; ++ ++ } ++ ++ return false; ++} ++ ++/* ++ * ================ Find LCM (Least Common Multiplier === ++ */ ++static u32 findLcm(u32 a, u32 b) ++{ ++ u32 retVal; ++ ++ retVal = a * b / findGcf(a, b); ++ ++ return retVal; ++} ++ ++/* ++ * ================ Find GCF (Greatest Common Factor ) === ++ */ ++static u32 findGcf(u32 a, u32 b) ++{ ++ u32 c; ++ ++ /* Get the GCF (Greatest common factor between the numbers, ++ * using Euclidian Algo */ ++ while ((c = (a % b))) { ++ a = b; ++ b = c; ++ } ++ return b; ++} ++ +diff --git a/drivers/dsp/bridge/rmgr/node.c b/drivers/dsp/bridge/rmgr/node.c +new file mode 100644 +index 0000000..178b802 +--- /dev/null ++++ b/drivers/dsp/bridge/rmgr/node.c +@@ -0,0 +1,3544 @@ ++/* ++ * node.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== node.c ======== ++ * ++ * Description: ++ * DSP/BIOS Bridge Node Manager. ++ * ++ * Public Functions: ++ * NODE_Allocate ++ * NODE_AllocMsgBuf ++ * NODE_ChangePriority ++ * NODE_Connect ++ * NODE_Create ++ * NODE_CreateMgr ++ * NODE_Delete ++ * NODE_DeleteMgr ++ * NODE_EnumNodes ++ * NODE_Exit ++ * NODE_FreeMsgBuf ++ * NODE_GetAttr ++ * NODE_GetChannelId ++ * NODE_GetMessage ++ * NODE_GetStrmMgr ++ * NODE_Init ++ * NODE_OnExit ++ * NODE_Pause ++ * NODE_PutMessage ++ * NODE_RegisterNotify ++ * NODE_Run ++ * NODE_Terminate ++ * ++ *! Revision History: ++ *! ================= ++ *! 12-Apr-2004 hp Compile IVA only for 24xx ++ *! 09-Feb-2004 vp Updated to support IVA. ++ *! 07-Apr-2003 map Eliminated references to old DLDR ++ *! 26-Mar-2003 vp Commented the call to DSP deep sleep in Node_Delete ++ *! function. ++ *! 18-Feb-2003 vp Code review updates. ++ *! 06-Feb-2003 kc Fixed FreeStream to release streams correctly. ++ *! 23-Jan-2003 map Removed call to DISP_DoCinit within Write() ++ *! 03-Jan-2003 map Only unload code after phase has executed if ++ *! overlay or split dynload phases ++ *! 18-Oct-2002 vp Ported to Linux platform. ++ *! 06-Nov-2002 map Fixed NODE_Run on NODE_PAUSED bug ++ *! 12-Oct-2002 map Fixed DeleteNode bug in NODE_Create ++ *! 11-Sep-2002 rr DeleteNode frees the memory for strmConnect and dcd obj ++ *! 29-Aug-2002 map Modified Ovly and Write to use ARM-side copy ++ *! 22-May-2002 sg Changed use of cbData for PWR calls. ++ *! 17-May-2002 jeh Removed LoadLoaderFxns(). Get address of RMS_cinit() ++ *! function. Call DISP_DoCinit() from Write(), if .cinit. ++ *! 13-May-2002 sg Added timeout to wake/sleep calls. ++ *! 02-May-2002 sg Added wake/sleep of DSP to support "nap" mode. ++ *! 18-Apr-2002 jeh Use dynamic loader if compile flag is set. ++ *! 13-Feb-2002 jeh Get uSysStackSize from DSP_NDBPROPS. ++ *! 07-Jan-2002 ag STRMMODE_ZEROCOPY(shared memory buffer swap) enabled. ++ *! 17-Dec-2001 ag STRMMODE_RDMA(DDMA) enabled. ++ *! 12-Dec-2001 ag Check for valid stream mode in NODE_Connect(). ++ *! 04-Dec-2001 jeh Check for node sufficiently connected in NODE_Create(). ++ *! 15-Nov-2001 jeh Removed DBC_Require(pNode->hXlator != NULL) from ++ *! NODE_AllocMsgBuf(), and check node type != NODE_DEVICE. ++ *! 11-Sep-2001 ag Zero-copy messaging support. ++ *! 28-Aug-2001 jeh Overlay/dynamic loader infrastructure added. Removed ++ *! NODE_GetDispatcher, excess node states. ++ *! 07-Aug-2001 jeh Removed critical section for dispatcher. ++ *! 26-Jul-2001 jeh Get ZL dll name through CFG. ++ *! 05-Jun-2001 jeh Assume DSP_STRMATTRS.uBufsize in GPP bytes. ++ *! 11-May-2001 jeh Some code review cleanup. ++ *! 13-Feb-2001 kc: DSP/BIOS Bridge name updates. ++ *! 15-Dec-2000 sg Convert IALG_Fxn address from byte addr to word addr. ++ *! 04-Dec-2000 jeh Call MSG Get and Put functions. ++ *! 04-Dec-2000 ag Added SM support for node messaging. ++ *! 10-Nov-2000 rr: NODE_MIN/MAX Priority is defined in dspdefs.h. ++ *! 27-Oct-2000 jeh Added NODE_AllocMsgBuf(), NODE_FreeMsgBuf(). ++ *! 11-Oct-2000 jeh Changed NODE_EnumNodeInfo to NODE_EnumNodes. Added ++ *! NODE_CloseOrphans(). Remove NODE_RegisterNotifyAllNodes ++ *! 19-Jun-2000 jeh Created. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Resource Manager */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Link Driver */ ++#include ++#include ++ ++/* ----------------------------------- Others */ ++#include ++#ifdef DEBUG ++#include ++#include ++#endif ++ ++/* ----------------------------------- This */ ++#include ++#include ++ ++/* Static/Dynamic Loader includes */ ++#include ++#include ++ ++#ifndef RES_CLEANUP_DISABLE ++#include ++#include ++#include ++#include ++#endif ++ ++ ++#define NODE_SIGNATURE 0x45444f4e /* "EDON" */ ++#define NODEMGR_SIGNATURE 0x52474d4e /* "RGMN" */ ++ ++#define HOSTPREFIX "/host" ++#define PIPEPREFIX "/dbpipe" ++ ++#define MaxInputs(h) ((h)->dcdProps.objData.nodeObj.ndbProps.uNumInputStreams) ++#define MaxOutputs(h) ((h)->dcdProps.objData.nodeObj.ndbProps.uNumOutputStreams) ++ ++#define NODE_GetPriority(h) ((h)->nPriority) ++#define NODE_SetPriority(hNode, nPriority) ((hNode)->nPriority = nPriority) ++#define NODE_SetState(hNode, state) ((hNode)->nState = state) ++ ++#define MAXPIPES 100 /* Max # of /pipe connections (CSL limit) */ ++#define MAXDEVSUFFIXLEN 2 /* Max(Log base 10 of MAXPIPES, MAXSTREAMS) */ ++ ++#define PIPENAMELEN (sizeof(PIPEPREFIX) + MAXDEVSUFFIXLEN) ++#define HOSTNAMELEN (sizeof(HOSTPREFIX) + MAXDEVSUFFIXLEN) ++ ++#define MAXDEVNAMELEN 32 /* DSP_NDBPROPS.acName size */ ++#define CREATEPHASE 1 ++#define EXECUTEPHASE 2 ++#define DELETEPHASE 3 ++ ++/* Define default STRM parameters */ ++/* ++ * TBD: Put in header file, make global DSP_STRMATTRS with defaults, ++ * or make defaults configurable. ++ */ ++#define DEFAULTBUFSIZE 32 ++#define DEFAULTNBUFS 2 ++#define DEFAULTSEGID 0 ++#define DEFAULTALIGNMENT 0 ++#define DEFAULTTIMEOUT 10000 ++ ++#define RMSQUERYSERVER 0 ++#define RMSCONFIGURESERVER 1 ++#define RMSCREATENODE 2 ++#define RMSEXECUTENODE 3 ++#define RMSDELETENODE 4 ++#define RMSCHANGENODEPRIORITY 5 ++#define RMSREADMEMORY 6 ++#define RMSWRITEMEMORY 7 ++#define RMSCOPY 8 ++#define MAXTIMEOUT 2000 ++ ++#define NUMRMSFXNS 9 ++ ++#define PWR_TIMEOUT 500 /* default PWR timeout in msec */ ++ ++#define STACKSEGLABEL "L1DSRAM_HEAP" /* Label for DSP Stack Segment Address */ ++ ++/* ++ * ======== NODE_MGR ======== ++ */ ++struct NODE_MGR { ++ u32 dwSignature; /* For object validation */ ++ struct DEV_OBJECT *hDevObject; /* Device object */ ++ struct WMD_DRV_INTERFACE *pIntfFxns; /* Function interface to WMD */ ++ struct DCD_MANAGER *hDcdMgr; /* Proc/Node data manager */ ++ struct DISP_OBJECT *hDisp; /* Node dispatcher */ ++ struct LST_LIST *nodeList; /* List of all allocated nodes */ ++ u32 uNumNodes; /* Number of nodes in nodeList */ ++ u32 uNumCreated; /* Number of nodes *created* on DSP */ ++ struct GB_TMap *pipeMap; /* Pipe connection bit map */ ++ struct GB_TMap *pipeDoneMap; /* Pipes that are half free */ ++ struct GB_TMap *chnlMap; /* Channel allocation bit map */ ++ struct GB_TMap *dmaChnlMap; /* DMA Channel allocation bit map */ ++ struct GB_TMap *zChnlMap; /* Zero-Copy Channel alloc bit map */ ++ struct NTFY_OBJECT *hNtfy; /* Manages registered notifications */ ++ struct SYNC_CSOBJECT *hSync; /* For critical sections */ ++ u32 ulFxnAddrs[NUMRMSFXNS]; /* RMS function addresses */ ++ struct MSG_MGR *hMsg; ++ ++ /* Processor properties needed by Node Dispatcher */ ++ u32 ulNumChnls; /* Total number of channels */ ++ u32 ulChnlOffset; /* Offset of chnl ids rsvd for RMS */ ++ u32 ulChnlBufSize; /* Buffer size for data to RMS */ ++ DSP_PROCFAMILY procFamily; /* eg, 5000 */ ++ DSP_PROCTYPE procType; /* eg, 5510 */ ++ u32 uDSPWordSize; /* Size of DSP word on host bytes */ ++ u32 uDSPDataMauSize; /* Size of DSP data MAU */ ++ u32 uDSPMauSize; /* Size of MAU */ ++ s32 nMinPri; /* Minimum runtime priority for node */ ++ s32 nMaxPri; /* Maximum runtime priority for node */ ++ ++ struct STRM_MGR *hStrmMgr; /* STRM manager */ ++ ++ /* Loader properties */ ++ struct NLDR_OBJECT *hNldr; /* Handle to loader */ ++ struct NLDR_FXNS nldrFxns; /* Handle to loader functions */ ++ bool fLoaderInit; /* Loader Init function succeeded? */ ++}; ++ ++/* ++ * ======== CONNECTTYPE ======== ++ */ ++enum CONNECTTYPE { ++ NOTCONNECTED = 0, ++ NODECONNECT, ++ HOSTCONNECT, ++ DEVICECONNECT, ++} ; ++ ++/* ++ * ======== STREAM ======== ++ */ ++struct STREAM { ++ enum CONNECTTYPE type; /* Type of stream connection */ ++ u32 devId; /* pipe or channel id */ ++}; ++ ++/* ++ * ======== NODE_OBJECT ======== ++ */ ++struct NODE_OBJECT { ++ struct LST_ELEM listElem; ++ u32 dwSignature; /* For object validation */ ++ struct NODE_MGR *hNodeMgr; /* The manager of this node */ ++ struct PROC_OBJECT *hProcessor; /* Back pointer to processor */ ++ struct DSP_UUID nodeId; /* Node's ID */ ++ s32 nPriority; /* Node's current priority */ ++ u32 uTimeout; /* Timeout for blocking NODE calls */ ++ u32 uHeapSize; /* Heap Size */ ++ u32 uDSPHeapVirtAddr; /* Heap Size */ ++ u32 uGPPHeapVirtAddr; /* Heap Size */ ++ enum NODE_TYPE nType; /* Type of node: message, task, etc */ ++ enum NODE_STATE nState; /* NODE_ALLOCATED, NODE_CREATED, ... */ ++ u32 uNumInputs; /* Current number of inputs */ ++ u32 uNumOutputs; /* Current number of outputs */ ++ u32 uMaxInputIndex; /* Current max input stream index */ ++ u32 uMaxOutputIndex; /* Current max output stream index */ ++ struct STREAM *inputs; /* Node's input streams */ ++ struct STREAM *outputs; /* Node's output streams */ ++ struct NODE_CREATEARGS createArgs; /* Args for node create function */ ++ NODE_ENV nodeEnv; /* Environment returned by RMS */ ++ struct DCD_GENERICOBJ dcdProps; /* Node properties from DCD */ ++ struct DSP_CBDATA *pArgs; /* Optional args to pass to node */ ++ struct NTFY_OBJECT *hNtfy; /* Manages registered notifications */ ++ char *pstrDevName; /* device name, if device node */ ++ struct SYNC_OBJECT *hSyncDone; /* Synchronize NODE_Terminate */ ++ s32 nExitStatus; /* execute function return status */ ++ ++ /* Information needed for NODE_GetAttr() */ ++ DSP_HNODE hDeviceOwner; /* If dev node, task that owns it */ ++ u32 uNumGPPInputs; /* Current # of from GPP streams */ ++ u32 uNumGPPOutputs; /* Current # of to GPP streams */ ++ /* Current stream connections */ ++ struct DSP_STREAMCONNECT *streamConnect; ++ ++ /* Message queue */ ++ struct MSG_QUEUE *hMsgQueue; ++ ++ /* These fields used for SM messaging */ ++ struct CMM_XLATOROBJECT *hXlator; /* Node's SM address translator */ ++ ++ /* Handle to pass to dynamic loader */ ++ struct NLDR_NODEOBJECT *hNldrNode; ++ bool fLoaded; /* Code is (dynamically) loaded */ ++ bool fPhaseSplit; /* Phases split in many libs or ovly */ ++ ++} ; ++ ++/* Default buffer attributes */ ++static struct DSP_BUFFERATTR NODE_DFLTBUFATTRS = { ++ 0, /* cbStruct */ ++ 1, /* uSegment */ ++ 0, /* uAlignment */ ++}; ++ ++static void DeleteNode(struct NODE_OBJECT *hNode); ++static void DeleteNodeMgr(struct NODE_MGR *hNodeMgr); ++static void FillStreamConnect(struct NODE_OBJECT *hNode1, ++ struct NODE_OBJECT *hNode2, u32 uStream1, ++ u32 uStream2); ++static void FillStreamDef(struct NODE_OBJECT *hNode, ++ struct NODE_STRMDEF *pstrmDef, ++ struct DSP_STRMATTR *pAttrs); ++static void FreeStream(struct NODE_MGR *hNodeMgr, struct STREAM stream); ++static DSP_STATUS GetFxnAddress(struct NODE_OBJECT *hNode, u32 *pulFxnAddr, ++ u32 uPhase); ++static DSP_STATUS GetNodeProps(struct DCD_MANAGER *hDcdMgr, ++ struct NODE_OBJECT *hNode, ++ CONST struct DSP_UUID *pNodeId, ++ struct DCD_GENERICOBJ *pdcdProps); ++static DSP_STATUS GetProcProps(struct NODE_MGR *hNodeMgr, ++ struct DEV_OBJECT *hDevObject); ++static DSP_STATUS GetRMSFxns(struct NODE_MGR *hNodeMgr); ++static u32 Ovly(void *pPrivRef, u32 ulDspRunAddr, u32 ulDspLoadAddr, ++ u32 ulNumBytes, u32 nMemSpace); ++static u32 Write(void *pPrivRef, u32 ulDspAddr, void *pBuf, ++ u32 ulNumBytes, u32 nMemSpace); ++ ++#if GT_TRACE ++static struct GT_Mask NODE_debugMask = { NULL, NULL }; /* GT trace variable */ ++#endif ++ ++#ifdef DSP_DMM_DEBUG ++extern u32 DMM_MemMapDump(struct DMM_OBJECT *hDmmMgr); ++#endif ++ ++static u32 cRefs; /* module reference count */ ++ ++/* Dynamic loader functions. */ ++static struct NLDR_FXNS nldrFxns = { ++ NLDR_Allocate, ++ NLDR_Create, ++ NLDR_Delete, ++ NLDR_Exit, ++ NLDR_Free, ++ NLDR_GetFxnAddr, ++ NLDR_Init, ++ NLDR_Load, ++ NLDR_Unload, ++}; ++ ++enum NODE_STATE NODE_GetState(HANDLE hNode) ++{ ++ struct NODE_OBJECT *pNode = (struct NODE_OBJECT *)hNode; ++ if (!MEM_IsValidHandle(pNode, NODE_SIGNATURE)) { ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "NODE_GetState:hNode 0x%x\n", pNode); ++ return -1; ++ } else ++ return pNode->nState; ++ ++} ++ ++/* ++ * ======== NODE_Allocate ======== ++ * Purpose: ++ * Allocate GPP resources to manage a node on the DSP. ++ */ ++DSP_STATUS NODE_Allocate(struct PROC_OBJECT *hProcessor, ++ IN CONST struct DSP_UUID *pNodeId, ++ OPTIONAL IN CONST struct DSP_CBDATA *pArgs, ++ OPTIONAL IN CONST struct DSP_NODEATTRIN *pAttrIn, ++ OUT struct NODE_OBJECT **phNode) ++{ ++ struct NODE_MGR *hNodeMgr; ++ struct DEV_OBJECT *hDevObject; ++ struct NODE_OBJECT *pNode = NULL; ++ enum NODE_TYPE nodeType = NODE_TASK; ++ struct NODE_MSGARGS *pmsgArgs; ++ struct NODE_TASKARGS *ptaskArgs; ++ u32 uNumStreams; ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ DSP_STATUS status = DSP_SOK; ++ struct CMM_OBJECT *hCmmMgr = NULL; /* Shared memory manager hndl */ ++ u32 procId; ++ char *label; ++ u32 pulValue; ++ u32 dynextBase; ++ u32 offSet = 0; ++ u32 ulStackSegAddr, ulStackSegVal; ++ u32 ulGppMemBase; ++ struct CFG_HOSTRES hostRes; ++ u32 pMappedAddr = 0; ++ u32 mapAttrs = 0x0; ++ struct DSP_PROCESSORSTATE procStatus; ++#ifdef DSP_DMM_DEBUG ++ struct DMM_OBJECT *hDmmMgr; ++ struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProcessor; ++#endif ++ ++#ifndef RES_CLEANUP_DISABLE ++ HANDLE hDrvObject; ++ HANDLE nodeRes; ++ u32 hProcess; ++ struct PROCESS_CONTEXT *pPctxt = NULL; ++ DSP_STATUS res_status = DSP_SOK; ++#endif ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(hProcessor != NULL); ++ DBC_Require(phNode != NULL); ++ DBC_Require(pNodeId != NULL); ++ ++ GT_5trace(NODE_debugMask, GT_ENTER, "NODE_Allocate: \thProcessor: " ++ "0x%x\tpNodeId: 0x%x\tpArgs: 0x%x\tpAttrIn: " ++ "0x%x\tphNode: 0x%x\n", hProcessor, pNodeId, pArgs, pAttrIn, ++ phNode); ++ ++ *phNode = NULL; ++ ++ status = PROC_GetProcessorId(hProcessor, &procId); ++ ++ status = PROC_GetDevObject(hProcessor, &hDevObject); ++ if (DSP_SUCCEEDED(status)) { ++ status = DEV_GetNodeManager(hDevObject, &hNodeMgr); ++ if (hNodeMgr == NULL) ++ status = DSP_EFAIL; ++ ++ } ++ if (procId != DSP_UNIT) ++ goto func_cont; ++ ++ if (DSP_FAILED(status)) ++ goto func_cont; ++ ++ status = PROC_GetState(hProcessor, &procStatus, ++ sizeof(struct DSP_PROCESSORSTATE)); ++ if (DSP_FAILED(status)) ++ goto func_end; ++ /* If processor is in error state then don't attempt ++ to send the message */ ++ if (procStatus.iState == PROC_ERROR) { ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "NODE_Allocate: proc Status 0x%x\n", ++ procStatus.iState); ++ status = DSP_EFAIL; ++ goto func_end; ++ } ++ ++ /* Assuming that 0 is not a valid function address */ ++ if (hNodeMgr->ulFxnAddrs[0] == 0) { ++ /* No RMS on target - we currently can't handle this */ ++ GT_0trace(NODE_debugMask, GT_5CLASS, "No RMS functions in base " ++ "image. Node allocation fails.\n"); ++ status = DSP_EFAIL; ++ } else { ++ /* Validate pAttrIn fields, if non-NULL */ ++ if (pAttrIn) { ++ /* Check if pAttrIn->iPriority is within range */ ++ if (pAttrIn->iPriority < hNodeMgr->nMinPri || ++ pAttrIn->iPriority > hNodeMgr->nMaxPri) ++ status = DSP_ERANGE; ++ } ++ } ++func_cont: ++ /* Allocate node object and fill in */ ++ if (DSP_FAILED(status)) ++ goto func_cont2; ++ ++ MEM_AllocObject(pNode, struct NODE_OBJECT, NODE_SIGNATURE); ++ if (pNode == NULL) { ++ status = DSP_EMEMORY; ++ goto func_cont1; ++ } ++ pNode->hNodeMgr = hNodeMgr; ++ /* This critical section protects GetNodeProps */ ++ status = SYNC_EnterCS(hNodeMgr->hSync); ++ if (procId != DSP_UNIT) ++ goto func_cont3; ++ ++ /* Get DSP_NDBPROPS from node database */ ++ status = GetNodeProps(hNodeMgr->hDcdMgr, pNode, pNodeId, ++ &(pNode->dcdProps)); ++ if (DSP_FAILED(status)) ++ goto func_cont3; ++ ++ pNode->nodeId = *pNodeId; ++ pNode->hProcessor = hProcessor; ++ pNode->nType = pNode->dcdProps.objData.nodeObj.ndbProps.uNodeType; ++ pNode->uTimeout = pNode->dcdProps.objData.nodeObj.ndbProps.uTimeout; ++ pNode->nPriority = pNode->dcdProps.objData.nodeObj.ndbProps.iPriority; ++ ++ /* Currently only C64 DSP builds support Node Dynamic * heaps */ ++ /* Allocate memory for node heap */ ++ pNode->createArgs.asa.taskArgs.uHeapSize = 0; ++ pNode->createArgs.asa.taskArgs.uDSPHeapAddr = 0; ++ pNode->createArgs.asa.taskArgs.uDSPHeapResAddr = 0; ++ pNode->createArgs.asa.taskArgs.uGPPHeapAddr = 0; ++ if (!pAttrIn) ++ goto func_cont3; ++ ++ /* Check if we have a user allocated node heap */ ++ if (!(pAttrIn->pGPPVirtAddr)) ++ goto func_cont3; ++ ++ /* check for page aligned Heap size */ ++ if (((pAttrIn->uHeapSize) & (PG_SIZE_4K - 1))) { ++ GT_1trace(NODE_debugMask, GT_7CLASS, ++ "NODE_Allocate: node heap page size" ++ " not aligned to 4K page, size=0x%x \n", ++ pAttrIn->uHeapSize); ++ status = DSP_EINVALIDARG; ++ } else { ++ pNode->createArgs.asa.taskArgs.uHeapSize = pAttrIn->uHeapSize; ++ pNode->createArgs.asa.taskArgs.uGPPHeapAddr = ++ (u32)pAttrIn->pGPPVirtAddr; ++ } ++ if (DSP_FAILED(status)) ++ goto func_cont3; ++ ++ status = PROC_ReserveMemory(hProcessor, ++ pNode->createArgs.asa.taskArgs.uHeapSize + PAGE_SIZE, ++ (void **)&(pNode->createArgs.asa.taskArgs. ++ uDSPHeapResAddr)); ++ if (DSP_FAILED(status)) { ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "NODE_Allocate:Failed to reserve " ++ "memory for Heap: 0x%x\n", status); ++ } else { ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "NODE_Allocate: DSPProcessor_Reserve" ++ " Memory successful: 0x%x\n", status); ++ } ++#ifdef DSP_DMM_DEBUG ++ status = DMM_GetHandle(pProcObject, &hDmmMgr); ++ if (DSP_SUCCEEDED(status)) ++ DMM_MemMapDump(hDmmMgr); ++#endif ++ if (DSP_FAILED(status)) ++ goto func_cont3; ++ ++ mapAttrs |= DSP_MAPLITTLEENDIAN; ++ mapAttrs |= DSP_MAPELEMSIZE32; ++ mapAttrs |= DSP_MAPVIRTUALADDR; ++ status = PROC_Map(hProcessor, (void *)pAttrIn->pGPPVirtAddr, ++ pNode->createArgs.asa.taskArgs.uHeapSize, ++ (void *)pNode->createArgs.asa.taskArgs.uDSPHeapResAddr, ++ (void **)&pMappedAddr, mapAttrs); ++ if (DSP_FAILED(status)) { ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "NODE_Allocate: Failed to map memory" ++ " for Heap: 0x%x\n", status); ++ } else { ++ pNode->createArgs.asa.taskArgs.uDSPHeapAddr = ++ (u32) pMappedAddr; ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "NODE_Allocate:DSPProcessor_Map" ++ " successful: 0x%x\n", status); ++ } ++ ++func_cont3: ++ (void)SYNC_LeaveCS(hNodeMgr->hSync); ++func_cont1: ++ if (pAttrIn != NULL) { ++ /* Overrides of NBD properties */ ++ pNode->uTimeout = pAttrIn->uTimeout; ++ pNode->nPriority = pAttrIn->iPriority; ++ } ++func_cont2: ++ /* Create object to manage notifications */ ++ if (DSP_SUCCEEDED(status)) ++ status = NTFY_Create(&pNode->hNtfy); ++ ++ if (DSP_SUCCEEDED(status)) { ++ nodeType = NODE_GetType(pNode); ++ /* Allocate DSP_STREAMCONNECT array for device, task, and ++ * dais socket nodes. */ ++ if (nodeType != NODE_MESSAGE) { ++ uNumStreams = MaxInputs(pNode) + MaxOutputs(pNode); ++ pNode->streamConnect = MEM_Calloc(uNumStreams * ++ sizeof(struct DSP_STREAMCONNECT), ++ MEM_PAGED); ++ if (uNumStreams > 0 && pNode->streamConnect == NULL) ++ status = DSP_EMEMORY; ++ ++ } ++ if (DSP_SUCCEEDED(status) && (nodeType == NODE_TASK || ++ nodeType == NODE_DAISSOCKET)) { ++ /* Allocate arrays for maintainig stream connections */ ++ pNode->inputs = ++ MEM_Calloc(MaxInputs(pNode) * ++ sizeof(struct STREAM), MEM_PAGED); ++ pNode->outputs = ++ MEM_Calloc(MaxOutputs(pNode) * ++ sizeof(struct STREAM), MEM_PAGED); ++ ptaskArgs = &(pNode->createArgs.asa.taskArgs); ++ ptaskArgs->strmInDef = ++ MEM_Calloc(MaxInputs(pNode) * ++ sizeof(struct NODE_STRMDEF), ++ MEM_PAGED); ++ ptaskArgs->strmOutDef = ++ MEM_Calloc(MaxOutputs(pNode) * ++ sizeof(struct NODE_STRMDEF), ++ MEM_PAGED); ++ if ((MaxInputs(pNode) > 0 && (pNode->inputs == NULL || ++ ptaskArgs->strmInDef == NULL)) || ++ (MaxOutputs(pNode) > 0 && (pNode->outputs == NULL || ++ ptaskArgs->strmOutDef == NULL))) ++ status = DSP_EMEMORY; ++ } ++ } ++ if (DSP_SUCCEEDED(status) && (nodeType != NODE_DEVICE)) { ++ /* Create an event that will be posted when RMS_EXIT is ++ * received. */ ++ status = SYNC_OpenEvent(&pNode->hSyncDone, NULL); ++ if (DSP_SUCCEEDED(status)) { ++ /*Get the shared mem mgr for this nodes dev object */ ++ status = CMM_GetHandle(hProcessor, &hCmmMgr); ++ if (DSP_FAILED(status)) { ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "NODE_Allocate: Failed to" ++ " get CMM Mgr handle: 0x%x\n", status); ++ } else { ++ /* Allocate a SM addr translator for this node ++ * w/ deflt attr */ ++ status = CMM_XlatorCreate(&pNode->hXlator, ++ hCmmMgr, NULL); ++ if (DSP_FAILED(status)) { ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "NODE_Allocate: Failed" ++ " to create SM translator: 0x%x\n", ++ status); ++ } ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Fill in message args */ ++ if ((pArgs != NULL) && (pArgs->cbData > 0)) { ++ pmsgArgs = &(pNode->createArgs.asa.msgArgs); ++ pmsgArgs->pData = MEM_Calloc(pArgs->cbData, ++ MEM_PAGED); ++ if (pmsgArgs->pData == NULL) { ++ status = DSP_EMEMORY; ++ } else { ++ pmsgArgs->uArgLength = pArgs->cbData; ++ memcpy(pmsgArgs->pData, pArgs->cData, ++ pArgs->cbData); ++ } ++ } ++ } ++ } ++ ++ if (DSP_SUCCEEDED(status) && nodeType != NODE_DEVICE) { ++ /* Create a message queue for this node */ ++ pIntfFxns = hNodeMgr->pIntfFxns; ++ status = (*pIntfFxns->pfnMsgCreateQueue)(hNodeMgr->hMsg, ++ &pNode->hMsgQueue, 0, ++ pNode->createArgs.asa.msgArgs.uMaxMessages, ++ pNode); ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* Create object for dynamic loading */ ++ ++ status = hNodeMgr->nldrFxns.pfnAllocate(hNodeMgr->hNldr, ++ (void *) pNode, ++ &pNode->dcdProps.objData.nodeObj, ++ &pNode->hNldrNode, ++ &pNode->fPhaseSplit); ++ if (DSP_FAILED(status)) { ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "NODE_Allocate: Failed to " ++ "allocate NLDR node: 0x%x\n", status); ++ } ++ } ++ ++ /* Comapare value read from Node Properties and check if it is same as ++ * STACKSEGLABEL, if yes read the Address of STACKSEGLABEL, calculate ++ * GPP Address, Read the value in that address and override the ++ * uStackSeg value in task args */ ++ if (DSP_SUCCEEDED(status) && ++ (char *)pNode->dcdProps.objData.nodeObj.ndbProps.uStackSegName != ++ NULL) { ++ label = MEM_Calloc(sizeof(STACKSEGLABEL)+1, MEM_PAGED); ++ strncpy(label, STACKSEGLABEL, sizeof(STACKSEGLABEL)+1); ++ ++ if (strcmp((char *)pNode->dcdProps.objData.nodeObj. ++ ndbProps.uStackSegName, label) == 0) { ++ status = hNodeMgr->nldrFxns.pfnGetFxnAddr(pNode-> ++ hNldrNode, "DYNEXT_BEG", &dynextBase); ++ if (DSP_FAILED(status)) { ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "NODE_Allocate: Failed to get Address for " ++ "DYNEXT_BEG: 0x%x\n", status); ++ } ++ ++ status = hNodeMgr->nldrFxns.pfnGetFxnAddr(pNode-> ++ hNldrNode, "L1DSRAM_HEAP", &pulValue); ++ ++ if (DSP_FAILED(status)) { ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "NODE_Allocate: Failed to get Address for " ++ "L1DSRAM_HEAP: 0x%x\n", status); ++ } ++ ++ status = CFG_GetHostResources((struct CFG_DEVNODE *) ++ DRV_GetFirstDevExtension(), &hostRes); ++ ++ if (DSP_FAILED(status)) { ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "NODE_Allocate: Failed to get host resource " ++ "0x%x\n", status); ++ } ++ ++ ulGppMemBase = hostRes.dwMemBase[1]; ++ offSet = pulValue - dynextBase; ++ ulStackSegAddr = ulGppMemBase + offSet; ++ ulStackSegVal = (u32)*((REG_UWORD32 *) ++ ((u32)(ulStackSegAddr))); ++ ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "StackSegVal =0x%x\n", ulStackSegVal); ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "ulStackSegAddr = 0x%x\n", ulStackSegAddr); ++ ++ pNode->createArgs.asa.taskArgs.uStackSeg = ++ ulStackSegVal; ++ ++ } ++ ++ if (label) ++ MEM_Free(label); ++ ++ } ++ ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* Add the node to the node manager's list of allocated ++ * nodes. */ ++ LST_InitElem((struct LST_ELEM *)pNode); ++ NODE_SetState(pNode, NODE_ALLOCATED); ++ ++ status = SYNC_EnterCS(hNodeMgr->hSync); ++ ++ if (DSP_SUCCEEDED(status)) { ++ LST_PutTail(hNodeMgr->nodeList, ++ (struct LST_ELEM *) pNode); ++ ++(hNodeMgr->uNumNodes); ++ } ++ ++ /* Exit critical section */ ++ (void) SYNC_LeaveCS(hNodeMgr->hSync); ++ ++ /* Preset this to assume phases are split ++ * (for overlay and dll) */ ++ pNode->fPhaseSplit = true; ++ ++ if (DSP_SUCCEEDED(status)) ++ *phNode = pNode; ++ ++ ++ /* Notify all clients registered for DSP_NODESTATECHANGE. */ ++ PROC_NotifyAllClients(hProcessor, DSP_NODESTATECHANGE); ++ } else { ++ /* Cleanup */ ++ if (pNode) ++ DeleteNode(pNode); ++ ++ } ++ ++#ifndef RES_CLEANUP_DISABLE ++ if (DSP_SUCCEEDED(status)) { ++ /* Return PID instead of process handle */ ++ hProcess = current->pid; ++ ++ res_status = CFG_GetObject((u32 *)&hDrvObject, ++ REG_DRV_OBJECT); ++ if (DSP_SUCCEEDED(res_status)) { ++ DRV_GetProcContext(hProcess, ++ (struct DRV_OBJECT *)hDrvObject, ++ &pPctxt, *phNode, 0); ++ if (pPctxt == NULL) { ++ DRV_InsertProcContext( ++ (struct DRV_OBJECT *)hDrvObject, ++ &pPctxt); ++ if (pPctxt != NULL) { ++ DRV_ProcUpdatestate(pPctxt, ++ PROC_RES_ALLOCATED); ++ DRV_ProcSetPID(pPctxt, hProcess); ++ pPctxt->hProcessor = ++ (DSP_HPROCESSOR)hProcessor; ++ } ++ } ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Return PID instead of process handle */ ++ hProcess = current->pid; ++ res_status = CFG_GetObject((u32 *)&hDrvObject, ++ REG_DRV_OBJECT); ++ if (DSP_SUCCEEDED(res_status)) { ++ DRV_GetProcContext(hProcess, ++ (struct DRV_OBJECT *)hDrvObject, ++ &pPctxt, *phNode, 0); ++ if (pPctxt != NULL) { ++ DRV_InsertNodeResElement(*phNode, &nodeRes, ++ pPctxt); ++ DRV_ProcNodeUpdateHeapStatus(nodeRes, true); ++ DRV_ProcNodeUpdateStatus(nodeRes, true); ++ } ++ } ++ } ++#endif ++ DBC_Ensure((DSP_FAILED(status) && (*phNode == NULL)) || ++ (DSP_SUCCEEDED(status) ++ && MEM_IsValidHandle((*phNode), NODE_SIGNATURE))); ++func_end: ++ return status; ++} ++ ++/* ++ * ======== NODE_AllocMsgBuf ======== ++ * Purpose: ++ * Allocates buffer for zero copy messaging. ++ */ ++DBAPI NODE_AllocMsgBuf(struct NODE_OBJECT *hNode, u32 uSize, ++ OPTIONAL IN OUT struct DSP_BUFFERATTR *pAttr, ++ OUT u8 **pBuffer) ++{ ++ struct NODE_OBJECT *pNode = (struct NODE_OBJECT *)hNode; ++ DSP_STATUS status = DSP_SOK; ++ bool bVirtAddr = false; ++ bool bSetInfo; ++ u32 procId; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pBuffer != NULL); ++ ++ DBC_Require(uSize > 0); ++ ++ GT_4trace(NODE_debugMask, GT_ENTER, ++ "NODE_AllocMsgBuf: hNode: 0x%x\tuSize:" ++ " 0x%x\tpAttr: 0x%x\tpBuffer: %d\n", pNode, uSize, pAttr, ++ pBuffer); ++ ++ if (!MEM_IsValidHandle(pNode, NODE_SIGNATURE)) ++ status = DSP_EHANDLE; ++ ++ if (NODE_GetType(pNode) == NODE_DEVICE) ++ status = DSP_ENODETYPE; ++ ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ if (pAttr == NULL) ++ pAttr = &NODE_DFLTBUFATTRS; /* set defaults */ ++ ++ status = PROC_GetProcessorId(pNode->hProcessor, &procId); ++ if (procId != DSP_UNIT) { ++ DBC_Assert(NULL); ++ goto func_end; ++ } ++ /* If segment ID includes MEM_SETVIRTUALSEGID then pBuffer is a ++ * virt address, so set this info in this node's translator ++ * object for future ref. If MEM_GETVIRTUALSEGID then retrieve ++ * virtual address from node's translator. */ ++ if ((pAttr->uSegment & MEM_SETVIRTUALSEGID) || ++ (pAttr->uSegment & MEM_GETVIRTUALSEGID)) { ++ bVirtAddr = true; ++ bSetInfo = (pAttr->uSegment & MEM_SETVIRTUALSEGID) ? ++ true : false; ++ pAttr->uSegment &= ~MEM_MASKVIRTUALSEGID; /* clear mask bits */ ++ /* Set/get this node's translators virtual address base/size */ ++ status = CMM_XlatorInfo(pNode->hXlator, pBuffer, uSize, ++ pAttr->uSegment, bSetInfo); ++ if (DSP_FAILED(status)) { ++ GT_1trace(NODE_debugMask, GT_7CLASS, ++ "NODE_AllocMsgBuf " ++ "failed: 0x%lx\n", status); ++ } ++ } ++ if (DSP_SUCCEEDED(status) && (!bVirtAddr)) { ++ if (pAttr->uSegment != 1) { ++ /* Node supports single SM segment only. */ ++ status = DSP_EBADSEGID; ++ } ++ /* Arbitrary SM buffer alignment not supported for host side ++ * allocs, but guaranteed for the following alignment ++ * values. */ ++ switch (pAttr->uAlignment) { ++ case 0: ++ case 1: ++ case 2: ++ case 4: ++ break; ++ default: ++ /* alignment value not suportted */ ++ status = DSP_EALIGNMENT; ++ break; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* allocate physical buffer from segId in node's ++ * translator */ ++ (void)CMM_XlatorAllocBuf(pNode->hXlator, pBuffer, ++ uSize); ++ if (*pBuffer == NULL) { ++ GT_0trace(NODE_debugMask, GT_7CLASS, ++ "NODE_AllocMsgBuf: " ++ "ERROR: Out of shared memory.\n"); ++ status = DSP_EMEMORY; ++ } ++ } ++ } ++func_end: ++ return status; ++} ++ ++/* ++ * ======== NODE_ChangePriority ======== ++ * Purpose: ++ * Change the priority of a node in the allocated state, or that is ++ * currently running or paused on the target. ++ */ ++DSP_STATUS NODE_ChangePriority(struct NODE_OBJECT *hNode, s32 nPriority) ++{ ++ struct NODE_OBJECT *pNode = (struct NODE_OBJECT *)hNode; ++ struct NODE_MGR *hNodeMgr = NULL; ++ enum NODE_TYPE nodeType; ++ enum NODE_STATE state; ++ DSP_STATUS status = DSP_SOK; ++ u32 procId; ++ ++ DBC_Require(cRefs > 0); ++ ++ GT_2trace(NODE_debugMask, GT_ENTER, "NODE_ChangePriority: " ++ "hNode: 0x%x\tnPriority: %d\n", hNode, nPriority); ++ ++ if (!MEM_IsValidHandle(hNode, NODE_SIGNATURE)) { ++ GT_1trace(NODE_debugMask, GT_7CLASS, ++ "Invalid NODE Handle: 0x%x\n", hNode); ++ status = DSP_EHANDLE; ++ } else { ++ hNodeMgr = hNode->hNodeMgr; ++ nodeType = NODE_GetType(hNode); ++ if (nodeType != NODE_TASK && nodeType != NODE_DAISSOCKET) ++ status = DSP_ENODETYPE; ++ else if (nPriority < hNodeMgr->nMinPri || ++ nPriority > hNodeMgr->nMaxPri) ++ status = DSP_ERANGE; ++ } ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ /* Enter critical section */ ++ status = SYNC_EnterCS(hNodeMgr->hSync); ++ if (DSP_FAILED(status)) ++ goto func_cont; ++ ++ state = NODE_GetState(hNode); ++ if (state == NODE_ALLOCATED || state == NODE_PAUSED) { ++ NODE_SetPriority(hNode, nPriority); ++ } else { ++ if (state != NODE_RUNNING) { ++ status = DSP_EWRONGSTATE; ++ goto func_cont; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ status = PROC_GetProcessorId(pNode->hProcessor, ++ &procId); ++ if (procId == DSP_UNIT) { ++ status = DISP_NodeChangePriority(hNodeMgr-> ++ hDisp, hNode, ++ hNodeMgr->ulFxnAddrs[RMSCHANGENODEPRIORITY], ++ hNode->nodeEnv, nPriority); ++ } ++ if (DSP_SUCCEEDED(status)) ++ NODE_SetPriority(hNode, nPriority); ++ ++ } ++ } ++func_cont: ++ /* Leave critical section */ ++ (void)SYNC_LeaveCS(hNodeMgr->hSync); ++func_end: ++ return status; ++} ++ ++/* ++ * ======== NODE_Connect ======== ++ * Purpose: ++ * Connect two nodes on the DSP, or a node on the DSP to the GPP. ++ */ ++DSP_STATUS NODE_Connect(struct NODE_OBJECT *hNode1, u32 uStream1, ++ struct NODE_OBJECT *hNode2, ++ u32 uStream2, OPTIONAL IN struct DSP_STRMATTR *pAttrs, ++ OPTIONAL IN struct DSP_CBDATA *pConnParam) ++{ ++ struct NODE_MGR *hNodeMgr; ++ char *pstrDevName = NULL; ++ enum NODE_TYPE node1Type = NODE_TASK; ++ enum NODE_TYPE node2Type = NODE_TASK; ++ struct NODE_STRMDEF *pstrmDef; ++ struct NODE_STRMDEF *pInput = NULL; ++ struct NODE_STRMDEF *pOutput = NULL; ++ struct NODE_OBJECT *hDevNode; ++ struct NODE_OBJECT *hNode; ++ struct STREAM *pStream; ++ GB_BitNum pipeId = GB_NOBITS; ++ GB_BitNum chnlId = GB_NOBITS; ++ CHNL_MODE uMode; ++ u32 dwLength; ++ DSP_STATUS status = DSP_SOK; ++ DBC_Require(cRefs > 0); ++ GT_5trace(NODE_debugMask, GT_ENTER, ++ "NODE_Connect: hNode1: 0x%x\tuStream1:" ++ " %d\thNode2: 0x%x\tuStream2: %d\tpAttrs: 0x%x\n", hNode1, ++ uStream1, hNode2, uStream2, pAttrs); ++ if (DSP_SUCCEEDED(status)) { ++ if ((hNode1 != (struct NODE_OBJECT *) DSP_HGPPNODE && ++ !MEM_IsValidHandle(hNode1, NODE_SIGNATURE)) || ++ (hNode2 != (struct NODE_OBJECT *) DSP_HGPPNODE && ++ !MEM_IsValidHandle(hNode2, NODE_SIGNATURE))) ++ status = DSP_EHANDLE; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* The two nodes must be on the same processor */ ++ if (hNode1 != (struct NODE_OBJECT *)DSP_HGPPNODE && ++ hNode2 != (struct NODE_OBJECT *)DSP_HGPPNODE && ++ hNode1->hNodeMgr != hNode2->hNodeMgr) ++ status = DSP_EFAIL; ++ /* Cannot connect a node to itself */ ++ if (hNode1 == hNode2) ++ status = DSP_EFAIL; ++ ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* NODE_GetType() will return NODE_GPP if hNode = ++ * DSP_HGPPNODE. */ ++ node1Type = NODE_GetType(hNode1); ++ node2Type = NODE_GetType(hNode2); ++ /* Check stream indices ranges */ ++ if ((node1Type != NODE_GPP && node1Type != NODE_DEVICE && ++ uStream1 >= MaxOutputs(hNode1)) || (node2Type != NODE_GPP && ++ node2Type != NODE_DEVICE && uStream2 >= MaxInputs(hNode2))) ++ status = DSP_EVALUE; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* ++ * Only the following types of connections are allowed: ++ * task/dais socket < == > task/dais socket ++ * task/dais socket < == > device ++ * task/dais socket < == > GPP ++ * ++ * ie, no message nodes, and at least one task or dais ++ * socket node. ++ */ ++ if (node1Type == NODE_MESSAGE || node2Type == NODE_MESSAGE || ++ (node1Type != NODE_TASK && node1Type != NODE_DAISSOCKET && ++ node2Type != NODE_TASK && node2Type != NODE_DAISSOCKET)) ++ status = DSP_EFAIL; ++ } ++ /* ++ * Check stream mode. Default is STRMMODE_PROCCOPY. ++ */ ++ if (DSP_SUCCEEDED(status) && pAttrs) { ++ if (pAttrs->lMode != STRMMODE_PROCCOPY) ++ status = DSP_ESTRMMODE; /* illegal stream mode */ ++ ++ } ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ if (node1Type != NODE_GPP) { ++ hNodeMgr = hNode1->hNodeMgr; ++ } else { ++ DBC_Assert(hNode2 != (struct NODE_OBJECT *)DSP_HGPPNODE); ++ hNodeMgr = hNode2->hNodeMgr; ++ } ++ /* Enter critical section */ ++ status = SYNC_EnterCS(hNodeMgr->hSync); ++ if (DSP_FAILED(status)) ++ goto func_cont; ++ ++ /* Nodes must be in the allocated state */ ++ if (node1Type != NODE_GPP && NODE_GetState(hNode1) != NODE_ALLOCATED) ++ status = DSP_EWRONGSTATE; ++ ++ if (node2Type != NODE_GPP && NODE_GetState(hNode2) != NODE_ALLOCATED) ++ status = DSP_EWRONGSTATE; ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* Check that stream indices for task and dais socket nodes ++ * are not already be used. (Device nodes checked later) */ ++ if (node1Type == NODE_TASK || node1Type == NODE_DAISSOCKET) { ++ pOutput = &(hNode1->createArgs.asa.taskArgs. ++ strmOutDef[uStream1]); ++ if (pOutput->szDevice != NULL) ++ status = DSP_EALREADYCONNECTED; ++ ++ } ++ if (node2Type == NODE_TASK || node2Type == NODE_DAISSOCKET) { ++ pInput = &(hNode2->createArgs.asa.taskArgs. ++ strmInDef[uStream2]); ++ if (pInput->szDevice != NULL) ++ status = DSP_EALREADYCONNECTED; ++ ++ } ++ } ++ /* Connecting two task nodes? */ ++ if (DSP_SUCCEEDED(status) && ((node1Type == NODE_TASK || ++ node1Type == NODE_DAISSOCKET) && (node2Type == NODE_TASK || ++ node2Type == NODE_DAISSOCKET))) { ++ /* Find available pipe */ ++ pipeId = GB_findandset(hNodeMgr->pipeMap); ++ if (pipeId == GB_NOBITS) { ++ status = DSP_ENOMORECONNECTIONS; ++ } else { ++ hNode1->outputs[uStream1].type = NODECONNECT; ++ hNode2->inputs[uStream2].type = NODECONNECT; ++ hNode1->outputs[uStream1].devId = pipeId; ++ hNode2->inputs[uStream2].devId = pipeId; ++ pOutput->szDevice = MEM_Calloc(PIPENAMELEN + 1, ++ MEM_PAGED); ++ pInput->szDevice = MEM_Calloc(PIPENAMELEN + 1, ++ MEM_PAGED); ++ if (pOutput->szDevice == NULL || ++ pInput->szDevice == NULL) { ++ /* Undo the connection */ ++ if (pOutput->szDevice) ++ MEM_Free(pOutput->szDevice); ++ ++ if (pInput->szDevice) ++ MEM_Free(pInput->szDevice); ++ ++ pOutput->szDevice = NULL; ++ pInput->szDevice = NULL; ++ GB_clear(hNodeMgr->pipeMap, pipeId); ++ status = DSP_EMEMORY; ++ } else { ++ /* Copy "/dbpipe" name to device names */ ++ sprintf(pOutput->szDevice, "%s%d", ++ PIPEPREFIX, pipeId); ++ strcpy(pInput->szDevice, pOutput->szDevice); ++ } ++ } ++ } ++ /* Connecting task node to host? */ ++ if (DSP_SUCCEEDED(status) && (node1Type == NODE_GPP || ++ node2Type == NODE_GPP)) { ++ if (node1Type == NODE_GPP) { ++ uMode = CHNL_MODETODSP; ++ } else { ++ DBC_Assert(node2Type == NODE_GPP); ++ uMode = CHNL_MODEFROMDSP; ++ } ++ /* Reserve a channel id. We need to put the name "/host" ++ * in the node's createArgs, but the host ++ * side channel will not be opened until DSPStream_Open is ++ * called for this node. */ ++ if (pAttrs) { ++ if (pAttrs->lMode == STRMMODE_RDMA) { ++ chnlId = GB_findandset(hNodeMgr->dmaChnlMap); ++ /* dma chans are 2nd transport chnl set ++ * ids(e.g. 16-31)*/ ++ (chnlId != GB_NOBITS) ? ++ (chnlId = chnlId + hNodeMgr->ulNumChnls) : ++ chnlId; ++ } else if (pAttrs->lMode == STRMMODE_ZEROCOPY) { ++ chnlId = GB_findandset(hNodeMgr->zChnlMap); ++ /* zero-copy chans are 3nd transport set ++ * (e.g. 32-47) */ ++ (chnlId != GB_NOBITS) ? (chnlId = chnlId + ++ (2 * hNodeMgr->ulNumChnls)) : chnlId; ++ } else { /* must be PROCCOPY */ ++ DBC_Assert(pAttrs->lMode == STRMMODE_PROCCOPY); ++ chnlId = GB_findandset(hNodeMgr->chnlMap); ++ /* e.g. 0-15 */ ++ } ++ } else { ++ /* default to PROCCOPY */ ++ chnlId = GB_findandset(hNodeMgr->chnlMap); ++ } ++ if (chnlId == GB_NOBITS) { ++ status = DSP_ENOMORECONNECTIONS; ++ goto func_cont2; ++ } ++ pstrDevName = MEM_Calloc(HOSTNAMELEN + 1, MEM_PAGED); ++ if (pstrDevName != NULL) ++ goto func_cont2; ++ ++ if (pAttrs) { ++ if (pAttrs->lMode == STRMMODE_RDMA) { ++ GB_clear(hNodeMgr->dmaChnlMap, chnlId - ++ hNodeMgr->ulNumChnls); ++ } else if (pAttrs->lMode == STRMMODE_ZEROCOPY) { ++ GB_clear(hNodeMgr->zChnlMap, chnlId - ++ (2*hNodeMgr->ulNumChnls)); ++ } else { ++ DBC_Assert(pAttrs->lMode == STRMMODE_PROCCOPY); ++ GB_clear(hNodeMgr->chnlMap, chnlId); ++ } ++ } else { ++ GB_clear(hNodeMgr->chnlMap, chnlId); ++ } ++ status = DSP_EMEMORY; ++func_cont2: ++ if (DSP_SUCCEEDED(status)) { ++ if (hNode1 == (struct NODE_OBJECT *) DSP_HGPPNODE) { ++ hNode2->inputs[uStream2].type = HOSTCONNECT; ++ hNode2->inputs[uStream2].devId = chnlId; ++ pInput->szDevice = pstrDevName; ++ } else { ++ hNode1->outputs[uStream1].type = HOSTCONNECT; ++ hNode1->outputs[uStream1].devId = chnlId; ++ pOutput->szDevice = pstrDevName; ++ } ++ sprintf(pstrDevName, "%s%d", HOSTPREFIX, chnlId); ++ } ++ } ++ /* Connecting task node to device node? */ ++ if (DSP_SUCCEEDED(status) && ((node1Type == NODE_DEVICE) || ++ (node2Type == NODE_DEVICE))) { ++ if (node2Type == NODE_DEVICE) { ++ /* node1 == > device */ ++ hDevNode = hNode2; ++ hNode = hNode1; ++ pStream = &(hNode1->outputs[uStream1]); ++ pstrmDef = pOutput; ++ } else { ++ /* device == > node2 */ ++ hDevNode = hNode1; ++ hNode = hNode2; ++ pStream = &(hNode2->inputs[uStream2]); ++ pstrmDef = pInput; ++ } ++ /* Set up create args */ ++ pStream->type = DEVICECONNECT; ++ dwLength = strlen(hDevNode->pstrDevName); ++ if (pConnParam != NULL) { ++ pstrmDef->szDevice = MEM_Calloc(dwLength + 1 + ++ (u32) pConnParam->cbData, ++ MEM_PAGED); ++ } else { ++ pstrmDef->szDevice = MEM_Calloc(dwLength + 1, ++ MEM_PAGED); ++ } ++ if (pstrmDef->szDevice == NULL) { ++ status = DSP_EMEMORY; ++ } else { ++ /* Copy device name */ ++ strncpy(pstrmDef->szDevice, hDevNode->pstrDevName, ++ dwLength); ++ if (pConnParam != NULL) { ++ strncat(pstrmDef->szDevice, ++ (char *)pConnParam->cData, ++ (u32)pConnParam->cbData); ++ } ++ hDevNode->hDeviceOwner = hNode; ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Fill in create args */ ++ if (node1Type == NODE_TASK || node1Type == NODE_DAISSOCKET) { ++ hNode1->createArgs.asa.taskArgs.uNumOutputs++; ++ FillStreamDef(hNode1, pOutput, pAttrs); ++ } ++ if (node2Type == NODE_TASK || node2Type == NODE_DAISSOCKET) { ++ hNode2->createArgs.asa.taskArgs.uNumInputs++; ++ FillStreamDef(hNode2, pInput, pAttrs); ++ } ++ /* Update hNode1 and hNode2 streamConnect */ ++ if (node1Type != NODE_GPP && node1Type != NODE_DEVICE) { ++ hNode1->uNumOutputs++; ++ if (uStream1 > hNode1->uMaxOutputIndex) ++ hNode1->uMaxOutputIndex = uStream1; ++ ++ } ++ if (node2Type != NODE_GPP && node2Type != NODE_DEVICE) { ++ hNode2->uNumInputs++; ++ if (uStream2 > hNode2->uMaxInputIndex) ++ hNode2->uMaxInputIndex = uStream2; ++ ++ } ++ FillStreamConnect(hNode1, hNode2, uStream1, uStream2); ++ } ++func_cont: ++ /* end of SYNC_EnterCS */ ++ /* Exit critical section */ ++ (void)SYNC_LeaveCS(hNodeMgr->hSync); ++func_end: ++ return status; ++} ++ ++/* ++ * ======== NODE_Create ======== ++ * Purpose: ++ * Create a node on the DSP by remotely calling the node's create function. ++ */ ++DSP_STATUS NODE_Create(struct NODE_OBJECT *hNode) ++{ ++ struct NODE_OBJECT *pNode = (struct NODE_OBJECT *)hNode; ++ struct NODE_MGR *hNodeMgr; ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ u32 ulCreateFxn; ++ enum NODE_TYPE nodeType; ++ DSP_STATUS status = DSP_SOK; ++ DSP_STATUS status1 = DSP_SOK; ++ bool bJustWokeDSP = false; ++ struct DSP_CBDATA cbData; ++ u32 procId = 255; ++ struct DSP_PROCESSORSTATE procStatus; ++ struct PROC_OBJECT *hProcessor; ++#if defined(CONFIG_BRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ) ++ struct dspbridge_platform_data *pdata = ++ omap_dspbridge_dev->dev.platform_data; ++#endif ++ ++ DBC_Require(cRefs > 0); ++ GT_1trace(NODE_debugMask, GT_ENTER, "NODE_Create: hNode: 0x%x\n", ++ hNode); ++ hProcessor = hNode->hProcessor; ++ status = PROC_GetState(hProcessor, &procStatus, ++ sizeof(struct DSP_PROCESSORSTATE)); ++ if (DSP_FAILED(status)) ++ goto func_end; ++ /* If processor is in error state then don't attempt to create ++ new node */ ++ if (procStatus.iState == PROC_ERROR) { ++ GT_1trace(NODE_debugMask, GT_4CLASS, "NODE_Create:" ++ " proc Status 0x%x\n", procStatus.iState); ++ status = DSP_EFAIL; ++ goto func_end; ++ } ++ /* create struct DSP_CBDATA struct for PWR calls */ ++ cbData.cbData = PWR_TIMEOUT; ++ nodeType = NODE_GetType(hNode); ++ hNodeMgr = hNode->hNodeMgr; ++ pIntfFxns = hNodeMgr->pIntfFxns; ++ /* Get access to node dispatcher */ ++ status = SYNC_EnterCS(hNodeMgr->hSync); ++ if (DSP_FAILED(status)) ++ goto func_cont; ++ ++ /* Check node state */ ++ if (NODE_GetState(hNode) != NODE_ALLOCATED) ++ status = DSP_EWRONGSTATE; ++ ++ if (DSP_SUCCEEDED(status)) ++ status = PROC_GetProcessorId(pNode->hProcessor, &procId); ++ ++ if (DSP_FAILED(status)) ++ goto func_cont2; ++ ++ if (procId != DSP_UNIT) ++ goto func_cont2; ++ ++ /* Make sure streams are properly connected */ ++ if ((hNode->uNumInputs && hNode->uMaxInputIndex > ++ hNode->uNumInputs - 1) || ++ (hNode->uNumOutputs && hNode->uMaxOutputIndex > ++ hNode->uNumOutputs - 1)) ++ status = DSP_ENOTCONNECTED; ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* If node's create function is not loaded, load it */ ++ /* Boost the OPP level to max level that DSP can be requested */ ++#if defined(CONFIG_BRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ) ++ if (pdata->cpu_set_freq) { ++ (*pdata->cpu_set_freq)(pdata->mpu_speed[VDD1_OPP3]); ++ ++ if (pdata->dsp_get_opp) { ++ GT_1trace(NODE_debugMask, GT_4CLASS, "opp level" ++ "after setting to VDD1_OPP3 is %d\n", ++ (*pdata->dsp_get_opp)()); ++ } ++ } ++#endif ++ status = hNodeMgr->nldrFxns.pfnLoad(hNode->hNldrNode, ++ NLDR_CREATE); ++ /* Get address of node's create function */ ++ if (DSP_SUCCEEDED(status)) { ++ hNode->fLoaded = true; ++ if (nodeType != NODE_DEVICE) { ++ status = GetFxnAddress(hNode, &ulCreateFxn, ++ CREATEPHASE); ++ } ++ } else { ++ GT_1trace(NODE_debugMask, GT_ENTER, ++ "NODE_Create: failed to load" ++ " create code: 0x%x\n", status); ++ } ++ /* Request the lowest OPP level*/ ++#if defined(CONFIG_BRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ) ++ if (pdata->cpu_set_freq) { ++ (*pdata->cpu_set_freq)(pdata->mpu_speed[VDD1_OPP1]); ++ ++ if (pdata->dsp_get_opp) { ++ GT_1trace(NODE_debugMask, GT_4CLASS, "opp level" ++ "after setting to VDD1_OPP1 is %d\n", ++ (*pdata->dsp_get_opp)()); ++ } ++ } ++#endif ++ /* Get address of iAlg functions, if socket node */ ++ if (DSP_SUCCEEDED(status)) { ++ if (nodeType == NODE_DAISSOCKET) { ++ status = hNodeMgr->nldrFxns.pfnGetFxnAddr ++ (hNode->hNldrNode, hNode->dcdProps. ++ objData.nodeObj.pstrIAlgName, ++ &hNode->createArgs.asa.taskArgs. ++ ulDaisArg); ++ } ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ if (nodeType != NODE_DEVICE) { ++ status = DISP_NodeCreate(hNodeMgr->hDisp, hNode, ++ hNodeMgr->ulFxnAddrs[RMSCREATENODE], ++ ulCreateFxn, &(hNode->createArgs), ++ &(hNode->nodeEnv)); ++ if (DSP_SUCCEEDED(status)) { ++ /* Set the message queue id to the node env ++ * pointer */ ++ pIntfFxns = hNodeMgr->pIntfFxns; ++ (*pIntfFxns->pfnMsgSetQueueId)(hNode->hMsgQueue, ++ hNode->nodeEnv); ++ } ++ } ++ } ++ /* Phase II/Overlays: Create, execute, delete phases possibly in ++ * different files/sections. */ ++ if (hNode->fLoaded && hNode->fPhaseSplit) { ++ /* If create code was dynamically loaded, we can now unload ++ * it. */ ++ status1 = hNodeMgr->nldrFxns.pfnUnload(hNode->hNldrNode, ++ NLDR_CREATE); ++ hNode->fLoaded = false; ++ } ++ if (DSP_FAILED(status1)) { ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "NODE_Create: Failed to unload " ++ "create code: 0x%x\n", status1); ++ } ++func_cont2: ++ /* Update node state and node manager state */ ++ if (DSP_SUCCEEDED(status)) { ++ NODE_SetState(hNode, NODE_CREATED); ++ hNodeMgr->uNumCreated++; ++ goto func_cont; ++ } ++ if (status != DSP_EWRONGSTATE) { ++ /* Put back in NODE_ALLOCATED state if error occurred */ ++ NODE_SetState(hNode, NODE_ALLOCATED); ++ } ++ if (procId == DSP_UNIT) { ++ /* If node create failed, see if should sleep DSP now */ ++ if (bJustWokeDSP == true) { ++ /* Check to see if partial create happened on DSP */ ++ if (hNode->nodeEnv == (u32)NULL) { ++ /* No environment allocated on DSP, re-sleep ++ * DSP now */ ++ PROC_Ctrl(hNode->hProcessor, WMDIOCTL_DEEPSLEEP, ++ &cbData); ++ } else { ++ /* Increment count, sleep later when node fully ++ * deleted */ ++ hNodeMgr->uNumCreated++; ++ } ++ } ++ } ++func_cont: ++ /* Free access to node dispatcher */ ++ (void)SYNC_LeaveCS(hNodeMgr->hSync); ++func_end: ++ if (DSP_SUCCEEDED(status)) { ++ PROC_NotifyClients(hNode->hProcessor, DSP_NODESTATECHANGE); ++ NTFY_Notify(hNode->hNtfy, DSP_NODESTATECHANGE); ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== NODE_CreateMgr ======== ++ * Purpose: ++ * Create a NODE Manager object. ++ */ ++DSP_STATUS NODE_CreateMgr(OUT struct NODE_MGR **phNodeMgr, ++ struct DEV_OBJECT *hDevObject) ++{ ++ u32 i; ++ struct NODE_MGR *pNodeMgr = NULL; ++ struct DISP_ATTRS dispAttrs; ++ char *szZLFile = ""; ++ struct NLDR_ATTRS nldrAttrs; ++ DSP_STATUS status = DSP_SOK; ++ u32 devType; ++ DBC_Require(cRefs > 0); ++ DBC_Require(phNodeMgr != NULL); ++ DBC_Require(hDevObject != NULL); ++ GT_2trace(NODE_debugMask, GT_ENTER, "NODE_CreateMgr: phNodeMgr: 0x%x\t" ++ "hDevObject: 0x%x\n", phNodeMgr, hDevObject); ++ *phNodeMgr = NULL; ++ /* Allocate Node manager object */ ++ MEM_AllocObject(pNodeMgr, struct NODE_MGR, NODEMGR_SIGNATURE); ++ if (pNodeMgr) { ++ pNodeMgr->hDevObject = hDevObject; ++ pNodeMgr->nodeList = LST_Create(); ++ pNodeMgr->pipeMap = GB_create(MAXPIPES); ++ pNodeMgr->pipeDoneMap = GB_create(MAXPIPES); ++ if (pNodeMgr->nodeList == NULL || pNodeMgr->pipeMap == NULL || ++ pNodeMgr->pipeDoneMap == NULL) { ++ status = DSP_EMEMORY; ++ GT_0trace(NODE_debugMask, GT_6CLASS, ++ "NODE_CreateMgr: Memory " ++ "allocation failed\n"); ++ } else { ++ status = NTFY_Create(&pNodeMgr->hNtfy); ++ } ++ pNodeMgr->uNumCreated = 0; ++ } else { ++ GT_0trace(NODE_debugMask, GT_6CLASS, ++ "NODE_CreateMgr: Memory allocation failed\n"); ++ status = DSP_EMEMORY; ++ } ++ /* get devNodeType */ ++ if (DSP_SUCCEEDED(status)) ++ status = DEV_GetDevType(hDevObject, &devType); ++ ++ /* Create the DCD Manager */ ++ if (DSP_SUCCEEDED(status)) { ++ status = DCD_CreateManager(szZLFile, &pNodeMgr->hDcdMgr); ++ if (DSP_SUCCEEDED(status)) ++ status = GetProcProps(pNodeMgr, hDevObject); ++ ++ } ++ /* Create NODE Dispatcher */ ++ if (DSP_SUCCEEDED(status)) { ++ dispAttrs.ulChnlOffset = pNodeMgr->ulChnlOffset; ++ dispAttrs.ulChnlBufSize = pNodeMgr->ulChnlBufSize; ++ dispAttrs.procFamily = pNodeMgr->procFamily; ++ dispAttrs.procType = pNodeMgr->procType; ++ status = DISP_Create(&pNodeMgr->hDisp, hDevObject, &dispAttrs); ++ } ++ /* Create a STRM Manager */ ++ if (DSP_SUCCEEDED(status)) ++ status = STRM_Create(&pNodeMgr->hStrmMgr, hDevObject); ++ ++ if (DSP_SUCCEEDED(status)) { ++ DEV_GetIntfFxns(hDevObject, &pNodeMgr->pIntfFxns); ++ /* Get MSG queue manager */ ++ DEV_GetMsgMgr(hDevObject, &pNodeMgr->hMsg); ++ status = SYNC_InitializeCS(&pNodeMgr->hSync); ++ if (DSP_FAILED(status)) ++ status = DSP_EMEMORY; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ pNodeMgr->chnlMap = GB_create(pNodeMgr->ulNumChnls); ++ /* dma chnl map. ulNumChnls is # per transport */ ++ pNodeMgr->dmaChnlMap = GB_create(pNodeMgr->ulNumChnls); ++ pNodeMgr->zChnlMap = GB_create(pNodeMgr->ulNumChnls); ++ if ((pNodeMgr->chnlMap == NULL) || ++ (pNodeMgr->dmaChnlMap == NULL) || ++ (pNodeMgr->zChnlMap == NULL)) { ++ status = DSP_EMEMORY; ++ } else { ++ /* Block out reserved channels */ ++ for (i = 0; i < pNodeMgr->ulChnlOffset; i++) ++ GB_set(pNodeMgr->chnlMap, i); ++ ++ /* Block out channels reserved for RMS */ ++ GB_set(pNodeMgr->chnlMap, pNodeMgr->ulChnlOffset); ++ GB_set(pNodeMgr->chnlMap, pNodeMgr->ulChnlOffset + 1); ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* NO RM Server on the IVA */ ++ if (devType != IVA_UNIT) { ++ /* Get addresses of any RMS functions loaded */ ++ status = GetRMSFxns(pNodeMgr); ++ if (DSP_FAILED(status)) { ++ GT_1trace(NODE_debugMask, GT_6CLASS, ++ "NODE_CreateMgr: Failed to" ++ " get RMS functions: status = 0x%x", status); ++ } ++ } ++ } ++ ++ /* Get loader functions and create loader */ ++ if (DSP_SUCCEEDED(status)) { ++ GT_0trace(NODE_debugMask, GT_1CLASS, ++ "NODE_CreateMgr: using dynamic loader\n"); ++ pNodeMgr->nldrFxns = nldrFxns; /* Dynamic loader functions */ ++ } ++ if (DSP_SUCCEEDED(status)) { ++ nldrAttrs.pfnOvly = Ovly; ++ nldrAttrs.pfnWrite = Write; ++ nldrAttrs.usDSPWordSize = pNodeMgr->uDSPWordSize; ++ nldrAttrs.usDSPMauSize = pNodeMgr->uDSPMauSize; ++ pNodeMgr->fLoaderInit = pNodeMgr->nldrFxns.pfnInit(); ++ status = pNodeMgr->nldrFxns.pfnCreate(&pNodeMgr->hNldr, ++ hDevObject, &nldrAttrs); ++ if (DSP_FAILED(status)) { ++ GT_1trace(NODE_debugMask, GT_6CLASS, ++ "NODE_CreateMgr: Failed to " ++ "create loader: status = 0x%x\n", status); ++ } ++ } ++ if (DSP_SUCCEEDED(status)) ++ *phNodeMgr = pNodeMgr; ++ else ++ DeleteNodeMgr(pNodeMgr); ++ ++ DBC_Ensure((DSP_FAILED(status) && (*phNodeMgr == NULL)) || ++ (DSP_SUCCEEDED(status) && ++ MEM_IsValidHandle((*phNodeMgr), NODEMGR_SIGNATURE))); ++ ++ return status; ++} ++ ++/* ++ * ======== NODE_Delete ======== ++ * Purpose: ++ * Delete a node on the DSP by remotely calling the node's delete function. ++ * Loads the node's delete function if necessary. Free GPP side resources ++ * after node's delete function returns. ++ */ ++DSP_STATUS NODE_Delete(struct NODE_OBJECT *hNode) ++{ ++ struct NODE_OBJECT *pNode = (struct NODE_OBJECT *)hNode; ++ struct NODE_MGR *hNodeMgr; ++ struct PROC_OBJECT *hProcessor; ++ struct DISP_OBJECT *hDisp; ++ u32 ulDeleteFxn; ++ enum NODE_TYPE nodeType; ++ enum NODE_STATE state; ++ DSP_STATUS status = DSP_SOK; ++ DSP_STATUS status1 = DSP_SOK; ++ struct DSP_CBDATA cbData; ++ u32 procId; ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ ++#ifndef RES_CLEANUP_DISABLE ++ u32 hProcess; ++ HANDLE nodeRes; ++ HANDLE hDrvObject; ++ struct PROCESS_CONTEXT *pCtxt = NULL; ++ DSP_STATUS res_status = DSP_SOK; ++#endif ++ struct DSP_PROCESSORSTATE procStatus; ++ DBC_Require(cRefs > 0); ++ GT_1trace(NODE_debugMask, GT_ENTER, "NODE_Delete: hNode: 0x%x\n", ++ hNode); ++ if (!MEM_IsValidHandle(hNode, NODE_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ goto func_end; ++ } ++ /* create struct DSP_CBDATA struct for PWR call */ ++ cbData.cbData = PWR_TIMEOUT; ++ hNodeMgr = hNode->hNodeMgr; ++ hProcessor = hNode->hProcessor; ++ hDisp = hNodeMgr->hDisp; ++ nodeType = NODE_GetType(hNode); ++ pIntfFxns = hNodeMgr->pIntfFxns; ++ /* Enter critical section */ ++ status = SYNC_EnterCS(hNodeMgr->hSync); ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ state = NODE_GetState(hNode); ++ /* Execute delete phase code for non-device node in all cases ++ * except when the node was only allocated. Delete phase must be ++ * executed even if create phase was executed, but failed. ++ * If the node environment pointer is non-NULL, the delete phase ++ * code must be executed. */ ++ if (!(state == NODE_ALLOCATED && hNode->nodeEnv == (u32)NULL) && ++ nodeType != NODE_DEVICE) { ++ status = PROC_GetProcessorId(pNode->hProcessor, &procId); ++ if (DSP_FAILED(status)) ++ goto func_cont1; ++ ++ if (procId == DSP_UNIT || procId == IVA_UNIT) { ++ /* If node has terminated, execute phase code will ++ * have already been unloaded in NODE_OnExit(). If the ++ * node is PAUSED, the execute phase is loaded, and it ++ * is now ok to unload it. If the node is running, we ++ * will unload the execute phase only after deleting ++ * the node. */ ++ if (state == NODE_PAUSED && hNode->fLoaded && ++ hNode->fPhaseSplit) { ++ /* Ok to unload execute code as long as node ++ * is not * running */ ++ status1 = hNodeMgr->nldrFxns.pfnUnload(hNode-> ++ hNldrNode, NLDR_EXECUTE); ++ hNode->fLoaded = false; ++ NODE_SetState(hNode, NODE_DONE); ++ } ++ /* Load delete phase code if not loaded or if haven't ++ * * unloaded EXECUTE phase */ ++ if ((!(hNode->fLoaded) || (state == NODE_RUNNING)) && ++ hNode->fPhaseSplit) { ++ status = hNodeMgr->nldrFxns.pfnLoad(hNode-> ++ hNldrNode, NLDR_DELETE); ++ if (DSP_SUCCEEDED(status)) { ++ hNode->fLoaded = true; ++ } else { ++ GT_1trace(NODE_debugMask, GT_ENTER, ++ "NODE_Delete: failed to " ++ "load delete code: 0x%x\n", ++ status); ++ } ++ } ++ } ++func_cont1: ++ if (DSP_SUCCEEDED(status)) { ++ /* Unblock a thread trying to terminate the node */ ++ (void)SYNC_SetEvent(hNode->hSyncDone); ++ if (procId == DSP_UNIT) { ++ /* ulDeleteFxn = address of node's delete ++ * function */ ++ status = GetFxnAddress(hNode, &ulDeleteFxn, ++ DELETEPHASE); ++ } else if (procId == IVA_UNIT) ++ ulDeleteFxn = (u32)hNode->nodeEnv; ++ if (DSP_SUCCEEDED(status)) { ++ status = PROC_GetState(hProcessor, &procStatus, ++ sizeof(struct DSP_PROCESSORSTATE)); ++ GT_1trace(NODE_debugMask, GT_4CLASS, ++ "NODE_Delete: proc Status " ++ "0x%x\n", procStatus.iState); ++ if (procStatus.iState != PROC_ERROR) { ++ status = DISP_NodeDelete(hDisp, hNode, ++ hNodeMgr->ulFxnAddrs[RMSDELETENODE], ++ ulDeleteFxn, hNode->nodeEnv); ++ } else ++ NODE_SetState(hNode, NODE_DONE); ++ ++ /* Unload execute, if not unloaded, and delete ++ * function */ ++ if (state == NODE_RUNNING && ++ hNode->fPhaseSplit) { ++ status1 = hNodeMgr->nldrFxns.pfnUnload( ++ hNode->hNldrNode, NLDR_EXECUTE); ++ } ++ if (DSP_FAILED(status1)) { ++ GT_1trace(NODE_debugMask, GT_ENTER, ++ "NODE_Delete: failed to" ++ "unload execute code: 0x%x\n", ++ status1); ++ } ++ status1 = hNodeMgr->nldrFxns.pfnUnload( ++ hNode->hNldrNode, NLDR_DELETE); ++ hNode->fLoaded = false; ++ if (DSP_FAILED(status1)) { ++ GT_1trace(NODE_debugMask, GT_ENTER, ++ "NODE_Delete: failed to" ++ "unload delete code: 0x%x\n", ++ status1); ++ } ++ } ++ } ++ } ++ /* Free host side resources even if a failure occurred */ ++ /* Remove node from hNodeMgr->nodeList */ ++ LST_RemoveElem(hNodeMgr->nodeList, (struct LST_ELEM *) hNode); ++ hNodeMgr->uNumNodes--; ++ /* Decrement count of nodes created on DSP */ ++ if ((state != NODE_ALLOCATED) || ((state == NODE_ALLOCATED) && ++ (hNode->nodeEnv != (u32) NULL))) ++ hNodeMgr->uNumCreated--; ++ /* Free host-side resources allocated by NODE_Create() ++ * DeleteNode() fails if SM buffers not freed by client! */ ++#ifndef RES_CLEANUP_DISABLE ++ /* Return PID instead of process handle */ ++ hProcess = current->pid; ++ res_status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT); ++ if (DSP_FAILED(res_status)) ++ goto func_cont; ++ DRV_GetProcContext(0, (struct DRV_OBJECT *)hDrvObject, ++ &pCtxt, hNode, 0); ++ if (pCtxt == NULL) ++ goto func_cont; ++ if (DRV_GetNodeResElement(hNode, &nodeRes, pCtxt) != DSP_ENOTFOUND) { ++ GT_0trace(NODE_debugMask, GT_5CLASS, "\nNODE_Delete12:\n"); ++ DRV_ProcNodeUpdateStatus(nodeRes, false); ++ } ++#endif ++func_cont: ++ GT_0trace(NODE_debugMask, GT_ENTER, "\nNODE_Delete13:\n "); ++ DeleteNode(hNode); ++#ifndef RES_CLEANUP_DISABLE ++ GT_0trace(NODE_debugMask, GT_5CLASS, "\nNODE_Delete2:\n "); ++ if (pCtxt != NULL) ++ DRV_RemoveNodeResElement(nodeRes, (HANDLE)pCtxt); ++#endif ++ GT_0trace(NODE_debugMask, GT_ENTER, "\nNODE_Delete3:\n "); ++ /* Exit critical section */ ++ (void)SYNC_LeaveCS(hNodeMgr->hSync); ++ PROC_NotifyClients(hProcessor, DSP_NODESTATECHANGE); ++func_end: ++ return status; ++} ++ ++/* ++ * ======== NODE_DeleteMgr ======== ++ * Purpose: ++ * Delete the NODE Manager. ++ */ ++DSP_STATUS NODE_DeleteMgr(struct NODE_MGR *hNodeMgr) ++{ ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(hNodeMgr, NODEMGR_SIGNATURE)); ++ ++ GT_1trace(NODE_debugMask, GT_ENTER, "NODE_DeleteMgr: hNodeMgr: 0x%x\n", ++ hNodeMgr); ++ DeleteNodeMgr(hNodeMgr); ++ ++ return status; ++} ++ ++/* ++ * ======== NODE_EnumNodes ======== ++ * Purpose: ++ * Enumerate currently allocated nodes. ++ */ ++DSP_STATUS NODE_EnumNodes(struct NODE_MGR *hNodeMgr, IN DSP_HNODE *aNodeTab, ++ u32 uNodeTabSize, OUT u32 *puNumNodes, ++ OUT u32 *puAllocated) ++{ ++ struct NODE_OBJECT *hNode; ++ u32 i; ++ DSP_STATUS status = DSP_SOK; ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(hNodeMgr, NODEMGR_SIGNATURE)); ++ DBC_Require(aNodeTab != NULL || uNodeTabSize == 0); ++ DBC_Require(puNumNodes != NULL); ++ DBC_Require(puAllocated != NULL); ++ GT_5trace(NODE_debugMask, GT_ENTER, "NODE_EnumNodes: hNodeMgr: 0x%x\t" ++ "aNodeTab: %d\tuNodeTabSize: 0x%x\tpuNumNodes: 0x%x\t" ++ "puAllocated\n", hNodeMgr, aNodeTab, uNodeTabSize, puNumNodes, ++ puAllocated); ++ /* Enter critical section */ ++ status = SYNC_EnterCS(hNodeMgr->hSync); ++ if (DSP_SUCCEEDED(status)) { ++ if (hNodeMgr->uNumNodes > uNodeTabSize) { ++ *puAllocated = hNodeMgr->uNumNodes; ++ *puNumNodes = 0; ++ status = DSP_ESIZE; ++ } else { ++ hNode = (struct NODE_OBJECT *)LST_First(hNodeMgr-> ++ nodeList); ++ for (i = 0; i < hNodeMgr->uNumNodes; i++) { ++ DBC_Assert(MEM_IsValidHandle(hNode, ++ NODE_SIGNATURE)); ++ aNodeTab[i] = hNode; ++ hNode = (struct NODE_OBJECT *)LST_Next ++ (hNodeMgr->nodeList, ++ (struct LST_ELEM *)hNode); ++ } ++ *puAllocated = *puNumNodes = hNodeMgr->uNumNodes; ++ } ++ } ++ /* end of SYNC_EnterCS */ ++ /* Exit critical section */ ++ (void)SYNC_LeaveCS(hNodeMgr->hSync); ++ return status; ++} ++ ++/* ++ * ======== NODE_Exit ======== ++ * Purpose: ++ * Discontinue usage of NODE module. ++ */ ++void NODE_Exit(void) ++{ ++ DBC_Require(cRefs > 0); ++ ++ cRefs--; ++ ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "Entered NODE_Exit, ref count: 0x%x\n", cRefs); ++ ++ DBC_Ensure(cRefs >= 0); ++} ++ ++/* ++ * ======== NODE_FreeMsgBuf ======== ++ * Purpose: ++ * Frees the message buffer. ++ */ ++DSP_STATUS NODE_FreeMsgBuf(struct NODE_OBJECT *hNode, IN u8 *pBuffer, ++ OPTIONAL struct DSP_BUFFERATTR *pAttr) ++{ ++ struct NODE_OBJECT *pNode = (struct NODE_OBJECT *)hNode; ++ DSP_STATUS status = DSP_SOK; ++ u32 procId; ++ DBC_Require(cRefs > 0); ++ DBC_Require(pBuffer != NULL); ++ DBC_Require(pNode != NULL); ++ DBC_Require(pNode->hXlator != NULL); ++ GT_3trace(NODE_debugMask, GT_ENTER, "NODE_FreeMsgBuf: hNode: 0x%x\t" ++ "pBuffer: 0x%x\tpAttr: 0x%x\n", hNode, pBuffer, pAttr); ++ if (!MEM_IsValidHandle(hNode, NODE_SIGNATURE)) ++ status = DSP_EHANDLE; ++ ++ status = PROC_GetProcessorId(pNode->hProcessor, &procId); ++ if (procId == DSP_UNIT) { ++ if (DSP_SUCCEEDED(status)) { ++ if (pAttr == NULL) { ++ /* set defaults */ ++ pAttr = &NODE_DFLTBUFATTRS; ++ } ++ /* Node supports single SM segment only */ ++ if (pAttr->uSegment != 1) ++ status = DSP_EBADSEGID; ++ ++ /* pBuffer is clients Va. */ ++ status = CMM_XlatorFreeBuf(pNode->hXlator, pBuffer); ++ if (DSP_FAILED(status)) ++ status = DSP_EFAIL; ++ else ++ status = DSP_SOK; ++ ++ } ++ } else { ++ DBC_Assert(NULL); /* BUG */ ++ } ++ return status; ++} ++ ++/* ++ * ======== NODE_GetAttr ======== ++ * Purpose: ++ * Copy the current attributes of the specified node into a DSP_NODEATTR ++ * structure. ++ */ ++DSP_STATUS NODE_GetAttr(struct NODE_OBJECT *hNode, ++ OUT struct DSP_NODEATTR *pAttr, u32 uAttrSize) ++{ ++ struct NODE_MGR *hNodeMgr; ++ DSP_STATUS status = DSP_SOK; ++ DBC_Require(cRefs > 0); ++ DBC_Require(pAttr != NULL); ++ DBC_Require(uAttrSize >= sizeof(struct DSP_NODEATTR)); ++ GT_3trace(NODE_debugMask, GT_ENTER, "NODE_GetAttr: hNode: " ++ "0x%x\tpAttr: 0x%x \tuAttrSize: 0x%x\n", hNode, pAttr, ++ uAttrSize); ++ if (!MEM_IsValidHandle(hNode, NODE_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ } else { ++ hNodeMgr = hNode->hNodeMgr; ++ /* Enter hNodeMgr critical section (since we're accessing ++ * data that could be changed by NODE_ChangePriority() and ++ * NODE_Connect(). */ ++ status = SYNC_EnterCS(hNodeMgr->hSync); ++ if (DSP_SUCCEEDED(status)) { ++ pAttr->cbStruct = sizeof(struct DSP_NODEATTR); ++ /* DSP_NODEATTRIN */ ++ pAttr->inNodeAttrIn.cbStruct = ++ sizeof(struct DSP_NODEATTRIN); ++ pAttr->inNodeAttrIn.iPriority = hNode->nPriority; ++ pAttr->inNodeAttrIn.uTimeout = hNode->uTimeout; ++ pAttr->inNodeAttrIn.uHeapSize = ++ hNode->createArgs.asa.taskArgs.uHeapSize; ++ pAttr->inNodeAttrIn.pGPPVirtAddr = (void *) ++ hNode->createArgs.asa.taskArgs.uGPPHeapAddr; ++ pAttr->uInputs = hNode->uNumGPPInputs; ++ pAttr->uOutputs = hNode->uNumGPPOutputs; ++ /* DSP_NODEINFO */ ++ GetNodeInfo(hNode, &(pAttr->iNodeInfo)); ++ } ++ /* end of SYNC_EnterCS */ ++ /* Exit critical section */ ++ (void)SYNC_LeaveCS(hNodeMgr->hSync); ++ } ++ return status; ++} ++ ++/* ++ * ======== NODE_GetChannelId ======== ++ * Purpose: ++ * Get the channel index reserved for a stream connection between the ++ * host and a node. ++ */ ++DSP_STATUS NODE_GetChannelId(struct NODE_OBJECT *hNode, u32 uDir, u32 uIndex, ++ OUT u32 *pulId) ++{ ++ enum NODE_TYPE nodeType; ++ DSP_STATUS status = DSP_EVALUE; ++ DBC_Require(cRefs > 0); ++ DBC_Require(uDir == DSP_TONODE || uDir == DSP_FROMNODE); ++ DBC_Require(pulId != NULL); ++ GT_4trace(NODE_debugMask, GT_ENTER, "NODE_GetChannelId: hNode: " ++ "0x%x\tuDir: %d\tuIndex: %d\tpulId: 0x%x\n", hNode, uDir, ++ uIndex, pulId); ++ if (!MEM_IsValidHandle(hNode, NODE_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ return status; ++ } ++ nodeType = NODE_GetType(hNode); ++ if (nodeType != NODE_TASK && nodeType != NODE_DAISSOCKET) { ++ status = DSP_ENODETYPE; ++ return status; ++ } ++ if (uDir == DSP_TONODE) { ++ if (uIndex < MaxInputs(hNode)) { ++ if (hNode->inputs[uIndex].type == HOSTCONNECT) { ++ *pulId = hNode->inputs[uIndex].devId; ++ status = DSP_SOK; ++ } ++ } ++ } else { ++ DBC_Assert(uDir == DSP_FROMNODE); ++ if (uIndex < MaxOutputs(hNode)) { ++ if (hNode->outputs[uIndex].type == HOSTCONNECT) { ++ *pulId = hNode->outputs[uIndex].devId; ++ status = DSP_SOK; ++ } ++ } ++ } ++ return status; ++} ++ ++/* ++ * ======== NODE_GetMessage ======== ++ * Purpose: ++ * Retrieve a message from a node on the DSP. ++ */ ++DSP_STATUS NODE_GetMessage(struct NODE_OBJECT *hNode, OUT struct DSP_MSG *pMsg, ++ u32 uTimeout) ++{ ++ struct NODE_MGR *hNodeMgr; ++ enum NODE_TYPE nodeType; ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ DSP_STATUS status = DSP_SOK; ++ void *pTmpBuf; ++ struct DSP_PROCESSORSTATE procStatus; ++ struct PROC_OBJECT *hProcessor; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pMsg != NULL); ++ GT_3trace(NODE_debugMask, GT_ENTER, ++ "NODE_GetMessage: hNode: 0x%x\tpMsg: " ++ "0x%x\tuTimeout: 0x%x\n", hNode, pMsg, uTimeout); ++ hProcessor = hNode->hProcessor; ++ status = PROC_GetState(hProcessor, &procStatus, ++ sizeof(struct DSP_PROCESSORSTATE)); ++ if (DSP_FAILED(status)) ++ goto func_end; ++ /* If processor is in error state then don't attempt to get the ++ message */ ++ if (procStatus.iState == PROC_ERROR) { ++ GT_1trace(NODE_debugMask, GT_4CLASS, "NODE_GetMessage:" ++ " proc Status 0x%x\n", procStatus.iState); ++ status = DSP_EFAIL; ++ goto func_end; ++ } ++ if (!MEM_IsValidHandle(hNode, NODE_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ goto func_end; ++ } ++ hNodeMgr = hNode->hNodeMgr; ++ nodeType = NODE_GetType(hNode); ++ if (nodeType != NODE_MESSAGE && nodeType != NODE_TASK && ++ nodeType != NODE_DAISSOCKET) { ++ status = DSP_ENODETYPE; ++ goto func_end; ++ } ++ /* This function will block unless a message is available. Since ++ * DSPNode_RegisterNotify() allows notification when a message ++ * is available, the system can be designed so that ++ * DSPNode_GetMessage() is only called when a message is ++ * available. */ ++ pIntfFxns = hNodeMgr->pIntfFxns; ++ status = (*pIntfFxns->pfnMsgGet)(hNode->hMsgQueue, pMsg, uTimeout); ++ /* Check if message contains SM descriptor */ ++ if (DSP_FAILED(status) || !(pMsg->dwCmd & DSP_RMSBUFDESC)) ++ goto func_end; ++ ++ /* Translate DSP byte addr to GPP Va. */ ++ pTmpBuf = CMM_XlatorTranslate(hNode->hXlator, ++ (void *)(pMsg->dwArg1 * hNode->hNodeMgr->uDSPWordSize), ++ CMM_DSPPA2PA); ++ if (pTmpBuf != NULL) { ++ /* now convert this GPP Pa to Va */ ++ pTmpBuf = CMM_XlatorTranslate(hNode->hXlator, pTmpBuf, ++ CMM_PA2VA); ++ if (pTmpBuf != NULL) { ++ /* Adjust SM size in msg */ ++ pMsg->dwArg1 = (u32) pTmpBuf; ++ pMsg->dwArg2 *= hNode->hNodeMgr->uDSPWordSize; ++ } else { ++ GT_0trace(NODE_debugMask, GT_7CLASS, "NODE_GetMessage: " ++ "Failed SM translation!\n"); ++ status = DSP_ETRANSLATE; ++ } ++ } else { ++ GT_0trace(NODE_debugMask, GT_7CLASS, "NODE_GetMessage: Failed " ++ "SM Pa/Pa translation!\n"); ++ status = DSP_ETRANSLATE; ++ } ++func_end: ++ return status; ++} ++ ++/* ++ * ======== NODE_GetNldrObj ======== ++ */ ++DSP_STATUS NODE_GetNldrObj(struct NODE_MGR *hNodeMgr, ++ struct NLDR_OBJECT **phNldrObj) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct NODE_MGR *pNodeMgr = hNodeMgr; ++ DBC_Require(phNldrObj != NULL); ++ GT_2trace(NODE_debugMask, GT_ENTER, ++ "Entered NODE_GetNldrObj, hNodeMgr: " ++ "0x%x\n\tphNldrObj: 0x%x\n", hNodeMgr, phNldrObj); ++ if (!MEM_IsValidHandle(hNodeMgr, NODEMGR_SIGNATURE)) ++ status = DSP_EHANDLE; ++ else ++ *phNldrObj = pNodeMgr->hNldr; ++ ++ GT_2trace(NODE_debugMask, GT_ENTER, ++ "Exit NODE_GetNldrObj: status 0x%x\n\t" ++ "phNldrObj: 0x%x\n", status, *phNldrObj); ++ DBC_Ensure(DSP_SUCCEEDED(status) || ((phNldrObj != NULL) && ++ (*phNldrObj == NULL))); ++ return status; ++} ++ ++/* ++ * ======== NODE_GetStrmMgr ======== ++ * Purpose: ++ * Returns the Stream manager. ++ */ ++DSP_STATUS NODE_GetStrmMgr(struct NODE_OBJECT *hNode, ++ struct STRM_MGR **phStrmMgr) ++{ ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ ++ if (!MEM_IsValidHandle(hNode, NODE_SIGNATURE)) ++ status = DSP_EHANDLE; ++ else ++ *phStrmMgr = hNode->hNodeMgr->hStrmMgr; ++ ++ return status; ++} ++ ++/* ++ * ======== NODE_GetLoadType ======== ++ */ ++enum NLDR_LOADTYPE NODE_GetLoadType(struct NODE_OBJECT *hNode) ++{ ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(hNode, NODE_SIGNATURE)); ++ if (!MEM_IsValidHandle(hNode, NODE_SIGNATURE)) { ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "NODE_GetLoadType: Failed. hNode:" ++ " 0x%x\n", hNode); ++ return -1; ++ } else ++ return hNode->dcdProps.objData.nodeObj.usLoadType; ++} ++ ++/* ++ * ======== NODE_GetTimeout ======== ++ * Purpose: ++ * Returns the timeout value for this node. ++ */ ++u32 NODE_GetTimeout(struct NODE_OBJECT *hNode) ++{ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(hNode, NODE_SIGNATURE)); ++ if (!MEM_IsValidHandle(hNode, NODE_SIGNATURE)) { ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "NODE_GetTimeout: Failed. hNode:" ++ " 0x%x\n", hNode); ++ return 0; ++ } else ++ return hNode->uTimeout; ++} ++ ++/* ++ * ======== NODE_GetType ======== ++ * Purpose: ++ * Returns the node type. ++ */ ++enum NODE_TYPE NODE_GetType(struct NODE_OBJECT *hNode) ++{ ++ enum NODE_TYPE nodeType; ++ ++ if (hNode == (struct NODE_OBJECT *) DSP_HGPPNODE) ++ nodeType = NODE_GPP; ++ else { ++ if (!MEM_IsValidHandle(hNode, NODE_SIGNATURE)) ++ nodeType = -1; ++ else ++ nodeType = hNode->nType; ++ } ++ return nodeType; ++} ++ ++/* ++ * ======== NODE_Init ======== ++ * Purpose: ++ * Initialize the NODE module. ++ */ ++bool NODE_Init(void) ++{ ++ bool fRetVal = true; ++ ++ DBC_Require(cRefs >= 0); ++ ++ if (cRefs == 0) { ++ DBC_Assert(!NODE_debugMask.flags); ++ GT_create(&NODE_debugMask, "NO"); /* "NO" for NOde */ ++ } ++ ++ if (fRetVal) ++ cRefs++; ++ ++ GT_1trace(NODE_debugMask, GT_5CLASS, "NODE_Init(), ref count: 0x%x\n", ++ cRefs); ++ ++ DBC_Ensure((fRetVal && (cRefs > 0)) || (!fRetVal && (cRefs >= 0))); ++ return fRetVal; ++} ++ ++/* ++ * ======== NODE_OnExit ======== ++ * Purpose: ++ * Gets called when RMS_EXIT is received for a node. ++ */ ++void NODE_OnExit(struct NODE_OBJECT *hNode, s32 nStatus) ++{ ++ DBC_Assert(MEM_IsValidHandle(hNode, NODE_SIGNATURE)); ++ /* Set node state to done */ ++ NODE_SetState(hNode, NODE_DONE); ++ hNode->nExitStatus = nStatus; ++ if (hNode->fLoaded && hNode->fPhaseSplit) { ++ (void)hNode->hNodeMgr->nldrFxns.pfnUnload(hNode->hNldrNode, ++ NLDR_EXECUTE); ++ hNode->fLoaded = false; ++ } ++ /* Unblock call to NODE_Terminate */ ++ (void) SYNC_SetEvent(hNode->hSyncDone); ++ /* Notify clients */ ++ PROC_NotifyClients(hNode->hProcessor, DSP_NODESTATECHANGE); ++ NTFY_Notify(hNode->hNtfy, DSP_NODESTATECHANGE); ++} ++ ++/* ++ * ======== NODE_Pause ======== ++ * Purpose: ++ * Suspend execution of a node currently running on the DSP. ++ */ ++DSP_STATUS NODE_Pause(struct NODE_OBJECT *hNode) ++{ ++ struct NODE_OBJECT *pNode = (struct NODE_OBJECT *)hNode; ++ enum NODE_TYPE nodeType; ++ enum NODE_STATE state; ++ struct NODE_MGR *hNodeMgr; ++ DSP_STATUS status = DSP_SOK; ++ u32 procId; ++ struct DSP_PROCESSORSTATE procStatus; ++ struct PROC_OBJECT *hProcessor; ++ ++ DBC_Require(cRefs > 0); ++ ++ GT_1trace(NODE_debugMask, GT_ENTER, "NODE_Pause: hNode: 0x%x\n", hNode); ++ ++ if (!MEM_IsValidHandle(hNode, NODE_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ } else { ++ nodeType = NODE_GetType(hNode); ++ if (nodeType != NODE_TASK && nodeType != NODE_DAISSOCKET) ++ status = DSP_ENODETYPE; ++ ++ } ++ ++ status = PROC_GetProcessorId(pNode->hProcessor, &procId); ++ ++ if (procId == IVA_UNIT) ++ status = DSP_ENOTIMPL; ++ ++ if (DSP_SUCCEEDED(status)) { ++ hNodeMgr = hNode->hNodeMgr; ++ ++ /* Enter critical section */ ++ status = SYNC_EnterCS(hNodeMgr->hSync); ++ ++ if (DSP_SUCCEEDED(status)) { ++ state = NODE_GetState(hNode); ++ /* Check node state */ ++ if (state != NODE_RUNNING) ++ status = DSP_EWRONGSTATE; ++ ++ hProcessor = hNode->hProcessor; ++ status = PROC_GetState(hProcessor, &procStatus, ++ sizeof(struct DSP_PROCESSORSTATE)); ++ if (DSP_FAILED(status)) ++ goto func_end; ++ /* If processor is in error state then don't attempt ++ to send the message */ ++ if (procStatus.iState == PROC_ERROR) { ++ GT_1trace(NODE_debugMask, GT_4CLASS, ++ "NODE_Pause: proc Status 0x%x\n", ++ procStatus.iState); ++ status = DSP_EFAIL; ++ goto func_end; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ status = DISP_NodeChangePriority(hNodeMgr-> ++ hDisp, hNode, ++ hNodeMgr->ulFxnAddrs[RMSCHANGENODEPRIORITY], ++ hNode->nodeEnv, NODE_SUSPENDEDPRI); ++ } ++ ++ /* Update state */ ++ if (DSP_SUCCEEDED(status)) { ++ NODE_SetState(hNode, NODE_PAUSED); ++ } else { ++ GT_1trace(NODE_debugMask, GT_6CLASS, ++ "NODE_Pause: Failed. hNode:" ++ " 0x%x\n", hNode); ++ } ++ } ++ /* End of SYNC_EnterCS */ ++ /* Leave critical section */ ++ (void)SYNC_LeaveCS(hNodeMgr->hSync); ++ if (DSP_SUCCEEDED(status)) { ++ PROC_NotifyClients(hNode->hProcessor, ++ DSP_NODESTATECHANGE); ++ NTFY_Notify(hNode->hNtfy, DSP_NODESTATECHANGE); ++ } ++ } ++func_end: ++ return status; ++} ++ ++/* ++ * ======== NODE_PutMessage ======== ++ * Purpose: ++ * Send a message to a message node, task node, or XDAIS socket node. This ++ * function will block until the message stream can accommodate the ++ * message, or a timeout occurs. ++ */ ++DSP_STATUS NODE_PutMessage(struct NODE_OBJECT *hNode, ++ IN CONST struct DSP_MSG *pMsg, u32 uTimeout) ++{ ++ struct NODE_MGR *hNodeMgr = NULL; ++ enum NODE_TYPE nodeType; ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ enum NODE_STATE state; ++ DSP_STATUS status = DSP_SOK; ++ void *pTmpBuf; ++ struct DSP_MSG newMsg; ++ struct DSP_PROCESSORSTATE procStatus; ++ struct PROC_OBJECT *hProcessor; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pMsg != NULL); ++ GT_3trace(NODE_debugMask, GT_ENTER, ++ "NODE_PutMessage: hNode: 0x%x\tpMsg: " ++ "0x%x\tuTimeout: 0x%x\n", hNode, pMsg, uTimeout); ++ hProcessor = hNode->hProcessor; ++ status = PROC_GetState(hProcessor, &procStatus, ++ sizeof(struct DSP_PROCESSORSTATE)); ++ if (DSP_FAILED(status)) ++ goto func_end; ++ /* If processor is in bad state then don't attempt sending the ++ message */ ++ if (procStatus.iState == PROC_ERROR) { ++ GT_1trace(NODE_debugMask, GT_4CLASS, "NODE_PutMessage:" ++ " proc Status 0x%x\n", procStatus.iState); ++ status = DSP_EFAIL; ++ goto func_end; ++ } ++ if (!MEM_IsValidHandle(hNode, NODE_SIGNATURE)) ++ status = DSP_EHANDLE; ++ else { ++ hNodeMgr = hNode->hNodeMgr; ++ nodeType = NODE_GetType(hNode); ++ if (nodeType != NODE_MESSAGE && nodeType != NODE_TASK && ++ nodeType != NODE_DAISSOCKET) ++ status = DSP_ENODETYPE; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Check node state. Can't send messages to a node after ++ * we've sent the RMS_EXIT command. There is still the ++ * possibility that NODE_Terminate can be called after we've ++ * checked the state. Could add another SYNC object to ++ * prevent this (can't use hNodeMgr->hSync, since we don't ++ * want to block other NODE functions). However, the node may ++ * still exit on its own, before this message is sent. */ ++ status = SYNC_EnterCS(hNodeMgr->hSync); ++ if (DSP_SUCCEEDED(status)) { ++ state = NODE_GetState(hNode); ++ if (state == NODE_TERMINATING || state == NODE_DONE) ++ status = DSP_EWRONGSTATE; ++ ++ } ++ /* end of SYNC_EnterCS */ ++ (void)SYNC_LeaveCS(hNodeMgr->hSync); ++ } ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ /* assign pMsg values to new msg */ ++ newMsg = *pMsg; ++ /* Now, check if message contains a SM buffer descriptor */ ++ if (pMsg->dwCmd & DSP_RMSBUFDESC) { ++ /* Translate GPP Va to DSP physical buf Ptr. */ ++ pTmpBuf = CMM_XlatorTranslate(hNode->hXlator, ++ (void *)newMsg.dwArg1, CMM_VA2DSPPA); ++ if (pTmpBuf != NULL) { ++ /* got translation, convert to MAUs in msg */ ++ if (hNode->hNodeMgr->uDSPWordSize != 0) { ++ newMsg.dwArg1 = ++ (u32)pTmpBuf / ++ hNode->hNodeMgr->uDSPWordSize; ++ /* MAUs */ ++ newMsg.dwArg2 /= hNode->hNodeMgr->uDSPWordSize; ++ } else { ++ GT_0trace(NODE_debugMask, GT_7CLASS, ++ "NODE_PutMessage: " ++ "uDSPWordSize is zero!\n"); ++ status = DSP_EFAIL; /* bad DSPWordSize */ ++ } ++ } else { /* failed to translate buffer address */ ++ GT_0trace(NODE_debugMask, GT_7CLASS, ++ "NODE_PutMessage: Failed to" ++ " translate SM address\n"); ++ status = DSP_ETRANSLATE; ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ pIntfFxns = hNodeMgr->pIntfFxns; ++ status = (*pIntfFxns->pfnMsgPut)(hNode->hMsgQueue, ++ &newMsg, uTimeout); ++ } ++func_end: ++ return status; ++} ++ ++/* ++ * ======== NODE_RegisterNotify ======== ++ * Purpose: ++ * Register to be notified on specific events for this node. ++ */ ++DSP_STATUS NODE_RegisterNotify(struct NODE_OBJECT *hNode, u32 uEventMask, ++ u32 uNotifyType, ++ struct DSP_NOTIFICATION *hNotification) ++{ ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(hNotification != NULL); ++ ++ GT_4trace(NODE_debugMask, GT_ENTER, ++ "NODE_RegisterNotify: hNode: 0x%x\t" ++ "uEventMask: 0x%x\tuNotifyType: 0x%x\thNotification: 0x%x\n", ++ hNode, uEventMask, uNotifyType, hNotification); ++ ++ if (!MEM_IsValidHandle(hNode, NODE_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ } else { ++ /* Check if event mask is a valid node related event */ ++ if (uEventMask & ~(DSP_NODESTATECHANGE | ++ DSP_NODEMESSAGEREADY)) ++ status = DSP_EVALUE; ++ ++ /* Check if notify type is valid */ ++ if (uNotifyType != DSP_SIGNALEVENT) ++ status = DSP_EVALUE; ++ ++ /* Only one Notification can be registered at a ++ * time - Limitation */ ++ if (uEventMask == (DSP_NODESTATECHANGE | ++ DSP_NODEMESSAGEREADY)) ++ status = DSP_EVALUE; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ if (uEventMask == DSP_NODESTATECHANGE) { ++ status = NTFY_Register(hNode->hNtfy, hNotification, ++ uEventMask & DSP_NODESTATECHANGE, uNotifyType); ++ } else { ++ /* Send Message part of event mask to MSG */ ++ pIntfFxns = hNode->hNodeMgr->pIntfFxns; ++ status = (*pIntfFxns->pfnMsgRegisterNotify) ++ (hNode->hMsgQueue, ++ uEventMask & DSP_NODEMESSAGEREADY, uNotifyType, ++ hNotification); ++ } ++ ++ } ++ return status; ++} ++ ++/* ++ * ======== NODE_Run ======== ++ * Purpose: ++ * Start execution of a node's execute phase, or resume execution of a node ++ * that has been suspended (via NODE_NodePause()) on the DSP. Load the ++ * node's execute function if necessary. ++ */ ++DSP_STATUS NODE_Run(struct NODE_OBJECT *hNode) ++{ ++ struct NODE_OBJECT *pNode = (struct NODE_OBJECT *)hNode; ++ struct NODE_MGR *hNodeMgr; ++ enum NODE_TYPE nodeType; ++ enum NODE_STATE state; ++ u32 ulExecuteFxn; ++ u32 ulFxnAddr; ++ DSP_STATUS status = DSP_SOK; ++ u32 procId; ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ struct DSP_PROCESSORSTATE procStatus; ++ struct PROC_OBJECT *hProcessor; ++ ++ DBC_Require(cRefs > 0); ++ GT_1trace(NODE_debugMask, GT_ENTER, "NODE_Run: hNode: 0x%x\n", hNode); ++ hProcessor = hNode->hProcessor; ++ status = PROC_GetState(hProcessor, &procStatus, ++ sizeof(struct DSP_PROCESSORSTATE)); ++ if (DSP_FAILED(status)) ++ goto func_end; ++ /* If processor is in error state then don't attempt to run the node */ ++ if (procStatus.iState == PROC_ERROR) { ++ GT_1trace(NODE_debugMask, GT_4CLASS, "NODE_Run:" ++ " proc Status 0x%x\n", procStatus.iState); ++ status = DSP_EFAIL; ++ goto func_end; ++ } ++ if (!MEM_IsValidHandle(hNode, NODE_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ } else { ++ nodeType = NODE_GetType(hNode); ++ if (nodeType == NODE_DEVICE) ++ status = DSP_ENODETYPE; ++ } ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ hNodeMgr = hNode->hNodeMgr; ++ pIntfFxns = hNodeMgr->pIntfFxns; ++ /* Enter critical section */ ++ status = SYNC_EnterCS(hNodeMgr->hSync); ++ if (DSP_FAILED(status)) ++ goto func_cont; ++ ++ state = NODE_GetState(hNode); ++ if (state != NODE_CREATED && state != NODE_PAUSED) ++ status = DSP_EWRONGSTATE; ++ ++ if (DSP_SUCCEEDED(status)) ++ status = PROC_GetProcessorId(pNode->hProcessor, &procId); ++ ++ if (DSP_FAILED(status)) ++ goto func_cont1; ++ ++ if ((procId != DSP_UNIT) && (procId != IVA_UNIT)) ++ goto func_cont1; ++ ++ if (state == NODE_CREATED) { ++ /* If node's execute function is not loaded, load it */ ++ if (!(hNode->fLoaded) && hNode->fPhaseSplit) { ++ status = hNodeMgr->nldrFxns.pfnLoad(hNode->hNldrNode, ++ NLDR_EXECUTE); ++ if (DSP_SUCCEEDED(status)) { ++ hNode->fLoaded = true; ++ } else { ++ GT_1trace(NODE_debugMask, GT_ENTER, ++ "NODE_Run: failed to load " ++ "execute code:0x%x\n", status); ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Get address of node's execute function */ ++ if (procId == IVA_UNIT) ++ ulExecuteFxn = (u32) hNode->nodeEnv; ++ else { ++ status = GetFxnAddress(hNode, &ulExecuteFxn, ++ EXECUTEPHASE); ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ ulFxnAddr = hNodeMgr->ulFxnAddrs[RMSEXECUTENODE]; ++ status = DISP_NodeRun(hNodeMgr->hDisp, hNode, ulFxnAddr, ++ ulExecuteFxn, hNode->nodeEnv); ++ } ++ } else if (state == NODE_PAUSED) { ++ ulFxnAddr = hNodeMgr->ulFxnAddrs[RMSCHANGENODEPRIORITY]; ++ status = DISP_NodeChangePriority(hNodeMgr->hDisp, hNode, ++ ulFxnAddr, hNode->nodeEnv, ++ NODE_GetPriority(hNode)); ++ } else { ++ /* We should never get here */ ++ DBC_Assert(false); ++ } ++func_cont1: ++ /* Update node state. */ ++ if (DSP_SUCCEEDED(status)) ++ NODE_SetState(hNode, NODE_RUNNING); ++ else /* Set state back to previous value */ ++ NODE_SetState(hNode, state); ++ /*End of SYNC_EnterCS */ ++ /* Exit critical section */ ++func_cont: ++ (void)SYNC_LeaveCS(hNodeMgr->hSync); ++ if (DSP_SUCCEEDED(status)) { ++ PROC_NotifyClients(hNode->hProcessor, ++ DSP_NODESTATECHANGE); ++ NTFY_Notify(hNode->hNtfy, DSP_NODESTATECHANGE); ++ } ++func_end: ++ return status; ++} ++ ++/* ++ * ======== NODE_Terminate ======== ++ * Purpose: ++ * Signal a node running on the DSP that it should exit its execute phase ++ * function. ++ */ ++DSP_STATUS NODE_Terminate(struct NODE_OBJECT *hNode, OUT DSP_STATUS *pStatus) ++{ ++ struct NODE_OBJECT *pNode = (struct NODE_OBJECT *)hNode; ++ struct NODE_MGR *hNodeMgr = NULL; ++ enum NODE_TYPE nodeType; ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ enum NODE_STATE state; ++ struct DSP_MSG msg, killmsg; ++ DSP_STATUS status = DSP_SOK; ++ u32 procId, killTimeOut; ++ struct DEH_MGR *hDehMgr; ++ struct DSP_PROCESSORSTATE procStatus; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pStatus != NULL); ++ ++ GT_1trace(NODE_debugMask, GT_ENTER, ++ "NODE_Terminate: hNode: 0x%x\n", hNode); ++ ++ if (pNode->hProcessor == NULL) { ++ GT_1trace(NODE_debugMask, GT_4CLASS, ++ "NODE_Terminate: pNode->hProcessor = 0x%x\n", ++ pNode->hProcessor); ++ goto func_end; ++ } ++ status = PROC_GetProcessorId(pNode->hProcessor, &procId); ++ ++ if (DSP_SUCCEEDED(status)) { ++ hNodeMgr = hNode->hNodeMgr; ++ ++ if (!MEM_IsValidHandle(hNode, NODE_SIGNATURE)) ++ status = DSP_EHANDLE; ++ else { ++ nodeType = NODE_GetType(hNode); ++ if (nodeType != NODE_TASK && nodeType != ++ NODE_DAISSOCKET) ++ status = DSP_ENODETYPE; ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Check node state */ ++ status = SYNC_EnterCS(hNodeMgr->hSync); ++ if (DSP_SUCCEEDED(status)) { ++ state = NODE_GetState(hNode); ++ if (state != NODE_RUNNING) { ++ status = DSP_EWRONGSTATE; ++ /* Set the exit status if node terminated on ++ * its own. */ ++ if (state == NODE_DONE) ++ *pStatus = hNode->nExitStatus; ++ ++ } else { ++ NODE_SetState(hNode, NODE_TERMINATING); ++ } ++ } ++ /* end of SYNC_EnterCS */ ++ (void)SYNC_LeaveCS(hNodeMgr->hSync); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* ++ * Send exit message. Do not change state to NODE_DONE ++ * here. That will be done in callback. ++ */ ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "NODE_Terminate: env = 0x%x\n", hNode->nodeEnv); ++ ++ status = PROC_GetState(pNode->hProcessor, &procStatus, ++ sizeof(struct DSP_PROCESSORSTATE)); ++ if (DSP_FAILED(status)) ++ goto func_cont; ++ /* If processor is in error state then don't attempt to send ++ * A kill task command */ ++ if (procStatus.iState == PROC_ERROR) { ++ GT_1trace(NODE_debugMask, GT_4CLASS, "NODE_Terminate:" ++ " proc Status 0x%x\n", procStatus.iState); ++ status = DSP_EFAIL; ++ goto func_cont; ++ } ++ ++ msg.dwCmd = RMS_EXIT; ++ msg.dwArg1 = hNode->nodeEnv; ++ killmsg.dwCmd = RMS_KILLTASK; ++ killmsg.dwArg1 = hNode->nodeEnv; ++ pIntfFxns = hNodeMgr->pIntfFxns; ++ ++ if (hNode->uTimeout > MAXTIMEOUT) ++ killTimeOut = MAXTIMEOUT; ++ else ++ killTimeOut = (hNode->uTimeout)*2; ++ ++ status = (*pIntfFxns->pfnMsgPut)(hNode->hMsgQueue, &msg, ++ hNode->uTimeout); ++ if (DSP_SUCCEEDED(status)) { ++ /* Wait on synchronization object that will be ++ * posted in the callback on receiving RMS_EXIT ++ * message, or by NODE_Delete. Check for valid hNode, ++ * in case posted by NODE_Delete(). */ ++ status = SYNC_WaitOnEvent(hNode->hSyncDone, ++ killTimeOut/2); ++ if (DSP_FAILED(status)) { ++ if (status == DSP_ETIMEOUT) { ++ status = (*pIntfFxns->pfnMsgPut) ++ (hNode->hMsgQueue, &killmsg, ++ hNode->uTimeout); ++ if (DSP_SUCCEEDED(status)) { ++ status = SYNC_WaitOnEvent ++ (hNode->hSyncDone, ++ killTimeOut/2); ++ if (DSP_FAILED(status)) { ++ /* Here it goes the part ++ * of the simulation of ++ * the DSP exception */ ++ DEV_GetDehMgr(hNodeMgr-> ++ hDevObject, &hDehMgr); ++ if (hDehMgr) { ++ (*pIntfFxns-> ++ pfnDehNotify)(hDehMgr, ++ DSP_SYSERROR, ++ DSP_EXCEPTIONABORT); ++ status = DSP_EFAIL; ++ } ++ } else ++ status = DSP_SOK; ++ } ++ } else ++ status = DSP_EFAIL; ++ } else /* Convert SYNC status to DSP status */ ++ status = DSP_SOK; ++ } ++ } ++func_cont: ++ if (DSP_SUCCEEDED(status)) { ++ /* Enter CS before getting exit status, in case node was ++ * deleted. */ ++ status = SYNC_EnterCS(hNodeMgr->hSync); ++ /* Make sure node wasn't deleted while we blocked */ ++ if (!MEM_IsValidHandle(hNode, NODE_SIGNATURE)) { ++ status = DSP_EFAIL; ++ } else { ++ *pStatus = hNode->nExitStatus; ++ GT_1trace(NODE_debugMask, GT_ENTER, ++ "NODE_Terminate: env = 0x%x " ++ "succeeded.\n", hNode->nodeEnv); ++ } ++ (void)SYNC_LeaveCS(hNodeMgr->hSync); ++ } /*End of SYNC_EnterCS */ ++func_end: ++ return status; ++} ++ ++/* ++ * ======== DeleteNode ======== ++ * Purpose: ++ * Free GPP resources allocated in NODE_Allocate() or NODE_Connect(). ++ */ ++static void DeleteNode(struct NODE_OBJECT *hNode) ++{ ++ struct NODE_MGR *hNodeMgr; ++ struct CMM_XLATOROBJECT *hXlator; ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ u32 i; ++ enum NODE_TYPE nodeType; ++ struct STREAM stream; ++ struct NODE_MSGARGS msgArgs; ++ struct NODE_TASKARGS taskArgs; ++#ifdef DSP_DMM_DEBUG ++ struct DMM_OBJECT *hDmmMgr; ++ struct PROC_OBJECT *pProcObject = ++ (struct PROC_OBJECT *)hNode->hProcessor; ++#endif ++ DSP_STATUS status; ++ DBC_Require(MEM_IsValidHandle(hNode, NODE_SIGNATURE)); ++ hNodeMgr = hNode->hNodeMgr; ++ if (!MEM_IsValidHandle(hNodeMgr, NODEMGR_SIGNATURE)) ++ return; ++ hXlator = hNode->hXlator; ++ nodeType = NODE_GetType(hNode); ++ if (nodeType != NODE_DEVICE) { ++ msgArgs = hNode->createArgs.asa.msgArgs; ++ if (msgArgs.pData) ++ MEM_Free(msgArgs.pData); ++ ++ /* Free MSG queue */ ++ if (hNode->hMsgQueue) { ++ pIntfFxns = hNodeMgr->pIntfFxns; ++ (*pIntfFxns->pfnMsgDeleteQueue) (hNode->hMsgQueue); ++ hNode->hMsgQueue = NULL; ++ ++ } ++ if (hNode->hSyncDone) ++ (void) SYNC_CloseEvent(hNode->hSyncDone); ++ ++ /* Free all stream info */ ++ if (hNode->inputs) { ++ for (i = 0; i < MaxInputs(hNode); i++) { ++ stream = hNode->inputs[i]; ++ FreeStream(hNodeMgr, stream); ++ } ++ MEM_Free(hNode->inputs); ++ hNode->inputs = NULL; ++ } ++ if (hNode->outputs) { ++ for (i = 0; i < MaxOutputs(hNode); i++) { ++ stream = hNode->outputs[i]; ++ FreeStream(hNodeMgr, stream); ++ } ++ MEM_Free(hNode->outputs); ++ hNode->outputs = NULL; ++ } ++ taskArgs = hNode->createArgs.asa.taskArgs; ++ if (taskArgs.strmInDef) { ++ for (i = 0; i < MaxInputs(hNode); i++) { ++ if (taskArgs.strmInDef[i].szDevice) { ++ MEM_Free(taskArgs.strmInDef[i]. ++ szDevice); ++ taskArgs.strmInDef[i].szDevice = NULL; ++ } ++ } ++ MEM_Free(taskArgs.strmInDef); ++ taskArgs.strmInDef = NULL; ++ } ++ if (taskArgs.strmOutDef) { ++ for (i = 0; i < MaxOutputs(hNode); i++) { ++ if (taskArgs.strmOutDef[i].szDevice) { ++ MEM_Free(taskArgs.strmOutDef[i]. ++ szDevice); ++ taskArgs.strmOutDef[i].szDevice = NULL; ++ } ++ } ++ MEM_Free(taskArgs.strmOutDef); ++ taskArgs.strmOutDef = NULL; ++ } ++ if (taskArgs.uDSPHeapResAddr) { ++ status = PROC_UnMap(hNode->hProcessor, ++ (void *)taskArgs.uDSPHeapAddr); ++ if (DSP_SUCCEEDED(status)) { ++ GT_0trace(NODE_debugMask, GT_5CLASS, ++ "DSPProcessor_UnMap succeeded.\n"); ++ } else { ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "DSPProcessor_UnMap failed." ++ " Status = 0x%x\n", (u32)status); ++ } ++ status = PROC_UnReserveMemory(hNode->hProcessor, ++ (void *)taskArgs.uDSPHeapResAddr); ++ if (DSP_SUCCEEDED(status)) { ++ GT_0trace(NODE_debugMask, GT_5CLASS, ++ "DSPProcessor_UnReserveMemory " ++ "succeeded.\n"); ++ } else { ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "DSPProcessor_UnReserveMemory " ++ "failed. Status = 0x%x\n", ++ (u32)status); ++ } ++#ifdef DSP_DMM_DEBUG ++ status = DMM_GetHandle(pProcObject, &hDmmMgr); ++ if (DSP_SUCCEEDED(status)) ++ DMM_MemMapDump(hDmmMgr); ++#endif ++ } ++ } ++ if (nodeType != NODE_MESSAGE) { ++ if (hNode->streamConnect) { ++ MEM_Free(hNode->streamConnect); ++ hNode->streamConnect = NULL; ++ } ++ } ++ if (hNode->pstrDevName) { ++ MEM_Free(hNode->pstrDevName); ++ hNode->pstrDevName = NULL; ++ } ++ ++ if (hNode->hNtfy) { ++ NTFY_Delete(hNode->hNtfy); ++ hNode->hNtfy = NULL; ++ } ++ ++ /* These were allocated in DCD_GetObjectDef (via NODE_Allocate) */ ++ if (hNode->dcdProps.objData.nodeObj.pstrCreatePhaseFxn) { ++ MEM_Free(hNode->dcdProps.objData.nodeObj.pstrCreatePhaseFxn); ++ hNode->dcdProps.objData.nodeObj.pstrCreatePhaseFxn = NULL; ++ } ++ ++ if (hNode->dcdProps.objData.nodeObj.pstrExecutePhaseFxn) { ++ MEM_Free(hNode->dcdProps.objData.nodeObj.pstrExecutePhaseFxn); ++ hNode->dcdProps.objData.nodeObj.pstrExecutePhaseFxn = NULL; ++ } ++ ++ if (hNode->dcdProps.objData.nodeObj.pstrDeletePhaseFxn) { ++ MEM_Free(hNode->dcdProps.objData.nodeObj.pstrDeletePhaseFxn); ++ hNode->dcdProps.objData.nodeObj.pstrDeletePhaseFxn = NULL; ++ } ++ ++ if (hNode->dcdProps.objData.nodeObj.pstrIAlgName) { ++ MEM_Free(hNode->dcdProps.objData.nodeObj.pstrIAlgName); ++ hNode->dcdProps.objData.nodeObj.pstrIAlgName = NULL; ++ } ++ ++ /* Free all SM address translator resources */ ++ if (hXlator) { ++ (void) CMM_XlatorDelete(hXlator, TRUE); /* force free */ ++ hXlator = NULL; ++ } ++ ++ if (hNode->hNldrNode) { ++ hNodeMgr->nldrFxns.pfnFree(hNode->hNldrNode); ++ hNode->hNldrNode = NULL; ++ } ++ ++ MEM_FreeObject(hNode); ++ hNode = NULL; ++} ++ ++/* ++ * ======== DeleteNodeMgr ======== ++ * Purpose: ++ * Frees the node manager. ++ */ ++static void DeleteNodeMgr(struct NODE_MGR *hNodeMgr) ++{ ++ struct NODE_OBJECT *hNode; ++ ++ if (MEM_IsValidHandle(hNodeMgr, NODEMGR_SIGNATURE)) { ++ /* Free resources */ ++ if (hNodeMgr->hDcdMgr) ++ DCD_DestroyManager(hNodeMgr->hDcdMgr); ++ ++ /* Remove any elements remaining in lists */ ++ if (hNodeMgr->nodeList) { ++ while ((hNode = ++ (struct NODE_OBJECT *)LST_GetHead(hNodeMgr-> ++ nodeList))) ++ DeleteNode(hNode); ++ ++ DBC_Assert(LST_IsEmpty(hNodeMgr->nodeList)); ++ LST_Delete(hNodeMgr->nodeList); ++ } ++ if (hNodeMgr->hNtfy) ++ NTFY_Delete(hNodeMgr->hNtfy); ++ ++ if (hNodeMgr->pipeMap) ++ GB_delete(hNodeMgr->pipeMap); ++ ++ if (hNodeMgr->pipeDoneMap) ++ GB_delete(hNodeMgr->pipeDoneMap); ++ ++ if (hNodeMgr->chnlMap) ++ GB_delete(hNodeMgr->chnlMap); ++ ++ if (hNodeMgr->dmaChnlMap) ++ GB_delete(hNodeMgr->dmaChnlMap); ++ ++ if (hNodeMgr->zChnlMap) ++ GB_delete(hNodeMgr->zChnlMap); ++ ++ if (hNodeMgr->hDisp) ++ DISP_Delete(hNodeMgr->hDisp); ++ ++ if (hNodeMgr->hSync) ++ SYNC_DeleteCS(hNodeMgr->hSync); ++ ++ if (hNodeMgr->hStrmMgr) ++ STRM_Delete(hNodeMgr->hStrmMgr); ++ ++ /* Delete the loader */ ++ if (hNodeMgr->hNldr) ++ hNodeMgr->nldrFxns.pfnDelete(hNodeMgr->hNldr); ++ ++ if (hNodeMgr->fLoaderInit) ++ hNodeMgr->nldrFxns.pfnExit(); ++ ++ MEM_FreeObject(hNodeMgr); ++ } ++} ++ ++/* ++ * ======== FillStreamConnect ======== ++ * Purpose: ++ * Fills stream information. ++ */ ++static void FillStreamConnect(struct NODE_OBJECT *hNode1, ++ struct NODE_OBJECT *hNode2, ++ u32 uStream1, u32 uStream2) ++{ ++ u32 uStrmIndex; ++ struct DSP_STREAMCONNECT *pStrm1 = NULL; ++ struct DSP_STREAMCONNECT *pStrm2 = NULL; ++ enum NODE_TYPE node1Type = NODE_TASK; ++ enum NODE_TYPE node2Type = NODE_TASK; ++ ++ node1Type = NODE_GetType(hNode1); ++ node2Type = NODE_GetType(hNode2); ++ if (hNode1 != (struct NODE_OBJECT *)DSP_HGPPNODE) { ++ ++ if (node1Type != NODE_DEVICE) { ++ uStrmIndex = hNode1->uNumInputs + ++ hNode1->uNumOutputs - 1; ++ pStrm1 = &(hNode1->streamConnect[uStrmIndex]); ++ pStrm1->cbStruct = sizeof(struct DSP_STREAMCONNECT); ++ pStrm1->uThisNodeStreamIndex = uStream1; ++ } ++ ++ if (hNode2 != (struct NODE_OBJECT *)DSP_HGPPNODE) { ++ /* NODE == > NODE */ ++ if (node1Type != NODE_DEVICE) { ++ pStrm1->hConnectedNode = hNode2; ++ pStrm1->uiConnectedNodeID = hNode2->nodeId; ++ pStrm1->uConnectedNodeStreamIndex = uStream2; ++ pStrm1->lType = CONNECTTYPE_NODEOUTPUT; ++ } ++ if (node2Type != NODE_DEVICE) { ++ uStrmIndex = hNode2->uNumInputs + ++ hNode2->uNumOutputs - 1; ++ pStrm2 = &(hNode2->streamConnect[uStrmIndex]); ++ pStrm2->cbStruct = ++ sizeof(struct DSP_STREAMCONNECT); ++ pStrm2->uThisNodeStreamIndex = uStream2; ++ pStrm2->hConnectedNode = hNode1; ++ pStrm2->uiConnectedNodeID = hNode1->nodeId; ++ pStrm2->uConnectedNodeStreamIndex = uStream1; ++ pStrm2->lType = CONNECTTYPE_NODEINPUT; ++ } ++ } else if (node1Type != NODE_DEVICE) ++ pStrm1->lType = CONNECTTYPE_GPPOUTPUT; ++ } else { ++ /* GPP == > NODE */ ++ DBC_Assert(hNode2 != (struct NODE_OBJECT *)DSP_HGPPNODE); ++ uStrmIndex = hNode2->uNumInputs + hNode2->uNumOutputs - 1; ++ pStrm2 = &(hNode2->streamConnect[uStrmIndex]); ++ pStrm2->cbStruct = sizeof(struct DSP_STREAMCONNECT); ++ pStrm2->uThisNodeStreamIndex = uStream2; ++ pStrm2->lType = CONNECTTYPE_GPPINPUT; ++ } ++} ++ ++/* ++ * ======== FillStreamDef ======== ++ * Purpose: ++ * Fills Stream attributes. ++ */ ++static void FillStreamDef(struct NODE_OBJECT *hNode, ++ struct NODE_STRMDEF *pstrmDef, ++ struct DSP_STRMATTR *pAttrs) ++{ ++ struct NODE_MGR *hNodeMgr = hNode->hNodeMgr; ++ ++ if (pAttrs != NULL) { ++ pstrmDef->uNumBufs = pAttrs->uNumBufs; ++ pstrmDef->uBufsize = pAttrs->uBufsize / hNodeMgr-> ++ uDSPDataMauSize; ++ pstrmDef->uSegid = pAttrs->uSegid; ++ pstrmDef->uAlignment = pAttrs->uAlignment; ++ pstrmDef->uTimeout = pAttrs->uTimeout; ++ } else { ++ pstrmDef->uNumBufs = DEFAULTNBUFS; ++ pstrmDef->uBufsize = DEFAULTBUFSIZE / hNodeMgr-> ++ uDSPDataMauSize; ++ pstrmDef->uSegid = DEFAULTSEGID; ++ pstrmDef->uAlignment = DEFAULTALIGNMENT; ++ pstrmDef->uTimeout = DEFAULTTIMEOUT; ++ } ++} ++ ++/* ++ * ======== FreeStream ======== ++ * Purpose: ++ * Updates the channel mask and frees the pipe id. ++ */ ++static void FreeStream(struct NODE_MGR *hNodeMgr, struct STREAM stream) ++{ ++ /* Free up the pipe id unless other node has not yet been deleted. */ ++ if (stream.type == NODECONNECT) { ++ if (GB_test(hNodeMgr->pipeDoneMap, stream.devId)) { ++ /* The other node has already been deleted */ ++ GB_clear(hNodeMgr->pipeDoneMap, stream.devId); ++ GB_clear(hNodeMgr->pipeMap, stream.devId); ++ } else { ++ /* The other node has not been deleted yet */ ++ GB_set(hNodeMgr->pipeDoneMap, stream.devId); ++ } ++ } else if (stream.type == HOSTCONNECT) { ++ if (stream.devId < hNodeMgr->ulNumChnls) { ++ GB_clear(hNodeMgr->chnlMap, stream.devId); ++ } else if (stream.devId < (2 * hNodeMgr->ulNumChnls)) { ++ /* dsp-dma */ ++ GB_clear(hNodeMgr->dmaChnlMap, stream.devId - ++ (1 * hNodeMgr->ulNumChnls)); ++ } else if (stream.devId < (3 * hNodeMgr->ulNumChnls)) { ++ /* zero-copy */ ++ GB_clear(hNodeMgr->zChnlMap, stream.devId - ++ (2 * hNodeMgr->ulNumChnls)); ++ } ++ } ++} ++ ++/* ++ * ======== GetFxnAddress ======== ++ * Purpose: ++ * Retrieves the address for create, execute or delete phase for a node. ++ */ ++static DSP_STATUS GetFxnAddress(struct NODE_OBJECT *hNode, u32 *pulFxnAddr, ++ u32 uPhase) ++{ ++ char *pstrFxnName = NULL; ++ struct NODE_MGR *hNodeMgr = hNode->hNodeMgr; ++ DSP_STATUS status = DSP_SOK; ++ DBC_Require(NODE_GetType(hNode) == NODE_TASK || ++ NODE_GetType(hNode) == NODE_DAISSOCKET || ++ NODE_GetType(hNode) == NODE_MESSAGE); ++ ++ switch (uPhase) { ++ case CREATEPHASE: ++ pstrFxnName = hNode->dcdProps.objData.nodeObj. ++ pstrCreatePhaseFxn; ++ break; ++ case EXECUTEPHASE: ++ pstrFxnName = hNode->dcdProps.objData.nodeObj. ++ pstrExecutePhaseFxn; ++ break; ++ case DELETEPHASE: ++ pstrFxnName = hNode->dcdProps.objData.nodeObj. ++ pstrDeletePhaseFxn; ++ break; ++ default: ++ /* Should never get here */ ++ DBC_Assert(false); ++ break; ++ } ++ ++ status = hNodeMgr->nldrFxns.pfnGetFxnAddr(hNode->hNldrNode, pstrFxnName, ++ pulFxnAddr); ++ ++ return status; ++} ++ ++/* ++ * ======== GetNodeInfo ======== ++ * Purpose: ++ * Retrieves the node information. ++ */ ++void GetNodeInfo(struct NODE_OBJECT *hNode, struct DSP_NODEINFO *pNodeInfo) ++{ ++ u32 i; ++ ++ DBC_Require(MEM_IsValidHandle(hNode, NODE_SIGNATURE)); ++ DBC_Require(pNodeInfo != NULL); ++ ++ pNodeInfo->cbStruct = sizeof(struct DSP_NODEINFO); ++ pNodeInfo->nbNodeDatabaseProps = hNode->dcdProps.objData.nodeObj. ++ ndbProps; ++ pNodeInfo->uExecutionPriority = hNode->nPriority; ++ pNodeInfo->hDeviceOwner = hNode->hDeviceOwner; ++ pNodeInfo->uNumberStreams = hNode->uNumInputs + hNode->uNumOutputs; ++ pNodeInfo->uNodeEnv = hNode->nodeEnv; ++ ++ pNodeInfo->nsExecutionState = NODE_GetState(hNode); ++ ++ /* Copy stream connect data */ ++ for (i = 0; i < hNode->uNumInputs + hNode->uNumOutputs; i++) ++ pNodeInfo->scStreamConnection[i] = hNode->streamConnect[i]; ++ ++} ++ ++/* ++ * ======== GetNodeProps ======== ++ * Purpose: ++ * Retrieve node properties. ++ */ ++static DSP_STATUS GetNodeProps(struct DCD_MANAGER *hDcdMgr, ++ struct NODE_OBJECT *hNode, ++ CONST struct DSP_UUID *pNodeId, ++ struct DCD_GENERICOBJ *pdcdProps) ++{ ++ u32 uLen; ++ struct NODE_MSGARGS *pMsgArgs; ++ struct NODE_TASKARGS *pTaskArgs; ++ enum NODE_TYPE nodeType = NODE_TASK; ++ struct DSP_NDBPROPS *pndbProps = &(pdcdProps->objData.nodeObj.ndbProps); ++ DSP_STATUS status = DSP_SOK; ++#ifdef DEBUG ++ char szUuid[MAXUUIDLEN]; ++#endif ++ ++ status = DCD_GetObjectDef(hDcdMgr, (struct DSP_UUID *)pNodeId, ++ DSP_DCDNODETYPE, pdcdProps); ++ ++ if (DSP_SUCCEEDED(status)) { ++ hNode->nType = nodeType = pndbProps->uNodeType; ++ ++#ifdef DEBUG ++ /* Create UUID value to set in registry. */ ++ UUID_UuidToString((struct DSP_UUID *)pNodeId, szUuid, ++ MAXUUIDLEN); ++ DBG_Trace(DBG_LEVEL7, "\n** (node) UUID: %s\n", szUuid); ++#endif ++ ++ /* Fill in message args that come from NDB */ ++ if (nodeType != NODE_DEVICE) { ++ pMsgArgs = &(hNode->createArgs.asa.msgArgs); ++ pMsgArgs->uSegid = pdcdProps->objData.nodeObj.uMsgSegid; ++ pMsgArgs->uNotifyType = pdcdProps->objData.nodeObj. ++ uMsgNotifyType; ++ pMsgArgs->uMaxMessages = pndbProps->uMessageDepth; ++#ifdef DEBUG ++ DBG_Trace(DBG_LEVEL7, ++ "** (node) Max Number of Messages: 0x%x\n", ++ pMsgArgs->uMaxMessages); ++#endif ++ } else { ++ /* Copy device name */ ++ DBC_Require(pndbProps->acName); ++ uLen = strlen(pndbProps->acName); ++ DBC_Assert(uLen < MAXDEVNAMELEN); ++ hNode->pstrDevName = MEM_Calloc(uLen + 1, MEM_PAGED); ++ if (hNode->pstrDevName == NULL) { ++ status = DSP_EMEMORY; ++ } else { ++ strncpy(hNode->pstrDevName, ++ pndbProps->acName, uLen); ++ } ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Fill in create args that come from NDB */ ++ if (nodeType == NODE_TASK || nodeType == NODE_DAISSOCKET) { ++ pTaskArgs = &(hNode->createArgs.asa.taskArgs); ++ pTaskArgs->nPriority = pndbProps->iPriority; ++ pTaskArgs->uStackSize = pndbProps->uStackSize; ++ pTaskArgs->uSysStackSize = pndbProps->uSysStackSize; ++ pTaskArgs->uStackSeg = pndbProps->uStackSeg; ++#ifdef DEBUG ++ DBG_Trace(DBG_LEVEL7, ++ "** (node) Priority: 0x%x\n" "** (node) Stack" ++ " Size: 0x%x words\n" "** (node) System Stack" ++ " Size: 0x%x words\n" "** (node) Stack" ++ " Segment: 0x%x\n\n", ++ "** (node) profile count : 0x%x \n \n", ++ pTaskArgs->nPriority, pTaskArgs->uStackSize, ++ pTaskArgs->uSysStackSize, ++ pTaskArgs->uStackSeg, ++ pndbProps->uCountProfiles); ++#endif ++ } ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== GetProcProps ======== ++ * Purpose: ++ * Retrieve the processor properties. ++ */ ++static DSP_STATUS GetProcProps(struct NODE_MGR *hNodeMgr, ++ struct DEV_OBJECT *hDevObject) ++{ ++ struct CFG_DEVNODE *hDevNode; ++ struct CFG_HOSTRES hostRes; ++ DSP_STATUS status = DSP_SOK; ++ ++ status = DEV_GetDevNode(hDevObject, &hDevNode); ++ if (DSP_SUCCEEDED(status)) ++ status = CFG_GetHostResources(hDevNode, &hostRes); ++ ++ if (DSP_SUCCEEDED(status)) { ++ hNodeMgr->ulChnlOffset = hostRes.dwChnlOffset; ++ hNodeMgr->ulChnlBufSize = hostRes.dwChnlBufSize; ++ hNodeMgr->ulNumChnls = hostRes.dwNumChnls; ++ ++ /* ++ * PROC will add an API to get DSP_PROCESSORINFO. ++ * Fill in default values for now. ++ */ ++ /* TODO -- Instead of hard coding, take from registry */ ++ hNodeMgr->procFamily = 6000; ++ hNodeMgr->procType = 6410; ++ hNodeMgr->nMinPri = DSP_NODE_MIN_PRIORITY; ++ hNodeMgr->nMaxPri = DSP_NODE_MAX_PRIORITY; ++ hNodeMgr->uDSPWordSize = DSPWORDSIZE; ++ hNodeMgr->uDSPDataMauSize = DSPWORDSIZE; ++ hNodeMgr->uDSPMauSize = 1; ++ ++ } ++ return status; ++} ++ ++ ++ ++/* ++ * ======== NODE_GetUUIDProps ======== ++ * Purpose: ++ * Fetch Node UUID properties from DCD/DOF file. ++ */ ++DSP_STATUS NODE_GetUUIDProps(DSP_HPROCESSOR hProcessor, ++ IN CONST struct DSP_UUID *pNodeId, ++ OUT struct DSP_NDBPROPS *pNodeProps) ++{ ++ struct NODE_MGR *hNodeMgr = NULL; ++ struct DEV_OBJECT *hDevObject; ++ DSP_STATUS status = DSP_SOK; ++ struct DCD_NODEPROPS dcdNodeProps; ++ struct DSP_PROCESSORSTATE procStatus; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(hProcessor != NULL); ++ DBC_Require(pNodeId != NULL); ++ ++ if (hProcessor == NULL || pNodeId == NULL) { ++ status = DSP_EHANDLE; ++ goto func_end; ++ } ++ status = PROC_GetState(hProcessor, &procStatus, ++ sizeof(struct DSP_PROCESSORSTATE)); ++ if (DSP_FAILED(status)) ++ goto func_end; ++ /* If processor is in error state then don't attempt ++ to send the message */ ++ if (procStatus.iState == PROC_ERROR) { ++ GT_1trace(NODE_debugMask, GT_5CLASS, ++ "NODE_GetUUIDProps: proc Status 0x%x\n", ++ procStatus.iState); ++ status = DSP_EFAIL; ++ goto func_end; ++ } ++ ++ GT_3trace(NODE_debugMask, GT_ENTER, ++ "NODE_GetUUIDProps: " "\thProcessor: " ++ "0x%x\tpNodeId: 0x%x" "\tpNodeProps: 0x%x\n", hProcessor, ++ pNodeId, pNodeProps); ++ ++ status = PROC_GetDevObject(hProcessor, &hDevObject); ++ if (DSP_SUCCEEDED(status) && hDevObject != NULL) { ++ status = DEV_GetNodeManager(hDevObject, &hNodeMgr); ++ if (hNodeMgr == NULL) { ++ status = DSP_EHANDLE; ++ goto func_end; ++ } ++ } ++ ++ /* ++ * Enter the critical section. This is needed because ++ * DCD_GetObjectDef will ultimately end up calling DBLL_open/close, ++ * which needs to be protected in order to not corrupt the zlib manager ++ * (COD). ++ */ ++ status = SYNC_EnterCS(hNodeMgr->hSync); ++ ++ if (DSP_SUCCEEDED(status)) { ++ dcdNodeProps.pstrCreatePhaseFxn = NULL; ++ dcdNodeProps.pstrExecutePhaseFxn = NULL; ++ dcdNodeProps.pstrDeletePhaseFxn = NULL; ++ dcdNodeProps.pstrIAlgName = NULL; ++ ++ status = DCD_GetObjectDef(hNodeMgr->hDcdMgr, ++ (struct DSP_UUID *) pNodeId, ++ DSP_DCDNODETYPE, ++ (struct DCD_GENERICOBJ *) &dcdNodeProps); ++ if (DSP_SUCCEEDED(status)) { ++ *pNodeProps = dcdNodeProps.ndbProps; ++ if (dcdNodeProps.pstrCreatePhaseFxn) ++ MEM_Free(dcdNodeProps.pstrCreatePhaseFxn); ++ ++ if (dcdNodeProps.pstrExecutePhaseFxn) ++ MEM_Free(dcdNodeProps.pstrExecutePhaseFxn); ++ ++ if (dcdNodeProps.pstrDeletePhaseFxn) ++ MEM_Free(dcdNodeProps.pstrDeletePhaseFxn); ++ ++ if (dcdNodeProps.pstrIAlgName) ++ MEM_Free(dcdNodeProps.pstrIAlgName); ++ } ++ /* Leave the critical section, we're done. */ ++ (void)SYNC_LeaveCS(hNodeMgr->hSync); ++ } ++func_end: ++ return status; ++} ++ ++/* ++ * ======== GetRMSFxns ======== ++ * Purpose: ++ * Retrieve the RMS functions. ++ */ ++static DSP_STATUS GetRMSFxns(struct NODE_MGR *hNodeMgr) ++{ ++ s32 i; ++ struct DEV_OBJECT *hDev = hNodeMgr->hDevObject; ++ DSP_STATUS status = DSP_SOK; ++ ++ static char *pszFxns[NUMRMSFXNS] = { ++ "RMS_queryServer", /* RMSQUERYSERVER */ ++ "RMS_configureServer", /* RMSCONFIGURESERVER */ ++ "RMS_createNode", /* RMSCREATENODE */ ++ "RMS_executeNode", /* RMSEXECUTENODE */ ++ "RMS_deleteNode", /* RMSDELETENODE */ ++ "RMS_changeNodePriority", /* RMSCHANGENODEPRIORITY */ ++ "RMS_readMemory", /* RMSREADMEMORY */ ++ "RMS_writeMemory", /* RMSWRITEMEMORY */ ++ "RMS_copy", /* RMSCOPY */ ++ }; ++ ++ for (i = 0; i < NUMRMSFXNS; i++) { ++ status = DEV_GetSymbol(hDev, pszFxns[i], ++ &(hNodeMgr->ulFxnAddrs[i])); ++ if (DSP_FAILED(status)) { ++ if (status == COD_E_SYMBOLNOTFOUND) { ++ /* ++ * May be loaded dynamically (in the future), ++ * but return an error for now. ++ */ ++ GT_1trace(NODE_debugMask, GT_6CLASS, ++ "RMS function: %s " ++ "currently not loaded\n", pszFxns[i]); ++ } else { ++ GT_2trace(NODE_debugMask, GT_6CLASS, ++ "GetRMSFxns: Symbol not " ++ "found: %s\tstatus = 0x%x\n", ++ pszFxns[i], status); ++ break; ++ } ++ } ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== Ovly ======== ++ * Purpose: ++ * Called during overlay.Sends command to RMS to copy a block of data. ++ */ ++static u32 Ovly(void *pPrivRef, u32 ulDspRunAddr, u32 ulDspLoadAddr, ++ u32 ulNumBytes, u32 nMemSpace) ++{ ++ struct NODE_OBJECT *hNode = (struct NODE_OBJECT *)pPrivRef; ++ struct NODE_MGR *hNodeMgr; ++ u32 ulBytes = 0; ++ u32 ulSize; ++ u32 ulTimeout; ++ DSP_STATUS status = DSP_SOK; ++ struct WMD_DEV_CONTEXT *hWmdContext; ++ struct WMD_DRV_INTERFACE *pIntfFxns; /* Function interface to WMD */ ++ ++ DBC_Require(MEM_IsValidHandle(hNode, NODE_SIGNATURE)); ++ ++ hNodeMgr = hNode->hNodeMgr; ++ ++ ulSize = ulNumBytes / hNodeMgr->uDSPWordSize; ++ ulTimeout = hNode->uTimeout; ++ ++ /* Call new MemCopy function */ ++ pIntfFxns = hNodeMgr->pIntfFxns; ++ status = DEV_GetWMDContext(hNodeMgr->hDevObject, &hWmdContext); ++ status = (*pIntfFxns->pfnBrdMemCopy)(hWmdContext, ulDspRunAddr, ++ ulDspLoadAddr, ulNumBytes, (u32) nMemSpace); ++ ++ if (DSP_SUCCEEDED(status)) ++ ulBytes = ulNumBytes; ++ ++ return ulBytes; ++} ++ ++/* ++ * ======== Write ======== ++ */ ++static u32 Write(void *pPrivRef, u32 ulDspAddr, void *pBuf, ++ u32 ulNumBytes, u32 nMemSpace) ++{ ++ struct NODE_OBJECT *hNode = (struct NODE_OBJECT *) pPrivRef; ++ struct NODE_MGR *hNodeMgr; ++ u16 memType; ++ u32 ulTimeout; ++ DSP_STATUS status = DSP_SOK; ++ struct WMD_DEV_CONTEXT *hWmdContext; ++ struct WMD_DRV_INTERFACE *pIntfFxns; /* Function interface to WMD */ ++ ++ DBC_Require(MEM_IsValidHandle(hNode, NODE_SIGNATURE)); ++ DBC_Require(nMemSpace & DBLL_CODE || nMemSpace & DBLL_DATA); ++ ++ hNodeMgr = hNode->hNodeMgr; ++ ++ ulTimeout = hNode->uTimeout; ++ memType = (nMemSpace & DBLL_CODE) ? RMS_CODE : RMS_DATA; ++ ++ /* Call new MemWrite function */ ++ pIntfFxns = hNodeMgr->pIntfFxns; ++ status = DEV_GetWMDContext(hNodeMgr->hDevObject, &hWmdContext); ++ status = (*pIntfFxns->pfnBrdMemWrite) (hWmdContext, pBuf, ulDspAddr, ++ ulNumBytes, memType); ++ ++ return ulNumBytes; ++} ++ +diff --git a/drivers/dsp/bridge/rmgr/proc.c b/drivers/dsp/bridge/rmgr/proc.c +new file mode 100644 +index 0000000..332e01a +--- /dev/null ++++ b/drivers/dsp/bridge/rmgr/proc.c +@@ -0,0 +1,1985 @@ ++/* ++ * proc.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== proc.c ======== ++ * Description: ++ * Processor interface at the driver level. ++ * ++ * Public Functions: ++ * PROC_Attach ++ * PROC_Ctrl ++ * PROC_Detach ++ * PROC_EnumNodes ++ * PROC_GetResourceInfo ++ * PROC_Exit ++ * PROC_FlushMemory ++ * PROC_GetState ++ * PROC_GetProcessorId ++ * PROC_GetTrace ++ * PROC_Init ++ * PROC_Load ++ * PROC_Map ++ * PROC_NotifyClients ++ * PROC_RegisterNotify ++ * PROC_ReserveMemory ++ * PROC_Start ++ * PROC_UnMap ++ * PROC_UnReserveMemory ++ * PROC_InvalidateMemory ++ ++ *! Revision History ++ *! ======== ======== ++ *! 04-Apr-2007 sh Added PROC_InvalidateMemory API ++ *! 19-Apr-2004 sb Aligned DMM definitions with Symbian ++ *! Used MEM_FlushCache instead of OS specific API ++ *! Integrated Alan's code review updates ++ *! 08-Mar-2004 sb Added the Dynamic Memory Mapping feature ++ *! 08-Mar-2004 vp Added g_pszLastCoff member to PROC_OBJECT. ++ *! This is required for multiprocessor environment. ++ *! 09-Feb-2004 vp Added PROC_GetProcessorID function ++ *! 22-Apr-2003 vp Fixed issue with the string that stores coff file name ++ *! 03-Apr-2003 sb Fix DEH deregistering bug ++ *! 26-Mar-2003 vp Commented the call to DSP deep sleep in PROC_Start function. ++ *! 18-Feb-2003 vp Code review updates. ++ *! 18-Oct-2002 vp Ported to Linux platform. ++ *! 22-May-2002 sg Do IOCTL-to-PWR translation before calling PWR_SleepDSP. ++ *! 14-May-2002 sg Use CSL_Atoi() instead of atoi(). ++ *! 13-May-2002 sg Propagate PWR return codes upwards. ++ *! 07-May-2002 sg Added check for, and call to PWR functions in PROC_Ctrl. ++ *! 02-May-2002 sg Added "nap" mode: put DSP to sleep once booted. ++ *! 01-Apr-2002 jeh Assume word addresses in PROC_GetTrace(). ++ *! 29-Nov-2001 jeh Don't call DEH function if hDehMgr == NULL. ++ *! 05-Nov-2001 kc: Updated PROC_RegisterNotify and PROC_GetState to support ++ *! DEH module. ++ *! 09-Oct-2001 jeh Fix number of bytes calculated in PROC_GetTrace(). ++ *! 11-Sep-2001 jeh Delete MSG manager in PROC_Monitor() to fix memory leak. ++ *! 29-Aug-2001 rr: DCD_AutoRegister and IOOnLoaded moved before COD_LoadBase ++ *! to facilitate the external loading. ++ *! 14-Aug-2001 ag DCD_AutoRegister() now called before IOOnLoaded() fxn. ++ *! 21-Jun-2001 rr: MSG_Create is done only the first time. ++ *! 02-May-2001 jeh Return failure in PROC_Load if IOOnLoaded function returns ++ *! error other than E_NOTIMPL. ++ *! 03-Apr-2001 sg: Changed DSP_DCD_ENOAUTOREGISTER to DSP_EDCDNOAUTOREGISTER. ++ *! 13-Feb-2001 kc: DSP/BIOS Bridge name updates. ++ *! 05-Jan-2001 rr: PROC_LOAD MSG_Create error is checked. ++ *! 15-Dec-2000 rr: IoOnLoaded is checked for WSX_STATUS. We fail to load ++ *! if DEV_Create2 fails; ie, no non-RMS targets can be ++ *! loaded. ++ *! 12-Dec-2000 rr: PROC_Start's DEV_Create2 is checked for WSX_STATUS. ++ *! 28-Nov-2000 jeh Added call to IO OnLoaded function to PROC_Load(). ++ *! 29-Nov-2000 rr: Incorporated code review changes. ++ *! 03-Nov-2000 rr: Auto_Register happens after PROC_Load. ++ *! 06-Oct-2000 rr: Updated to ver 0.9. PROC_Start calls DEV_Create2 and ++ *! WMD_BRD_STOP is always followed by DEV_Destroy2. ++ *! 05-Sep-2000 rr: PROC_GetTrace calculates the Trace symbol for 55 in a ++ *! different way. ++ *! 10-Aug-2000 rr: PROC_NotifyClients, PROC_GetProcessorHandle Added ++ *! 07-Aug-2000 rr: PROC_IDLE/SYNCINIT/UNKNOWN state removed. ++ *! WMD fxns are checked for WSX_STATUS. ++ *! PROC_Attach does not alter the state of the BRD. ++ *! PROC_Run removed. ++ *! 04-Aug-2000 rr: All the functions return DSP_EHANDLE if proc handle is ++ *! invalid ++ *! 27-Jul-2000 rr: PROC_GetTrace and PROC_Load implemented. Updated to ++ *! ver 0.8 API. ++ *! 06-Jul-2000 rr: Created. ++ */ ++ ++/* ------------------------------------ Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++#include ++#include ++#include ++/* ----------------------------------- Mini Driver */ ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Resource Manager */ ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Others */ ++#include ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++#include ++ ++#ifndef RES_CLEANUP_DISABLE ++#include ++#endif ++/* ----------------------------------- Defines, Data Structures, Typedefs */ ++#define PROC_SIGNATURE 0x434F5250 /* "PROC" (in reverse). */ ++#define MAXCMDLINELEN 255 ++#define PROC_ENVPROCID "PROC_ID=%d" ++#define MAXPROCIDLEN (8 + 5) ++#define PROC_DFLT_TIMEOUT 10000 /* Time out in milliseconds */ ++#define PWR_TIMEOUT 500 /* Sleep/wake timout in msec */ ++#define EXTEND "_EXT_END" /* Extmem end addr in DSP binary */ ++ ++extern char *iva_img; ++/* The PROC_OBJECT structure. */ ++struct PROC_OBJECT { ++ struct LST_ELEM link; /* Link to next PROC_OBJECT */ ++ u32 dwSignature; /* Used for object validation */ ++ struct DEV_OBJECT *hDevObject; /* Device this PROC represents */ ++ u32 hProcess; /* Process owning this Processor */ ++ struct MGR_OBJECT *hMgrObject; /* Manager Object Handle */ ++ u32 uAttachCount; /* Processor attach count */ ++ u32 uProcessor; /* Processor number */ ++ u32 uTimeout; /* Time out count */ ++ enum DSP_PROCSTATE sState; /* Processor state */ ++ u32 ulUnit; /* DDSP unit number */ ++ bool bIsAlreadyAttached; /* ++ * True if the Device below has ++ * GPP Client attached ++ */ ++ struct NTFY_OBJECT *hNtfy; /* Manages notifications */ ++ struct WMD_DEV_CONTEXT *hWmdContext; /* WMD Context Handle */ ++ struct WMD_DRV_INTERFACE *pIntfFxns; /* Function interface to WMD */ ++ char *g_pszLastCoff; ++} ; ++ ++/* ----------------------------------- Globals */ ++#if GT_TRACE ++static struct GT_Mask PROC_DebugMask = { NULL, NULL }; /* WCD MGR Mask */ ++#endif ++ ++static u32 cRefs; ++ ++struct SYNC_CSOBJECT *hProcLock; /* For critical sections */ ++ ++/* ----------------------------------- Function Prototypes */ ++static DSP_STATUS PROC_Monitor(struct PROC_OBJECT *hProcessor); ++static s32 GetEnvpCount(char **envp); ++static char **PrependEnvp(char **newEnvp, char **envp, s32 cEnvp, s32 cNewEnvp, ++ char *szVar); ++ ++ ++/* ++ * ======== PROC_Attach ======== ++ * Purpose: ++ * Prepare for communication with a particular DSP processor, and return ++ * a handle to the processor object. ++ */ ++DSP_STATUS ++PROC_Attach(u32 uProcessor, OPTIONAL CONST struct DSP_PROCESSORATTRIN *pAttrIn, ++ OUT DSP_HPROCESSOR *phProcessor) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEV_OBJECT *hDevObject; ++ struct PROC_OBJECT *pProcObject = NULL; ++ struct MGR_OBJECT *hMgrObject = NULL; ++ struct DRV_OBJECT *hDrvObject = NULL; ++ u32 devType; ++ ++#ifndef RES_CLEANUP_DISABLE ++ HANDLE hDRVObject; ++ u32 hProcess; ++ DSP_STATUS res_status = DSP_SOK; ++ struct PROCESS_CONTEXT *pPctxt = NULL; ++#endif ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phProcessor != NULL); ++ ++ GT_3trace(PROC_DebugMask, GT_ENTER, "Entered PROC_Attach, args:\n\t" ++ "uProcessor: 0x%x\n\tpAttrIn: 0x%x\n\tphProcessor:" ++ "0x%x\n", uProcessor, pAttrIn, phProcessor); ++ /* Get the Driver and Manager Object Handles */ ++ status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT); ++ if (DSP_SUCCEEDED(status)) { ++ status = CFG_GetObject((u32 *)&hMgrObject, REG_MGR_OBJECT); ++ if (DSP_FAILED(status)) { ++ /* don't propogate CFG errors from this PROC function */ ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Attach: DSP_FAILED to get" ++ "the Manager Object.\n", status); ++ } ++ } else { ++ /* don't propogate CFG errors from this PROC function */ ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Attach: failed to get the" ++ " DriverObject, 0x%x!\n", status); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Get the Device Object */ ++ status = DRV_GetDevObject(uProcessor, hDrvObject, &hDevObject); ++ if (DSP_FAILED(status)) { ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Attach: failed to get" ++ " DevObject, 0x%x!\n", status); ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ status = DEV_GetDevType(hDevObject, &devType); ++ if (DSP_FAILED(status)) { ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Attach: failed to get" ++ " DevType, 0x%x!\n", status); ++ } ++ } ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ /* If we made it this far, create the Proceesor object: */ ++ MEM_AllocObject(pProcObject, struct PROC_OBJECT, PROC_SIGNATURE); ++ /* Fill out the Processor Object: */ ++ if (pProcObject == NULL) { ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Attach:Out of memeory \n"); ++ status = DSP_EFAIL; ++ goto func_end; ++ } ++ pProcObject->hDevObject = hDevObject; ++ pProcObject->hMgrObject = hMgrObject; ++ pProcObject->uProcessor = devType; ++ /* Get Caller Process and store it */ ++ /* Return PID instead of process handle */ ++ pProcObject->hProcess = current->pid; ++ ++ if (pAttrIn) ++ pProcObject->uTimeout = pAttrIn->uTimeout; ++ else ++ pProcObject->uTimeout = PROC_DFLT_TIMEOUT; ++ ++ status = DEV_GetIntfFxns(hDevObject, &pProcObject->pIntfFxns); ++ if (DSP_SUCCEEDED(status)) { ++ status = DEV_GetWMDContext(hDevObject, ++ &pProcObject->hWmdContext); ++ if (DSP_FAILED(status)) { ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Attach Could not" ++ " get the WMD Context.\n", status); ++ MEM_FreeObject(pProcObject); ++ } ++ } else { ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Attach Could not get" ++ " the DEV_ Interface fxns.\n", status); ++ MEM_FreeObject(pProcObject); ++ } ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ /* Create the Notification Object */ ++ /* This is created with no event mask, no notify mask ++ * and no valid handle to the notification. They all get ++ * filled up when PROC_RegisterNotify is called */ ++ status = NTFY_Create(&pProcObject->hNtfy); ++ if (DSP_SUCCEEDED(status)) { ++ /* Insert the Processor Object into the DEV List. ++ * Return handle to this Processor Object: ++ * Find out if the Device is already attached to a ++ * Processor. If so, return AlreadyAttached status */ ++ LST_InitElem(&pProcObject->link); ++ status = DEV_InsertProcObject(pProcObject->hDevObject, ++ (u32)pProcObject, ++ &pProcObject->bIsAlreadyAttached); ++ if (DSP_SUCCEEDED(status)) { ++ if (pProcObject->bIsAlreadyAttached) { ++ status = DSP_SALREADYATTACHED; ++ GT_0trace(PROC_DebugMask, GT_1CLASS, ++ "PROC_Attach: Processor " ++ "Already Attached!\n"); ++ } ++ } else { ++ if (pProcObject->hNtfy) ++ NTFY_Delete(pProcObject->hNtfy); ++ ++ MEM_FreeObject(pProcObject); ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Attach: failed to insert " ++ "Proc Object into DEV, 0x%x!\n", status); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ *phProcessor = (DSP_HPROCESSOR)pProcObject; ++ (void)PROC_NotifyClients(pProcObject, ++ DSP_PROCESSORATTACH); ++ GT_0trace(PROC_DebugMask, GT_1CLASS, ++ "PROC_Attach: Processor " ++ "Attach Success!\n"); ++ } ++ } else { ++ /* Don't leak memory if DSP_FAILED */ ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Attach: Could not allocate " ++ "storage for notification \n"); ++ MEM_FreeObject(pProcObject); ++ } ++func_end: ++#ifndef RES_CLEANUP_DISABLE ++ if (DSP_FAILED(status)) ++ goto func_cont; ++ ++ /* Return PID instead of process handle */ ++ hProcess = current->pid; ++ ++ res_status = CFG_GetObject((u32 *)&hDRVObject, REG_DRV_OBJECT); ++ if (DSP_FAILED(res_status)) ++ goto func_cont; ++ ++ DRV_GetProcContext(hProcess, (struct DRV_OBJECT *)hDRVObject, ++ &pPctxt, NULL, 0); ++ if (pPctxt == NULL) { ++ DRV_InsertProcContext((struct DRV_OBJECT *)hDRVObject, &pPctxt); ++ if (pPctxt != NULL) { ++ DRV_ProcUpdatestate(pPctxt, PROC_RES_ALLOCATED); ++ DRV_ProcSetPID(pPctxt, hProcess); ++ } ++ } ++func_cont: ++ /* Return PID instead of process handle */ ++ hProcess = current->pid; ++ ++ res_status = CFG_GetObject((u32 *)&hDRVObject, REG_DRV_OBJECT); ++ if (DSP_SUCCEEDED(res_status)) { ++ DRV_GetProcContext(hProcess, ++ (struct DRV_OBJECT *)hDRVObject, &pPctxt, ++ NULL, 0); ++ if (pPctxt != NULL) ++ pPctxt->hProcessor = (DSP_HPROCESSOR)*phProcessor; ++ ++ } ++#endif ++ DBC_Ensure((status == DSP_EFAIL && *phProcessor == NULL) || ++ (DSP_SUCCEEDED(status) && ++ MEM_IsValidHandle(pProcObject, PROC_SIGNATURE)) || ++ (status == DSP_SALREADYATTACHED && ++ MEM_IsValidHandle(pProcObject, PROC_SIGNATURE))); ++ GT_2trace(PROC_DebugMask, GT_ENTER, "Exiting PROC_Attach, results:\n\t" ++ "status: 0x%x\n\thProcessor: 0x%x\n", status, *phProcessor); ++ ++ return status; ++} ++ ++static DSP_STATUS GetExecFile(struct CFG_DEVNODE *hDevNode, ++ struct DEV_OBJECT *hDevObject, ++ u32 size, char *execFile) ++{ ++ s32 devType; ++ s32 len; ++ ++ DEV_GetDevType(hDevObject, (u32 *) &devType); ++ if (devType == DSP_UNIT) { ++ return CFG_GetExecFile(hDevNode, size, execFile); ++ } else if (devType == IVA_UNIT) { ++ if (iva_img) { ++ len = strlen(iva_img); ++ strncpy(execFile, iva_img, len + 1); ++ return DSP_SOK; ++ } ++ } ++ return DSP_EFILE; ++} ++ ++/* ++ * ======== PROC_AutoStart ======== = ++ * Purpose: ++ * A Particular device gets loaded with the default image ++ * if the AutoStart flag is set. ++ * Parameters: ++ * hDevObject: Handle to the Device ++ * Returns: ++ * DSP_SOK: On Successful Loading ++ * DSP_EFAIL General Failure ++ * Requires: ++ * hDevObject != NULL ++ * Ensures: ++ */ ++DSP_STATUS PROC_AutoStart(struct CFG_DEVNODE *hDevNode, ++ struct DEV_OBJECT *hDevObject) ++{ ++ DSP_STATUS status = DSP_EFAIL; ++ u32 dwAutoStart = 0; /* autostart flag */ ++ struct PROC_OBJECT *pProcObject; ++ struct PROC_OBJECT *hProcObject; ++ char szExecFile[MAXCMDLINELEN]; ++ char *argv[2]; ++ struct MGR_OBJECT *hMgrObject = NULL; ++ s32 devType; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(hDevNode != NULL); ++ DBC_Require(hDevObject != NULL); ++ ++ GT_2trace(PROC_DebugMask, GT_ENTER, ++ "Entered PROC_AutoStart, args:\n\t" ++ "hDevNode: 0x%x\thDevObject: 0x%x\n", hDevNode, hDevObject); ++ /* Create a Dummy PROC Object */ ++ if (DSP_FAILED(CFG_GetObject((u32 *)&hMgrObject, ++ REG_MGR_OBJECT))) { ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_AutoStart: DSP_FAILED to " ++ "Get MGR Object\n"); ++ goto func_end; ++ } ++ MEM_AllocObject(pProcObject, struct PROC_OBJECT, PROC_SIGNATURE); ++ if (pProcObject == NULL) { ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_AutoStart: DSP_FAILED " ++ "to Create a dummy Processor\n"); ++ goto func_end; ++ } ++ GT_0trace(PROC_DebugMask, GT_1CLASS, "NTFY Created \n"); ++ pProcObject->hDevObject = hDevObject; ++ pProcObject->hMgrObject = hMgrObject; ++ hProcObject = pProcObject; ++ if (DSP_SUCCEEDED(DEV_GetIntfFxns(hDevObject, ++ &pProcObject->pIntfFxns))) { ++ if (DSP_SUCCEEDED(DEV_GetWMDContext(hDevObject, ++ &pProcObject->hWmdContext))) { ++ status = DSP_SOK; ++ } else { ++ MEM_FreeObject(hProcObject); ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_AutoStart: Failed " ++ "to get WMD Context \n"); ++ } ++ } else { ++ MEM_FreeObject(hProcObject); ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_AutoStart: Failed to " ++ "get IntFxns \n"); ++ } ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ /* Stop the Device, put it into standby mode */ ++ status = PROC_Stop(hProcObject); ++ if (DSP_FAILED(CFG_GetAutoStart(hDevNode, &dwAutoStart)) || ++ !dwAutoStart) { ++ status = DSP_EFAIL; ++ /* DSP_FAILED to Get s32 Fxn or Wmd Context */ ++ GT_0trace(PROC_DebugMask, GT_1CLASS, "PROC_AutoStart: " ++ "CFG_GetAutoStart DSP_FAILED \n"); ++ goto func_cont; ++ } ++ /* Get the default executable for this board... */ ++ DEV_GetDevType(hDevObject, (u32 *)&devType); ++ pProcObject->uProcessor = devType; ++ if (DSP_SUCCEEDED(GetExecFile(hDevNode, hDevObject, ++ sizeof(szExecFile), szExecFile))) { ++ argv[0] = szExecFile; ++ argv[1] = NULL; ++ /* ...and try to load it: */ ++ status = PROC_Load(hProcObject, 1, (CONST char **)argv, NULL); ++ if (DSP_SUCCEEDED(status)) { ++ status = PROC_Start(hProcObject); ++ if (DSP_SUCCEEDED(status)) { ++ GT_0trace(PROC_DebugMask, GT_1CLASS, ++ "PROC_AutoStart: Processor started " ++ "running\n"); ++ } else { ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_AutoStart: DSP_FAILED To " ++ "Start \n"); ++ } ++ } else { ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_AutoStart: DSP_FAILED to Load\n"); ++ } ++ } else { ++ status = DSP_EFILE; ++ GT_0trace(PROC_DebugMask, GT_7CLASS, "PROC_AutoStart: " ++ "No Exec file found \n"); ++ } ++func_cont: ++ MEM_FreeObject(hProcObject); ++func_end: ++ GT_1trace(PROC_DebugMask, GT_ENTER, ++ "Exiting PROC_AutoStart, status:0x%x\n", status); ++ return status; ++} ++ ++/* ++ * ======== PROC_Ctrl ======== ++ * Purpose: ++ * Pass control information to the GPP device driver managing the ++ * DSP processor. ++ * ++ * This will be an OEM-only function, and not part of the DSP/BIOS Bridge ++ * application developer's API. ++ * Call the WMD_ICOTL Fxn with the Argument This is a Synchronous ++ * Operation. arg can be null. ++ */ ++DSP_STATUS PROC_Ctrl(DSP_HPROCESSOR hProcessor, u32 dwCmd, ++ IN struct DSP_CBDATA *arg) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct PROC_OBJECT *pProcObject = hProcessor; ++ u32 timeout = 0; ++ ++ DBC_Require(cRefs > 0); ++ GT_3trace(PROC_DebugMask, GT_ENTER, ++ "Entered PROC_Ctrl, args:\n\thProcessor:" ++ " 0x%x\n\tdwCmd: 0x%x\n\targ: 0x%x\n", hProcessor, dwCmd, arg); ++ ++ if (MEM_IsValidHandle(pProcObject, PROC_SIGNATURE)) { ++ /* intercept PWR deep sleep command */ ++ if (dwCmd == WMDIOCTL_DEEPSLEEP) { ++ timeout = arg->cbData; ++ status = PWR_SleepDSP(PWR_DEEPSLEEP, timeout); ++ } ++ /* intercept PWR emergency sleep command */ ++ else if (dwCmd == WMDIOCTL_EMERGENCYSLEEP) { ++ timeout = arg->cbData; ++ status = PWR_SleepDSP(PWR_EMERGENCYDEEPSLEEP, timeout); ++ } else if (dwCmd == PWR_DEEPSLEEP) { ++ /* timeout = arg->cbData; */ ++ status = PWR_SleepDSP(PWR_DEEPSLEEP, timeout); ++ } ++ /* intercept PWR wake commands */ ++ else if (dwCmd == WMDIOCTL_WAKEUP) { ++ timeout = arg->cbData; ++ status = PWR_WakeDSP(timeout); ++ } else if (dwCmd == PWR_WAKEUP) { ++ /* timeout = arg->cbData; */ ++ status = PWR_WakeDSP(timeout); ++ } else ++ if (DSP_SUCCEEDED ++ ((*pProcObject->pIntfFxns->pfnDevCntrl) ++ (pProcObject->hWmdContext, dwCmd, arg))) { ++ status = DSP_SOK; ++ } else { ++ status = DSP_EFAIL; ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Ctrl: Failed \n"); ++ } ++ } else { ++ status = DSP_EHANDLE; ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Ctrl: InValid Processor Handle \n"); ++ } ++ GT_1trace(PROC_DebugMask, GT_ENTER, "Exiting PROC_Ctrl, 0x%x\n", ++ status); ++ return status; ++} ++ ++/* ++ * ======== PROC_Detach ======== ++ * Purpose: ++ * Destroys the Processor Object. Removes the notification from the Dev ++ * List. ++ */ ++DSP_STATUS PROC_Detach(DSP_HPROCESSOR hProcessor) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProcessor; ++#ifndef RES_CLEANUP_DISABLE ++ HANDLE hDRVObject; ++ u32 hProcess; ++ DSP_STATUS res_status = DSP_SOK; ++ struct PROCESS_CONTEXT *pPctxt = NULL; ++#endif ++ DBC_Require(cRefs > 0); ++ GT_1trace(PROC_DebugMask, GT_ENTER, "Entered PROC_Detach, args:\n\t" ++ "hProcessor: 0x%x\n", hProcessor); ++ ++ if (MEM_IsValidHandle(pProcObject, PROC_SIGNATURE)) { ++ /* Notify the Client */ ++ NTFY_Notify(pProcObject->hNtfy, DSP_PROCESSORDETACH); ++ /* Remove the notification memory */ ++ if (pProcObject->hNtfy) ++ NTFY_Delete(pProcObject->hNtfy); ++ ++ if (pProcObject->g_pszLastCoff) { ++ MEM_Free(pProcObject->g_pszLastCoff); ++ pProcObject->g_pszLastCoff = NULL; ++ } ++ ++#ifndef RES_CLEANUP_DISABLE ++ /* Return PID instead of process handle */ ++ hProcess = current->pid; ++ ++ res_status = CFG_GetObject((u32 *)&hDRVObject, REG_DRV_OBJECT); ++ if (DSP_SUCCEEDED(res_status)) { ++ DRV_GetProcContext(hProcess, ++ (struct DRV_OBJECT *)hDRVObject, &pPctxt, ++ NULL, 0); ++ if (pPctxt != NULL) { ++ DRV_ProcFreeDMMRes(pPctxt); ++ pPctxt->hProcessor = NULL; ++ } ++ } ++#endif ++ ++ /* Remove the Proc from the DEV List */ ++ (void)DEV_RemoveProcObject(pProcObject->hDevObject, ++ (u32)pProcObject); ++ /* Free the Processor Object */ ++ MEM_FreeObject(pProcObject); ++ } else { ++ status = DSP_EHANDLE; ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Detach: InValid Processor Handle \n"); ++ } ++ GT_1trace(PROC_DebugMask, GT_ENTER, "Exiting PROC_Detach, 0x%x\n", ++ status); ++ return status; ++} ++ ++/* ++ * ======== PROC_EnumNodes ======== ++ * Purpose: ++ * Enumerate and get configuration information about nodes allocated ++ * on a DSP processor. ++ */ ++DSP_STATUS PROC_EnumNodes(DSP_HPROCESSOR hProcessor, OUT DSP_HNODE *aNodeTab, ++ IN u32 uNodeTabSize, OUT u32 *puNumNodes, ++ OUT u32 *puAllocated) ++{ ++ DSP_STATUS status = DSP_EFAIL; ++ struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProcessor; ++ struct NODE_MGR *hNodeMgr = NULL; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(aNodeTab != NULL || uNodeTabSize == 0); ++ DBC_Require(puNumNodes != NULL); ++ DBC_Require(puAllocated != NULL); ++ ++ GT_5trace(PROC_DebugMask, GT_ENTER, "Entered PROC_EnumNodes, args:\n\t" ++ "hProcessor: 0x%x\n\taNodeTab: 0x%x\n\tuNodeTabSize: " ++ " 0x%x\n\t puNumNodes 0x%x\n\t puAllocated: 0x%x\n", ++ hProcessor, aNodeTab, uNodeTabSize, puNumNodes, ++ puAllocated); ++ if (MEM_IsValidHandle(pProcObject, PROC_SIGNATURE)) { ++ if (DSP_SUCCEEDED(DEV_GetNodeManager(pProcObject->hDevObject, ++ &hNodeMgr))) { ++ if (hNodeMgr) { ++ status = NODE_EnumNodes(hNodeMgr, aNodeTab, ++ uNodeTabSize, ++ puNumNodes, ++ puAllocated); ++ } ++ } ++ } else { ++ status = DSP_EHANDLE; ++ GT_0trace(PROC_DebugMask, GT_7CLASS, "PROC_EnumNodes: " ++ "InValid Processor Handle \n"); ++ } ++ GT_6trace(PROC_DebugMask, GT_ENTER, "Exit PROC_EnumNodes, args:\n\t" ++ "hProcessor: 0x%x\n\taNodeTab: 0x%x\n\tuNodeTabSize: " ++ " 0x%x\n\t puNumNodes 0x%x\n\t puAllocated: 0x%x\n\t " ++ "status: 0x%x \n", hProcessor, aNodeTab, uNodeTabSize, ++ puNumNodes, puAllocated, status); ++ ++ return status; ++} ++ ++/* ++ * ======== PROC_FlushMemory ======== ++ * Purpose: ++ * Flush cache ++ */ ++DSP_STATUS PROC_FlushMemory(DSP_HPROCESSOR hProcessor, void *pMpuAddr, ++ u32 ulSize, u32 ulFlags) ++{ ++ /* Keep STATUS here for future additions to this function */ ++ DSP_STATUS status = DSP_SOK; ++ enum DSP_FLUSHTYPE FlushMemType = PROC_WRITEBACK_INVALIDATE_MEM; ++ DBC_Require(cRefs > 0); ++ ++ GT_4trace(PROC_DebugMask, GT_ENTER, ++ "Entered PROC_FlushMemory, args:\n\t" ++ "hProcessor: 0x%x pMpuAddr: 0x%x ulSize 0x%x, ulFlags 0x%x\n", ++ hProcessor, pMpuAddr, ulSize, ulFlags); ++ /* Critical section */ ++ (void)SYNC_EnterCS(hProcLock); ++ MEM_FlushCache(pMpuAddr, ulSize, FlushMemType); ++ (void)SYNC_LeaveCS(hProcLock); ++ ++ GT_1trace(PROC_DebugMask, GT_ENTER, "Leaving PROC_FlushMemory [0x%x]", ++ status); ++ return status; ++} ++ ++ ++/* ++ * ======== PROC_InvalidateMemory ======== ++ * Purpose: ++ * Invalidates the memory specified ++ */ ++DSP_STATUS PROC_InvalidateMemory(DSP_HPROCESSOR hProcessor, void *pMpuAddr, ++ u32 ulSize) ++{ ++ /* Keep STATUS here for future additions to this function */ ++ DSP_STATUS status = DSP_SOK; ++ enum DSP_FLUSHTYPE FlushMemType = PROC_INVALIDATE_MEM; ++ DBC_Require(cRefs > 0); ++ GT_3trace(PROC_DebugMask, GT_ENTER, ++ "Entered PROC_InvalidateMemory, args:\n\t" ++ "hProcessor: 0x%x pMpuAddr: 0x%x ulSize 0x%x\n", hProcessor, ++ pMpuAddr, ulSize); ++ (void)SYNC_EnterCS(hProcLock); ++ MEM_FlushCache(pMpuAddr, ulSize, FlushMemType); ++ (void)SYNC_LeaveCS(hProcLock); ++ ++ GT_1trace(PROC_DebugMask, GT_ENTER, ++ "Leaving PROC_InvalidateMemory [0x%x]", status); ++ return status; ++} ++ ++/* ++ * ======== PROC_GetResourceInfo ======== ++ * Purpose: ++ * Enumerate the resources currently available on a processor. ++ */ ++DSP_STATUS PROC_GetResourceInfo(DSP_HPROCESSOR hProcessor, u32 uResourceType, ++ OUT struct DSP_RESOURCEINFO *pResourceInfo, ++ u32 uResourceInfoSize) ++{ ++ DSP_STATUS status = DSP_EFAIL; ++ struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProcessor; ++ struct NODE_MGR *hNodeMgr = NULL; ++ struct NLDR_OBJECT *hNldr = NULL; ++ struct RMM_TargetObj *rmm = NULL; ++ struct IO_MGR *hIOMgr = NULL; /* IO manager handle */ ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pResourceInfo != NULL); ++ DBC_Require(uResourceInfoSize >= sizeof(struct DSP_RESOURCEINFO)); ++ ++ GT_4trace(PROC_DebugMask, GT_ENTER, "Entered PROC_GetResourceInfo,\n\t" ++ "hProcessor: 0x%x\n\tuResourceType: 0x%x\n\tpResourceInfo:" ++ " 0x%x\n\t uResourceInfoSize 0x%x\n", hProcessor, ++ uResourceType, pResourceInfo, uResourceInfoSize); ++ if (!MEM_IsValidHandle(pProcObject, PROC_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_GetResourceInfo: InValid " ++ "Processor Handle \n"); ++ goto func_end; ++ } ++ switch (uResourceType) { ++ case DSP_RESOURCE_DYNDARAM: ++ case DSP_RESOURCE_DYNSARAM: ++ case DSP_RESOURCE_DYNEXTERNAL: ++ case DSP_RESOURCE_DYNSRAM: ++ if (DSP_FAILED(DEV_GetNodeManager(pProcObject->hDevObject, ++ &hNodeMgr))) ++ goto func_end; ++ ++ if (DSP_SUCCEEDED(NODE_GetNldrObj(hNodeMgr, &hNldr))) { ++ if (DSP_SUCCEEDED(NLDR_GetRmmManager(hNldr, &rmm))) { ++ DBC_Assert(rmm != NULL); ++ status = DSP_EVALUE; ++ if (RMM_stat(rmm, ++ (enum DSP_MEMTYPE)uResourceType, ++ (struct DSP_MEMSTAT *)&(pResourceInfo-> ++ result.memStat))) ++ status = DSP_SOK; ++ } ++ } ++ break; ++ case DSP_RESOURCE_PROCLOAD: ++ status = DEV_GetIOMgr(pProcObject->hDevObject, &hIOMgr); ++ status = pProcObject->pIntfFxns->pfnIOGetProcLoad(hIOMgr, ++ (struct DSP_PROCLOADSTAT *)&(pResourceInfo-> ++ result.procLoadStat)); ++ if (DSP_FAILED(status)) { ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "Error in procLoadStat function 0x%x\n", status); ++ } ++ break; ++ default: ++ status = DSP_EFAIL; ++ break; ++ } ++func_end: ++ GT_1trace(PROC_DebugMask, GT_ENTER, "Exiting PROC_GetResourceInfo, " ++ "status 0x%x\n", status); ++ return status; ++} ++ ++/* ++ * ======== PROC_Exit ======== ++ * Purpose: ++ * Decrement reference count, and free resources when reference count is ++ * 0. ++ */ ++void PROC_Exit(void) ++{ ++ DBC_Require(cRefs > 0); ++ ++ if (hProcLock) ++ (void)SYNC_DeleteCS(hProcLock); ++ ++ cRefs--; ++ ++ GT_1trace(PROC_DebugMask, GT_5CLASS, ++ "Entered PROC_Exit, ref count:0x%x\n", cRefs); ++ DBC_Ensure(cRefs >= 0); ++} ++ ++/* ++ * ======== PROC_GetDevObject ======== ++ * Purpose: ++ * Return the Dev Object handle for a given Processor. ++ * ++ */ ++DSP_STATUS PROC_GetDevObject(DSP_HPROCESSOR hProcessor, ++ struct DEV_OBJECT **phDevObject) ++{ ++ DSP_STATUS status = DSP_EFAIL; ++ struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProcessor; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phDevObject != NULL); ++ ++ if (MEM_IsValidHandle(pProcObject, PROC_SIGNATURE)) { ++ *phDevObject = pProcObject->hDevObject; ++ status = DSP_SOK; ++ } else { ++ *phDevObject = NULL; ++ } ++ ++ DBC_Ensure((DSP_SUCCEEDED(status) && *phDevObject != NULL) || ++ (DSP_FAILED(status) && *phDevObject == NULL)); ++ ++ return status; ++} ++ ++/* ++ * ======== PROC_GetState ======== ++ * Purpose: ++ * Report the state of the specified DSP processor. ++ */ ++DSP_STATUS PROC_GetState(DSP_HPROCESSOR hProcessor, ++ OUT struct DSP_PROCESSORSTATE *pProcStatus, ++ u32 uStateInfoSize) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProcessor; ++ BRD_STATUS brdStatus; ++ struct DEH_MGR *hDehMgr; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pProcStatus != NULL); ++ DBC_Require(uStateInfoSize >= sizeof(struct DSP_PROCESSORSTATE)); ++ ++ GT_3trace(PROC_DebugMask, GT_ENTER, "Entering PROC_GetState, args:\n\t" ++ "pProcStatus: 0x%x\n\thProcessor: 0x%x\n\t uStateInfoSize" ++ " 0x%x\n", pProcStatus, hProcessor, uStateInfoSize); ++ if (MEM_IsValidHandle(pProcObject, PROC_SIGNATURE)) { ++ /* First, retrieve BRD state information */ ++ if (DSP_SUCCEEDED((*pProcObject->pIntfFxns->pfnBrdStatus) ++ (pProcObject->hWmdContext, &brdStatus))) { ++ switch (brdStatus) { ++ case BRD_STOPPED: ++ pProcStatus->iState = PROC_STOPPED; ++ break; ++ case BRD_DSP_HIBERNATION: ++ /* Fall through */ ++ case BRD_RUNNING: ++ pProcStatus->iState = PROC_RUNNING; ++ break; ++ case BRD_LOADED: ++ pProcStatus->iState = PROC_LOADED; ++ break; ++ case BRD_ERROR: ++ pProcStatus->iState = PROC_ERROR; ++ break; ++ default: ++ pProcStatus->iState = 0xFF; ++ status = DSP_EFAIL; ++ break; ++ } ++ } else { ++ status = DSP_EFAIL; ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_GetState: General Failure" ++ " to read the PROC Status \n"); ++ } ++ /* Next, retrieve error information, if any */ ++ status = DEV_GetDehMgr(pProcObject->hDevObject, &hDehMgr); ++ if (DSP_SUCCEEDED(status) && hDehMgr) { ++ status = (*pProcObject->pIntfFxns->pfnDehGetInfo) ++ (hDehMgr, &(pProcStatus->errInfo)); ++ if (DSP_FAILED(status)) { ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_GetState: Failed " ++ "retrieve exception info.\n"); ++ } ++ } else { ++ status = DSP_EFAIL; ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_GetState: Failed to " ++ "retrieve DEH handle.\n"); ++ } ++ } else { ++ status = DSP_EHANDLE; ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_GetState:InValid Processor Handle \n"); ++ } ++ GT_2trace(PROC_DebugMask, GT_ENTER, ++ "Exiting PROC_GetState, results:\n\t" ++ "status: 0x%x\n\tpProcStatus: 0x%x\n", status, ++ pProcStatus->iState); ++ return status; ++} ++ ++/* ++ * ======== PROC_GetTrace ======== ++ * Purpose: ++ * Retrieve the current contents of the trace buffer, located on the ++ * Processor. Predefined symbols for the trace buffer must have been ++ * configured into the DSP executable. ++ * Details: ++ * We support using the symbols SYS_PUTCBEG and SYS_PUTCEND to define a ++ * trace buffer, only. Treat it as an undocumented feature. ++ * This call is destructive, meaning the processor is placed in the monitor ++ * state as a result of this function. ++ */ ++DSP_STATUS PROC_GetTrace(DSP_HPROCESSOR hProcessor, u8 *pBuf, u32 uMaxSize) ++{ ++ DSP_STATUS status; ++ status = DSP_ENOTIMPL; ++ return status; ++} ++ ++/* ++ * ======== PROC_Init ======== ++ * Purpose: ++ * Initialize PROC's private state, keeping a reference count on each call ++ */ ++bool PROC_Init(void) ++{ ++ bool fRetval = true; ++ ++ DBC_Require(cRefs >= 0); ++ ++ if (cRefs == 0) { ++ /* Set the Trace mask */ ++ DBC_Assert(!PROC_DebugMask.flags); ++ GT_create(&PROC_DebugMask, "PR"); /* "PR" for Processor */ ++ ++ (void)SYNC_InitializeCS(&hProcLock); ++ } ++ ++ if (fRetval) ++ cRefs++; ++ ++ GT_1trace(PROC_DebugMask, GT_5CLASS, ++ "Entered PROC_Init, ref count:0x%x\n", cRefs); ++ DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0))); ++ ++ return fRetval; ++} ++ ++/* ++ * ======== PROC_Load ======== ++ * Purpose: ++ * Reset a processor and load a new base program image. ++ * This will be an OEM-only function, and not part of the DSP/BIOS Bridge ++ * application developer's API. ++ */ ++DSP_STATUS PROC_Load(DSP_HPROCESSOR hProcessor, IN CONST s32 iArgc, ++ IN CONST char **aArgv, IN CONST char **aEnvp) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProcessor; ++ struct IO_MGR *hIOMgr; /* IO manager handle */ ++ struct MSG_MGR *hMsgMgr; ++ struct COD_MANAGER *hCodMgr; /* Code manager handle */ ++ char *pargv0; /* temp argv[0] ptr */ ++ char **newEnvp; /* Updated envp[] array. */ ++ char szProcID[MAXPROCIDLEN]; /* Size of "PROC_ID=" */ ++ s32 cEnvp; /* Num elements in envp[]. */ ++ s32 cNewEnvp; /* " " in newEnvp[] */ ++ s32 nProcID = 0; /* Anticipate MP version. */ ++ struct DCD_MANAGER *hDCDHandle; ++ struct DMM_OBJECT *hDmmMgr; ++ u32 dwExtEnd; ++ u32 uProcId; ++#ifdef DEBUG ++ BRD_STATUS uBrdState; ++#endif ++#ifdef OPT_LOAD_TIME_INSTRUMENTATION ++ struct timeval tv1; ++ struct timeval tv2; ++#endif ++ DBC_Require(cRefs > 0); ++ DBC_Require(iArgc > 0); ++ DBC_Require(aArgv != NULL); ++#ifdef OPT_LOAD_TIME_INSTRUMENTATION ++ do_gettimeofday(&tv1); ++#endif ++#if defined(CONFIG_BRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ) ++ struct dspbridge_platform_data *pdata = ++ omap_dspbridge_dev->dev.platform_data; ++#endif ++ GT_2trace(PROC_DebugMask, GT_ENTER, "Entered PROC_Load, args:\n\t" ++ "hProcessor: 0x%x\taArgv: 0x%x\n", hProcessor, aArgv[0]); ++ /* Call the WMD_BRD_Load Fxn */ ++ if (!MEM_IsValidHandle(pProcObject, PROC_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ GT_0trace(PROC_DebugMask, GT_1CLASS, ++ "PROC_Load: Invalid Processor Handle..\n"); ++ goto func_end; ++ } ++ if (pProcObject->bIsAlreadyAttached) { ++ status = DSP_EATTACHED; ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Load Abort becuase a GPP " ++ "Client is already attached status 0x%x \n", status); ++ goto func_end; ++ } ++ if (DSP_FAILED(DEV_GetCodMgr(pProcObject->hDevObject, &hCodMgr))) { ++ status = DSP_EFAIL; ++ GT_1trace(PROC_DebugMask, GT_7CLASS, "PROC_Load: DSP_FAILED in " ++ "DEV_GetCodMgr status 0x%x \n", status); ++ goto func_end; ++ } ++ status = PROC_Stop(hProcessor); ++ if (DSP_FAILED(status)) { ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Load: DSP_FAILED to Place the" ++ " Processor in Stop Mode(PROC_STOP) status 0x%x \n", ++ status); ++ goto func_end; ++ } ++ /* Place the board in the monitor state. */ ++ status = PROC_Monitor(hProcessor); ++ if (DSP_FAILED(status)) { ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Load: DSP_FAILED to Place the" ++ " Processor in Monitor Mode(PROC_IDLE) status 0x%x\n", ++ status); ++ goto func_end; ++ } ++ /* Save ptr to original argv[0]. */ ++ pargv0 = (char *)aArgv[0]; ++ /*Prepend "PROC_ID="to envp array for target.*/ ++ cEnvp = GetEnvpCount((char **)aEnvp); ++ cNewEnvp = (cEnvp ? (cEnvp + 1) : (cEnvp + 2)); ++ newEnvp = MEM_Calloc(cNewEnvp * sizeof(char **), MEM_PAGED); ++ if (newEnvp) { ++ status = snprintf(szProcID, MAXPROCIDLEN, PROC_ENVPROCID, ++ nProcID); ++ if (status == -1) { ++ GT_0trace(PROC_DebugMask, GT_7CLASS, "PROC_Load: " ++ "Proc ID string overflow \n"); ++ status = DSP_EFAIL; ++ } else { ++ newEnvp = PrependEnvp(newEnvp, (char **)aEnvp, cEnvp, ++ cNewEnvp, szProcID); ++ /* Get the DCD Handle */ ++ status = MGR_GetDCDHandle(pProcObject->hMgrObject, ++ (u32 *)&hDCDHandle); ++ if (DSP_SUCCEEDED(status)) { ++ /* Before proceeding with new load, ++ * check if a previously registered COFF ++ * exists. ++ * If yes, unregister nodes in previously ++ * registered COFF. If any error occurred, ++ * set previously registered COFF to NULL. */ ++ if (pProcObject->g_pszLastCoff != NULL) { ++ status = DCD_AutoUnregister(hDCDHandle, ++ pProcObject->g_pszLastCoff); ++ /* Regardless of auto unregister status, ++ * free previously allocated ++ * memory. */ ++ MEM_Free(pProcObject->g_pszLastCoff); ++ pProcObject->g_pszLastCoff = NULL; ++ } ++ } ++ /* On success, do COD_OpenBase() */ ++ status = COD_OpenBase(hCodMgr, (char *)aArgv[0], ++ COD_SYMB); ++ if (DSP_FAILED(status)) { ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Load: COD_OpenBase " ++ "failed (0x%x)\n", status); ++ } ++ } ++ } else { ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ " PROC_Load:Out of Memory \n"); ++ status = DSP_EMEMORY; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Auto-register data base */ ++ /* Get the DCD Handle */ ++ status = MGR_GetDCDHandle(pProcObject->hMgrObject, ++ (u32 *)&hDCDHandle); ++ if (DSP_SUCCEEDED(status)) { ++ /* Auto register nodes in specified COFF ++ * file. If registration did not fail, ++ * (status = DSP_SOK or DSP_EDCDNOAUTOREGISTER) ++ * save the name of the COFF file for ++ * de-registration in the future. */ ++ status = DCD_AutoRegister(hDCDHandle, (char *)aArgv[0]); ++ if (status == DSP_EDCDNOAUTOREGISTER) { ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Load: No Auto " ++ "Register section. Proceeding..\n"); ++ status = DSP_SOK; ++ } ++ if (DSP_FAILED(status)) { ++ status = DSP_EFAIL; ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Load: Failed to " ++ "Auto Register..\n"); ++ } else { ++ DBC_Assert(pProcObject->g_pszLastCoff == NULL); ++ /* Allocate memory for pszLastCoff */ ++ pProcObject->g_pszLastCoff = MEM_Calloc( ++ (strlen((char *)aArgv[0]) + 1), ++ MEM_PAGED); ++ /* If memory allocated, save COFF file name*/ ++ if (pProcObject->g_pszLastCoff) { ++ strncpy(pProcObject->g_pszLastCoff, ++ (char *)aArgv[0], ++ (strlen((char *)aArgv[0]) + 1)); ++ } ++ } ++ } ++ } ++ /* Update shared memory address and size */ ++ if (DSP_SUCCEEDED(status)) { ++ /* Create the message manager. This must be done ++ * before calling the IOOnLoaded function. */ ++ DEV_GetMsgMgr(pProcObject->hDevObject, &hMsgMgr); ++ if (!hMsgMgr) { ++ status = MSG_Create(&hMsgMgr, pProcObject->hDevObject, ++ (MSG_ONEXIT)NODE_OnExit); ++ DBC_Assert(DSP_SUCCEEDED(status)); ++ DEV_SetMsgMgr(pProcObject->hDevObject, hMsgMgr); ++ } ++ if (status == DSP_ENOTIMPL) { ++ /* It's OK not to have a message manager */ ++ status = DSP_SOK; ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Set the Device object's message manager */ ++ status = DEV_GetIOMgr(pProcObject->hDevObject, &hIOMgr); ++ DBC_Assert(DSP_SUCCEEDED(status)); ++ status = (*pProcObject->pIntfFxns->pfnIOOnLoaded)(hIOMgr); ++ if (status == DSP_ENOTIMPL) { ++ /* Ok not to implement this function */ ++ status = DSP_SOK; ++ } else { ++ if (DSP_FAILED(status)) { ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Load: Failed to get shared " ++ "memory or message buffer address " ++ "from COFF status 0x%x\n", status); ++ status = DSP_EFAIL; ++ } ++ } ++ } else { ++ status = DSP_EFAIL; ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Load: DSP_FAILED in " ++ "MSG_Create status 0x%x\n", status); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Now, attempt to load an exec: */ ++ ++ /* Boost the OPP level to Maximum level supported by baseport*/ ++#if defined(CONFIG_BRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ) ++ if (pdata->cpu_set_freq) ++ (*pdata->cpu_set_freq)(pdata->mpu_speed[VDD1_OPP5]); ++#endif ++ status = COD_LoadBase(hCodMgr, iArgc, (char **)aArgv, ++ DEV_BrdWriteFxn, ++ pProcObject->hDevObject, NULL); ++ if (DSP_FAILED(status)) { ++ if (status == COD_E_OPENFAILED) { ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Load:Failure to Load the EXE\n"); ++ } ++ if (status == COD_E_SYMBOLNOTFOUND) { ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Load:Could not parse the file\n"); ++ } else { ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Load: DSP_FAILED in " ++ "COD_Load status 0x%x \n", status); ++ } ++ } ++ /* Requesting the lowest opp supported*/ ++#if defined(CONFIG_BRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ) ++ if (pdata->cpu_set_freq) ++ (*pdata->cpu_set_freq)(pdata->mpu_speed[VDD1_OPP1]); ++#endif ++ ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Update the Processor status to loaded */ ++ status = (*pProcObject->pIntfFxns->pfnBrdSetState) ++ (pProcObject->hWmdContext, BRD_LOADED); ++ if (DSP_SUCCEEDED(status)) { ++ pProcObject->sState = PROC_LOADED; ++ if (pProcObject->hNtfy) { ++ PROC_NotifyClients(pProcObject, ++ DSP_PROCESSORSTATECHANGE); ++ } ++ } else { ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Load, pfnBrdSetState " ++ "failed: 0x%x\n", status); ++ status = DSP_EFAIL; ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ status = PROC_GetProcessorId(hProcessor, &uProcId); ++ if (uProcId == DSP_UNIT) { ++ /* Use all available DSP address space after EXTMEM ++ * for DMM */ ++ if (DSP_SUCCEEDED(status)) { ++ status = COD_GetSymValue(hCodMgr, EXTEND, ++ &dwExtEnd); ++ if (DSP_FAILED(status)) { ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Load: Failed on " ++ "COD_GetSymValue %s.\n", ++ EXTEND); ++ } ++ } ++ /* Reset DMM structs and add an initial free chunk*/ ++ if (DSP_SUCCEEDED(status)) { ++ status = DEV_GetDmmMgr(pProcObject->hDevObject, ++ &hDmmMgr); ++ if (DSP_SUCCEEDED(status)) { ++ /* Set dwExtEnd to DMM START u8 ++ * address */ ++ dwExtEnd = (dwExtEnd + 1) * DSPWORDSIZE; ++ /* DMM memory is from EXT_END */ ++ status = DMM_CreateTables(hDmmMgr, ++ dwExtEnd, DMMPOOLSIZE); ++ } ++ } ++ } ++ } ++ /* Restore the original argv[0] */ ++ MEM_Free(newEnvp); ++ aArgv[0] = pargv0; ++#ifdef DEBUG ++ if (DSP_SUCCEEDED(status)) { ++ if (DSP_SUCCEEDED((*pProcObject->pIntfFxns->pfnBrdStatus) ++ (pProcObject->hWmdContext, &uBrdState))) { ++ GT_0trace(PROC_DebugMask, GT_1CLASS, ++ "PROC_Load: Processor Loaded\n"); ++ DBC_Assert(uBrdState == BRD_LOADED); ++ } ++ } ++#endif ++func_end: ++#ifdef DEBUG ++ if (DSP_FAILED(status)) { ++ GT_0trace(PROC_DebugMask, GT_1CLASS, "PROC_Load: " ++ "Processor Load Failed.\n"); ++ ++ } ++#endif ++ GT_1trace(PROC_DebugMask, GT_ENTER, ++ "Exiting PROC_Load, status: 0x%x\n", status); ++ DBC_Ensure((DSP_SUCCEEDED(status) && pProcObject->sState == PROC_LOADED) ++ || DSP_FAILED(status)); ++#ifdef OPT_LOAD_TIME_INSTRUMENTATION ++ do_gettimeofday(&tv2); ++ if (tv2.tv_usec < tv1.tv_usec) { ++ tv2.tv_usec += 1000000; ++ tv2.tv_sec--; ++ } ++ GT_2trace(PROC_DebugMask, GT_1CLASS, ++ "Proc_Load: time to load %d sec and %d usec \n", ++ tv2.tv_sec - tv1.tv_sec, tv2.tv_usec - tv1.tv_usec); ++#endif ++ return status; ++} ++ ++/* ++ * ======== PROC_Map ======== ++ * Purpose: ++ * Maps a MPU buffer to DSP address space. ++ */ ++DSP_STATUS PROC_Map(DSP_HPROCESSOR hProcessor, void *pMpuAddr, u32 ulSize, ++ void *pReqAddr, void **ppMapAddr, u32 ulMapAttr) ++{ ++ u32 vaAlign; ++ u32 paAlign; ++ struct DMM_OBJECT *hDmmMgr; ++ u32 sizeAlign; ++ DSP_STATUS status = DSP_SOK; ++ struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProcessor; ++ ++#ifndef RES_CLEANUP_DISABLE ++ u32 hProcess; ++ HANDLE pCtxt = NULL; ++ HANDLE hDrvObject; ++ HANDLE dmmRes; ++ DSP_STATUS res_status = DSP_SOK; ++#endif ++ ++ GT_6trace(PROC_DebugMask, GT_ENTER, "Entered PROC_Map, args:\n\t" ++ "hProcessor %x, pMpuAddr %x, ulSize %x, pReqAddr %x, " ++ "ulMapAttr %x, ppMapAddr %x\n", hProcessor, pMpuAddr, ulSize, ++ pReqAddr, ulMapAttr, ppMapAddr); ++ /* Calculate the page-aligned PA, VA and size */ ++ vaAlign = PG_ALIGN_LOW((u32) pReqAddr, PG_SIZE_4K); ++ paAlign = PG_ALIGN_LOW((u32) pMpuAddr, PG_SIZE_4K); ++ sizeAlign = PG_ALIGN_HIGH(ulSize + (u32)pMpuAddr - paAlign, ++ PG_SIZE_4K); ++ ++ GT_3trace(PROC_DebugMask, GT_ENTER, "PROC_Map: vaAlign %x, paAlign %x, " ++ "sizeAlign %x\n", vaAlign, paAlign, sizeAlign); ++ ++ /* Critical section */ ++ (void)SYNC_EnterCS(hProcLock); ++ status = DMM_GetHandle(pProcObject, &hDmmMgr); ++ if (DSP_FAILED(status)) { ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Map: Failed to get DMM Mgr " ++ "handle: 0x%x\n", status); ++ } else { ++ status = DMM_MapMemory(hDmmMgr, vaAlign, sizeAlign); ++ } ++ /* Add mapping to the page tables. */ ++ if (DSP_SUCCEEDED(status)) { ++ ++ status = (*pProcObject->pIntfFxns->pfnBrdMemMap) ++ (pProcObject->hWmdContext, paAlign, vaAlign, sizeAlign, ++ ulMapAttr); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Mapped address = MSB of VA | LSB of PA */ ++ *ppMapAddr = (void *) (vaAlign | ((u32) pMpuAddr & ++ (PG_SIZE_4K - 1))); ++ } else { ++ DMM_UnMapMemory(hDmmMgr, vaAlign, &sizeAlign); ++ } ++ (void)SYNC_LeaveCS(hProcLock); ++ ++#ifndef RES_CLEANUP_DISABLE ++ if (DSP_SUCCEEDED(status)) { ++ /* Update the node and stream resource status */ ++ /* Return PID instead of process handle */ ++ hProcess = current->pid; ++ ++ res_status = CFG_GetObject((u32 *)&hDrvObject, ++ REG_DRV_OBJECT); ++ if (DSP_SUCCEEDED(res_status)) { ++ if (DRV_GetProcContext(hProcess, ++ (struct DRV_OBJECT *)hDrvObject, &pCtxt, NULL, ++ (u32)pMpuAddr) != DSP_ENOTFOUND) { ++ DRV_InsertDMMResElement(&dmmRes, pCtxt); ++ DRV_UpdateDMMResElement(dmmRes, (u32)pMpuAddr, ++ ulSize, (u32)pReqAddr, ++ (u32)*ppMapAddr, hProcessor); ++ } ++ } ++ } ++#endif ++ GT_1trace(PROC_DebugMask, GT_ENTER, "Leaving PROC_Map [0x%x]", status); ++ return status; ++} ++ ++/* ++ * ======== PROC_RegisterNotify ======== ++ * Purpose: ++ * Register to be notified of specific processor events. ++ */ ++DSP_STATUS PROC_RegisterNotify(DSP_HPROCESSOR hProcessor, u32 uEventMask, ++ u32 uNotifyType, struct DSP_NOTIFICATION ++ *hNotification) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProcessor; ++ struct DEH_MGR *hDehMgr; ++ ++ DBC_Require(hNotification != NULL); ++ DBC_Require(cRefs > 0); ++ ++ GT_4trace(PROC_DebugMask, GT_ENTER, ++ "Entered PROC_RegisterNotify, args:\n\t" ++ "hProcessor: 0x%x\n\tuEventMask: 0x%x\n\tuNotifyMask:" ++ " 0x%x\n\t hNotification 0x%x\n", hProcessor, uEventMask, ++ uNotifyType, hNotification); ++ ++ /* Check processor handle */ ++ if (!MEM_IsValidHandle(pProcObject, PROC_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_RegsiterNotify Invalid " ++ "ProcessorHandle 0x%x\n", hProcessor); ++ goto func_end; ++ } ++ /* Check if event mask is a valid processor related event */ ++ if (uEventMask & ~(DSP_PROCESSORSTATECHANGE | DSP_PROCESSORATTACH | ++ DSP_PROCESSORDETACH | DSP_PROCESSORRESTART | DSP_MMUFAULT | ++ DSP_SYSERROR)) ++ status = DSP_EVALUE; ++ ++ /* Check if notify type is valid */ ++ if (uNotifyType != DSP_SIGNALEVENT) ++ status = DSP_EVALUE; ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* * If event mask is not DSP_SYSERROR or DSP_MMUFAULT, ++ * then register event immediately. */ ++ if (uEventMask & ~(DSP_SYSERROR | DSP_MMUFAULT)) { ++ status = NTFY_Register(pProcObject->hNtfy, ++ hNotification, uEventMask, uNotifyType); ++ /* * Special case alert, special case alert! ++ * If we're trying to *deregister* (i.e. uEventMask ++ * is 0), a DSP_SYSERROR or DSP_MMUFAULT notification, ++ * we have to deregister with the DEH manager. ++ * There's no way to know, based on uEventMask which ++ * manager the notification event was registered with, ++ * so if we're trying to deregister and NTFY_Register ++ * failed, we'll give the deh manager a shot. ++ */ ++ if ((uEventMask == 0) && DSP_FAILED(status)) { ++ status = DEV_GetDehMgr(pProcObject->hDevObject, ++ &hDehMgr); ++ DBC_Assert(pProcObject->pIntfFxns-> ++ pfnDehRegisterNotify); ++ status = (*pProcObject->pIntfFxns-> ++ pfnDehRegisterNotify) ++ (hDehMgr, uEventMask, uNotifyType, ++ hNotification); ++ } ++ } else { ++ status = DEV_GetDehMgr(pProcObject->hDevObject, ++ &hDehMgr); ++ DBC_Assert(pProcObject->pIntfFxns-> ++ pfnDehRegisterNotify); ++ status = (*pProcObject->pIntfFxns->pfnDehRegisterNotify) ++ (hDehMgr, uEventMask, uNotifyType, ++ hNotification); ++ if (DSP_FAILED(status)) ++ status = DSP_EFAIL; ++ ++ } ++ } ++func_end: ++ return status; ++} ++ ++/* ++ * ======== PROC_ReserveMemory ======== ++ * Purpose: ++ * Reserve a virtually contiguous region of DSP address space. ++ */ ++DSP_STATUS PROC_ReserveMemory(DSP_HPROCESSOR hProcessor, u32 ulSize, ++ void **ppRsvAddr) ++{ ++ struct DMM_OBJECT *hDmmMgr; ++ DSP_STATUS status = DSP_SOK; ++ struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProcessor; ++ ++ GT_3trace(PROC_DebugMask, GT_ENTER, ++ "Entered PROC_ReserveMemory, args:\n\t" ++ "hProcessor: 0x%x ulSize: 0x%x ppRsvAddr: 0x%x\n", hProcessor, ++ ulSize, ppRsvAddr); ++ status = DMM_GetHandle(pProcObject, &hDmmMgr); ++ if (DSP_FAILED(status)) { ++ GT_1trace(PROC_DebugMask, GT_7CLASS, "PROC_ReserveMemory: " ++ "Failed to get DMM Mgr handle: 0x%x\n", status); ++ } else ++ status = DMM_ReserveMemory(hDmmMgr, ulSize, (u32 *)ppRsvAddr); ++ ++ GT_1trace(PROC_DebugMask, GT_ENTER, "Leaving PROC_ReserveMemory [0x%x]", ++ status); ++ return status; ++} ++ ++/* ++ * ======== PROC_Start ======== ++ * Purpose: ++ * Start a processor running. ++ */ ++DSP_STATUS PROC_Start(DSP_HPROCESSOR hProcessor) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProcessor; ++ struct COD_MANAGER *hCodMgr; /* Code manager handle */ ++ u32 dwDspAddr; /* Loaded code's entry point. */ ++#ifdef DEBUG ++ BRD_STATUS uBrdState; ++#endif ++ DBC_Require(cRefs > 0); ++ GT_1trace(PROC_DebugMask, GT_ENTER, "Entered PROC_Start, args:\n\t" ++ "hProcessor: 0x%x\n", hProcessor); ++ if (!MEM_IsValidHandle(pProcObject, PROC_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Start :InValid Handle \n"); ++ goto func_end; ++ } ++ /* Call the WMD_BRD_Start */ ++ if (pProcObject->sState != PROC_LOADED) { ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Start :Wrong state \n"); ++ status = DSP_EWRONGSTATE; ++ goto func_end; ++ } ++ status = DEV_GetCodMgr(pProcObject->hDevObject, &hCodMgr); ++ if (DSP_FAILED(status)) { ++ status = DSP_EFAIL; ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "Processor Start DSP_FAILED " ++ "in Getting DEV_GetCodMgr status 0x%x\n", status); ++ goto func_cont; ++ } ++ status = COD_GetEntry(hCodMgr, &dwDspAddr); ++ if (DSP_FAILED(status)) { ++ status = DSP_EFAIL; ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "Processor Start DSP_FAILED in " ++ "Getting COD_GetEntry status 0x%x\n", status); ++ goto func_cont; ++ } ++ status = (*pProcObject->pIntfFxns->pfnBrdStart) ++ (pProcObject->hWmdContext, dwDspAddr); ++ if (DSP_FAILED(status)) { ++ status = DSP_EFAIL; ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Start Failed to Start the board\n"); ++ goto func_cont; ++ } ++ /* Call DEV_Create2 */ ++ status = DEV_Create2(pProcObject->hDevObject); ++ if (DSP_SUCCEEDED(status)) { ++ pProcObject->sState = PROC_RUNNING; ++ /* Deep sleep switces off the peripheral clocks. ++ * we just put the DSP CPU in idle in the idle loop. ++ * so there is no need to send a command to DSP */ ++ ++ if (pProcObject->hNtfy) { ++ PROC_NotifyClients(pProcObject, ++ DSP_PROCESSORSTATECHANGE); ++ } ++ GT_0trace(PROC_DebugMask, GT_1CLASS, "PROC_Start: Processor " ++ "Started and running \n"); ++ } else { ++ /* Failed to Create Node Manager and DISP Object ++ * Stop the Processor from running. Put it in STOPPED State */ ++ (void)(*pProcObject->pIntfFxns->pfnBrdStop)(pProcObject-> ++ hWmdContext); ++ status = DSP_EFAIL; ++ pProcObject->sState = PROC_STOPPED; ++ GT_0trace(PROC_DebugMask, GT_7CLASS, "PROC_Start " ++ "Failed to Create the Node Manager\n"); ++ } ++func_cont: ++#ifdef DEBUG ++ if (DSP_SUCCEEDED(status)) { ++ if (DSP_SUCCEEDED((*pProcObject->pIntfFxns->pfnBrdStatus) ++ (pProcObject->hWmdContext, &uBrdState))) { ++ GT_0trace(PROC_DebugMask, GT_1CLASS, ++ "PROC_Start: Processor State is RUNNING \n"); ++ DBC_Assert(uBrdState != BRD_HIBERNATION); ++ } ++ } ++#endif ++func_end: ++ GT_1trace(PROC_DebugMask, GT_ENTER, ++ "Exiting PROC_Start, status 0x%x\n", status); ++ DBC_Ensure((DSP_SUCCEEDED(status) && pProcObject->sState == ++ PROC_RUNNING) || DSP_FAILED(status)); ++ return status; ++} ++ ++/* ++ * ======== PROC_Stop ======== ++ * Purpose: ++ * Stop a processor running. ++ */ ++DSP_STATUS PROC_Stop(DSP_HPROCESSOR hProcessor) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProcessor; ++ struct MSG_MGR *hMsgMgr; ++ struct NODE_MGR *hNodeMgr; ++ DSP_HNODE hNode; ++ u32 uNodeTabSize = 1; ++ u32 uNumNodes = 0; ++ u32 uNodesAllocated = 0; ++#ifdef DEBUG ++ BRD_STATUS uBrdState; ++#endif ++ DBC_Require(cRefs > 0); ++ GT_1trace(PROC_DebugMask, GT_ENTER, "Entered PROC_Stop, args:\n\t" ++ "hProcessor: 0x%x\n", hProcessor); ++ if (!MEM_IsValidHandle(pProcObject, PROC_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Stop :InValid Handle \n"); ++ goto func_end; ++ } ++ /* check if there are any running nodes */ ++ status = DEV_GetNodeManager(pProcObject->hDevObject, &hNodeMgr); ++ if (DSP_SUCCEEDED(status) && hNodeMgr) { ++ status = NODE_EnumNodes(hNodeMgr, &hNode, uNodeTabSize, ++ &uNumNodes, &uNodesAllocated); ++ if ((status == DSP_ESIZE) || (uNodesAllocated > 0)) { ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "Can't stop device, Active " ++ "nodes = 0x%x \n", uNodesAllocated); ++ return DSP_EWRONGSTATE; ++ } ++ } ++ /* Call the WMD_BRD_Stop */ ++ /* It is OK to stop a device that does n't have nodes OR not started */ ++ status = (*pProcObject->pIntfFxns->pfnBrdStop)(pProcObject-> ++ hWmdContext); ++ if (DSP_SUCCEEDED(status)) { ++ GT_0trace(PROC_DebugMask, GT_1CLASS, ++ "PROC_Stop: Processor Stopped, " ++ "i.e in standby mode \n"); ++ pProcObject->sState = PROC_STOPPED; ++ /* Destory the Node Manager, MSG Manager */ ++ if (DSP_SUCCEEDED(DEV_Destroy2(pProcObject->hDevObject))) { ++ /* Destroy the MSG by calling MSG_Delete */ ++ DEV_GetMsgMgr(pProcObject->hDevObject, &hMsgMgr); ++ if (hMsgMgr) { ++ MSG_Delete(hMsgMgr); ++ DEV_SetMsgMgr(pProcObject->hDevObject, NULL); ++ } ++#ifdef DEBUG ++ if (DSP_SUCCEEDED((*pProcObject->pIntfFxns-> ++ pfnBrdStatus)(pProcObject->hWmdContext, ++ &uBrdState))) { ++ GT_0trace(PROC_DebugMask, GT_1CLASS, ++ "PROC_Monitor:Processor Stopped \n"); ++ DBC_Assert(uBrdState == BRD_STOPPED); ++ } ++#endif ++ } else { ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Stop Couldn't delete node manager \n"); ++ } ++ } else { ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Stop Failed to Stop the processor/device \n"); ++ } ++func_end: ++ GT_1trace(PROC_DebugMask, GT_ENTER, "Exiting PROC_Stop, status 0x%x\n", ++ status); ++ ++ return status; ++} ++ ++/* ++ * ======== PROC_UnMap ======== ++ * Purpose: ++ * Removes a MPU buffer mapping from the DSP address space. ++ */ ++DSP_STATUS PROC_UnMap(DSP_HPROCESSOR hProcessor, void *pMapAddr) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProcessor; ++ struct DMM_OBJECT *hDmmMgr; ++ u32 vaAlign; ++ u32 sizeAlign; ++#ifndef RES_CLEANUP_DISABLE ++ u32 hProcess; ++ HANDLE pCtxt = NULL; ++ HANDLE hDrvObject; ++ HANDLE dmmRes; ++ DSP_STATUS res_status = DSP_SOK; ++#endif ++ GT_2trace(PROC_DebugMask, GT_ENTER, ++ "Entered PROC_UnMap, args:\n\thProcessor:" ++ "0x%x pMapAddr: 0x%x\n", hProcessor, pMapAddr); ++ ++ vaAlign = PG_ALIGN_LOW((u32) pMapAddr, PG_SIZE_4K); ++ ++ status = DMM_GetHandle(hProcessor, &hDmmMgr); ++ /* Critical section */ ++ (void)SYNC_EnterCS(hProcLock); ++ if (DSP_FAILED(status)) { ++ GT_1trace(PROC_DebugMask, GT_7CLASS, "PROC_UnMap: " ++ "Failed to get DMM Mgr handle: 0x%x\n", status); ++ } else { ++ /* Update DMM structures. Get the size to unmap. ++ This function returns error if the VA is not mapped */ ++ status = DMM_UnMapMemory(hDmmMgr, (u32) vaAlign, &sizeAlign); ++ } ++ /* Remove mapping from the page tables. */ ++ if (DSP_SUCCEEDED(status)) { ++ status = (*pProcObject->pIntfFxns->pfnBrdMemUnMap) ++ (pProcObject->hWmdContext, vaAlign, sizeAlign); ++ } ++ (void)SYNC_LeaveCS(hProcLock); ++#ifndef RES_CLEANUP_DISABLE ++ GT_1trace(PROC_DebugMask, GT_ENTER, ++ "PROC_UnMap DRV_GetDMMResElement " ++ "pMapAddr:[0x%x]", pMapAddr); ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ /* Update the node and stream resource status */ ++ /* Return PID instead of process handle */ ++ hProcess = current->pid; ++ ++ res_status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT); ++ if (DSP_FAILED(res_status)) ++ goto func_end; ++ ++ DRV_GetProcContext(hProcess, (struct DRV_OBJECT *)hDrvObject, ++ &pCtxt, NULL, (u32)pMapAddr); ++ if (pCtxt != NULL) { ++ if (DRV_GetDMMResElement((u32)pMapAddr, &dmmRes, pCtxt) != ++ DSP_ENOTFOUND) ++ DRV_RemoveDMMResElement(dmmRes, pCtxt); ++ } ++func_end: ++#endif ++ GT_1trace(PROC_DebugMask, GT_ENTER, ++ "Leaving PROC_UnMap [0x%x]", status); ++ return status; ++} ++ ++/* ++ * ======== PROC_UnReserveMemory ======== ++ * Purpose: ++ * Frees a previously reserved region of DSP address space. ++ */ ++DSP_STATUS PROC_UnReserveMemory(DSP_HPROCESSOR hProcessor, void *pRsvAddr) ++{ ++ struct DMM_OBJECT *hDmmMgr; ++ DSP_STATUS status = DSP_SOK; ++ struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProcessor; ++ ++ GT_2trace(PROC_DebugMask, GT_ENTER, ++ "Entered PROC_UnReserveMemory, args:\n\t" ++ "hProcessor: 0x%x pRsvAddr: 0x%x\n", hProcessor, pRsvAddr); ++ ++ status = DMM_GetHandle(pProcObject, &hDmmMgr); ++ if (DSP_FAILED(status)) ++ GT_1trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_UnReserveMemory: Failed to get DMM Mgr " ++ "handle: 0x%x\n", status); ++ else ++ status = DMM_UnReserveMemory(hDmmMgr, (u32) pRsvAddr); ++ ++ GT_1trace(PROC_DebugMask, GT_ENTER, ++ "Leaving PROC_UnReserveMemory [0x%x]", ++ status); ++ ++ return status; ++} ++ ++/* ++ * ======== = PROC_Monitor ======== == ++ * Purpose: ++ * Place the Processor in Monitor State. This is an internal ++ * function and a requirement before Processor is loaded. ++ * This does a WMD_BRD_Stop, DEV_Destroy2 and WMD_BRD_Monitor. ++ * In DEV_Destroy2 we delete the node manager. ++ * Parameters: ++ * hProcObject: Handle to Processor Object ++ * Returns: ++ * DSP_SOK: Processor placed in monitor mode. ++ * !DSP_SOK: Failed to place processor in monitor mode. ++ * Requires: ++ * Valid Processor Handle ++ * Ensures: ++ * Success: ProcObject state is PROC_IDLE ++ */ ++static DSP_STATUS PROC_Monitor(struct PROC_OBJECT *hProcObject) ++{ ++ DSP_STATUS status = DSP_EFAIL; ++ struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProcObject; ++ struct MSG_MGR *hMsgMgr; ++#ifdef DEBUG ++ BRD_STATUS uBrdState; ++#endif ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(pProcObject, PROC_SIGNATURE)); ++ ++ GT_1trace(PROC_DebugMask, GT_ENTER, "Entered PROC_Monitor, args:\n\t" ++ "hProcessor: 0x%x\n", hProcObject); ++ /* This is needed only when Device is loaded when it is ++ * already 'ACTIVE' */ ++ /* Destory the Node Manager, MSG Manager */ ++ if (DSP_SUCCEEDED(DEV_Destroy2(pProcObject->hDevObject))) { ++ /* Destroy the MSG by calling MSG_Delete */ ++ DEV_GetMsgMgr(pProcObject->hDevObject, &hMsgMgr); ++ if (hMsgMgr) { ++ MSG_Delete(hMsgMgr); ++ DEV_SetMsgMgr(pProcObject->hDevObject, NULL); ++ } ++ } ++ /* Place the Board in the Monitor State */ ++ if (DSP_SUCCEEDED((*pProcObject->pIntfFxns->pfnBrdMonitor) ++ (pProcObject->hWmdContext))) { ++ status = DSP_SOK; ++#ifdef DEBUG ++ if (DSP_SUCCEEDED((*pProcObject->pIntfFxns->pfnBrdStatus) ++ (pProcObject->hWmdContext, &uBrdState))) { ++ GT_0trace(PROC_DebugMask, GT_1CLASS, ++ "PROC_Monitor:Processor in " ++ "Monitor State\n"); ++ DBC_Assert(uBrdState == BRD_IDLE); ++ } ++#endif ++ } else { ++ /* Monitor Failure */ ++ GT_0trace(PROC_DebugMask, GT_7CLASS, ++ "PROC_Monitor: Processor Could not" ++ "be put in Monitor mode \n"); ++ } ++ GT_1trace(PROC_DebugMask, GT_ENTER, ++ "Exiting PROC_Monitor, status 0x%x\n", ++ status); ++#ifdef DEBUG ++ DBC_Ensure((DSP_SUCCEEDED(status) && uBrdState == BRD_IDLE) || ++ DSP_FAILED(status)); ++#endif ++ return status; ++} ++ ++/* ++ * ======== GetEnvpCount ======== ++ * Purpose: ++ * Return the number of elements in the envp array, including the ++ * terminating NULL element. ++ */ ++static s32 GetEnvpCount(char **envp) ++{ ++ s32 cRetval = 0; ++ if (envp) { ++ while (*envp++) ++ cRetval++; ++ ++ cRetval += 1; /* Include the terminating NULL in the count. */ ++ } ++ ++ return cRetval; ++} ++ ++/* ++ * ======== PrependEnvp ======== ++ * Purpose: ++ * Prepend an environment variable=value pair to the new envp array, and ++ * copy in the existing var=value pairs in the old envp array. ++ */ ++static char **PrependEnvp(char **newEnvp, char **envp, s32 cEnvp, s32 cNewEnvp, ++ char *szVar) ++{ ++ char **ppEnvp = newEnvp; ++ ++ DBC_Require(newEnvp); ++ ++ /* Prepend new environ var=value string */ ++ *newEnvp++ = szVar; ++ ++ /* Copy user's environment into our own. */ ++ while (cEnvp--) ++ *newEnvp++ = *envp++; ++ ++ /* Ensure NULL terminates the new environment strings array. */ ++ if (cEnvp == 0) ++ *newEnvp = NULL; ++ ++ return ppEnvp; ++} ++ ++/* ++ * ======== PROC_NotifyClients ======== ++ * Purpose: ++ * Notify the processor the events. ++ */ ++DSP_STATUS PROC_NotifyClients(DSP_HPROCESSOR hProc, u32 uEvents) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProc; ++ ++ DBC_Require(MEM_IsValidHandle(pProcObject, PROC_SIGNATURE)); ++ DBC_Require(IsValidProcEvent(uEvents)); ++ DBC_Require(cRefs > 0); ++ ++ NTFY_Notify(pProcObject->hNtfy, uEvents); ++ GT_0trace(PROC_DebugMask, GT_1CLASS, ++ "PROC_NotifyClients :Signaled. \n"); ++ ++ return status; ++} ++ ++/* ++ * ======== PROC_NotifyAllClients ======== ++ * Purpose: ++ * Notify the processor the events. This includes notifying all clients ++ * attached to a particulat DSP. ++ */ ++DSP_STATUS PROC_NotifyAllClients(DSP_HPROCESSOR hProc, u32 uEvents) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProc; ++ ++ DBC_Require(MEM_IsValidHandle(pProcObject, PROC_SIGNATURE)); ++ DBC_Require(IsValidProcEvent(uEvents)); ++ DBC_Require(cRefs > 0); ++ ++ DEV_NotifyClients(pProcObject->hDevObject, uEvents); ++ ++ GT_0trace(PROC_DebugMask, GT_1CLASS, ++ "PROC_NotifyAllClients :Signaled. \n"); ++ ++ return status; ++} ++ ++/* ++ * ======== PROC_GetProcessorId ======== ++ * Purpose: ++ * Retrieves the processor ID. ++ */ ++DSP_STATUS PROC_GetProcessorId(DSP_HPROCESSOR hProc, u32 *procID) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct PROC_OBJECT *pProcObject = (struct PROC_OBJECT *)hProc; ++ ++ *procID = pProcObject->uProcessor; ++ ++ return status; ++} ++ +diff --git a/drivers/dsp/bridge/rmgr/pwr.c b/drivers/dsp/bridge/rmgr/pwr.c +new file mode 100644 +index 0000000..50a3f79 +--- /dev/null ++++ b/drivers/dsp/bridge/rmgr/pwr.c +@@ -0,0 +1,184 @@ ++/* ++ * pwr.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== PWR.c ======== ++ * PWR API for controlling DSP power states. ++ * ++ * Public Functions: ++ * PWR_SleepDSP ++ * PWR_WakeDSP ++ * ++ *! Revision History ++ *! ================ ++ *! 18-Feb-2003 vp Code review updates. ++ *! 18-Oct-2002 vp Ported to Linux platform. ++ *! 22-May-2002 sg Do PWR-to-IOCTL code mapping in PWR_SleepDSP. ++ *! 29-Apr-2002 sg Initial. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++/* ----------------------------------- Resource Manager */ ++#include ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++ ++/* ----------------------------------- Link Driver */ ++#include ++ ++/* ++ * ======== PWR_SleepDSP ======== ++ * Send command to DSP to enter sleep state. ++ */ ++DSP_STATUS PWR_SleepDSP(IN CONST u32 sleepCode, IN CONST u32 timeout) ++{ ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ struct WMD_DEV_CONTEXT *dwContext; ++ DSP_STATUS status = DSP_EFAIL; ++ struct DEV_OBJECT *hDevObject = NULL; ++ u32 ioctlcode = 0; ++ u32 arg = timeout; ++ ++ for (hDevObject = (struct DEV_OBJECT *)DRV_GetFirstDevObject(); ++ hDevObject != NULL; ++ hDevObject = ++ (struct DEV_OBJECT *)DRV_GetNextDevObject ++ ((u32)hDevObject)) { ++ if (DSP_FAILED(DEV_GetWMDContext(hDevObject, ++ (struct WMD_DEV_CONTEXT **)&dwContext))) { ++ continue; ++ } ++ if (DSP_FAILED(DEV_GetIntfFxns(hDevObject, ++ (struct WMD_DRV_INTERFACE **)&pIntfFxns))) { ++ continue; ++ } ++ if (sleepCode == PWR_DEEPSLEEP) ++ ioctlcode = WMDIOCTL_DEEPSLEEP; ++ else if (sleepCode == PWR_EMERGENCYDEEPSLEEP) ++ ioctlcode = WMDIOCTL_EMERGENCYSLEEP; ++ else ++ status = DSP_EINVALIDARG; ++ ++ if (status != DSP_EINVALIDARG) { ++ status = (*pIntfFxns->pfnDevCntrl)(dwContext, ++ ioctlcode, (void *)&arg); ++ } ++ } ++ return status; ++} ++ ++/* ++ * ======== PWR_WakeDSP ======== ++ * Send command to DSP to wake it from sleep. ++ */ ++DSP_STATUS PWR_WakeDSP(IN CONST u32 timeout) ++{ ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ struct WMD_DEV_CONTEXT *dwContext; ++ DSP_STATUS status = DSP_EFAIL; ++ struct DEV_OBJECT *hDevObject = NULL; ++ u32 arg = timeout; ++ ++ for (hDevObject = (struct DEV_OBJECT *)DRV_GetFirstDevObject(); ++ hDevObject != NULL; ++ hDevObject = (struct DEV_OBJECT *)DRV_GetNextDevObject ++ ((u32)hDevObject)) { ++ if (DSP_SUCCEEDED(DEV_GetWMDContext(hDevObject, ++ (struct WMD_DEV_CONTEXT **)&dwContext))) { ++ if (DSP_SUCCEEDED(DEV_GetIntfFxns(hDevObject, ++ (struct WMD_DRV_INTERFACE **)&pIntfFxns))) { ++ status = (*pIntfFxns->pfnDevCntrl)(dwContext, ++ WMDIOCTL_WAKEUP, (void *)&arg); ++ } ++ } ++ } ++ return status; ++} ++ ++/* ++ * ======== PWR_PM_PreScale======== ++ * Sends pre-notification message to DSP. ++ */ ++DSP_STATUS PWR_PM_PreScale(IN u16 voltage_domain, u32 level) ++{ ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ struct WMD_DEV_CONTEXT *dwContext; ++ DSP_STATUS status = DSP_EFAIL; ++ struct DEV_OBJECT *hDevObject = NULL; ++ u32 arg[2]; ++ ++ arg[0] = voltage_domain; ++ arg[1] = level; ++ ++ for (hDevObject = (struct DEV_OBJECT *)DRV_GetFirstDevObject(); ++ hDevObject != NULL; ++ hDevObject = (struct DEV_OBJECT *)DRV_GetNextDevObject ++ ((u32)hDevObject)) { ++ if (DSP_SUCCEEDED(DEV_GetWMDContext(hDevObject, ++ (struct WMD_DEV_CONTEXT **)&dwContext))) { ++ if (DSP_SUCCEEDED(DEV_GetIntfFxns(hDevObject, ++ (struct WMD_DRV_INTERFACE **)&pIntfFxns))) { ++ status = (*pIntfFxns->pfnDevCntrl)(dwContext, ++ WMDIOCTL_PRESCALE_NOTIFY, ++ (void *)&arg); ++ } ++ } ++ } ++ return status; ++} ++ ++/* ++ * ======== PWR_PM_PostScale======== ++ * Sends post-notification message to DSP. ++ */ ++DSP_STATUS PWR_PM_PostScale(IN u16 voltage_domain, u32 level) ++{ ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ struct WMD_DEV_CONTEXT *dwContext; ++ DSP_STATUS status = DSP_EFAIL; ++ struct DEV_OBJECT *hDevObject = NULL; ++ u32 arg[2]; ++ ++ arg[0] = voltage_domain; ++ arg[1] = level; ++ ++ for (hDevObject = (struct DEV_OBJECT *)DRV_GetFirstDevObject(); ++ hDevObject != NULL; ++ hDevObject = (struct DEV_OBJECT *)DRV_GetNextDevObject ++ ((u32)hDevObject)) { ++ if (DSP_SUCCEEDED(DEV_GetWMDContext(hDevObject, ++ (struct WMD_DEV_CONTEXT **)&dwContext))) { ++ if (DSP_SUCCEEDED(DEV_GetIntfFxns(hDevObject, ++ (struct WMD_DRV_INTERFACE **)&pIntfFxns))) { ++ status = (*pIntfFxns->pfnDevCntrl)(dwContext, ++ WMDIOCTL_POSTSCALE_NOTIFY, ++ (void *)&arg); ++ } ++ } ++ } ++ return status; ++ ++} ++ ++ +diff --git a/drivers/dsp/bridge/rmgr/rmm.c b/drivers/dsp/bridge/rmgr/rmm.c +new file mode 100644 +index 0000000..575f675 +--- /dev/null ++++ b/drivers/dsp/bridge/rmgr/rmm.c +@@ -0,0 +1,604 @@ ++/* ++ * rmm.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== rmm.c ======== ++ * Description: ++ * ++ * This memory manager provides general heap management and arbitrary ++ * alignment for any number of memory segments. ++ * ++ * Notes: ++ * ++ * Memory blocks are allocated from the end of the first free memory ++ * block large enough to satisfy the request. Alignment requirements ++ * are satisfied by "sliding" the block forward until its base satisfies ++ * the alignment specification; if this is not possible then the next ++ * free block large enough to hold the request is tried. ++ * ++ * Since alignment can cause the creation of a new free block - the ++ * unused memory formed between the start of the original free block ++ * and the start of the allocated block - the memory manager must free ++ * this memory to prevent a memory leak. ++ * ++ * Overlay memory is managed by reserving through RMM_alloc, and freeing ++ * it through RMM_free. The memory manager prevents DSP code/data that is ++ * overlayed from being overwritten as long as the memory it runs at has ++ * been allocated, and not yet freed. ++ * ++ *! Revision History ++ *! ================ ++ *! 18-Feb-2003 vp Code review updates. ++ *! 18-Oct-2002 vp Ported to Linux Platform. ++ *! 24-Sep-2002 map Updated from Code Review ++ *! 25-Jun-2002 jeh Free from segid passed to RMM_free(). ++ *! 24-Apr-2002 jeh Determine segid based on address in RMM_free(). (No way ++ *! to keep track of segid with dynamic loader library.) ++ *! 16-Oct-2001 jeh Based on gen tree rm.c. Added support for overlays. ++ */ ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++#define RMM_TARGSIGNATURE 0x544d4d52 /* "TMMR" */ ++ ++/* ++ * ======== RMM_Header ======== ++ * This header is used to maintain a list of free memory blocks. ++ */ ++struct RMM_Header { ++ struct RMM_Header *next; /* form a free memory link list */ ++ u32 size; /* size of the free memory */ ++ u32 addr; /* DSP address of memory block */ ++} ; ++ ++/* ++ * ======== RMM_OvlySect ======== ++ * Keeps track of memory occupied by overlay section. ++ */ ++struct RMM_OvlySect { ++ struct LST_ELEM listElem; ++ u32 addr; /* Start of memory section */ ++ u32 size; /* Length (target MAUs) of section */ ++ s32 page; /* Memory page */ ++}; ++ ++/* ++ * ======== RMM_TargetObj ======== ++ */ ++struct RMM_TargetObj { ++ u32 dwSignature; ++ struct RMM_Segment *segTab; ++ struct RMM_Header **freeList; ++ u32 numSegs; ++ struct LST_LIST *ovlyList; /* List of overlay memory in use */ ++}; ++ ++#if GT_TRACE ++static struct GT_Mask RMM_debugMask = { NULL, NULL }; /* GT trace variable */ ++#endif ++ ++static u32 cRefs; /* module reference count */ ++ ++static bool allocBlock(struct RMM_TargetObj *target, u32 segid, u32 size, ++ u32 align, u32 *dspAddr); ++static bool freeBlock(struct RMM_TargetObj *target, u32 segid, u32 addr, ++ u32 size); ++ ++/* ++ * ======== RMM_alloc ======== ++ */ ++DSP_STATUS RMM_alloc(struct RMM_TargetObj *target, u32 segid, u32 size, ++ u32 align, u32 *dspAddr, bool reserve) ++{ ++ struct RMM_OvlySect *sect; ++ struct RMM_OvlySect *prevSect = NULL; ++ struct RMM_OvlySect *newSect; ++ u32 addr; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(MEM_IsValidHandle(target, RMM_TARGSIGNATURE)); ++ DBC_Require(dspAddr != NULL); ++ DBC_Require(size > 0); ++ DBC_Require(reserve || (target->numSegs > 0)); ++ DBC_Require(cRefs > 0); ++ ++ GT_6trace(RMM_debugMask, GT_ENTER, ++ "RMM_alloc(0x%lx, 0x%lx, 0x%lx, 0x%lx, " ++ "0x%lx, 0x%lx)\n", target, segid, size, align, dspAddr, ++ reserve); ++ if (!reserve) { ++ if (!allocBlock(target, segid, size, align, dspAddr)) { ++ status = DSP_EMEMORY; ++ } else { ++ /* Increment the number of allocated blocks in this ++ * segment */ ++ target->segTab[segid].number++; ++ } ++ goto func_end; ++ } ++ /* An overlay section - See if block is already in use. If not, ++ * insert into the list in ascending address size. */ ++ addr = *dspAddr; ++ sect = (struct RMM_OvlySect *)LST_First(target->ovlyList); ++ /* Find place to insert new list element. List is sorted from ++ * smallest to largest address. */ ++ while (sect != NULL) { ++ if (addr <= sect->addr) { ++ /* Check for overlap with sect */ ++ if ((addr + size > sect->addr) || (prevSect && ++ (prevSect->addr + prevSect->size > addr))) { ++ status = DSP_EOVERLAYMEMORY; ++ } ++ break; ++ } ++ prevSect = sect; ++ sect = (struct RMM_OvlySect *)LST_Next(target->ovlyList, ++ (struct LST_ELEM *)sect); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* No overlap - allocate list element for new section. */ ++ newSect = MEM_Calloc(sizeof(struct RMM_OvlySect), MEM_PAGED); ++ if (newSect == NULL) { ++ status = DSP_EMEMORY; ++ } else { ++ LST_InitElem((struct LST_ELEM *)newSect); ++ newSect->addr = addr; ++ newSect->size = size; ++ newSect->page = segid; ++ if (sect == NULL) { ++ /* Put new section at the end of the list */ ++ LST_PutTail(target->ovlyList, ++ (struct LST_ELEM *)newSect); ++ } else { ++ /* Put new section just before sect */ ++ LST_InsertBefore(target->ovlyList, ++ (struct LST_ELEM *)newSect, ++ (struct LST_ELEM *)sect); ++ } ++ } ++ } ++func_end: ++ return status; ++} ++ ++/* ++ * ======== RMM_create ======== ++ */ ++DSP_STATUS RMM_create(struct RMM_TargetObj **pTarget, ++ struct RMM_Segment segTab[], u32 numSegs) ++{ ++ struct RMM_Header *hptr; ++ struct RMM_Segment *sptr, *tmp; ++ struct RMM_TargetObj *target; ++ s32 i; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(pTarget != NULL); ++ DBC_Require(numSegs == 0 || segTab != NULL); ++ ++ GT_3trace(RMM_debugMask, GT_ENTER, ++ "RMM_create(0x%lx, 0x%lx, 0x%lx)\n", ++ pTarget, segTab, numSegs); ++ ++ /* Allocate DBL target object */ ++ MEM_AllocObject(target, struct RMM_TargetObj, RMM_TARGSIGNATURE); ++ ++ if (target == NULL) { ++ GT_0trace(RMM_debugMask, GT_6CLASS, ++ "RMM_create: Memory allocation failed\n"); ++ status = DSP_EMEMORY; ++ } ++ if (DSP_FAILED(status)) ++ goto func_cont; ++ ++ target->numSegs = numSegs; ++ if (!(numSegs > 0)) ++ goto func_cont; ++ ++ /* Allocate the memory for freelist from host's memory */ ++ target->freeList = MEM_Calloc(numSegs * sizeof(struct RMM_Header *), ++ MEM_PAGED); ++ if (target->freeList == NULL) { ++ GT_0trace(RMM_debugMask, GT_6CLASS, ++ "RMM_create: Memory allocation failed\n"); ++ status = DSP_EMEMORY; ++ } else { ++ /* Allocate headers for each element on the free list */ ++ for (i = 0; i < (s32) numSegs; i++) { ++ target->freeList[i] = ++ MEM_Calloc(sizeof(struct RMM_Header), ++ MEM_PAGED); ++ if (target->freeList[i] == NULL) { ++ GT_0trace(RMM_debugMask, GT_6CLASS, ++ "RMM_create: Memory " ++ "allocation failed\n"); ++ status = DSP_EMEMORY; ++ break; ++ } ++ } ++ /* Allocate memory for initial segment table */ ++ target->segTab = MEM_Calloc(numSegs * ++ sizeof(struct RMM_Segment), MEM_PAGED); ++ if (target->segTab == NULL) { ++ GT_0trace(RMM_debugMask, GT_6CLASS, ++ "RMM_create: Memory allocation failed\n"); ++ status = DSP_EMEMORY; ++ } else { ++ /* Initialize segment table and free list */ ++ sptr = target->segTab; ++ for (i = 0, tmp = segTab; numSegs > 0; numSegs--, i++) { ++ *sptr = *tmp; ++ hptr = target->freeList[i]; ++ hptr->addr = tmp->base; ++ hptr->size = tmp->length; ++ hptr->next = NULL; ++ tmp++; ++ sptr++; ++ } ++ } ++ } ++func_cont: ++ /* Initialize overlay memory list */ ++ if (DSP_SUCCEEDED(status)) { ++ target->ovlyList = LST_Create(); ++ if (target->ovlyList == NULL) { ++ GT_0trace(RMM_debugMask, GT_6CLASS, ++ "RMM_create: Memory allocation failed\n"); ++ status = DSP_EMEMORY; ++ } ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ *pTarget = target; ++ } else { ++ *pTarget = NULL; ++ if (target) ++ RMM_delete(target); ++ ++ } ++ ++ DBC_Ensure((DSP_SUCCEEDED(status) && MEM_IsValidHandle((*pTarget), ++ RMM_TARGSIGNATURE)) || (DSP_FAILED(status) && *pTarget == ++ NULL)); ++ ++ return status; ++} ++ ++/* ++ * ======== RMM_delete ======== ++ */ ++void RMM_delete(struct RMM_TargetObj *target) ++{ ++ struct RMM_OvlySect *pSect; ++ struct RMM_Header *hptr; ++ struct RMM_Header *next; ++ u32 i; ++ ++ DBC_Require(MEM_IsValidHandle(target, RMM_TARGSIGNATURE)); ++ ++ GT_1trace(RMM_debugMask, GT_ENTER, "RMM_delete(0x%lx)\n", target); ++ ++ if (target->segTab != NULL) ++ MEM_Free(target->segTab); ++ ++ if (target->ovlyList) { ++ while ((pSect = (struct RMM_OvlySect *)LST_GetHead ++ (target->ovlyList))) { ++ MEM_Free(pSect); ++ } ++ DBC_Assert(LST_IsEmpty(target->ovlyList)); ++ LST_Delete(target->ovlyList); ++ } ++ ++ if (target->freeList != NULL) { ++ /* Free elements on freelist */ ++ for (i = 0; i < target->numSegs; i++) { ++ hptr = next = target->freeList[i]; ++ while (next) { ++ hptr = next; ++ next = hptr->next; ++ MEM_Free(hptr); ++ } ++ } ++ MEM_Free(target->freeList); ++ } ++ ++ MEM_FreeObject(target); ++} ++ ++/* ++ * ======== RMM_exit ======== ++ */ ++void RMM_exit(void) ++{ ++ DBC_Require(cRefs > 0); ++ ++ cRefs--; ++ ++ GT_1trace(RMM_debugMask, GT_5CLASS, "RMM_exit() ref count: 0x%x\n", ++ cRefs); ++ ++ if (cRefs == 0) ++ MEM_Exit(); ++ ++ DBC_Ensure(cRefs >= 0); ++} ++ ++/* ++ * ======== RMM_free ======== ++ */ ++bool RMM_free(struct RMM_TargetObj *target, u32 segid, u32 addr, u32 size, ++ bool reserved) ++ ++{ ++ struct RMM_OvlySect *sect; ++ bool retVal = true; ++ ++ DBC_Require(MEM_IsValidHandle(target, RMM_TARGSIGNATURE)); ++ ++ DBC_Require(reserved || segid < target->numSegs); ++ DBC_Require(reserved || (addr >= target->segTab[segid].base && ++ (addr + size) <= (target->segTab[segid].base + ++ target->segTab[segid].length))); ++ ++ GT_5trace(RMM_debugMask, GT_ENTER, ++ "RMM_free(0x%lx, 0x%lx, 0x%lx, 0x%lx, " ++ "0x%lx)\n", target, segid, addr, size, reserved); ++ /* ++ * Free or unreserve memory. ++ */ ++ if (!reserved) { ++ retVal = freeBlock(target, segid, addr, size); ++ if (retVal) ++ target->segTab[segid].number--; ++ ++ } else { ++ /* Unreserve memory */ ++ sect = (struct RMM_OvlySect *)LST_First(target->ovlyList); ++ while (sect != NULL) { ++ if (addr == sect->addr) { ++ DBC_Assert(size == sect->size); ++ /* Remove from list */ ++ LST_RemoveElem(target->ovlyList, ++ (struct LST_ELEM *)sect); ++ MEM_Free(sect); ++ break; ++ } ++ sect = (struct RMM_OvlySect *)LST_Next(target->ovlyList, ++ (struct LST_ELEM *)sect); ++ } ++ if (sect == NULL) ++ retVal = false; ++ ++ } ++ return retVal; ++} ++ ++/* ++ * ======== RMM_init ======== ++ */ ++bool RMM_init(void) ++{ ++ bool retVal = true; ++ ++ DBC_Require(cRefs >= 0); ++ ++ if (cRefs == 0) { ++ DBC_Assert(!RMM_debugMask.flags); ++ GT_create(&RMM_debugMask, "RM"); /* "RM" for RMm */ ++ ++ retVal = MEM_Init(); ++ ++ if (!retVal) ++ MEM_Exit(); ++ ++ } ++ ++ if (retVal) ++ cRefs++; ++ ++ GT_1trace(RMM_debugMask, GT_5CLASS, ++ "RMM_init(), ref count: 0x%x\n", ++ cRefs); ++ ++ DBC_Ensure((retVal && (cRefs > 0)) || (!retVal && (cRefs >= 0))); ++ ++ return retVal; ++} ++ ++/* ++ * ======== RMM_stat ======== ++ */ ++bool RMM_stat(struct RMM_TargetObj *target, enum DSP_MEMTYPE segid, ++ struct DSP_MEMSTAT *pMemStatBuf) ++{ ++ struct RMM_Header *head; ++ bool retVal = false; ++ u32 maxFreeSize = 0; ++ u32 totalFreeSize = 0; ++ u32 freeBlocks = 0; ++ ++ DBC_Require(pMemStatBuf != NULL); ++ DBC_Assert(target != NULL); ++ ++ if ((u32) segid < target->numSegs) { ++ head = target->freeList[segid]; ++ ++ /* Collect data from freeList */ ++ while (head != NULL) { ++ maxFreeSize = max(maxFreeSize, head->size); ++ totalFreeSize += head->size; ++ freeBlocks++; ++ head = head->next; ++ } ++ ++ /* ulSize */ ++ pMemStatBuf->ulSize = target->segTab[segid].length; ++ ++ /* ulNumFreeBlocks */ ++ pMemStatBuf->ulNumFreeBlocks = freeBlocks; ++ ++ /* ulTotalFreeSize */ ++ pMemStatBuf->ulTotalFreeSize = totalFreeSize; ++ ++ /* ulLenMaxFreeBlock */ ++ pMemStatBuf->ulLenMaxFreeBlock = maxFreeSize; ++ ++ /* ulNumAllocBlocks */ ++ pMemStatBuf->ulNumAllocBlocks = target->segTab[segid].number; ++ ++ retVal = true; ++ } ++ ++ return retVal; ++} ++ ++/* ++ * ======== balloc ======== ++ * This allocation function allocates memory from the lowest addresses ++ * first. ++ */ ++static bool allocBlock(struct RMM_TargetObj *target, u32 segid, u32 size, ++ u32 align, u32 *dspAddr) ++{ ++ struct RMM_Header *head; ++ struct RMM_Header *prevhead = NULL; ++ struct RMM_Header *next; ++ u32 tmpalign; ++ u32 alignbytes; ++ u32 hsize; ++ u32 allocsize; ++ u32 addr; ++ ++ alignbytes = (align == 0) ? 1 : align; ++ prevhead = NULL; ++ head = target->freeList[segid]; ++ ++ do { ++ hsize = head->size; ++ next = head->next; ++ ++ addr = head->addr; /* alloc from the bottom */ ++ ++ /* align allocation */ ++ (tmpalign = (u32) addr % alignbytes); ++ if (tmpalign != 0) ++ tmpalign = alignbytes - tmpalign; ++ ++ allocsize = size + tmpalign; ++ ++ if (hsize >= allocsize) { /* big enough */ ++ if (hsize == allocsize && prevhead != NULL) { ++ prevhead->next = next; ++ MEM_Free(head); ++ } else { ++ head->size = hsize - allocsize; ++ head->addr += allocsize; ++ } ++ ++ /* free up any hole created by alignment */ ++ if (tmpalign) ++ freeBlock(target, segid, addr, tmpalign); ++ ++ *dspAddr = addr + tmpalign; ++ return true; ++ } ++ ++ prevhead = head; ++ head = next; ++ ++ } while (head != NULL); ++ ++ return false; ++} ++ ++/* ++ * ======== freeBlock ======== ++ * TO DO: freeBlock() allocates memory, which could result in failure. ++ * Could allocate an RMM_Header in RMM_alloc(), to be kept in a pool. ++ * freeBlock() could use an RMM_Header from the pool, freeing as blocks ++ * are coalesced. ++ */ ++static bool freeBlock(struct RMM_TargetObj *target, u32 segid, u32 addr, ++ u32 size) ++{ ++ struct RMM_Header *head; ++ struct RMM_Header *thead; ++ struct RMM_Header *rhead; ++ bool retVal = true; ++ ++ /* Create a memory header to hold the newly free'd block. */ ++ rhead = MEM_Calloc(sizeof(struct RMM_Header), MEM_PAGED); ++ if (rhead == NULL) { ++ retVal = false; ++ } else { ++ /* search down the free list to find the right place for addr */ ++ head = target->freeList[segid]; ++ ++ if (addr >= head->addr) { ++ while (head->next != NULL && addr > head->next->addr) ++ head = head->next; ++ ++ thead = head->next; ++ ++ head->next = rhead; ++ rhead->next = thead; ++ rhead->addr = addr; ++ rhead->size = size; ++ } else { ++ *rhead = *head; ++ head->next = rhead; ++ head->addr = addr; ++ head->size = size; ++ thead = rhead->next; ++ } ++ ++ /* join with upper block, if possible */ ++ if (thead != NULL && (rhead->addr + rhead->size) == ++ thead->addr) { ++ head->next = rhead->next; ++ thead->size = size + thead->size; ++ thead->addr = addr; ++ MEM_Free(rhead); ++ rhead = thead; ++ } ++ ++ /* join with the lower block, if possible */ ++ if ((head->addr + head->size) == rhead->addr) { ++ head->next = rhead->next; ++ head->size = head->size + rhead->size; ++ MEM_Free(rhead); ++ } ++ } ++ ++ return retVal; ++} ++ +diff --git a/drivers/dsp/bridge/rmgr/strm.c b/drivers/dsp/bridge/rmgr/strm.c +new file mode 100644 +index 0000000..bd55fd3 +--- /dev/null ++++ b/drivers/dsp/bridge/rmgr/strm.c +@@ -0,0 +1,1066 @@ ++/* ++ * strm.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== strm.c ======== ++ * Description: ++ * DSP/BIOS Bridge Stream Manager. ++ * ++ * Public Functions: ++ * STRM_AllocateBuffer ++ * STRM_Close ++ * STRM_Create ++ * STRM_Delete ++ * STRM_Exit ++ * STRM_FreeBuffer ++ * STRM_GetEventHandle ++ * STRM_GetInfo ++ * STRM_Idle ++ * STRM_Init ++ * STRM_Issue ++ * STRM_Open ++ * STRM_PrepareBuffer ++ * STRM_Reclaim ++ * STRM_RegisterNotify ++ * STRM_Select ++ * STRM_UnprepareBuffer ++ * ++ * Notes: ++ * ++ *! Revision History: ++ *! ================= ++ *! 18-Feb-2003 vp Code review updates. ++ *! 18-Oct-2002 vp Ported to Linux platform. ++ *! 13-Mar-2002 map pStrm init'd to NULL in STRM_Open to prevent error ++ *! 12-Mar-2002 map Changed return var to WSX "wStatus" instead of "status" ++ *! in DEV and CMM function calls to avoid confusion. ++ *! Return DSP_SOK instead of S_OK from API fxns. ++ *! 12-Mar-2002 map Changed FAILED(..) to DSP_FAILED(..) ++ *! 25-Jan-2002 ag Allow neg seg ids(e.g. DSP_SHMSEG0) to denote SM. ++ *! 15-Nov-2001 ag Added STRMMODE & SM for DMA/ZCopy streaming. ++ *! Changed DSP_STREAMINFO to STRM_INFO in STRM_GetInfo(). ++ *! Use strm timeout value for dma flush timeout. ++ *! 09-May-2001 jeh Code review cleanup. ++ *! 06-Feb-2001 kc Updated DBC_Ensure in STRM_Select to check timeout. ++ *! 23-Oct-2000 jeh Allow NULL STRM_ATTRS passed to STRM_Open() for DLL ++ *! tests to pass. ++ *! 25-Sep-2000 jeh Created. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++ ++/* ----------------------------------- Mini Driver */ ++#include ++ ++/* ----------------------------------- Resource Manager */ ++#include ++ ++/* ----------------------------------- Others */ ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++#ifndef RES_CLEANUP_DISABLE ++#include ++#include ++#include ++#endif ++ ++/* ----------------------------------- Defines, Data Structures, Typedefs */ ++#define STRM_SIGNATURE 0x4d525453 /* "MRTS" */ ++#define STRMMGR_SIGNATURE 0x5254534d /* "RTSM" */ ++ ++#define DEFAULTTIMEOUT 10000 ++#define DEFAULTNUMBUFS 2 ++ ++/* ++ * ======== STRM_MGR ======== ++ * The STRM_MGR contains device information needed to open the underlying ++ * channels of a stream. ++ */ ++struct STRM_MGR { ++ u32 dwSignature; ++ struct DEV_OBJECT *hDev; /* Device for this processor */ ++ struct CHNL_MGR *hChnlMgr; /* Channel manager */ ++ struct WMD_DRV_INTERFACE *pIntfFxns; /* Function interface to WMD */ ++ struct SYNC_CSOBJECT *hSync; /* For critical sections */ ++} ; ++ ++/* ++ * ======== STRM_OBJECT ======== ++ * This object is allocated in STRM_Open(). ++ */ ++ struct STRM_OBJECT { ++ u32 dwSignature; ++ struct STRM_MGR *hStrmMgr; ++ struct CHNL_OBJECT *hChnl; ++ u32 uDir; /* DSP_TONODE or DSP_FROMNODE */ ++ u32 uTimeout; ++ u32 uNumBufs; /* Max # of bufs allowed in stream */ ++ u32 uNBufsInStrm; /* Current # of bufs in stream */ ++ u32 ulNBytes; /* bytes transferred since idled */ ++ enum DSP_STREAMSTATE strmState; /* STREAM_IDLE, STREAM_READY, ... */ ++ HANDLE hUserEvent; /* Saved for STRM_GetInfo() */ ++ enum DSP_STRMMODE lMode; /* STRMMODE_[PROCCOPY][ZEROCOPY]... */ ++ u32 uDMAChnlId; /* DMA chnl id */ ++ u32 uDMAPriority; /* DMA priority:DMAPRI_[LOW][HIGH] */ ++ u32 uSegment; /* >0 is SM segment.=0 is local heap */ ++ u32 uAlignment; /* Alignment for stream bufs */ ++ struct CMM_XLATOROBJECT *hXlator; /* Stream's SM address translator */ ++} ; ++ ++/* ----------------------------------- Globals */ ++#if GT_TRACE ++static struct GT_Mask STRM_debugMask = { NULL, NULL }; /* GT trace variable */ ++#endif ++static u32 cRefs; /* module reference count */ ++ ++/* ----------------------------------- Function Prototypes */ ++static DSP_STATUS DeleteStrm(struct STRM_OBJECT *hStrm); ++static void DeleteStrmMgr(struct STRM_MGR *hStrmMgr); ++ ++/* ++ * ======== STRM_AllocateBuffer ======== ++ * Purpose: ++ * Allocates buffers for a stream. ++ */ ++DSP_STATUS STRM_AllocateBuffer(struct STRM_OBJECT *hStrm, u32 uSize, ++ OUT u8 **apBuffer, u32 uNumBufs) ++{ ++ DSP_STATUS status = DSP_SOK; ++ u32 uAllocated = 0; ++ u32 i; ++ #ifndef RES_CLEANUP_DISABLE ++ DSP_STATUS res_status = DSP_SOK; ++ u32 hProcess; ++ HANDLE pCtxt = NULL; ++ HANDLE hDrvObject; ++ HANDLE hSTRMRes; ++ #endif ++ DBC_Require(cRefs > 0); ++ DBC_Require(apBuffer != NULL); ++ ++ GT_4trace(STRM_debugMask, GT_ENTER, "STRM_AllocateBuffer: hStrm: 0x%x\t" ++ "uSize: 0x%x\tapBuffer: 0x%x\tuNumBufs: 0x%x\n", ++ hStrm, uSize, apBuffer, uNumBufs); ++ if (MEM_IsValidHandle(hStrm, STRM_SIGNATURE)) { ++ /* ++ * Allocate from segment specified at time of stream open. ++ */ ++ if (uSize == 0) ++ status = DSP_ESIZE; ++ ++ } ++ if (DSP_FAILED(status)) { ++ status = DSP_EHANDLE; ++ goto func_end; ++ } ++ for (i = 0; i < uNumBufs; i++) { ++ DBC_Assert(hStrm->hXlator != NULL); ++ (void)CMM_XlatorAllocBuf(hStrm->hXlator, &apBuffer[i], uSize); ++ if (apBuffer[i] == NULL) { ++ GT_0trace(STRM_debugMask, GT_7CLASS, ++ "STRM_AllocateBuffer: " ++ "DSP_FAILED to alloc shared memory.\n"); ++ status = DSP_EMEMORY; ++ uAllocated = i; ++ break; ++ } ++ } ++ if (DSP_FAILED(status)) ++ STRM_FreeBuffer(hStrm, apBuffer, uAllocated); ++ ++#ifndef RES_CLEANUP_DISABLE ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ /* Return PID instead of process handle */ ++ hProcess = current->pid; ++ ++ res_status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT); ++ if (DSP_FAILED(res_status)) ++ goto func_end; ++ ++ DRV_GetProcContext(hProcess, (struct DRV_OBJECT *)hDrvObject, ++ &pCtxt, NULL, 0); ++ if (pCtxt != NULL) { ++ if (DRV_GetSTRMResElement(hStrm, &hSTRMRes, pCtxt) != ++ DSP_ENOTFOUND) { ++ DRV_ProcUpdateSTRMRes(uNumBufs, hSTRMRes, pCtxt); ++ } ++ } ++#endif ++func_end: ++ return status; ++} ++ ++/* ++ * ======== STRM_Close ======== ++ * Purpose: ++ * Close a stream opened with STRM_Open(). ++ */ ++DSP_STATUS STRM_Close(struct STRM_OBJECT *hStrm) ++{ ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ struct CHNL_INFO chnlInfo; ++ DSP_STATUS status = DSP_SOK; ++ ++ ++#ifndef RES_CLEANUP_DISABLE ++ u32 hProcess; ++ HANDLE pCtxt = NULL; ++ HANDLE hDrvObject; ++ HANDLE hSTRMRes; ++ DSP_STATUS res_status = DSP_SOK; ++#endif ++ ++ ++ DBC_Require(cRefs > 0); ++ ++ GT_1trace(STRM_debugMask, GT_ENTER, "STRM_Close: hStrm: 0x%x\n", hStrm); ++ ++ if (!MEM_IsValidHandle(hStrm, STRM_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ } else { ++ /* Have all buffers been reclaimed? If not, return ++ * DSP_EPENDING */ ++ pIntfFxns = hStrm->hStrmMgr->pIntfFxns; ++ status = (*pIntfFxns->pfnChnlGetInfo) (hStrm->hChnl, &chnlInfo); ++ DBC_Assert(DSP_SUCCEEDED(status)); ++ ++ if (chnlInfo.cIOCs > 0 || chnlInfo.cIOReqs > 0) { ++ status = DSP_EPENDING; ++ } else { ++ ++ status = DeleteStrm(hStrm); ++ ++ if (DSP_FAILED(status)) { ++ /* we already validated the handle. */ ++ DBC_Assert(status != DSP_EHANDLE); ++ ++ /* make sure we return a documented result */ ++ status = DSP_EFAIL; ++ } ++ } ++ } ++#ifndef RES_CLEANUP_DISABLE ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ /* Update the node and stream resource status */ ++ /* Return PID instead of process handle */ ++ hProcess = current->pid; ++ ++ res_status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT); ++ if (DSP_FAILED(res_status)) ++ goto func_end; ++ ++ DRV_GetProcContext(hProcess, (struct DRV_OBJECT *)hDrvObject, ++ &pCtxt, NULL, 0); ++ if (pCtxt != NULL) { ++ if (DRV_GetSTRMResElement(hStrm, &hSTRMRes, pCtxt) != ++ DSP_ENOTFOUND) { ++ DRV_ProcRemoveSTRMResElement(hSTRMRes, pCtxt); ++ } ++ } ++func_end: ++#endif ++ DBC_Ensure(status == DSP_SOK || status == DSP_EHANDLE || ++ status == DSP_EPENDING || status == DSP_EFAIL); ++ ++ return status; ++} ++ ++/* ++ * ======== STRM_Create ======== ++ * Purpose: ++ * Create a STRM manager object. ++ */ ++DSP_STATUS STRM_Create(OUT struct STRM_MGR **phStrmMgr, struct DEV_OBJECT *hDev) ++{ ++ struct STRM_MGR *pStrmMgr; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(phStrmMgr != NULL); ++ DBC_Require(hDev != NULL); ++ ++ GT_2trace(STRM_debugMask, GT_ENTER, "STRM_Create: phStrmMgr: " ++ "0x%x\thDev: 0x%x\n", phStrmMgr, hDev); ++ *phStrmMgr = NULL; ++ /* Allocate STRM manager object */ ++ MEM_AllocObject(pStrmMgr, struct STRM_MGR, STRMMGR_SIGNATURE); ++ if (pStrmMgr == NULL) { ++ status = DSP_EMEMORY; ++ GT_0trace(STRM_debugMask, GT_6CLASS, "STRM_Create: " ++ "MEM_AllocObject() failed!\n "); ++ } else { ++ pStrmMgr->hDev = hDev; ++ } ++ /* Get Channel manager and WMD function interface */ ++ if (DSP_SUCCEEDED(status)) { ++ status = DEV_GetChnlMgr(hDev, &(pStrmMgr->hChnlMgr)); ++ if (DSP_SUCCEEDED(status)) { ++ (void) DEV_GetIntfFxns(hDev, &(pStrmMgr->pIntfFxns)); ++ DBC_Assert(pStrmMgr->pIntfFxns != NULL); ++ } else { ++ GT_1trace(STRM_debugMask, GT_6CLASS, "STRM_Create: " ++ "Failed to get channel manager! status = " ++ "0x%x\n", status); ++ } ++ } ++ if (DSP_SUCCEEDED(status)) ++ status = SYNC_InitializeCS(&pStrmMgr->hSync); ++ ++ if (DSP_SUCCEEDED(status)) ++ *phStrmMgr = pStrmMgr; ++ else ++ DeleteStrmMgr(pStrmMgr); ++ ++ DBC_Ensure(DSP_SUCCEEDED(status) && ++ (MEM_IsValidHandle((*phStrmMgr), STRMMGR_SIGNATURE) || ++ (DSP_FAILED(status) && *phStrmMgr == NULL))); ++ ++ return status; ++} ++ ++/* ++ * ======== STRM_Delete ======== ++ * Purpose: ++ * Delete the STRM Manager Object. ++ */ ++void STRM_Delete(struct STRM_MGR *hStrmMgr) ++{ ++ DBC_Require(cRefs > 0); ++ DBC_Require(MEM_IsValidHandle(hStrmMgr, STRMMGR_SIGNATURE)); ++ ++ GT_1trace(STRM_debugMask, GT_ENTER, "STRM_Delete: hStrmMgr: 0x%x\n", ++ hStrmMgr); ++ ++ DeleteStrmMgr(hStrmMgr); ++ ++ DBC_Ensure(!MEM_IsValidHandle(hStrmMgr, STRMMGR_SIGNATURE)); ++} ++ ++/* ++ * ======== STRM_Exit ======== ++ * Purpose: ++ * Discontinue usage of STRM module. ++ */ ++void STRM_Exit(void) ++{ ++ DBC_Require(cRefs > 0); ++ ++ cRefs--; ++ ++ GT_1trace(STRM_debugMask, GT_5CLASS, ++ "Entered STRM_Exit, ref count: 0x%x\n", cRefs); ++ ++ DBC_Ensure(cRefs >= 0); ++} ++ ++/* ++ * ======== STRM_FreeBuffer ======== ++ * Purpose: ++ * Frees the buffers allocated for a stream. ++ */ ++DSP_STATUS STRM_FreeBuffer(struct STRM_OBJECT *hStrm, u8 **apBuffer, ++ u32 uNumBufs) ++{ ++ DSP_STATUS status = DSP_SOK; ++ u32 i = 0; ++ ++ #ifndef RES_CLEANUP_DISABLE ++ DSP_STATUS res_status = DSP_SOK; ++ u32 hProcess; ++ HANDLE pCtxt = NULL; ++ HANDLE hDrvObject; ++ HANDLE hSTRMRes = NULL; ++ #endif ++ DBC_Require(cRefs > 0); ++ DBC_Require(apBuffer != NULL); ++ ++ GT_3trace(STRM_debugMask, GT_ENTER, "STRM_FreeBuffer: hStrm: 0x%x\t" ++ "apBuffer: 0x%x\tuNumBufs: 0x%x\n", hStrm, apBuffer, uNumBufs); ++ ++ if (!MEM_IsValidHandle(hStrm, STRM_SIGNATURE)) ++ status = DSP_EHANDLE; ++ ++ if (DSP_SUCCEEDED(status)) { ++ for (i = 0; i < uNumBufs; i++) { ++ DBC_Assert(hStrm->hXlator != NULL); ++ status = CMM_XlatorFreeBuf(hStrm->hXlator, apBuffer[i]); ++ if (DSP_FAILED(status)) { ++ GT_0trace(STRM_debugMask, GT_7CLASS, ++ "STRM_FreeBuffer: DSP_FAILED" ++ " to free shared memory.\n"); ++ break; ++ } ++ apBuffer[i] = NULL; ++ } ++ } ++#ifndef RES_CLEANUP_DISABLE ++ /* Update the node and stream resource status */ ++ /* Return PID instead of process handle */ ++ hProcess = current->pid; ++ ++ res_status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT); ++ if (DSP_SUCCEEDED(res_status)) { ++ DRV_GetProcContext(hProcess, ++ (struct DRV_OBJECT *)hDrvObject, &pCtxt, ++ NULL, 0); ++ if (pCtxt != NULL) { ++ if (DRV_GetSTRMResElement(hStrm, hSTRMRes, pCtxt) != ++ DSP_ENOTFOUND) { ++ DRV_ProcUpdateSTRMRes(uNumBufs-i, hSTRMRes, ++ pCtxt); ++ } ++ } ++ } ++#endif ++ return status; ++} ++ ++/* ++ * ======== STRM_GetInfo ======== ++ * Purpose: ++ * Retrieves information about a stream. ++ */ ++DSP_STATUS STRM_GetInfo(struct STRM_OBJECT *hStrm, ++ OUT struct STRM_INFO *pStreamInfo, ++ u32 uStreamInfoSize) ++{ ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ struct CHNL_INFO chnlInfo; ++ DSP_STATUS status = DSP_SOK; ++ void *pVirtBase = NULL; /* NULL if no SM used */ ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pStreamInfo != NULL); ++ DBC_Require(uStreamInfoSize >= sizeof(struct STRM_INFO)); ++ ++ GT_3trace(STRM_debugMask, GT_ENTER, "STRM_GetInfo: hStrm: 0x%x\t" ++ "pStreamInfo: 0x%x\tuStreamInfoSize: 0x%x\n", hStrm, ++ pStreamInfo, uStreamInfoSize); ++ if (!MEM_IsValidHandle(hStrm, STRM_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ } else { ++ if (uStreamInfoSize < sizeof(struct STRM_INFO)) { ++ /* size of users info */ ++ status = DSP_ESIZE; ++ } ++ } ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ pIntfFxns = hStrm->hStrmMgr->pIntfFxns; ++ status = (*pIntfFxns->pfnChnlGetInfo) (hStrm->hChnl, &chnlInfo); ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ if (hStrm->hXlator) { ++ /* We have a translator */ ++ DBC_Assert(hStrm->uSegment > 0); ++ CMM_XlatorInfo(hStrm->hXlator, (u8 **)&pVirtBase, 0, ++ hStrm->uSegment, false); ++ } ++ pStreamInfo->uSegment = hStrm->uSegment; ++ pStreamInfo->lMode = hStrm->lMode; ++ pStreamInfo->pVirtBase = pVirtBase; ++ pStreamInfo->pUser->uNumberBufsAllowed = hStrm->uNumBufs; ++ pStreamInfo->pUser->uNumberBufsInStream = chnlInfo.cIOCs + ++ chnlInfo.cIOReqs; ++ /* # of bytes transferred since last call to DSPStream_Idle() */ ++ pStreamInfo->pUser->ulNumberBytes = chnlInfo.cPosition; ++ pStreamInfo->pUser->hSyncObjectHandle = chnlInfo.hEvent; ++ /* Determine stream state based on channel state and info */ ++ if (chnlInfo.dwState & CHNL_STATEEOS) { ++ pStreamInfo->pUser->ssStreamState = STREAM_DONE; ++ } else { ++ if (chnlInfo.cIOCs > 0) ++ pStreamInfo->pUser->ssStreamState = STREAM_READY; ++ else if (chnlInfo.cIOReqs > 0) ++ pStreamInfo->pUser->ssStreamState = STREAM_PENDING; ++ else ++ pStreamInfo->pUser->ssStreamState = STREAM_IDLE; ++ ++ } ++func_end: ++ return status; ++} ++ ++/* ++ * ======== STRM_Idle ======== ++ * Purpose: ++ * Idles a particular stream. ++ */ ++DSP_STATUS STRM_Idle(struct STRM_OBJECT *hStrm, bool fFlush) ++{ ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ ++ GT_2trace(STRM_debugMask, GT_ENTER, "STRM_Idle: hStrm: 0x%x\t" ++ "fFlush: 0x%x\n", hStrm, fFlush); ++ ++ if (!MEM_IsValidHandle(hStrm, STRM_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ } else { ++ pIntfFxns = hStrm->hStrmMgr->pIntfFxns; ++ ++ status = (*pIntfFxns->pfnChnlIdle) (hStrm->hChnl, ++ hStrm->uTimeout, fFlush); ++ } ++ return status; ++} ++ ++/* ++ * ======== STRM_Init ======== ++ * Purpose: ++ * Initialize the STRM module. ++ */ ++bool STRM_Init(void) ++{ ++ bool fRetVal = true; ++ ++ DBC_Require(cRefs >= 0); ++ ++ if (cRefs == 0) { ++#if GT_TRACE ++ DBC_Assert(!STRM_debugMask.flags); ++ GT_create(&STRM_debugMask, "ST"); /* "ST" for STrm */ ++#endif ++ } ++ ++ if (fRetVal) ++ cRefs++; ++ ++ GT_1trace(STRM_debugMask, GT_5CLASS, "STRM_Init(), ref count: 0x%x\n", ++ cRefs); ++ ++ DBC_Ensure((fRetVal && (cRefs > 0)) || (!fRetVal && (cRefs >= 0))); ++ ++ return fRetVal; ++} ++ ++/* ++ * ======== STRM_Issue ======== ++ * Purpose: ++ * Issues a buffer on a stream ++ */ ++DSP_STATUS STRM_Issue(struct STRM_OBJECT *hStrm, IN u8 *pBuf, u32 ulBytes, ++ u32 ulBufSize, u32 dwArg) ++{ ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ DSP_STATUS status = DSP_SOK; ++ void *pTmpBuf = NULL; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pBuf != NULL); ++ ++ GT_4trace(STRM_debugMask, GT_ENTER, "STRM_Issue: hStrm: 0x%x\tpBuf: " ++ "0x%x\tulBytes: 0x%x\tdwArg: 0x%x\n", hStrm, pBuf, ulBytes, ++ dwArg); ++ if (!MEM_IsValidHandle(hStrm, STRM_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ } else { ++ pIntfFxns = hStrm->hStrmMgr->pIntfFxns; ++ ++ if (hStrm->uSegment != 0) { ++ pTmpBuf = CMM_XlatorTranslate(hStrm->hXlator, ++ (void *)pBuf, CMM_VA2DSPPA); ++ if (pTmpBuf == NULL) ++ status = DSP_ETRANSLATE; ++ ++ } ++ if (DSP_SUCCEEDED(status)) { ++ status = (*pIntfFxns->pfnChnlAddIOReq) ++ (hStrm->hChnl, pBuf, ulBytes, ulBufSize, ++ (u32) pTmpBuf, dwArg); ++ } ++ if (DSP_FAILED(status)) { ++ if (status == CHNL_E_NOIORPS) ++ status = DSP_ESTREAMFULL; ++ else ++ status = DSP_EFAIL; ++ ++ } ++ } ++ return status; ++} ++ ++/* ++ * ======== STRM_Open ======== ++ * Purpose: ++ * Open a stream for sending/receiving data buffers to/from a task or ++ * XDAIS socket node on the DSP. ++ */ ++DSP_STATUS STRM_Open(struct NODE_OBJECT *hNode, u32 uDir, u32 uIndex, ++ IN struct STRM_ATTR *pAttr, OUT struct STRM_OBJECT **phStrm) ++{ ++ struct STRM_MGR *hStrmMgr; ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ u32 ulChnlId; ++ struct STRM_OBJECT *pStrm = NULL; ++ CHNL_MODE uMode; ++ struct CHNL_ATTRS chnlAttrs; ++ DSP_STATUS status = DSP_SOK; ++ struct CMM_OBJECT *hCmmMgr = NULL; /* Shared memory manager hndl */ ++ ++ #ifndef RES_CLEANUP_DISABLE ++ DSP_STATUS res_status = DSP_SOK; ++ u32 hProcess; ++ HANDLE pCtxt = NULL; ++ HANDLE hDrvObject; ++ HANDLE hSTRMRes; ++ #endif ++ DBC_Require(cRefs > 0); ++ DBC_Require(phStrm != NULL); ++ DBC_Require(pAttr != NULL); ++ GT_5trace(STRM_debugMask, GT_ENTER, ++ "STRM_Open: hNode: 0x%x\tuDir: 0x%x\t" ++ "uIndex: 0x%x\tpAttr: 0x%x\tphStrm: 0x%x\n", ++ hNode, uDir, uIndex, pAttr, phStrm); ++ *phStrm = NULL; ++ if (uDir != DSP_TONODE && uDir != DSP_FROMNODE) { ++ status = DSP_EDIRECTION; ++ } else { ++ /* Get the channel id from the node (set in NODE_Connect()) */ ++ status = NODE_GetChannelId(hNode, uDir, uIndex, &ulChnlId); ++ } ++ if (DSP_SUCCEEDED(status)) ++ status = NODE_GetStrmMgr(hNode, &hStrmMgr); ++ ++ if (DSP_SUCCEEDED(status)) { ++ MEM_AllocObject(pStrm, struct STRM_OBJECT, STRM_SIGNATURE); ++ if (pStrm == NULL) { ++ status = DSP_EMEMORY; ++ GT_0trace(STRM_debugMask, GT_6CLASS, ++ "STRM_Open: MEM_AllocObject() failed!\n "); ++ } else { ++ pStrm->hStrmMgr = hStrmMgr; ++ pStrm->uDir = uDir; ++ pStrm->strmState = STREAM_IDLE; ++ pStrm->hUserEvent = pAttr->hUserEvent; ++ if (pAttr->pStreamAttrIn != NULL) { ++ pStrm->uTimeout = pAttr->pStreamAttrIn-> ++ uTimeout; ++ pStrm->uNumBufs = pAttr->pStreamAttrIn-> ++ uNumBufs; ++ pStrm->lMode = pAttr->pStreamAttrIn->lMode; ++ pStrm->uSegment = pAttr->pStreamAttrIn-> ++ uSegment; ++ pStrm->uAlignment = pAttr->pStreamAttrIn-> ++ uAlignment; ++ pStrm->uDMAChnlId = pAttr->pStreamAttrIn-> ++ uDMAChnlId; ++ pStrm->uDMAPriority = pAttr->pStreamAttrIn-> ++ uDMAPriority; ++ chnlAttrs.uIOReqs = pAttr->pStreamAttrIn-> ++ uNumBufs; ++ } else { ++ pStrm->uTimeout = DEFAULTTIMEOUT; ++ pStrm->uNumBufs = DEFAULTNUMBUFS; ++ pStrm->lMode = STRMMODE_PROCCOPY; ++ pStrm->uSegment = 0; /* local memory */ ++ pStrm->uAlignment = 0; ++ pStrm->uDMAChnlId = 0; ++ pStrm->uDMAPriority = 0; ++ chnlAttrs.uIOReqs = DEFAULTNUMBUFS; ++ } ++ chnlAttrs.hReserved1 = NULL; ++ /* DMA chnl flush timeout */ ++ chnlAttrs.hReserved2 = pStrm->uTimeout; ++ chnlAttrs.hEvent = NULL; ++ if (pAttr->hUserEvent != NULL) ++ chnlAttrs.hEvent = pAttr->hUserEvent; ++ ++ } ++ } ++ if (DSP_FAILED(status)) ++ goto func_cont; ++ ++ if ((pAttr->pVirtBase == NULL) || !(pAttr->ulVirtSize > 0)) ++ goto func_cont; ++ ++ DBC_Assert(pStrm->lMode != STRMMODE_LDMA); /* no System DMA */ ++ /* Get the shared mem mgr for this streams dev object */ ++ status = DEV_GetCmmMgr(hStrmMgr->hDev, &hCmmMgr); ++ if (DSP_FAILED(status)) { ++ GT_1trace(STRM_debugMask, GT_6CLASS, "STRM_Open: Failed to get " ++ "CMM Mgr handle: 0x%x\n", status); ++ } else { ++ /*Allocate a SM addr translator for this strm.*/ ++ status = CMM_XlatorCreate(&pStrm->hXlator, hCmmMgr, NULL); ++ if (DSP_FAILED(status)) { ++ GT_1trace(STRM_debugMask, GT_6CLASS, ++ "STRM_Open: Failed to " ++ "create SM translator: 0x%x\n", status); ++ } else { ++ DBC_Assert(pStrm->uSegment > 0); ++ /* Set translators Virt Addr attributes */ ++ status = CMM_XlatorInfo(pStrm->hXlator, ++ (u8 **)&pAttr->pVirtBase, pAttr->ulVirtSize, ++ pStrm->uSegment, true); ++ if (status != DSP_SOK) { ++ GT_0trace(STRM_debugMask, GT_6CLASS, ++ "STRM_Open: ERROR: " ++ "in setting CMM_XlatorInfo.\n"); ++ } ++ } ++ } ++func_cont: ++ if (DSP_SUCCEEDED(status)) { ++ /* Open channel */ ++ uMode = (uDir == DSP_TONODE) ? ++ CHNL_MODETODSP : CHNL_MODEFROMDSP; ++ pIntfFxns = hStrmMgr->pIntfFxns; ++ status = (*pIntfFxns->pfnChnlOpen) (&(pStrm->hChnl), ++ hStrmMgr->hChnlMgr, uMode, ulChnlId, &chnlAttrs); ++ if (DSP_FAILED(status)) { ++ /* ++ * over-ride non-returnable status codes so we return ++ * something documented ++ */ ++ if (status != DSP_EMEMORY && status != ++ DSP_EINVALIDARG && status != DSP_EFAIL) { ++ /* ++ * We got a status that's not return-able. ++ * Assert that we got something we were ++ * expecting (DSP_EHANDLE isn't acceptable, ++ * hStrmMgr->hChnlMgr better be valid or we ++ * assert here), and then return DSP_EFAIL. ++ */ ++ DBC_Assert(status == CHNL_E_OUTOFSTREAMS || ++ status == CHNL_E_BADCHANID || ++ status == CHNL_E_CHANBUSY || ++ status == CHNL_E_NOIORPS); ++ status = DSP_EFAIL; ++ } ++ GT_2trace(STRM_debugMask, GT_6CLASS, ++ "STRM_Open: Channel open failed, " ++ "chnl id = %d, status = 0x%x\n", ulChnlId, ++ status); ++ } ++ } ++ if (DSP_SUCCEEDED(status)) ++ *phStrm = pStrm; ++ else ++ (void)DeleteStrm(pStrm); ++ ++#ifndef RES_CLEANUP_DISABLE ++ /* Return PID instead of process handle */ ++ hProcess = current->pid; ++ ++ res_status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT); ++ if (DSP_SUCCEEDED(res_status)) { ++ DRV_GetProcContext(hProcess, ++ (struct DRV_OBJECT *)hDrvObject, &pCtxt, ++ hNode, 0); ++ if (pCtxt != NULL) ++ DRV_ProcInsertSTRMResElement(*phStrm, &hSTRMRes, pCtxt); ++ ++ } ++#endif ++ ++ /* ensure we return a documented error code */ ++ DBC_Ensure((DSP_SUCCEEDED(status) && ++ MEM_IsValidHandle((*phStrm), STRM_SIGNATURE)) || ++ (*phStrm == NULL && (status == DSP_EHANDLE || ++ status == DSP_EDIRECTION || status == DSP_EVALUE || ++ status == DSP_EFAIL))); ++ return status; ++} ++ ++/* ++ * ======== STRM_Reclaim ======== ++ * Purpose: ++ * Relcaims a buffer from a stream. ++ */ ++DSP_STATUS STRM_Reclaim(struct STRM_OBJECT *hStrm, OUT u8 **pBufPtr, ++ u32 *pulBytes, u32 *pulBufSize, u32 *pdwArg) ++{ ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ struct CHNL_IOC chnlIOC; ++ DSP_STATUS status = DSP_SOK; ++ void *pTmpBuf = NULL; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pBufPtr != NULL); ++ DBC_Require(pulBytes != NULL); ++ DBC_Require(pdwArg != NULL); ++ ++ GT_4trace(STRM_debugMask, GT_ENTER, ++ "STRM_Reclaim: hStrm: 0x%x\tpBufPtr: 0x%x" ++ "\tpulBytes: 0x%x\tpdwArg: 0x%x\n", hStrm, pBufPtr, pulBytes, ++ pdwArg); ++ ++ if (!MEM_IsValidHandle(hStrm, STRM_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ goto func_end; ++ } ++ pIntfFxns = hStrm->hStrmMgr->pIntfFxns; ++ ++ status = (*pIntfFxns->pfnChnlGetIOC)(hStrm->hChnl, hStrm->uTimeout, ++ &chnlIOC); ++ if (DSP_FAILED(status)) { ++ GT_1trace(STRM_debugMask, GT_6CLASS, ++ "STRM_Reclaim: GetIOC failed! " ++ "Status = 0x%x\n", status); ++ } else { ++ *pulBytes = chnlIOC.cBytes; ++ if (pulBufSize) ++ *pulBufSize = chnlIOC.cBufSize; ++ ++ *pdwArg = chnlIOC.dwArg; ++ if (!CHNL_IsIOComplete(chnlIOC)) { ++ if (CHNL_IsTimedOut(chnlIOC)) { ++ status = DSP_ETIMEOUT; ++ } else { ++ /* Allow reclaims after idle to succeed */ ++ if (!CHNL_IsIOCancelled(chnlIOC)) ++ status = DSP_EFAIL; ++ ++ } ++ } ++ /* Translate zerocopy buffer if channel not canceled. */ ++ if (DSP_SUCCEEDED(status) && (!CHNL_IsIOCancelled(chnlIOC)) && ++ (hStrm->lMode == STRMMODE_ZEROCOPY)) { ++ /* ++ * This is a zero-copy channel so chnlIOC.pBuf ++ * contains the DSP address of SM. We need to ++ * translate it to a virtual address for the user ++ * thread to access. ++ * Note: Could add CMM_DSPPA2VA to CMM in the future. ++ */ ++ pTmpBuf = CMM_XlatorTranslate(hStrm->hXlator, ++ chnlIOC.pBuf, CMM_DSPPA2PA); ++ if (pTmpBuf != NULL) { ++ /* now convert this GPP Pa to Va */ ++ pTmpBuf = CMM_XlatorTranslate(hStrm->hXlator, ++ pTmpBuf, CMM_PA2VA); ++ } ++ if (pTmpBuf == NULL) { ++ GT_0trace(STRM_debugMask, GT_7CLASS, ++ "STRM_Reclaim: Failed " ++ "SM translation!\n"); ++ status = DSP_ETRANSLATE; ++ } ++ chnlIOC.pBuf = pTmpBuf; ++ } ++ *pBufPtr = chnlIOC.pBuf; ++ } ++func_end: ++ /* ensure we return a documented return code */ ++ DBC_Ensure(DSP_SUCCEEDED(status) || status == DSP_EHANDLE || ++ status == DSP_ETIMEOUT || status == DSP_ETRANSLATE || ++ status == DSP_EFAIL); ++ return status; ++} ++ ++/* ++ * ======== STRM_RegisterNotify ======== ++ * Purpose: ++ * Register to be notified on specific events for this stream. ++ */ ++DSP_STATUS STRM_RegisterNotify(struct STRM_OBJECT *hStrm, u32 uEventMask, ++ u32 uNotifyType, struct DSP_NOTIFICATION ++ *hNotification) ++{ ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(hNotification != NULL); ++ ++ GT_4trace(STRM_debugMask, GT_ENTER, ++ "STRM_RegisterNotify: hStrm: 0x%x\t" ++ "uEventMask: 0x%x\tuNotifyType: 0x%x\thNotification: 0x%x\n", ++ hStrm, uEventMask, uNotifyType, hNotification); ++ if (!MEM_IsValidHandle(hStrm, STRM_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ } else if ((uEventMask & ~((DSP_STREAMIOCOMPLETION) | ++ DSP_STREAMDONE)) != 0) { ++ status = DSP_EVALUE; ++ } else { ++ if (uNotifyType != DSP_SIGNALEVENT) ++ status = DSP_ENOTIMPL; ++ ++ } ++ if (DSP_SUCCEEDED(status)) { ++ pIntfFxns = hStrm->hStrmMgr->pIntfFxns; ++ ++ status = (*pIntfFxns->pfnChnlRegisterNotify)(hStrm->hChnl, ++ uEventMask, uNotifyType, hNotification); ++ } ++ /* ensure we return a documented return code */ ++ DBC_Ensure(DSP_SUCCEEDED(status) || status == DSP_EHANDLE || ++ status == DSP_ETIMEOUT || status == DSP_ETRANSLATE || ++ status == DSP_ENOTIMPL || status == DSP_EFAIL); ++ return status; ++} ++ ++/* ++ * ======== STRM_Select ======== ++ * Purpose: ++ * Selects a ready stream. ++ */ ++DSP_STATUS STRM_Select(IN struct STRM_OBJECT **aStrmTab, u32 nStrms, ++ OUT u32 *pMask, u32 uTimeout) ++{ ++ u32 uIndex; ++ struct CHNL_INFO chnlInfo; ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ struct SYNC_OBJECT **hSyncEvents = NULL; ++ u32 i; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(cRefs > 0); ++ DBC_Require(aStrmTab != NULL); ++ DBC_Require(pMask != NULL); ++ DBC_Require(nStrms > 0); ++ ++ GT_4trace(STRM_debugMask, GT_ENTER, ++ "STRM_Select: aStrmTab: 0x%x \tnStrms: " ++ "0x%x\tpMask: 0x%x\tuTimeout: 0x%x\n", aStrmTab, ++ nStrms, pMask, uTimeout); ++ *pMask = 0; ++ for (i = 0; i < nStrms; i++) { ++ if (!MEM_IsValidHandle(aStrmTab[i], STRM_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ break; ++ } ++ } ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ /* Determine which channels have IO ready */ ++ for (i = 0; i < nStrms; i++) { ++ pIntfFxns = aStrmTab[i]->hStrmMgr->pIntfFxns; ++ status = (*pIntfFxns->pfnChnlGetInfo)(aStrmTab[i]->hChnl, ++ &chnlInfo); ++ if (DSP_FAILED(status)) { ++ break; ++ } else { ++ if (chnlInfo.cIOCs > 0) ++ *pMask |= (1 << i); ++ ++ } ++ } ++ if (DSP_SUCCEEDED(status) && uTimeout > 0 && *pMask == 0) { ++ /* Non-zero timeout */ ++ hSyncEvents = (struct SYNC_OBJECT **)MEM_Alloc(nStrms * ++ sizeof(struct SYNC_OBJECT *), MEM_PAGED); ++ if (hSyncEvents == NULL) { ++ status = DSP_EMEMORY; ++ } else { ++ for (i = 0; i < nStrms; i++) { ++ pIntfFxns = aStrmTab[i]->hStrmMgr->pIntfFxns; ++ status = (*pIntfFxns->pfnChnlGetInfo) ++ (aStrmTab[i]->hChnl, &chnlInfo); ++ if (DSP_FAILED(status)) ++ break; ++ else ++ hSyncEvents[i] = chnlInfo.hSyncEvent; ++ ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ status = SYNC_WaitOnMultipleEvents(hSyncEvents, nStrms, ++ uTimeout, &uIndex); ++ if (DSP_SUCCEEDED(status)) { ++ /* Since we waited on the event, we have to ++ * reset it */ ++ SYNC_SetEvent(hSyncEvents[uIndex]); ++ *pMask = 1 << uIndex; ++ } ++ } ++ } ++func_end: ++ if (hSyncEvents) ++ MEM_Free(hSyncEvents); ++ ++ DBC_Ensure((DSP_SUCCEEDED(status) && (*pMask != 0 || uTimeout == 0)) || ++ (DSP_FAILED(status) && *pMask == 0)); ++ ++ return status; ++} ++ ++/* ++ * ======== DeleteStrm ======== ++ * Purpose: ++ * Frees the resources allocated for a stream. ++ */ ++static DSP_STATUS DeleteStrm(struct STRM_OBJECT *hStrm) ++{ ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ DSP_STATUS status = DSP_SOK; ++ ++ if (MEM_IsValidHandle(hStrm, STRM_SIGNATURE)) { ++ if (hStrm->hChnl) { ++ pIntfFxns = hStrm->hStrmMgr->pIntfFxns; ++ /* Channel close can fail only if the channel handle ++ * is invalid. */ ++ status = (*pIntfFxns->pfnChnlClose) (hStrm->hChnl); ++ /* Free all SM address translator resources */ ++ if (DSP_SUCCEEDED(status)) { ++ if (hStrm->hXlator) { ++ /* force free */ ++ (void)CMM_XlatorDelete(hStrm->hXlator, ++ true); ++ } ++ } ++ } ++ MEM_FreeObject(hStrm); ++ } else { ++ status = DSP_EHANDLE; ++ } ++ return status; ++} ++ ++/* ++ * ======== DeleteStrmMgr ======== ++ * Purpose: ++ * Frees stream manager. ++ */ ++static void DeleteStrmMgr(struct STRM_MGR *hStrmMgr) ++{ ++ if (MEM_IsValidHandle(hStrmMgr, STRMMGR_SIGNATURE)) { ++ ++ if (hStrmMgr->hSync) ++ SYNC_DeleteCS(hStrmMgr->hSync); ++ ++ MEM_FreeObject(hStrmMgr); ++ } ++} ++ +diff --git a/drivers/dsp/bridge/services/cfg.c b/drivers/dsp/bridge/services/cfg.c +new file mode 100644 +index 0000000..67656bf +--- /dev/null ++++ b/drivers/dsp/bridge/services/cfg.c +@@ -0,0 +1,483 @@ ++/* ++ * cfg.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== cfgce.c ======== ++ * Purpose: ++ * Implementation of platform specific config services. ++ * ++ * Private Functions: ++ * CFG_Exit ++ * CFG_GetAutoStart ++ * CFG_GetDevObject ++ * CFG_GetDSPResources ++ * CFG_GetExecFile ++ * CFG_GetHostResources ++ * CFG_GetObject ++ * CFG_Init ++ * CFG_SetDevObject ++ * CFG_SetObject ++ * ++ * ++ *! Revision History: ++ *! ================ ++ *! 26-Arp-2004 hp Support for handling more than one Device. ++ *! 26-Feb-2003 kc Removed unused CFG fxns. ++ *! 10-Nov-2000 rr: CFG_GetBoardName local var initialized. ++ *! 30-Oct-2000 kc: Changed local var. names to use Hungarian notation. ++ *! 10-Aug-2000 rr: Cosmetic changes. ++ *! 26-Jul-2000 rr: Added CFG_GetDCDName. CFG_Get/SetObject(based on a flag) ++ *! replaces CFG_GetMgrObject & CFG_SetMgrObject. ++ *! 17-Jul-2000 rr: Added CFG_GetMgrObject & CFG_SetMgrObject. ++ *! 03-Feb-2000 rr: Module init/exit is handled by SERVICES Init/Exit. ++ *! GT Changes. ++ *! 31-Jan-2000 rr: Comments and bugfixes: modified after code review ++ *! 07-Jan-2000 rr: CFG_GetBoardName Ensure class checks strlen of the ++ *! read value from the registry against the passed in BufSize; ++ *! CFG_GetZLFile,CFG_GetWMDFileName and ++ *! CFG_GetExecFile also modified same way. ++ *! 06-Jan-2000 rr: CFG_GetSearchPath & CFG_GetWinBRIDGEDir removed. ++ *! 09-Dec-1999 rr: CFG_SetDevObject stores the DevNodeString pointer. ++ *! 03-Dec-1999 rr: CFG_GetDevObject reads stored DevObject from Registry. ++ *! CFG_GetDevNode reads the Devnodestring from the registry. ++ *! CFG_SetDevObject stores the registry path as ++ *! DevNodestring in the registry. ++ *! 02-Dec-1999 rr: CFG_debugMask is declared static now. stdwin.h included ++ *! 22-Nov-1999 kc: Added windows.h to remove warnings. ++ *! 25-Oct-1999 rr: CFG_GetHostResources reads the HostResource structure ++ *! from the registry which was set by the DRV Request ++ *! Resources. ++ *! 15-Oct-1999 rr: Changes in CFG_SetPrivateDword & HostResources reflecting ++ *! changes for drv.h resource structure and wsxreg.h new ++ *! entry(DevObject) Hard coded entries removed for those items ++ *! 08-Oct-1999 rr: CFG_SetPrivateDword modified. it sets devobject into the ++ *! registry. CFG_Get HostResources modified for opening up ++ *! two mem winodws. ++ *! 24-Sep-1999 rr: CFG_GetHostResources uses hardcoded Registry calls,uses NT ++ *! type of Resource Structure. ++ *! 19-Jul-1999 a0216266: Stubbed from cfgnt.c. ++ */ ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++ ++/* ----------------------------------- Others */ ++#include ++ ++/* ----------------------------------- This */ ++#include ++#include ++ ++struct DRV_EXT { ++ struct LST_ELEM link; ++ char szString[MAXREGPATHLENGTH]; ++}; ++ ++/* ----------------------------------- Globals */ ++#if GT_TRACE ++static struct GT_Mask CFG_debugMask = { NULL, NULL }; /* CFG debug Mask */ ++#endif ++ ++/* ++ * ======== CFG_Exit ======== ++ * Purpose: ++ * Discontinue usage of the CFG module. ++ */ ++void CFG_Exit(void) ++{ ++ GT_0trace(CFG_debugMask, GT_5CLASS, "Entered CFG_Exit\n"); ++} ++ ++/* ++ * ======== CFG_GetAutoStart ======== ++ * Purpose: ++ * Retreive the autostart mask, if any, for this board. ++ */ ++DSP_STATUS CFG_GetAutoStart(struct CFG_DEVNODE *hDevNode, ++ OUT u32 *pdwAutoStart) ++{ ++ DSP_STATUS status = DSP_SOK; ++ u32 dwBufSize; ++ GT_2trace(CFG_debugMask, GT_ENTER, ++ "Entered CFG_GetAutoStart: \n\thDevNode:" ++ "0x%x\n\tpdwAutoStart: 0x%x\n", hDevNode, pdwAutoStart); ++ dwBufSize = sizeof(*pdwAutoStart); ++ if (!hDevNode) ++ status = CFG_E_INVALIDHDEVNODE; ++ if (!pdwAutoStart) ++ status = CFG_E_INVALIDPOINTER; ++ if (DSP_SUCCEEDED(status)) { ++ status = REG_GetValue(NULL, (char *)hDevNode, AUTOSTART, ++ (u8 *)pdwAutoStart, &dwBufSize); ++ if (DSP_FAILED(status)) ++ status = CFG_E_RESOURCENOTAVAIL; ++ } ++#ifdef DEBUG ++ if (DSP_SUCCEEDED(status)) { ++ GT_0trace(CFG_debugMask, GT_1CLASS, ++ "CFG_GetAutoStart SUCCESS \n"); ++ } else { ++ GT_0trace(CFG_debugMask, GT_6CLASS, ++ "CFG_GetAutoStart Failed \n"); ++ } ++#endif ++ DBC_Ensure((status == DSP_SOK && ++ (*pdwAutoStart == 0 || *pdwAutoStart == 1)) ++ || status != DSP_SOK); ++ return status; ++} ++ ++/* ++ * ======== CFG_GetDevObject ======== ++ * Purpose: ++ * Retrieve the Device Object handle for a given devnode. ++ */ ++DSP_STATUS CFG_GetDevObject(struct CFG_DEVNODE *hDevNode, OUT u32 *pdwValue) ++{ ++ DSP_STATUS status = DSP_SOK; ++ u32 dwBufSize; ++ GT_2trace(CFG_debugMask, GT_ENTER, "Entered CFG_GetDevObject, args: " ++ "\n\thDevNode: 0x%x\n\tpdwValue: 0x%x\n", hDevNode, ++ *pdwValue); ++ if (!hDevNode) ++ status = CFG_E_INVALIDHDEVNODE; ++ ++ if (!pdwValue) ++ status = CFG_E_INVALIDHDEVNODE; ++ ++ dwBufSize = sizeof(pdwValue); ++ if (DSP_SUCCEEDED(status)) { ++ ++ /* check the device string and then call the REG_SetValue*/ ++ if (!(strcmp((char *)((struct DRV_EXT *)hDevNode)->szString, ++ "TIOMAP1510"))) { ++ GT_0trace(CFG_debugMask, GT_1CLASS, ++ "Fetching DSP Device from " ++ "Registry \n"); ++ status = REG_GetValue(NULL, (char *)hDevNode, ++ "DEVICE_DSP", ++ (u8 *)pdwValue, &dwBufSize); ++ } else { ++ GT_0trace(CFG_debugMask, GT_6CLASS, ++ "Failed to Identify the Device to Fetch \n"); ++ } ++ } ++#ifdef DEBUG ++ if (DSP_SUCCEEDED(status)) { ++ GT_1trace(CFG_debugMask, GT_1CLASS, ++ "CFG_GetDevObject SUCCESS DevObject" ++ ": 0x%x\n ", *pdwValue); ++ } else { ++ GT_0trace(CFG_debugMask, GT_6CLASS, ++ "CFG_GetDevObject Failed \n"); ++ } ++#endif ++ return status; ++} ++ ++/* ++ * ======== CFG_GetDSPResources ======== ++ * Purpose: ++ * Get the DSP resources available to a given device. ++ */ ++DSP_STATUS CFG_GetDSPResources(struct CFG_DEVNODE *hDevNode, ++ OUT struct CFG_DSPRES *pDSPResTable) ++{ ++ DSP_STATUS status = DSP_SOK; /* return value */ ++ u32 dwResSize; ++ GT_2trace(CFG_debugMask, GT_ENTER, ++ "Entered CFG_GetDSPResources, args: " ++ "\n\thDevNode: 0x%x\n\tpDSPResTable: 0x%x\n", ++ hDevNode, pDSPResTable); ++ if (!hDevNode) { ++ status = CFG_E_INVALIDHDEVNODE; ++ } else if (!pDSPResTable) { ++ status = CFG_E_INVALIDPOINTER; ++ } else { ++ status = REG_GetValue(NULL, CONFIG, DSPRESOURCES, ++ (u8 *)pDSPResTable, ++ &dwResSize); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ GT_0trace(CFG_debugMask, GT_1CLASS, ++ "CFG_GetDSPResources SUCCESS\n"); ++ } else { ++ status = CFG_E_RESOURCENOTAVAIL; ++ GT_0trace(CFG_debugMask, GT_6CLASS, ++ "CFG_GetDSPResources Failed \n"); ++ } ++#ifdef DEBUG ++ /* assert that resource values are reasonable */ ++ DBC_Assert(pDSPResTable->uChipType < 256); ++ DBC_Assert(pDSPResTable->uWordSize > 0); ++ DBC_Assert(pDSPResTable->uWordSize < 32); ++ DBC_Assert(pDSPResTable->cChips > 0); ++ DBC_Assert(pDSPResTable->cChips < 256); ++#endif ++ return status; ++} ++ ++/* ++ * ======== CFG_GetExecFile ======== ++ * Purpose: ++ * Retreive the default executable, if any, for this board. ++ */ ++DSP_STATUS CFG_GetExecFile(struct CFG_DEVNODE *hDevNode, u32 ulBufSize, ++ OUT char *pstrExecFile) ++{ ++ DSP_STATUS status = DSP_SOK; ++ u32 cExecSize = ulBufSize; ++ GT_3trace(CFG_debugMask, GT_ENTER, ++ "Entered CFG_GetExecFile:\n\tthDevNode: " ++ "0x%x\n\tulBufSize: 0x%x\n\tpstrExecFile: 0x%x\n", hDevNode, ++ ulBufSize, pstrExecFile); ++ if (!hDevNode) ++ status = CFG_E_INVALIDHDEVNODE; ++ ++ if (!pstrExecFile) ++ status = CFG_E_INVALIDPOINTER; ++ ++ if (DSP_SUCCEEDED(status)) { ++ status = REG_GetValue(NULL, (char *)hDevNode, DEFEXEC, ++ (u8 *)pstrExecFile, &cExecSize); ++ if (DSP_FAILED(status)) ++ status = CFG_E_RESOURCENOTAVAIL; ++ else if (cExecSize > ulBufSize) ++ status = DSP_ESIZE; ++ ++ } ++#ifdef DEBUG ++ if (DSP_SUCCEEDED(status)) { ++ GT_1trace(CFG_debugMask, GT_1CLASS, ++ "CFG_GetExecFile SUCCESS Exec File" ++ "name : %s\n ", pstrExecFile); ++ } else { ++ GT_0trace(CFG_debugMask, GT_6CLASS, ++ "CFG_GetExecFile Failed \n"); ++ } ++#endif ++ DBC_Ensure(((status == DSP_SOK) && ++ (strlen(pstrExecFile) <= ulBufSize)) || (status != DSP_SOK)); ++ return status; ++} ++ ++/* ++ * ======== CFG_GetHostResources ======== ++ * Purpose: ++ * Get the Host allocated resources assigned to a given device. ++ */ ++DSP_STATUS CFG_GetHostResources(struct CFG_DEVNODE *hDevNode, ++ OUT struct CFG_HOSTRES *pHostResTable) ++{ ++ DSP_STATUS status = DSP_SOK; ++ u32 dwBufSize; ++ GT_2trace(CFG_debugMask, GT_ENTER, ++ "Entered CFG_GetHostResources, args:\n\t" ++ "pHostResTable: 0x%x\n\thDevNode: 0x%x\n", ++ pHostResTable, hDevNode); ++ if (!hDevNode) ++ status = CFG_E_INVALIDHDEVNODE; ++ ++ if (!pHostResTable) ++ status = CFG_E_INVALIDPOINTER; ++ ++ if (DSP_SUCCEEDED(status)) { ++ dwBufSize = sizeof(struct CFG_HOSTRES); ++ if (DSP_FAILED(REG_GetValue(NULL, (char *)hDevNode, ++ CURRENTCONFIG, ++ (u8 *)pHostResTable, &dwBufSize))) { ++ status = CFG_E_RESOURCENOTAVAIL; ++ } ++ } ++#ifdef DEBUG ++ if (DSP_SUCCEEDED(status)) { ++ GT_0trace(CFG_debugMask, GT_1CLASS, ++ "CFG_GetHostResources SUCCESS \n"); ++ } else { ++ GT_0trace(CFG_debugMask, GT_6CLASS, ++ "CFG_GetHostResources Failed \n"); ++ } ++#endif ++ return status; ++} ++ ++/* ++ * ======== CFG_GetObject ======== ++ * Purpose: ++ * Retrieve the Object handle from the Registry ++ */ ++DSP_STATUS CFG_GetObject(OUT u32 *pdwValue, u32 dwType) ++{ ++ DSP_STATUS status = DSP_EINVALIDARG; ++ u32 dwBufSize; ++ DBC_Require(pdwValue != NULL); ++ GT_1trace(CFG_debugMask, GT_ENTER, ++ "Entered CFG_GetObject, args:pdwValue: " ++ "0x%x\n", *pdwValue); ++ dwBufSize = sizeof(pdwValue); ++ switch (dwType) { ++ case (REG_DRV_OBJECT): ++ status = REG_GetValue(NULL, CONFIG, DRVOBJECT, ++ (u8 *)pdwValue, ++ &dwBufSize); ++ break; ++ case (REG_MGR_OBJECT): ++ status = REG_GetValue(NULL, CONFIG, MGROBJECT, ++ (u8 *)pdwValue, ++ &dwBufSize); ++ break; ++ default: ++ break; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ GT_1trace(CFG_debugMask, GT_1CLASS, ++ "CFG_GetObject SUCCESS DrvObject: " ++ "0x%x\n ", *pdwValue); ++ } else { ++ status = CFG_E_RESOURCENOTAVAIL; ++ *pdwValue = 0; ++ GT_0trace(CFG_debugMask, GT_6CLASS, "CFG_GetObject Failed \n"); ++ } ++ DBC_Ensure((DSP_SUCCEEDED(status) && *pdwValue != 0) || ++ (DSP_FAILED(status) && *pdwValue == 0)); ++ return status; ++} ++ ++/* ++ * ======== CFG_Init ======== ++ * Purpose: ++ * Initialize the CFG module's private state. ++ */ ++bool CFG_Init(void) ++{ ++ struct CFG_DSPRES dspResources; ++ GT_create(&CFG_debugMask, "CF"); /* CF for ConFig */ ++ GT_0trace(CFG_debugMask, GT_5CLASS, "Entered CFG_Init\n"); ++ GT_0trace(CFG_debugMask, GT_5CLASS, "Intializing DSP Registry Info \n"); ++ ++ dspResources.uChipType = DSPTYPE_64; ++ dspResources.cChips = 1; ++ dspResources.uWordSize = DSPWORDSIZE; ++ dspResources.cMemTypes = 0; ++ dspResources.aMemDesc[0].uMemType = 0; ++ dspResources.aMemDesc[0].ulMin = 0; ++ dspResources.aMemDesc[0].ulMax = 0; ++ if (DSP_SUCCEEDED(REG_SetValue(NULL, CONFIG, DSPRESOURCES, REG_BINARY, ++ (u8 *)&dspResources, sizeof(struct CFG_DSPRES)))) { ++ GT_0trace(CFG_debugMask, GT_5CLASS, ++ "Initialized DSP resources in " ++ "Registry \n"); ++ } else ++ GT_0trace(CFG_debugMask, GT_5CLASS, ++ "Failed to Initialize DSP resources" ++ " in Registry \n"); ++ return true; ++} ++ ++/* ++ * ======== CFG_SetDevObject ======== ++ * Purpose: ++ * Store the Device Object handle and devNode pointer for a given devnode. ++ */ ++DSP_STATUS CFG_SetDevObject(struct CFG_DEVNODE *hDevNode, u32 dwValue) ++{ ++ DSP_STATUS status = DSP_SOK; ++ u32 dwBuffSize; ++ GT_2trace(CFG_debugMask, GT_ENTER, ++ "Entered CFG_SetDevObject, args: \n\t" ++ "hDevNode: 0x%x\n\tdwValue: 0x%x\n", hDevNode, dwValue); ++ if (!hDevNode) ++ status = CFG_E_INVALIDHDEVNODE; ++ ++ dwBuffSize = sizeof(dwValue); ++ if (DSP_SUCCEEDED(status)) { ++ /* Store the WCD device object in the Registry */ ++ ++ if (!(strcmp((char *)hDevNode, "TIOMAP1510"))) { ++ GT_0trace(CFG_debugMask, GT_1CLASS, ++ "Registering the DSP Device \n"); ++ status = REG_SetValue(NULL, (char *)hDevNode, ++ "DEVICE_DSP", REG_DWORD,\ ++ (u8 *)&dwValue, dwBuffSize); ++ if (DSP_SUCCEEDED(status)) { ++ dwBuffSize = sizeof(hDevNode); ++ status = REG_SetValue(NULL, ++ (char *)hDevNode, "DEVNODESTRING_DSP", ++ REG_DWORD, (u8 *)&hDevNode, ++ dwBuffSize); ++ } ++ } else { ++ GT_0trace(CFG_debugMask, GT_6CLASS, ++ "Failed to Register Device \n"); ++ } ++ } ++#ifdef DEBUG ++ if (DSP_SUCCEEDED(status)) { ++ GT_0trace(CFG_debugMask, GT_1CLASS, ++ "CFG_SetDevObject SUCCESS \n"); ++ } else { ++ GT_0trace(CFG_debugMask, GT_6CLASS, ++ "CFG_SetDevObject Failed \n"); ++ } ++#endif ++ return status; ++} ++ ++/* ++ * ======== CFG_SetObject ======== ++ * Purpose: ++ * Store the Driver Object handle ++ */ ++DSP_STATUS CFG_SetObject(u32 dwValue, u32 dwType) ++{ ++ DSP_STATUS status = DSP_EINVALIDARG; ++ u32 dwBuffSize; ++ GT_1trace(CFG_debugMask, GT_ENTER, ++ "Entered CFG_SetObject, args: dwValue: " ++ "0x%x\n", dwValue); ++ dwBuffSize = sizeof(dwValue); ++ switch (dwType) { ++ case (REG_DRV_OBJECT): ++ status = REG_SetValue(NULL, CONFIG, DRVOBJECT, REG_DWORD, ++ (u8 *)&dwValue, dwBuffSize); ++ break; ++ case (REG_MGR_OBJECT): ++ status = REG_SetValue(NULL, CONFIG, MGROBJECT, REG_DWORD, ++ (u8 *) &dwValue, dwBuffSize); ++ break; ++ default: ++ break; ++ } ++#ifdef DEBUG ++ if (DSP_SUCCEEDED(status)) ++ GT_0trace(CFG_debugMask, GT_1CLASS, "CFG_SetObject SUCCESS \n"); ++ else ++ GT_0trace(CFG_debugMask, GT_6CLASS, "CFG_SetObject Failed \n"); ++ ++#endif ++ return status; ++} +diff --git a/drivers/dsp/bridge/services/clk.c b/drivers/dsp/bridge/services/clk.c +new file mode 100644 +index 0000000..b499b14 +--- /dev/null ++++ b/drivers/dsp/bridge/services/clk.c +@@ -0,0 +1,375 @@ ++/* ++ * clk.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== clk.c ======== ++ * Purpose: ++ * Clock and Timer services. ++ * ++ * Public Functions: ++ * CLK_Exit ++ * CLK_Init ++ * CLK_Enable ++ * CLK_Disable ++ * CLK_GetRate ++ * CLK_Set_32KHz ++ *! Revision History: ++ *! ================ ++ *! 08-May-2007 rg: moved all clock functions from sync module. ++ * And added CLK_Set_32KHz, CLK_Set_SysClk. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++#include ++ ++ ++/* ----------------------------------- Defines, Data Structures, Typedefs */ ++ ++typedef volatile unsigned long REG_UWORD32; ++ ++#define SSI_Base 0x48058000 ++ ++#define SSI_BASE IO_ADDRESS(SSI_Base) ++ ++ ++struct SERVICES_Clk_t { ++ struct clk *clk_handle; ++ const char *clk_name; ++ int id; ++}; ++ ++/* The row order of the below array needs to match with the clock enumerations ++ * 'SERVICES_ClkId' provided in the header file.. any changes in the ++ * enumerations needs to be fixed in the array as well */ ++static struct SERVICES_Clk_t SERVICES_Clks[] = { ++ {NULL, "iva2_ck", -1}, ++ {NULL, "mailboxes_ick", -1}, ++ {NULL, "gpt5_fck", -1}, ++ {NULL, "gpt5_ick", -1}, ++ {NULL, "gpt6_fck", -1}, ++ {NULL, "gpt6_ick", -1}, ++ {NULL, "gpt7_fck", -1}, ++ {NULL, "gpt7_ick", -1}, ++ {NULL, "gpt8_fck", -1}, ++ {NULL, "gpt8_ick", -1}, ++ {NULL, "wdt_fck", 3}, ++ {NULL, "wdt_ick", 3}, ++ {NULL, "mcbsp_fck", 1}, ++ {NULL, "mcbsp_ick", 1}, ++ {NULL, "mcbsp_fck", 2}, ++ {NULL, "mcbsp_ick", 2}, ++ {NULL, "mcbsp_fck", 3}, ++ {NULL, "mcbsp_ick", 3}, ++ {NULL, "mcbsp_fck", 4}, ++ {NULL, "mcbsp_ick", 4}, ++ {NULL, "mcbsp_fck", 5}, ++ {NULL, "mcbsp_ick", 5}, ++ {NULL, "ssi_ssr_sst_fck", -1}, ++ {NULL, "ssi_ick", -1}, ++ {NULL, "omap_32k_fck", -1}, ++ {NULL, "sys_ck", -1}, ++ {NULL, ""} ++}; ++ ++/* Generic TIMER object: */ ++struct TIMER_OBJECT { ++ struct timer_list timer; ++}; ++ ++/* ----------------------------------- Globals */ ++#if GT_TRACE ++static struct GT_Mask CLK_debugMask = { NULL, NULL }; /* GT trace variable */ ++#endif ++ ++/* ++ * ======== CLK_Exit ======== ++ * Purpose: ++ * Cleanup CLK module. ++ */ ++void CLK_Exit(void) ++{ ++ int i = 0; ++ ++ GT_0trace(CLK_debugMask, GT_5CLASS, "CLK_Exit\n"); ++ /* Relinquish the clock handles */ ++ while (i < SERVICESCLK_NOT_DEFINED) { ++ if (SERVICES_Clks[i].clk_handle) ++ clk_put(SERVICES_Clks[i].clk_handle); ++ ++ SERVICES_Clks[i].clk_handle = NULL; ++ i++; ++ } ++ ++} ++ ++/* ++ * ======== CLK_Init ======== ++ * Purpose: ++ * Initialize CLK module. ++ */ ++bool CLK_Init(void) ++{ ++ static struct platform_device dspbridge_device; ++ struct clk *clk_handle; ++ int i = 0; ++ GT_create(&CLK_debugMask, "CK"); /* CK for CLK */ ++ GT_0trace(CLK_debugMask, GT_5CLASS, "CLK_Init\n"); ++ ++ dspbridge_device.dev.bus = &platform_bus_type; ++ ++ /* Get the clock handles from base port and store locally */ ++ while (i < SERVICESCLK_NOT_DEFINED) { ++ /* get the handle from BP */ ++ dspbridge_device.id = SERVICES_Clks[i].id; ++ ++ clk_handle = clk_get(&dspbridge_device.dev, ++ SERVICES_Clks[i].clk_name); ++ ++ if (!clk_handle) { ++ GT_2trace(CLK_debugMask, GT_7CLASS, ++ "CLK_Init: failed to get Clk handle %s, " ++ "CLK dev id = %d\n", ++ SERVICES_Clks[i].clk_name, ++ SERVICES_Clks[i].id); ++ /* should we fail here?? */ ++ } else { ++ GT_2trace(CLK_debugMask, GT_7CLASS, ++ "CLK_Init: PASS and Clk handle %s, " ++ "CLK dev id = %d\n", ++ SERVICES_Clks[i].clk_name, ++ SERVICES_Clks[i].id); ++ } ++ SERVICES_Clks[i].clk_handle = clk_handle; ++ i++; ++ } ++ ++ return true; ++} ++ ++/* ++ * ======== CLK_Enable ======== ++ * Purpose: ++ * Enable Clock . ++ * ++*/ ++DSP_STATUS CLK_Enable(IN enum SERVICES_ClkId clk_id) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct clk *pClk; ++ ++ DBC_Require(clk_id < SERVICESCLK_NOT_DEFINED); ++ GT_2trace(CLK_debugMask, GT_6CLASS, "CLK_Enable: CLK %s, " ++ "CLK dev id = %d\n", SERVICES_Clks[clk_id].clk_name, ++ SERVICES_Clks[clk_id].id); ++ ++ pClk = SERVICES_Clks[clk_id].clk_handle; ++ if (pClk) { ++ if (clk_enable(pClk) == 0x0) { ++ /* Success ? */ ++ } else { ++ pr_err("CLK_Enable: failed to Enable CLK %s, " ++ "CLK dev id = %d\n", ++ SERVICES_Clks[clk_id].clk_name, ++ SERVICES_Clks[clk_id].id); ++ status = DSP_EFAIL; ++ } ++ } else { ++ pr_err("CLK_Enable: failed to get CLK %s, CLK dev id = %d\n", ++ SERVICES_Clks[clk_id].clk_name, ++ SERVICES_Clks[clk_id].id); ++ status = DSP_EFAIL; ++ } ++ /* The SSI module need to configured not to have the Forced idle for ++ * master interface. If it is set to forced idle, the SSI module is ++ * transitioning to standby thereby causing the client in the DSP hang ++ * waiting for the SSI module to be active after enabling the clocks ++ */ ++ if (clk_id == SERVICESCLK_ssi_fck) ++ SSI_Clk_Prepare(true); ++ ++ return status; ++} ++/* ++ * ======== CLK_Set_32KHz ======== ++ * Purpose: ++ * To Set parent of a clock to 32KHz. ++ */ ++ ++DSP_STATUS CLK_Set_32KHz(IN enum SERVICES_ClkId clk_id) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct clk *pClk; ++ struct clk *pClkParent; ++ enum SERVICES_ClkId sys_32k_id = SERVICESCLK_sys_32k_ck; ++ pClkParent = SERVICES_Clks[sys_32k_id].clk_handle; ++ ++ DBC_Require(clk_id < SERVICESCLK_NOT_DEFINED); ++ GT_2trace(CLK_debugMask, GT_6CLASS, "CLK_Set_32KHz: CLK %s, " ++ "CLK dev id = %d is setting to 32KHz \n", ++ SERVICES_Clks[clk_id].clk_name, ++ SERVICES_Clks[clk_id].id); ++ pClk = SERVICES_Clks[clk_id].clk_handle; ++ if (pClk) { ++ if (!(clk_set_parent(pClk, pClkParent) == 0x0)) { ++ GT_2trace(CLK_debugMask, GT_7CLASS, "CLK_Set_32KHz: " ++ "Failed to set to 32KHz %s, CLK dev id = %d\n", ++ SERVICES_Clks[clk_id].clk_name, ++ SERVICES_Clks[clk_id].id); ++ status = DSP_EFAIL; ++ } ++ } ++ return status; ++} ++ ++/* ++ * ======== CLK_Disable ======== ++ * Purpose: ++ * Disable the clock. ++ * ++*/ ++DSP_STATUS CLK_Disable(IN enum SERVICES_ClkId clk_id) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct clk *pClk; ++ s32 clkUseCnt; ++ ++ DBC_Require(clk_id < SERVICESCLK_NOT_DEFINED); ++ GT_2trace(CLK_debugMask, GT_6CLASS, "CLK_Disable: CLK %s, " ++ "CLK dev id = %d\n", SERVICES_Clks[clk_id].clk_name, ++ SERVICES_Clks[clk_id].id); ++ ++ pClk = SERVICES_Clks[clk_id].clk_handle; ++ ++ clkUseCnt = CLK_Get_UseCnt(clk_id); ++ if (clkUseCnt == -1) { ++ pr_err("CLK_Disable: failed to get CLK Use count for CLK %s," ++ "CLK dev id = %d\n", ++ SERVICES_Clks[clk_id].clk_name, ++ SERVICES_Clks[clk_id].id); ++ } else if (clkUseCnt == 0) { ++ pr_err("CLK_Disable: CLK %s, CLK dev id= %d is already" ++ "disabled\n", ++ SERVICES_Clks[clk_id].clk_name, ++ SERVICES_Clks[clk_id].id); ++ return status; ++ } ++ if (clk_id == SERVICESCLK_ssi_ick) ++ SSI_Clk_Prepare(false); ++ ++ if (pClk) { ++ clk_disable(pClk); ++ } else { ++ pr_err("CLK_Disable: failed to get CLK %s," ++ "CLK dev id = %d\n", ++ SERVICES_Clks[clk_id].clk_name, ++ SERVICES_Clks[clk_id].id); ++ status = DSP_EFAIL; ++ } ++ return status; ++} ++ ++/* ++ * ======== CLK_GetRate ======== ++ * Purpose: ++ * GetClock Speed. ++ * ++ */ ++ ++DSP_STATUS CLK_GetRate(IN enum SERVICES_ClkId clk_id, u32 *speedKhz) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct clk *pClk; ++ u32 clkSpeedHz; ++ ++ DBC_Require(clk_id < SERVICESCLK_NOT_DEFINED); ++ *speedKhz = 0x0; ++ ++ GT_2trace(CLK_debugMask, GT_7CLASS, "CLK_GetRate: CLK %s, " ++ "CLK dev Id = %d \n", SERVICES_Clks[clk_id].clk_name, ++ SERVICES_Clks[clk_id].id); ++ pClk = SERVICES_Clks[clk_id].clk_handle; ++ if (pClk) { ++ clkSpeedHz = clk_get_rate(pClk); ++ *speedKhz = clkSpeedHz / 1000; ++ GT_2trace(CLK_debugMask, GT_6CLASS, ++ "CLK_GetRate: clkSpeedHz = %d , " ++ "speedinKhz=%d\n", clkSpeedHz, *speedKhz); ++ } else { ++ GT_2trace(CLK_debugMask, GT_7CLASS, ++ "CLK_GetRate: failed to get CLK %s, " ++ "CLK dev Id = %d\n", SERVICES_Clks[clk_id].clk_name, ++ SERVICES_Clks[clk_id].id); ++ status = DSP_EFAIL; ++ } ++ return status; ++} ++ ++s32 CLK_Get_UseCnt(IN enum SERVICES_ClkId clk_id) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct clk *pClk; ++ s32 useCount = -1; ++ DBC_Require(clk_id < SERVICESCLK_NOT_DEFINED); ++ ++ pClk = SERVICES_Clks[clk_id].clk_handle; ++ ++ if (pClk) { ++ useCount = pClk->usecount; /* FIXME: usecount shouldn't be used */ ++ } else { ++ GT_2trace(CLK_debugMask, GT_7CLASS, ++ "CLK_GetRate: failed to get CLK %s, " ++ "CLK dev Id = %d\n", SERVICES_Clks[clk_id].clk_name, ++ SERVICES_Clks[clk_id].id); ++ status = DSP_EFAIL; ++ } ++ return useCount; ++} ++ ++void SSI_Clk_Prepare(bool FLAG) ++{ ++ u32 ssi_sysconfig; ++ ssi_sysconfig = __raw_readl((SSI_BASE) + 0x10); ++ ++ if (FLAG) { ++ /* Set Autoidle, SIDLEMode to smart idle, and MIDLEmode to ++ * no idle ++ */ ++ ssi_sysconfig = 0x1011; ++ } else { ++ /* Set Autoidle, SIDLEMode to forced idle, and MIDLEmode to ++ * forced idle ++ */ ++ ssi_sysconfig = 0x1; ++ } ++ __raw_writel((u32)ssi_sysconfig, SSI_BASE + 0x10); ++} +diff --git a/drivers/dsp/bridge/services/csl.c b/drivers/dsp/bridge/services/csl.c +new file mode 100644 +index 0000000..dd33c2d +--- /dev/null ++++ b/drivers/dsp/bridge/services/csl.c +@@ -0,0 +1,173 @@ ++/* ++ * csl.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== cslce.c ======== ++ * Purpose: ++ * Provides platform independent C Standard library functions. ++ * ++ * Public Functions: ++ * CSL_Atoi ++ * CSL_Exit ++ * CSL_Init ++ * CSL_NumToAscii ++ * CSL_Strtokr ++ * ++ *! Revision History: ++ *! ================ ++ *! 07-Aug-2002 jeh: Added CSL_Strtokr(). ++ *! 21-Sep-2001 jeh: Added CSL_Strncmp(). Alphabetized functions. ++ *! 22-Nov-2000 map: Added CSL_Atoi and CSL_Strtok ++ *! 19-Nov-2000 kc: Added CSL_ByteSwap. ++ *! 09-Nov-2000 kc: Added CSL_Strncat. ++ *! 03-Feb-2000 rr: Module init/exit is handled by SERVICES Init/Exit. ++ *! GT Changes. ++ *! 15-Dec-1999 ag: Removed incorrect assertion CSL_NumToAscii() ++ *! 29-Oct-1999 kc: Added CSL_Wstrlen for UNICODE strings. ++ *! 30-Sep-1999 ag: Removed DBC assertion (!CSL_DebugMask.flags) in ++ * CSP_Init(). ++ *! 20-Sep-1999 ag: Added CSL_WcharToAnsi(). ++ *! Removed call to GT_set(). ++ *! 19-Jan-1998 cr: Code review cleanup. ++ *! 29-Dec-1997 cr: Made platform independant, using MS CRT code, and ++ *! combined csl32.c csl95.c and cslnt.c into csl.c. Also ++ *! changed CSL_lowercase to CSL_Uppercase. ++ *! 21-Aug-1997 gp: Fix to CSL_strcpyn to initialize Source string, the NT way. ++ *! 25-Jun-1997 cr: Created from csl95, added CSL_strcmp. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++/* Is character c in the string pstrDelim? */ ++#define IsDelimiter(c, pstrDelim) ((c != '\0') && \ ++ (strchr(pstrDelim, c) != NULL)) ++ ++/* ----------------------------------- Globals */ ++#if GT_TRACE ++static struct GT_Mask CSL_DebugMask = { NULL, NULL }; /* GT trace var. */ ++#endif ++ ++/* ++ * ======== CSL_Exit ======== ++ * Purpose: ++ * Discontinue usage of the CSL module. ++ */ ++void CSL_Exit(void) ++{ ++ GT_0trace(CSL_DebugMask, GT_5CLASS, "CSL_Exit\n"); ++} ++ ++/* ++ * ======== CSL_Init ======== ++ * Purpose: ++ * Initialize the CSL module's private state. ++ */ ++bool CSL_Init(void) ++{ ++ GT_create(&CSL_DebugMask, "CS"); ++ ++ GT_0trace(CSL_DebugMask, GT_5CLASS, "CSL_Init\n"); ++ ++ return true; ++} ++ ++/* ++ * ======== CSL_NumToAscii ======== ++ * Purpose: ++ * Convert a 1 or 2 digit number to a 2 digit string. ++ */ ++void CSL_NumToAscii(OUT char *pstrNumber, u32 dwNum) ++{ ++ char tens; ++ ++ DBC_Require(dwNum < 100); ++ ++ if (dwNum < 100) { ++ tens = (char) dwNum / 10; ++ dwNum = dwNum % 10; ++ ++ if (tens) { ++ pstrNumber[0] = tens + '0'; ++ pstrNumber[1] = (char) dwNum + '0'; ++ pstrNumber[2] = '\0'; ++ } else { ++ pstrNumber[0] = (char) dwNum + '0'; ++ pstrNumber[1] = '\0'; ++ } ++ } else { ++ pstrNumber[0] = '\0'; ++ } ++} ++ ++ ++ ++ ++/* ++ * ======= CSL_Strtokr ======= ++ * Purpose: ++ * Re-entrant version of strtok. ++ */ ++char *CSL_Strtokr(IN char *pstrSrc, IN CONST char *szSeparators, ++ OUT char **ppstrLast) ++{ ++ char *pstrTemp; ++ char *pstrToken; ++ ++ DBC_Require(szSeparators != NULL); ++ DBC_Require(ppstrLast != NULL); ++ DBC_Require(pstrSrc != NULL || *ppstrLast != NULL); ++ ++ /* ++ * Set string location to beginning (pstrSrc != NULL) or to the ++ * beginning of the next token. ++ */ ++ pstrTemp = (pstrSrc != NULL) ? pstrSrc : *ppstrLast; ++ if (*pstrTemp == '\0') { ++ pstrToken = NULL; ++ } else { ++ pstrToken = pstrTemp; ++ while (*pstrTemp != '\0' && !IsDelimiter(*pstrTemp, ++ szSeparators)) { ++ pstrTemp++; ++ } ++ if (*pstrTemp != '\0') { ++ while (IsDelimiter(*pstrTemp, szSeparators)) { ++ /* TODO: Shouldn't we do this for ++ * only 1 char?? */ ++ *pstrTemp = '\0'; ++ pstrTemp++; ++ } ++ } ++ ++ /* Location in string for next call */ ++ *ppstrLast = pstrTemp; ++ } ++ ++ return pstrToken; ++} +diff --git a/drivers/dsp/bridge/services/dbg.c b/drivers/dsp/bridge/services/dbg.c +new file mode 100644 +index 0000000..5e1773f +--- /dev/null ++++ b/drivers/dsp/bridge/services/dbg.c +@@ -0,0 +1,119 @@ ++/* ++ * dbg.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== dbgce.c ======== ++ * Purpose: ++ * Provide debugging services for DSP/BIOS Bridge Mini Drivers. ++ * ++ * Public Functions: ++ * DBG_Exit ++ * DBG_Init ++ * DBG_Trace ++ * ++ * Notes: ++ * Requires gt.h. ++ * ++ * This implementation does not create GT masks on a per WMD basis. ++ * There is currently no facility for a WMD to alter the GT mask. ++ * ++ *! Revision History: ++ *! ================ ++ *! 15-Feb-2000 rr: DBG_Trace prints based on the DebugZones. ++ *! 03-Feb-2000 rr: Module init/exit is handled by SERVICES Init/Exit. ++ *! GT Changes. ++ *! 29-Oct-1999 kc: Cleaned up for code review. ++ *! 10-Oct-1997 cr: Added DBG_Printf service. ++ *! 28-May-1997 cr: Added reference counting. ++ *! 23-May-1997 cr: Updated DBG_Trace to new gt interface. ++ *! 29-May-1996 gp: Removed WCD_ prefix. ++ *! 20-May-1996 gp: Remove DEBUG conditional compilation. ++ *! 15-May-1996 gp: Created. ++ */ ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++/* ----------------------------------- Globals */ ++#if GT_TRACE ++static struct GT_Mask DBG_debugMask = { NULL, NULL }; /* GT trace var. */ ++#endif ++ ++#if (defined(DEBUG) || defined (DDSP_DEBUG_PRODUCT)) && GT_TRACE ++ ++/* ++ * ======== DBG_Init ======== ++ * Purpose: ++ * Ensures trace capability is set up for link drivers. ++ */ ++bool DBG_Init(void) ++{ ++ GT_create(&DBG_debugMask, "WD"); /* for WmD (link driver) debug */ ++ ++ GT_0trace(DBG_debugMask, GT_5CLASS, "DBG_Init\n"); ++ ++ return true; ++} ++ ++/* ++ * ======== DBG_Trace ======== ++ * Purpose: ++ * Output a trace message to the debugger, if the given trace level ++ * is unmasked. ++ */ ++DSP_STATUS DBG_Trace(u8 bLevel, char *pstrFormat, ...) ++{ ++ s32 arg1, arg2, arg3, arg4, arg5, arg6; ++ va_list va; ++ ++ va_start(va, pstrFormat); ++ ++ arg1 = va_arg(va, s32); ++ arg2 = va_arg(va, s32); ++ arg3 = va_arg(va, s32); ++ arg4 = va_arg(va, s32); ++ arg5 = va_arg(va, s32); ++ arg6 = va_arg(va, s32); ++ ++ va_end(va); ++ ++ if (bLevel & *(DBG_debugMask).flags) ++ printk(pstrFormat, arg1, arg2, arg3, arg4, arg5, arg6); ++ ++ return DSP_SOK; ++} ++ ++/* ++ * ======== DBG_Exit ======== ++ * Purpose: ++ * Discontinue usage of the DBG module. ++ */ ++void DBG_Exit(void) ++{ ++ GT_0trace(DBG_debugMask, GT_5CLASS, "DBG_Exit\n"); ++} ++ ++#endif /* (defined(DEBUG) || defined(DDSP_DEBUG_PRODUCT)) && GT_TRACE */ +diff --git a/drivers/dsp/bridge/services/dpc.c b/drivers/dsp/bridge/services/dpc.c +new file mode 100644 +index 0000000..bd608d1 +--- /dev/null ++++ b/drivers/dsp/bridge/services/dpc.c +@@ -0,0 +1,274 @@ ++/* ++ * dpc.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== dpcce.c ======== ++ * Purpose: ++ * Deferred Procedure Call(DPC) Services. ++ * ++ * ++ * Public Functions: ++ * DPC_Create ++ * DPC_Destroy ++ * DPC_Exit ++ * DPC_Init ++ * DPC_Schedule ++ * ++ *! Revision History: ++ *! ================ ++ *! 28-Mar-2001 ag: Added #ifdef CHNL_NOIPCINTR to set DPC thread priority ++ *! to THREAD_PRIORITY_IDLE for polling IPC. ++ *! 03-Feb-2000 rr: Module init/exit is handled by SERVICES Init/Exit. ++ *! GT Changes. ++ *! 31-Jan-2000 rr: Changes after code review.Terminate thread,handle ++ *! modified.DPC_Destroy frees the DPC_Object only on ++ *! Successful termination of the thread and the handle. ++ *! 06-Jan-1999 ag: Format cleanup for code review. ++ *! Removed DPC_[Lower|Raise]IRQL[From|To]DispatchLevel. ++ *! 10-Dec-1999 ag: Added SetProcPermissions in DPC_DeferredProcedure(). ++ *! (Needed to access client(s) CHNL buffers). ++ *! 19-Sep-1999 a0216266: Stubbed from dpcnt.c. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++/* ----------------------------------- Defines, Data Structures, Typedefs */ ++#define SIGNATURE 0x5f435044 /* "DPC_" (in reverse). */ ++ ++/* The DPC object, passed to our priority event callback routine: */ ++struct DPC_OBJECT { ++ u32 dwSignature; /* Used for object validation. */ ++ void *pRefData; /* Argument for client's DPC. */ ++ DPC_PROC pfnDPC; /* Client's DPC. */ ++ u32 numRequested; /* Number of requested DPC's. */ ++ u32 numScheduled; /* Number of executed DPC's. */ ++ struct tasklet_struct dpc_tasklet; ++ ++#ifdef DEBUG ++ u32 cEntryCount; /* Number of times DPC reentered. */ ++ u32 numRequestedMax; /* Keep track of max pending DPC's. */ ++#endif ++ ++ spinlock_t dpc_lock; ++}; ++ ++/* ----------------------------------- Globals */ ++#if GT_TRACE ++static struct GT_Mask DPC_DebugMask = { NULL, NULL }; /* DPC Debug Mask */ ++#endif ++ ++/* ----------------------------------- Function Prototypes */ ++static void DPC_DeferredProcedure(IN unsigned long pDeferredContext); ++ ++/* ++ * ======== DPC_Create ======== ++ * Purpose: ++ * Create a DPC object, allowing a client's own DPC procedure to be ++ * scheduled for a call with client reference data. ++ */ ++DSP_STATUS DPC_Create(OUT struct DPC_OBJECT **phDPC, DPC_PROC pfnDPC, ++ void *pRefData) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DPC_OBJECT *pDPCObject = NULL; ++ ++ if ((phDPC != NULL) && (pfnDPC != NULL)) { ++ /* ++ * Allocate a DPC object to store information allowing our DPC ++ * callback to dispatch to the client's DPC. ++ */ ++ MEM_AllocObject(pDPCObject, struct DPC_OBJECT, SIGNATURE); ++ if (pDPCObject != NULL) { ++ tasklet_init(&pDPCObject->dpc_tasklet, ++ DPC_DeferredProcedure, ++ (u32) pDPCObject); ++ /* Fill out our DPC Object: */ ++ pDPCObject->pRefData = pRefData; ++ pDPCObject->pfnDPC = pfnDPC; ++ pDPCObject->numRequested = 0; ++ pDPCObject->numScheduled = 0; ++#ifdef DEBUG ++ pDPCObject->numRequestedMax = 0; ++ pDPCObject->cEntryCount = 0; ++#endif ++ spin_lock_init(&pDPCObject->dpc_lock); ++ *phDPC = pDPCObject; ++ } else { ++ GT_0trace(DPC_DebugMask, GT_6CLASS, ++ "DPC_Create: DSP_EMEMORY\n"); ++ status = DSP_EMEMORY; ++ } ++ } else { ++ GT_0trace(DPC_DebugMask, GT_6CLASS, ++ "DPC_Create: DSP_EPOINTER\n"); ++ status = DSP_EPOINTER; ++ } ++ DBC_Ensure((DSP_FAILED(status) && (!phDPC || (phDPC && *phDPC == NULL))) ++ || DSP_SUCCEEDED(status)); ++ return status; ++} ++ ++/* ++ * ======== DPC_Destroy ======== ++ * Purpose: ++ * Cancel the last scheduled DPC, and deallocate a DPC object previously ++ * allocated with DPC_Create(). Frees the Object only if the thread ++ * and the event terminated successfuly. ++ */ ++DSP_STATUS DPC_Destroy(struct DPC_OBJECT *hDPC) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DPC_OBJECT *pDPCObject = (struct DPC_OBJECT *)hDPC; ++ ++ if (MEM_IsValidHandle(hDPC, SIGNATURE)) { ++ ++ /* Free our DPC object: */ ++ if (DSP_SUCCEEDED(status)) { ++ tasklet_kill(&pDPCObject->dpc_tasklet); ++ MEM_FreeObject(pDPCObject); ++ pDPCObject = NULL; ++ GT_0trace(DPC_DebugMask, GT_2CLASS, ++ "DPC_Destroy: SUCCESS\n"); ++ } ++ } else { ++ GT_0trace(DPC_DebugMask, GT_6CLASS, ++ "DPC_Destroy: DSP_EHANDLE\n"); ++ status = DSP_EHANDLE; ++ } ++ DBC_Ensure((DSP_SUCCEEDED(status) && pDPCObject == NULL) ++ || DSP_FAILED(status)); ++ return status; ++} ++ ++/* ++ * ======== DPC_Exit ======== ++ * Purpose: ++ * Discontinue usage of the DPC module. ++ */ ++void DPC_Exit(void) ++{ ++ GT_0trace(DPC_DebugMask, GT_5CLASS, "Entered DPC_Exit\n"); ++} ++ ++/* ++ * ======== DPC_Init ======== ++ * Purpose: ++ * Initialize the DPC module's private state. ++ */ ++bool DPC_Init(void) ++{ ++ GT_create(&DPC_DebugMask, "DP"); ++ ++ GT_0trace(DPC_DebugMask, GT_5CLASS, "Entered DPC_Init\n"); ++ ++ return true; ++} ++ ++/* ++ * ======== DPC_Schedule ======== ++ * Purpose: ++ * Schedule a deferred procedure call to be executed at a later time. ++ * Latency and order of DPC execution is platform specific. ++ */ ++DSP_STATUS DPC_Schedule(struct DPC_OBJECT *hDPC) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DPC_OBJECT *pDPCObject = (struct DPC_OBJECT *)hDPC; ++ unsigned long flags; ++ ++ GT_1trace(DPC_DebugMask, GT_ENTER, "DPC_Schedule hDPC %x\n", hDPC); ++ if (MEM_IsValidHandle(hDPC, SIGNATURE)) { ++ /* Increment count of DPC's pending. Needs to be protected ++ * from ISRs since this function is called from process ++ * context also. */ ++ spin_lock_irqsave(&hDPC->dpc_lock, flags); ++ pDPCObject->numRequested++; ++ spin_unlock_irqrestore(&hDPC->dpc_lock, flags); ++ tasklet_schedule(&(hDPC->dpc_tasklet)); ++#ifdef DEBUG ++ if (pDPCObject->numRequested > pDPCObject->numScheduled + ++ pDPCObject->numRequestedMax) { ++ pDPCObject->numRequestedMax = pDPCObject->numRequested - ++ pDPCObject->numScheduled; ++ } ++#endif ++ /* If an interrupt occurs between incrementing numRequested and the ++ * assertion below, then DPC will get executed while returning from ++ * ISR, which will complete all requests and make numRequested equal ++ * to numScheduled, firing this assertion. This happens only when ++ * DPC is being scheduled in process context */ ++ } else { ++ GT_0trace(DPC_DebugMask, GT_6CLASS, ++ "DPC_Schedule: DSP_EHANDLE\n"); ++ status = DSP_EHANDLE; ++ } ++ GT_1trace(DPC_DebugMask, GT_ENTER, "DPC_Schedule status %x\n", status); ++ return status; ++} ++ ++/* ++ * ======== DeferredProcedure ======== ++ * Purpose: ++ * Main DPC routine. This is called by host OS DPC callback ++ * mechanism with interrupts enabled. ++ */ ++static void DPC_DeferredProcedure(IN unsigned long pDeferredContext) ++{ ++ struct DPC_OBJECT *pDPCObject = (struct DPC_OBJECT *)pDeferredContext; ++ /* read numRequested in local variable */ ++ u32 requested; ++ u32 serviced; ++ ++ DBC_Require(pDPCObject != NULL); ++ requested = pDPCObject->numRequested; ++ serviced = pDPCObject->numScheduled; ++ ++ GT_1trace(DPC_DebugMask, GT_ENTER, "> DPC_DeferredProcedure " ++ "pDeferredContext=%x\n", pDeferredContext); ++ /* Rollover taken care of using != instead of < */ ++ if (serviced != requested) { ++ if (pDPCObject->pfnDPC != NULL) { ++ /* Process pending DPC's: */ ++ do { ++ /* Call client's DPC: */ ++ (*(pDPCObject->pfnDPC))(pDPCObject->pRefData); ++ serviced++; ++ } while (serviced != requested); ++ } ++ pDPCObject->numScheduled = requested; ++ } ++ GT_2trace(DPC_DebugMask, GT_ENTER, ++ "< DPC_DeferredProcedure requested %d" ++ " serviced %d\n", requested, serviced); ++} ++ +diff --git a/drivers/dsp/bridge/services/kfile.c b/drivers/dsp/bridge/services/kfile.c +new file mode 100644 +index 0000000..ba1d26f +--- /dev/null ++++ b/drivers/dsp/bridge/services/kfile.c +@@ -0,0 +1,338 @@ ++/* ++ * kfile.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== kfilece.c ======== ++ * Purpose: ++ * This module provides file i/o services. ++ * ++ * Public Functions: ++ * KFILE_Close ++ * KFILE_Exit ++ * KFILE_Init ++ * KFILE_Open ++ * KFILE_Read ++ * KFILE_Seek ++ * KFILE_Tell ++ * ++ *! Revision History ++ *! ================ ++ *! 03-Feb-2000 rr: Module init/exit is handled by SERVICES Init/Exit. ++ *! GT Changes. ++ *! 22-Nov-1999 kc: Added changes from code review. ++ *! 12-Nov-1999 kc: Enabled CSL for UNICODE/ANSI string conversions. ++ *! 30-Sep-1999 ag: Changed KFILE_Read() GT level from _ENTER to _4CLASS. ++ *! Removed GT_set(). ++ *! 25-Aug-1999 ag: Changed MEM_Calloc allocation type to MEM_PAGED. ++ *! 13-Jul-1999 a0216266(ww - TID): Stubbed from kfilent.c. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++/* ----------------------------------- Defines, Data Structures, Typedefs */ ++#define SIGNATURE 0x4c49464b /* hex code of KFIL (reversed) */ ++#define MAXFILENAMELENGTH 256 ++#define GENERAL_FAILURE 0xffffffff /* SetFilePointer error */ ++ ++/* The KFILE_FileObj abstracts the true file handle from a KFILE handle. */ ++struct KFILE_FileObj { ++ u32 dwSignature; ++ __kernel_pid_t owner_pid; /* PID of process that opened this file */ ++ char *fileName ; ++ bool isOpen ; ++ u32 size ; ++ u32 curPos ; ++ long hInternal; /* internal handle of file */ ++ struct file *fileDesc; ++ ++}; ++ ++/* ----------------------------------- Globals */ ++#if GT_TRACE ++static struct GT_Mask KFILE_debugMask = { NULL, NULL }; /* Debug mask */ ++#endif ++ ++/* ++ * ======== KFILE_Close ======== ++ * Purpose: ++ * This function closes a file's stream. ++ */ ++s32 KFILE_Close(struct KFILE_FileObj *hFile) ++{ ++ s32 cRetVal = 0; /* 0 indicates success */ ++ s32 fRetVal = 0; ++ __kernel_pid_t curr_pid; ++ ++ GT_1trace(KFILE_debugMask, GT_ENTER, "KFILE_Close: hFile 0x%x\n", ++ hFile); ++ ++ /* Check for valid handle */ ++ if (MEM_IsValidHandle(hFile, SIGNATURE)) { ++ /* Close file only if opened by the same process (id). Otherwise ++ * Linux closes all open file handles when process exits.*/ ++ /* Return PID instead of process handle */ ++ curr_pid = (__kernel_pid_t)current->pid; ++ fRetVal = filp_close(hFile->fileDesc, NULL) ; ++ if (fRetVal) { ++ cRetVal = E_KFILE_ERROR; ++ GT_1trace(KFILE_debugMask, GT_6CLASS, ++ "KFILE_Close: sys_close " ++ "returned %d\n", fRetVal); ++ } ++ MEM_FreeObject(hFile); ++ } else { ++ cRetVal = E_KFILE_INVALIDHANDLE; ++ GT_0trace(KFILE_debugMask, GT_6CLASS, "KFILE_Close: " ++ "invalid file handle\n"); ++ } ++ return cRetVal; ++} ++ ++/* ++ * ======== KFILE_Exit ======== ++ * Purpose: ++ * Decrement reference count, and free resources when reference count ++ * is 0. ++ */ ++void KFILE_Exit(void) ++{ ++ GT_0trace(KFILE_debugMask, GT_5CLASS, "KFILE_Exit\n"); ++} ++ ++/* ++ * ======== KFILE_Init ======== ++ */ ++bool KFILE_Init(void) ++{ ++ GT_create(&KFILE_debugMask, "KF"); /* "KF" for KFile */ ++ ++ GT_0trace(KFILE_debugMask, GT_5CLASS, "KFILE_Init\n"); ++ ++ return true; ++} ++ ++/* ++ * ======== KFILE_Open ======== ++ * Purpose: ++ * Open a file for reading ONLY ++ */ ++struct KFILE_FileObj *KFILE_Open(CONST char *pszFileName, CONST char *pszMode) ++{ ++ struct KFILE_FileObj *hFile; /* file handle */ ++ DSP_STATUS status; ++ mm_segment_t fs; ++ ++ struct file*fileDesc = NULL; ++ DBC_Require(pszMode != NULL); ++ DBC_Require(pszFileName != NULL); ++ ++ GT_2trace(KFILE_debugMask, GT_ENTER, ++ "KFILE_Open: pszFileName %s, pszMode " ++ "%s\n", pszFileName, pszMode); ++ ++ /* create a KFILE object */ ++ MEM_AllocObject(hFile, struct KFILE_FileObj, SIGNATURE); ++ ++ if (hFile) { ++ fs = get_fs(); ++ set_fs(get_ds()); ++ /* Third argument is mode (permissions). Ignored unless creating file */ ++ fileDesc = filp_open(pszFileName, O_RDONLY, 0); ++ if ((IS_ERR(fileDesc)) || (fileDesc == NULL) || ++ (fileDesc->f_op == NULL) || (fileDesc->f_op->read == NULL) ++ || (fileDesc->f_op->llseek == NULL)) { ++ status = DSP_EFILE; ++ } else { ++ hFile->fileDesc = fileDesc; ++ hFile->fileName = (char *)pszFileName; ++ hFile->isOpen = true; ++ hFile->curPos = 0; ++ hFile->size = fileDesc->f_op->llseek(fileDesc, 0, ++ SEEK_END); ++ fileDesc->f_op->llseek(fileDesc, 0, SEEK_SET); ++ /* Return PID instead of process handle */ ++ hFile->owner_pid = current->pid; ++ ++ status = DSP_SOK; ++ } ++ set_fs(fs); ++ if (DSP_FAILED(status)) { ++ /* free memory, and clear handle */ ++ MEM_FreeObject(hFile); ++ hFile = NULL; ++ } ++ } else { ++ GT_0trace(KFILE_debugMask, GT_6CLASS, ++ "KFILE_Open: MEM_AllocObject failed\n"); ++ status = DSP_EMEMORY; ++ } ++ return hFile; ++} ++ ++/* ++ * ======== KFILE_Read ======== ++ * Purpose: ++ * Reads a specified number of bytes into a buffer. ++ */ ++s32 ++KFILE_Read(void __user*pBuffer, s32 cSize, s32 cCount, ++ struct KFILE_FileObj *hFile) ++{ ++ u32 dwBytesRead = 0; ++ s32 cRetVal = 0; ++ mm_segment_t fs; ++ ++ DBC_Require(pBuffer != NULL); ++ ++ GT_4trace(KFILE_debugMask, GT_4CLASS, ++ "KFILE_Read: buffer 0x%x, cSize 0x%x," ++ "cCount 0x%x, hFile 0x%x\n", pBuffer, cSize, cCount, hFile); ++ ++ /* check for valid file handle */ ++ if (MEM_IsValidHandle(hFile, SIGNATURE)) { ++ if ((cSize > 0) && (cCount > 0) && pBuffer) { ++ /* read from file */ ++ fs = get_fs(); ++ set_fs(get_ds()); ++ dwBytesRead = hFile->fileDesc->f_op->read(hFile-> ++ fileDesc, pBuffer, cSize *cCount, ++ &(hFile->fileDesc->f_pos)); ++ set_fs(fs); ++ if (dwBytesRead) { ++ cRetVal = dwBytesRead / cSize; ++ hFile->curPos += dwBytesRead; ++ DBC_Assert((dwBytesRead / cSize) <= \ ++ (u32)cCount); ++ } else { ++ cRetVal = E_KFILE_ERROR; ++ GT_0trace(KFILE_debugMask, GT_6CLASS, ++ "KFILE_Read: sys_read() failed\n"); ++ } ++ } else { ++ cRetVal = DSP_EINVALIDARG; ++ GT_0trace(KFILE_debugMask, GT_6CLASS, ++ "KFILE_Read: Invalid argument(s)\n"); ++ } ++ } else { ++ cRetVal = E_KFILE_INVALIDHANDLE; ++ GT_0trace(KFILE_debugMask, GT_6CLASS, ++ "KFILE_Read: invalid file handle\n"); ++ } ++ ++ return cRetVal; ++} ++ ++/* ++ * ======== KFILE_Seek ======== ++ * Purpose: ++ * Sets the file position indicator. NOTE: we don't support seeking ++ * beyond the boundaries of a file. ++ */ ++s32 KFILE_Seek(struct KFILE_FileObj *hFile, s32 lOffset, s32 cOrigin) ++{ ++ s32 cRetVal = 0; /* 0 for success */ ++ u32 dwCurPos = 0; ++ ++ struct file *fileDesc = NULL; ++ ++ GT_3trace(KFILE_debugMask, GT_ENTER, "KFILE_Seek: hFile 0x%x, " ++ "lOffset 0x%x, cOrigin 0x%x\n", ++ hFile, lOffset, cOrigin); ++ ++ /* check for valid file handle */ ++ if (MEM_IsValidHandle(hFile, SIGNATURE)) { ++ /* based on the origin flag, move the internal pointer */ ++ ++ fileDesc = hFile->fileDesc; ++ switch (cOrigin) { ++ case KFILE_SEEK_SET: ++ dwCurPos = hFile->fileDesc->f_op->llseek(hFile-> ++ fileDesc, lOffset, SEEK_SET); ++ cRetVal = ((dwCurPos >= 0) ? 0 : E_KFILE_ERROR); ++ break; ++ ++ case KFILE_SEEK_CUR: ++ dwCurPos = hFile->fileDesc->f_op->llseek(hFile-> ++ fileDesc, lOffset, SEEK_CUR); ++ cRetVal = ((dwCurPos >= 0) ? 0 : E_KFILE_ERROR); ++ break; ++ case KFILE_SEEK_END: ++ dwCurPos = hFile->fileDesc->f_op->llseek(hFile-> ++ fileDesc, lOffset, SEEK_END); ++ cRetVal = ((dwCurPos >= 0) ? 0 : E_KFILE_ERROR); ++ break; ++ default: ++ cRetVal = E_KFILE_BADORIGINFLAG; ++ GT_0trace(KFILE_debugMask, GT_6CLASS, ++ "KFILE_Seek:bad origin flag\n"); ++ break; ++ } ++ } else { ++ cRetVal = E_KFILE_INVALIDHANDLE; ++ GT_0trace(KFILE_debugMask, GT_6CLASS, ++ "KFILE_Seek:invalid file handle\n"); ++ } ++ return cRetVal; ++} ++ ++/* ++ * ======== KFILE_Tell ======== ++ * Purpose: ++ * Reports the current value of the position indicator. We did not ++ * consider 64 bit long file size, which implies a 4GB file limit ++ * (2 to 32 power). ++ */ ++s32 KFILE_Tell(struct KFILE_FileObj *hFile) ++{ ++ u32 dwCurPos = 0; ++ s32 lRetVal = E_KFILE_ERROR; ++ ++ GT_1trace(KFILE_debugMask, GT_ENTER, "KFILE_Tell: hFile 0x%x\n", hFile); ++ ++ if (MEM_IsValidHandle(hFile, SIGNATURE)) { ++ ++ /* Get current position. */ ++ dwCurPos = hFile->fileDesc->f_op->llseek(hFile->fileDesc, 0, ++ SEEK_CUR); ++ if (dwCurPos >= 0) ++ lRetVal = dwCurPos; ++ ++ } else { ++ lRetVal = E_KFILE_INVALIDHANDLE; ++ GT_0trace(KFILE_debugMask, GT_6CLASS, ++ "KFILE_Seek:invalid file handle\n"); ++ } ++ return lRetVal; ++} ++ +diff --git a/drivers/dsp/bridge/services/list.c b/drivers/dsp/bridge/services/list.c +new file mode 100644 +index 0000000..7fa3e76 +--- /dev/null ++++ b/drivers/dsp/bridge/services/list.c +@@ -0,0 +1,285 @@ ++/* ++ * list.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== listce.c ======== ++ * Purpose ++ * Provides standard circular list handling functions. ++ * ++ * Public Functions: ++ * LST_Create ++ * LST_Delete ++ * LST_Exit ++ * LST_First ++ * LST_GetHead ++ * LST_Init ++ * LST_InitElem ++ * LST_InsertBefore ++ * LST_Next ++ * LST_PutTail ++ * LST_RemoveElem ++ * ++ *! Revision History ++ *! ================ ++ *! 06-Mar-2002 jeh Don't set element self to NULL in LST_RemoveElem(). ++ *! 10-Aug-2000 ag: Added LST_InsertBefore(). ++ *! 03-Feb-2000 rr: Module init/exit is handled by SERVICES Init/Exit. ++ *! GT Changes. ++ *! 22-Nov-1999 kc: Added changes from code review. ++ *! 10-Aug-1999 kc: Based on wsx-c18. ++ *! 16-Jun-1997 gp: Removed unnecessary enabling/disabling of interrupts around ++ *! list manipulation code. ++ *! 22-Oct-1996 gp: Added LST_RemoveElem, and LST_First/LST_Next iterators. ++ *! 10-Aug-1996 gp: Acquired from SMM for WinSPOX v. 1.1; renamed identifiers. ++ */ ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++/* ----------------------------------- Globals */ ++#if GT_TRACE ++static struct GT_Mask LST_debugMask = { NULL, NULL }; /* GT trace var. */ ++#endif ++ ++/* ++ * ======== LST_Create ======== ++ * Purpose: ++ * Allocates and initializes a circular list. ++ */ ++struct LST_LIST *LST_Create(void) ++{ ++ struct LST_LIST *pList; ++ ++ GT_0trace(LST_debugMask, GT_ENTER, "LST_Create: entered\n"); ++ ++ pList = (struct LST_LIST *) MEM_Calloc(sizeof(struct LST_LIST), ++ MEM_NONPAGED); ++ if (pList != NULL) { ++ pList->head.next = &pList->head; ++ pList->head.prev = &pList->head; ++ pList->head.self = NULL; ++ } ++ ++ return pList; ++} ++ ++/* ++ * ======== LST_Delete ======== ++ * Purpose: ++ * Removes a list by freeing its control structure's memory space. ++ */ ++void LST_Delete(struct LST_LIST *pList) ++{ ++ DBC_Require(pList != NULL); ++ ++ GT_1trace(LST_debugMask, GT_ENTER, "LST_Delete: pList 0x%x\n", pList); ++ ++ MEM_Free(pList); ++} ++ ++/* ++ * ======== LST_Exit ======== ++ * Purpose: ++ * Discontinue usage of the LST module. ++ */ ++void LST_Exit(void) ++{ ++ GT_0trace(LST_debugMask, GT_5CLASS, "LST_Exit\n"); ++} ++ ++/* ++ * ======== LST_First ======== ++ * Purpose: ++ * Returns a pointer to the first element of the list, or NULL if the ++ * list is empty. ++ */ ++struct LST_ELEM *LST_First(struct LST_LIST *pList) ++{ ++ struct LST_ELEM *pElem = NULL; ++ ++ DBC_Require(pList != NULL); ++ ++ GT_1trace(LST_debugMask, GT_ENTER, "LST_First: pList 0x%x\n", pList); ++ ++ if (!LST_IsEmpty(pList)) ++ pElem = pList->head.next; ++ ++ return pElem; ++} ++ ++/* ++ * ======== LST_GetHead ======== ++ * Purpose: ++ * "Pops" the head off the list and returns a pointer to it. ++ */ ++struct LST_ELEM *LST_GetHead(struct LST_LIST *pList) ++{ ++ struct LST_ELEM *pElem; ++ ++ DBC_Require(pList != NULL); ++ ++ GT_1trace(LST_debugMask, GT_ENTER, "LST_GetHead: pList 0x%x\n", pList); ++ ++ if (LST_IsEmpty(pList)) ++ return NULL; ++ ++ /* pElem is always valid because the list cannot be empty ++ * at this point */ ++ pElem = pList->head.next; ++ pList->head.next = pElem->next; ++ pElem->next->prev = &pList->head; ++ ++ return pElem->self; ++} ++ ++/* ++ * ======== LST_Init ======== ++ * Purpose: ++ * Initialize LST module private state. ++ */ ++bool LST_Init(void) ++{ ++ GT_create(&LST_debugMask, "LS"); /* LS for LSt module */ ++ ++ GT_0trace(LST_debugMask, GT_5CLASS, "LST_Init\n"); ++ ++ return true; ++} ++ ++/* ++ * ======== LST_InitElem ======== ++ * Purpose: ++ * Initializes a list element to default (cleared) values ++ */ ++void LST_InitElem(struct LST_ELEM *pElem) ++{ ++ DBC_Require(pElem != NULL); ++ ++ GT_1trace(LST_debugMask, GT_ENTER, "LST_InitElem: pElem 0x%x\n", pElem); ++ ++ if (pElem) { ++ pElem->next = NULL; ++ pElem->prev = NULL; ++ pElem->self = pElem; ++ } ++} ++ ++/* ++ * ======== LST_InsertBefore ======== ++ * Purpose: ++ * Insert the element before the existing element. ++ */ ++void LST_InsertBefore(struct LST_LIST *pList, struct LST_ELEM *pElem, ++ struct LST_ELEM *pElemExisting) ++{ ++ DBC_Require(pList != NULL); ++ DBC_Require(pElem != NULL); ++ DBC_Require(pElemExisting != NULL); ++ ++ GT_3trace(LST_debugMask, GT_ENTER, "LST_InsertBefore: pList 0x%x, " ++ "pElem 0x%x pElemExisting 0x%x\n", pList, pElem, ++ pElemExisting); ++ ++ pElemExisting->prev->next = pElem; ++ pElem->prev = pElemExisting->prev; ++ pElem->next = pElemExisting; ++ pElemExisting->prev = pElem; ++} ++ ++/* ++ * ======== LST_Next ======== ++ * Purpose: ++ * Returns a pointer to the next element of the list, or NULL if the ++ * next element is the head of the list or the list is empty. ++ */ ++struct LST_ELEM *LST_Next(struct LST_LIST *pList, struct LST_ELEM *pCurElem) ++{ ++ struct LST_ELEM *pNextElem = NULL; ++ ++ DBC_Require(pList != NULL); ++ DBC_Require(pCurElem != NULL); ++ ++ GT_2trace(LST_debugMask, GT_ENTER, ++ "LST_Next: pList 0x%x, pCurElem 0x%x\n", ++ pList, pCurElem); ++ ++ if (!LST_IsEmpty(pList)) { ++ if (pCurElem->next != &pList->head) ++ pNextElem = pCurElem->next; ++ } ++ ++ return pNextElem; ++} ++ ++/* ++ * ======== LST_PutTail ======== ++ * Purpose: ++ * Adds the specified element to the tail of the list ++ */ ++void LST_PutTail(struct LST_LIST *pList, struct LST_ELEM *pElem) ++{ ++ DBC_Require(pList != NULL); ++ DBC_Require(pElem != NULL); ++ ++ GT_2trace(LST_debugMask, GT_ENTER, ++ "LST_PutTail: pList 0x%x, pElem 0x%x\n", ++ pList, pElem); ++ ++ pElem->prev = pList->head.prev; ++ pElem->next = &pList->head; ++ pList->head.prev = pElem; ++ pElem->prev->next = pElem; ++ ++ DBC_Ensure(!LST_IsEmpty(pList)); ++} ++ ++/* ++ * ======== LST_RemoveElem ======== ++ * Purpose: ++ * Removes (unlinks) the given element from the list, if the list is not ++ * empty. Does not free the list element. ++ */ ++void LST_RemoveElem(struct LST_LIST *pList, struct LST_ELEM *pCurElem) ++{ ++ DBC_Require(pList != NULL); ++ DBC_Require(pCurElem != NULL); ++ ++ GT_2trace(LST_debugMask, GT_ENTER, ++ "LST_RemoveElem: pList 0x%x, pCurElem " ++ "0x%x\n", pList, pCurElem); ++ ++ if (!LST_IsEmpty(pList)) { ++ pCurElem->prev->next = pCurElem->next; ++ pCurElem->next->prev = pCurElem->prev; ++ ++ /* set elem fields to NULL to prevent illegal references */ ++ pCurElem->next = NULL; ++ pCurElem->prev = NULL; ++ } ++} ++ +diff --git a/drivers/dsp/bridge/services/mem.c b/drivers/dsp/bridge/services/mem.c +new file mode 100644 +index 0000000..0a10304 +--- /dev/null ++++ b/drivers/dsp/bridge/services/mem.c +@@ -0,0 +1,599 @@ ++/* ++ * mem.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== mem.c ======== ++ * Purpose: ++ * Implementation of platform specific memory services. ++ * ++ * Public Functions: ++ * MEM_Alloc ++ * MEM_AllocPhysMem ++ * MEM_Calloc ++ * MEM_Exit ++ * MEM_FlushCache ++ * MEM_Free ++ * MEM_FreePhysMem ++ * MEM_Init ++ * MEM_ExtPhysPoolInit ++ * ++ *! Revision History: ++ *! ================= ++ *! 18-Jan-2004 hp: Added support for External physical memory pool ++ *! 19-Apr-2004 sb: Added Alloc/Free PhysMem, FlushCache, VirtualToPhysical ++ *! 01-Sep-2001 ag: Code cleanup. ++ *! 02-May-2001 ag: MEM_[UnMap]LinearAddress revamped to align Phys to Virt. ++ *! Set PAGE_PHYSICAL if phy addr <= 512MB. Opposite uSoft doc! ++ *! 29-Aug-2000 rr: MEM_LinearAddress does not check for 512MB for non-x86. ++ *! 28-Mar-2000 rr: MEM_LinearAddress changed.Handles address larger than 512MB ++ *! 03-Feb-2000 rr: Module init/exit is handled by SERVICES Init/Exit. ++ *! GT Changes. ++ *! 22-Nov-1999 kc: Added changes from code review. ++ *! 16-Aug-1999 kc: modified for WinCE. ++ *! 20-Mar-1999 ag: SP 4 fix in MEM_UMBCalloc(). ++ *! Mdl offset now ORed not added to userBuf. ++ *! 23-Dec-1997 cr: Code review changes. ++ *! 08-Dec-1997 cr: Prepared for code review. ++ *! 24-Jun-1997 cr: Created. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++#include ++ ++/* ----------------------------------- Defines */ ++#define MEM_512MB 0x1fffffff ++#define memInfoSign 0x464E494D /* "MINF" (in reverse). */ ++ ++#ifdef DEBUG ++#define MEM_CHECK /* Use to detect source of memory leaks */ ++#endif ++ ++/* ----------------------------------- Globals */ ++#if GT_TRACE ++static struct GT_Mask MEM_debugMask = { NULL, NULL }; /* GT trace variable */ ++#endif ++ ++static u32 cRefs; /* module reference count */ ++ ++static bool extPhysMemPoolEnabled; ++ ++struct extPhysMemPool { ++ u32 physMemBase; ++ u32 physMemSize; ++ u32 virtMemBase; ++ u32 nextPhysAllocPtr; ++}; ++ ++static struct extPhysMemPool extMemPool; ++ ++/* Information about each element allocated on heap */ ++struct memInfo { ++ struct LST_ELEM link; /* Must be first */ ++ size_t size; ++ void *caller; ++ u32 dwSignature; /* Should be last */ ++}; ++ ++#ifdef MEM_CHECK ++ ++/* ++ * This structure holds a linked list to all memory elements allocated on ++ * heap by DSP/BIOS Bridge. This is used to report memory leaks and free ++ * such elements while removing the DSP/BIOS Bridge driver ++ */ ++struct memMan { ++ struct LST_LIST lst; ++ spinlock_t lock; ++}; ++ ++static struct memMan mMan; ++ ++/* ++ * These functions are similar to LST_PutTail and LST_RemoveElem and are ++ * duplicated here to make MEM independent of LST ++ */ ++static inline void MLST_PutTail(struct LST_LIST *pList, struct LST_ELEM *pElem) ++{ ++ pElem->prev = pList->head.prev; ++ pElem->next = &pList->head; ++ pList->head.prev = pElem; ++ pElem->prev->next = pElem; ++ pElem->self = pElem; ++} ++ ++static inline void MLST_RemoveElem(struct LST_LIST *pList, ++ struct LST_ELEM *pCurElem) ++{ ++ pCurElem->prev->next = pCurElem->next; ++ pCurElem->next->prev = pCurElem->prev; ++ pCurElem->next = NULL; ++ pCurElem->prev = NULL; ++} ++ ++static void MEM_Check(void) ++{ ++ struct memInfo *pMem; ++ struct LST_ELEM *last = &mMan.lst.head; ++ struct LST_ELEM *curr = mMan.lst.head.next; ++ ++ if (!LST_IsEmpty(&mMan.lst)) { ++ GT_0trace(MEM_debugMask, GT_7CLASS, "*** MEMORY LEAK ***\n"); ++ GT_0trace(MEM_debugMask, GT_7CLASS, ++ "Addr Size Caller\n"); ++ while (curr != last) { ++ pMem = (struct memInfo *)curr; ++ curr = curr->next; ++ if ((u32)pMem > PAGE_OFFSET && ++ MEM_IsValidHandle(pMem, memInfoSign)) { ++ GT_3trace(MEM_debugMask, GT_7CLASS, ++ "%lx %d\t [<%p>]\n", ++ (u32) pMem + sizeof(struct memInfo), ++ pMem->size, pMem->caller); ++ MLST_RemoveElem(&mMan.lst, ++ (struct LST_ELEM *) pMem); ++ kfree(pMem); ++ } else { ++ GT_1trace(MEM_debugMask, GT_7CLASS, ++ "Invalid allocation or " ++ "Buffer underflow at %x\n", ++ (u32)pMem + sizeof(struct memInfo)); ++ break; ++ } ++ } ++ } ++ DBC_Ensure(LST_IsEmpty(&mMan.lst)); ++} ++ ++#endif ++ ++void MEM_ExtPhysPoolInit(u32 poolPhysBase, u32 poolSize) ++{ ++ u32 poolVirtBase; ++ ++ /* get the virtual address for the physical memory pool passed */ ++ poolVirtBase = (u32)ioremap(poolPhysBase, poolSize); ++ ++ if ((void **)poolVirtBase == NULL) { ++ GT_0trace(MEM_debugMask, GT_7CLASS, ++ "[PHYS_POOL]Mapping External " ++ "physical memory to virt failed \n"); ++ extPhysMemPoolEnabled = false; ++ } else { ++ extMemPool.physMemBase = poolPhysBase; ++ extMemPool.physMemSize = poolSize; ++ extMemPool.virtMemBase = poolVirtBase; ++ extMemPool.nextPhysAllocPtr = poolPhysBase; ++ extPhysMemPoolEnabled = true; ++ GT_3trace(MEM_debugMask, GT_1CLASS, ++ "ExtMemory Pool details " "Pool" ++ "Physical mem base = %0x " "Pool Physical mem size " ++ "= %0x" "Pool Virtual mem base = %0x \n", ++ poolPhysBase, poolSize, poolVirtBase); ++ } ++} ++ ++static void MEM_ExtPhysPoolRelease(void) ++{ ++ GT_0trace(MEM_debugMask, GT_1CLASS, ++ "Releasing External memory pool \n"); ++ if (extPhysMemPoolEnabled) { ++ iounmap((void *)(extMemPool.virtMemBase)); ++ extPhysMemPoolEnabled = false; ++ } ++} ++ ++/* ++ * ======== MEM_ExtPhysMemAlloc ======== ++ * Purpose: ++ * Allocate physically contiguous, uncached memory from external memory pool ++ */ ++ ++static void *MEM_ExtPhysMemAlloc(u32 bytes, u32 align, OUT u32 *pPhysAddr) ++{ ++ u32 newAllocPtr; ++ u32 offset; ++ u32 virtAddr; ++ ++ GT_2trace(MEM_debugMask, GT_1CLASS, ++ "Ext Memory Allocation" "bytes=0x%x , " ++ "align=0x%x \n", bytes, align); ++ if (align == 0) { ++ GT_0trace(MEM_debugMask, GT_7CLASS, ++ "ExtPhysical Memory Allocation " ++ "No alignment request in allocation call !! \n"); ++ align = 1; ++ } ++ if (bytes > ((extMemPool.physMemBase + extMemPool.physMemSize) ++ - extMemPool.nextPhysAllocPtr)) { ++ GT_1trace(MEM_debugMask, GT_7CLASS, ++ "ExtPhysical Memory Allocation " ++ "unable to allocate memory for bytes = 0x%x \n", ++ bytes); ++ pPhysAddr = NULL; ++ return NULL; ++ } else { ++ offset = (extMemPool.nextPhysAllocPtr & (align - 1)); ++ if (offset == 0) ++ newAllocPtr = extMemPool.nextPhysAllocPtr; ++ else ++ newAllocPtr = (extMemPool.nextPhysAllocPtr) + ++ (align - offset); ++ if ((newAllocPtr + bytes) <= ++ (extMemPool.physMemBase + extMemPool.physMemSize)) { ++ /* we can allocate */ ++ *pPhysAddr = newAllocPtr; ++ extMemPool.nextPhysAllocPtr = newAllocPtr + bytes; ++ virtAddr = extMemPool.virtMemBase + (newAllocPtr - ++ extMemPool.physMemBase); ++ GT_2trace(MEM_debugMask, GT_1CLASS, ++ "Ext Memory Allocation succedded " ++ "phys address=0x%x , virtaddress=0x%x \n", ++ newAllocPtr, virtAddr); ++ return (void *)virtAddr; ++ } else { ++ *pPhysAddr = 0; ++ return NULL; ++ } ++ } ++} ++ ++/* ++ * ======== MEM_Alloc ======== ++ * Purpose: ++ * Allocate memory from the paged or non-paged pools. ++ */ ++void *MEM_Alloc(u32 cBytes, enum MEM_POOLATTRS type) ++{ ++ struct memInfo *pMem = NULL; ++ ++ GT_2trace(MEM_debugMask, GT_ENTER, ++ "MEM_Alloc: cBytes 0x%x\ttype 0x%x\n", cBytes, type); ++ if (cBytes > 0) { ++ switch (type) { ++ case MEM_NONPAGED: ++ /* If non-paged memory required, see note at top of file. */ ++ case MEM_PAGED: ++#ifndef MEM_CHECK ++ pMem = kmalloc(cBytes, ++ (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL); ++#else ++ pMem = kmalloc(cBytes + sizeof(struct memInfo), ++ (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL); ++ if (pMem) { ++ pMem->size = cBytes; ++ pMem->caller = __builtin_return_address(0); ++ pMem->dwSignature = memInfoSign; ++ ++ spin_lock(&mMan.lock); ++ MLST_PutTail(&mMan.lst, ++ (struct LST_ELEM *)pMem); ++ spin_unlock(&mMan.lock); ++ ++ pMem = (void *)((u32)pMem + ++ sizeof(struct memInfo)); ++ } ++#endif ++ break; ++ case MEM_LARGEVIRTMEM: ++#ifndef MEM_CHECK ++ /* FIXME - Replace with 'vmalloc' after BP fix */ ++ pMem = __vmalloc(cBytes, ++ (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL, PAGE_KERNEL); ++#else ++ /* FIXME - Replace with 'vmalloc' after BP fix */ ++ pMem = __vmalloc((cBytes + sizeof(struct memInfo)), ++ (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL, PAGE_KERNEL); ++ if (pMem) { ++ pMem->size = cBytes; ++ pMem->caller = __builtin_return_address(0); ++ pMem->dwSignature = memInfoSign; ++ ++ spin_lock(&mMan.lock); ++ MLST_PutTail(&mMan.lst, ++ (struct LST_ELEM *) pMem); ++ spin_unlock(&mMan.lock); ++ ++ pMem = (void *)((u32)pMem + ++ sizeof(struct memInfo)); ++ } ++#endif ++ break; ++ ++ default: ++ GT_0trace(MEM_debugMask, GT_6CLASS, ++ "MEM_Alloc: unexpected " ++ "MEM_POOLATTRS value\n"); ++ break; ++ } ++ } ++ ++ return pMem; ++} ++ ++/* ++ * ======== MEM_AllocPhysMem ======== ++ * Purpose: ++ * Allocate physically contiguous, uncached memory ++ */ ++void *MEM_AllocPhysMem(u32 cBytes, u32 ulAlign, OUT u32 *pPhysicalAddress) ++{ ++ void *pVaMem = NULL; ++ dma_addr_t paMem; ++ ++ DBC_Require(cRefs > 0); ++ ++ GT_2trace(MEM_debugMask, GT_ENTER, ++ "MEM_AllocPhysMem: cBytes 0x%x\tulAlign" ++ "0x%x\n", cBytes, ulAlign); ++ ++ if (cBytes > 0) { ++ if (extPhysMemPoolEnabled) { ++ pVaMem = MEM_ExtPhysMemAlloc(cBytes, ulAlign, ++ (u32 *)&paMem); ++ } else ++ pVaMem = dma_alloc_coherent(NULL, cBytes, &paMem, ++ (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL); ++ if (pVaMem == NULL) { ++ *pPhysicalAddress = 0; ++ GT_1trace(MEM_debugMask, GT_6CLASS, ++ "MEM_AllocPhysMem failed: " ++ "0x%x\n", pVaMem); ++ } else { ++ *pPhysicalAddress = paMem; ++ } ++ } ++ return pVaMem; ++} ++ ++/* ++ * ======== MEM_Calloc ======== ++ * Purpose: ++ * Allocate zero-initialized memory from the paged or non-paged pools. ++ */ ++void *MEM_Calloc(u32 cBytes, enum MEM_POOLATTRS type) ++{ ++ struct memInfo *pMem = NULL; ++ ++ GT_2trace(MEM_debugMask, GT_ENTER, ++ "MEM_Calloc: cBytes 0x%x\ttype 0x%x\n", ++ cBytes, type); ++ ++ if (cBytes > 0) { ++ switch (type) { ++ case MEM_NONPAGED: ++ /* If non-paged memory required, see note at top of file. */ ++ case MEM_PAGED: ++#ifndef MEM_CHECK ++ pMem = kmalloc(cBytes, ++ (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL); ++ if (pMem) ++ memset(pMem, 0, cBytes); ++ ++#else ++ pMem = kmalloc(cBytes + sizeof(struct memInfo), ++ (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL); ++ if (pMem) { ++ memset((void *)((u32)pMem + ++ sizeof(struct memInfo)), 0, cBytes); ++ pMem->size = cBytes; ++ pMem->caller = __builtin_return_address(0); ++ pMem->dwSignature = memInfoSign; ++ spin_lock(&mMan.lock); ++ MLST_PutTail(&mMan.lst, ++ (struct LST_ELEM *) pMem); ++ spin_unlock(&mMan.lock); ++ pMem = (void *)((u32)pMem + ++ sizeof(struct memInfo)); ++ } ++#endif ++ break; ++ case MEM_LARGEVIRTMEM: ++#ifndef MEM_CHECK ++ /* FIXME - Replace with 'vmalloc' after BP fix */ ++ pMem = __vmalloc(cBytes, ++ (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL, PAGE_KERNEL); ++ if (pMem) ++ memset(pMem, 0, cBytes); ++ ++#else ++ /* FIXME - Replace with 'vmalloc' after BP fix */ ++ pMem = __vmalloc(cBytes + sizeof(struct memInfo), ++ (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL, PAGE_KERNEL); ++ if (pMem) { ++ memset((void *)((u32)pMem + ++ sizeof(struct memInfo)), 0, cBytes); ++ pMem->size = cBytes; ++ pMem->caller = __builtin_return_address(0); ++ pMem->dwSignature = memInfoSign; ++ spin_lock(&mMan.lock); ++ MLST_PutTail(&mMan.lst, (struct LST_ELEM *) ++ pMem); ++ spin_unlock(&mMan.lock); ++ pMem = (void *)((u32)pMem + ++ sizeof(struct memInfo)); ++ } ++#endif ++ break; ++ default: ++ GT_1trace(MEM_debugMask, GT_6CLASS, ++ "MEM_Calloc: unexpected " ++ "MEM_POOLATTRS value 0x%x\n", type); ++ break; ++ } ++ } ++ ++ return pMem; ++} ++ ++/* ++ * ======== MEM_Exit ======== ++ * Purpose: ++ * Discontinue usage of the MEM module. ++ */ ++void MEM_Exit(void) ++{ ++ DBC_Require(cRefs > 0); ++ ++ GT_1trace(MEM_debugMask, GT_5CLASS, "MEM_Exit: cRefs 0x%x\n", cRefs); ++ ++ cRefs--; ++#ifdef MEM_CHECK ++ if (cRefs == 0) ++ MEM_Check(); ++ ++#endif ++ MEM_ExtPhysPoolRelease(); ++ DBC_Ensure(cRefs >= 0); ++} ++ ++/* ++ * ======== MEM_FlushCache ======== ++ * Purpose: ++ * Flush cache ++ */ ++void MEM_FlushCache(void *pMemBuf, u32 cBytes, s32 FlushType) ++{ ++ DBC_Require(cRefs > 0); ++ ++ switch (FlushType) { ++ /* invalidate only */ ++ case PROC_INVALIDATE_MEM: ++ dmac_inv_range(pMemBuf, pMemBuf + cBytes); ++ outer_inv_range(__pa((u32)pMemBuf), __pa((u32)pMemBuf + ++ cBytes)); ++ break; ++ /* writeback only */ ++ case PROC_WRITEBACK_MEM: ++ dmac_clean_range(pMemBuf, pMemBuf + cBytes); ++ outer_clean_range(__pa((u32)pMemBuf), __pa((u32)pMemBuf + ++ cBytes)); ++ break; ++ /* writeback and invalidate */ ++ case PROC_WRITEBACK_INVALIDATE_MEM: ++ dmac_flush_range(pMemBuf, pMemBuf + cBytes); ++ outer_flush_range(__pa((u32)pMemBuf), __pa((u32)pMemBuf + ++ cBytes)); ++ break; ++ default: ++ GT_1trace(MEM_debugMask, GT_6CLASS, "MEM_FlushCache: invalid " ++ "FlushMemType 0x%x\n", FlushType); ++ break; ++ } ++ ++} ++ ++ ++/* ++ * ======== MEM_Free ======== ++ * Purpose: ++ * Free the given block of system memory. ++ */ ++void MEM_Free(IN void *pMemBuf) ++{ ++#ifdef MEM_CHECK ++ struct memInfo *pMem = (void *)((u32)pMemBuf - sizeof(struct memInfo)); ++#endif ++ ++ DBC_Require(pMemBuf != NULL); ++ ++ GT_1trace(MEM_debugMask, GT_ENTER, "MEM_Free: pMemBufs 0x%x\n", ++ pMemBuf); ++ ++ if (pMemBuf) { ++#ifndef MEM_CHECK ++ kfree(pMemBuf); ++#else ++ if (pMem) { ++ if (pMem->dwSignature == memInfoSign) { ++ spin_lock(&mMan.lock); ++ MLST_RemoveElem(&mMan.lst, ++ (struct LST_ELEM *) pMem); ++ spin_unlock(&mMan.lock); ++ pMem->dwSignature = 0; ++ kfree(pMem); ++ } else { ++ GT_1trace(MEM_debugMask, GT_7CLASS, ++ "Invalid allocation or " ++ "Buffer underflow at %x\n", ++ (u32) pMem + sizeof(struct memInfo)); ++ } ++ } ++#endif ++ } ++} ++ ++/* ++ * ======== MEM_FreePhysMem ======== ++ * Purpose: ++ * Free the given block of physically contiguous memory. ++ */ ++void MEM_FreePhysMem(void *pVirtualAddress, u32 pPhysicalAddress, ++ u32 cBytes) ++{ ++ DBC_Require(cRefs > 0); ++ DBC_Require(pVirtualAddress != NULL); ++ ++ GT_1trace(MEM_debugMask, GT_ENTER, "MEM_FreePhysMem: pVirtualAddress " ++ "0x%x\n", pVirtualAddress); ++ ++ if (!extPhysMemPoolEnabled) ++ dma_free_coherent(NULL, cBytes, pVirtualAddress, ++ pPhysicalAddress); ++} ++ ++/* ++ * ======== MEM_Init ======== ++ * Purpose: ++ * Initialize MEM module private state. ++ */ ++bool MEM_Init(void) ++{ ++ DBC_Require(cRefs >= 0); ++ ++ if (cRefs == 0) { ++ GT_create(&MEM_debugMask, "MM"); /* MM for MeM module */ ++ ++#ifdef MEM_CHECK ++ mMan.lst.head.next = &mMan.lst.head; ++ mMan.lst.head.prev = &mMan.lst.head; ++ mMan.lst.head.self = NULL; ++ spin_lock_init(&mMan.lock); ++#endif ++ ++ } ++ ++ cRefs++; ++ ++ GT_1trace(MEM_debugMask, GT_5CLASS, "MEM_Init: cRefs 0x%x\n", cRefs); ++ ++ DBC_Ensure(cRefs > 0); ++ ++ return true; ++} +diff --git a/drivers/dsp/bridge/services/ntfy.c b/drivers/dsp/bridge/services/ntfy.c +new file mode 100644 +index 0000000..2eff3eb +--- /dev/null ++++ b/drivers/dsp/bridge/services/ntfy.c +@@ -0,0 +1,329 @@ ++/* ++ * ntfy.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== ntfyce.c ======== ++ * Purpose: ++ * Manage lists of notification events. ++ * ++ * Public Functions: ++ * NTFY_Create ++ * NTFY_Delete ++ * NTFY_Exit ++ * NTFY_Init ++ * NTFY_Notify ++ * NTFY_Register ++ * ++ *! Revision History: ++ *! ================= ++ *! 06-Feb-2003 kc Removed DSP_POSTMESSAGE related code. ++ *! 05-Nov-2001 kc Updated DSP_HNOTIFICATION structure. ++ *! 10-May-2001 jeh Removed SERVICES module init/exit from NTFY_Init/Exit. ++ *! NTFY_Register() returns DSP_ENOTIMPL for all but ++ *! DSP_SIGNALEVENT. ++ *! 12-Oct-2000 jeh Use MEM_IsValidHandle(). ++ *! 07-Sep-2000 jeh Created. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++/* ----------------------------------- Defines, Data Structures, Typedefs */ ++#define NTFY_SIGNATURE 0x5946544e /* "YFTN" */ ++ ++/* ++ * ======== NTFY_OBJECT ======== ++ */ ++struct NTFY_OBJECT { ++ u32 dwSignature; /* For object validation */ ++ struct LST_LIST *notifyList; /* List of NOTIFICATION objects */ ++ struct SYNC_CSOBJECT *hSync; /* For critical sections */ ++}; ++ ++/* ++ * ======== NOTIFICATION ======== ++ * This object will be created when a client registers for events. ++ */ ++struct NOTIFICATION { ++ struct LST_ELEM listElem; ++ u32 uEventMask; /* Events to be notified about */ ++ u32 uNotifyType; /* Type of notification to be sent */ ++ ++ /* ++ * We keep a copy of the event name to check if the event has ++ * already been registered. (SYNC also keeps a copy of the name). ++ */ ++ char *pstrName; /* Name of event */ ++ HANDLE hEvent; /* Handle for notification */ ++ struct SYNC_OBJECT *hSync; ++}; ++ ++/* ----------------------------------- Globals */ ++#if GT_TRACE ++static struct GT_Mask NTFY_debugMask = { NULL, NULL }; /* GT trace variable */ ++#endif ++ ++/* ----------------------------------- Function Prototypes */ ++static void DeleteNotify(struct NOTIFICATION *pNotify); ++ ++/* ++ * ======== NTFY_Create ======== ++ * Purpose: ++ * Create an empty list of notifications. ++ */ ++DSP_STATUS NTFY_Create(struct NTFY_OBJECT **phNtfy) ++{ ++ struct NTFY_OBJECT *pNtfy; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(phNtfy != NULL); ++ ++ *phNtfy = NULL; ++ MEM_AllocObject(pNtfy, struct NTFY_OBJECT, NTFY_SIGNATURE); ++ ++ if (pNtfy) { ++ ++ status = SYNC_InitializeDPCCS(&pNtfy->hSync); ++ if (DSP_SUCCEEDED(status)) { ++ pNtfy->notifyList = LST_Create(); ++ if (pNtfy->notifyList == NULL) { ++ (void) SYNC_DeleteCS(pNtfy->hSync); ++ MEM_FreeObject(pNtfy); ++ status = DSP_EMEMORY; ++ } else { ++ *phNtfy = pNtfy; ++ } ++ } ++ } else { ++ status = DSP_EMEMORY; ++ } ++ ++ DBC_Ensure((DSP_FAILED(status) && *phNtfy == NULL) || ++ (DSP_SUCCEEDED(status) && MEM_IsValidHandle((*phNtfy), ++ NTFY_SIGNATURE))); ++ ++ return status; ++} ++ ++/* ++ * ======== NTFY_Delete ======== ++ * Purpose: ++ * Free resources allocated in NTFY_Create. ++ */ ++void NTFY_Delete(struct NTFY_OBJECT *hNtfy) ++{ ++ struct NOTIFICATION *pNotify; ++ ++ DBC_Require(MEM_IsValidHandle(hNtfy, NTFY_SIGNATURE)); ++ ++ /* Remove any elements remaining in list */ ++ if (hNtfy->notifyList) { ++ while ((pNotify = (struct NOTIFICATION *)LST_GetHead(hNtfy-> ++ notifyList))) { ++ DeleteNotify(pNotify); ++ } ++ DBC_Assert(LST_IsEmpty(hNtfy->notifyList)); ++ LST_Delete(hNtfy->notifyList); ++ } ++ if (hNtfy->hSync) ++ (void)SYNC_DeleteCS(hNtfy->hSync); ++ ++ MEM_FreeObject(hNtfy); ++} ++ ++/* ++ * ======== NTFY_Exit ======== ++ * Purpose: ++ * Discontinue usage of NTFY module. ++ */ ++void NTFY_Exit(void) ++{ ++ GT_0trace(NTFY_debugMask, GT_5CLASS, "Entered NTFY_Exit\n"); ++} ++ ++/* ++ * ======== NTFY_Init ======== ++ * Purpose: ++ * Initialize the NTFY module. ++ */ ++bool NTFY_Init(void) ++{ ++ GT_create(&NTFY_debugMask, "NY"); /* "NY" for NtfY */ ++ ++ GT_0trace(NTFY_debugMask, GT_5CLASS, "NTFY_Init()\n"); ++ ++ return true; ++} ++ ++/* ++ * ======== NTFY_Notify ======== ++ * Purpose: ++ * Execute notify function (signal event) for every ++ * element in the notification list that is to be notified about the ++ * event specified in uEventMask. ++ */ ++void NTFY_Notify(struct NTFY_OBJECT *hNtfy, u32 uEventMask) ++{ ++ struct NOTIFICATION *pNotify; ++ ++ DBC_Require(MEM_IsValidHandle(hNtfy, NTFY_SIGNATURE)); ++ ++ /* ++ * Go through notifyList and notify all clients registered for ++ * uEventMask events. ++ */ ++ ++ (void) SYNC_EnterCS(hNtfy->hSync); ++ ++ pNotify = (struct NOTIFICATION *)LST_First(hNtfy->notifyList); ++ while (pNotify != NULL) { ++ if (pNotify->uEventMask & uEventMask) { ++ /* Notify */ ++ if (pNotify->uNotifyType == DSP_SIGNALEVENT) ++ (void)SYNC_SetEvent(pNotify->hSync); ++ ++ } ++ pNotify = (struct NOTIFICATION *)LST_Next(hNtfy->notifyList, ++ (struct LST_ELEM *)pNotify); ++ } ++ ++ (void) SYNC_LeaveCS(hNtfy->hSync); ++} ++ ++/* ++ * ======== NTFY_Register ======== ++ * Purpose: ++ * Add a notification element to the list. If the notification is already ++ * registered, and uEventMask != 0, the notification will get posted for ++ * events specified in the new event mask. If the notification is already ++ * registered and uEventMask == 0, the notification will be unregistered. ++ */ ++DSP_STATUS NTFY_Register(struct NTFY_OBJECT *hNtfy, ++ struct DSP_NOTIFICATION *hNotification, ++ u32 uEventMask, u32 uNotifyType) ++{ ++ struct NOTIFICATION *pNotify; ++ struct SYNC_ATTRS syncAttrs; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(MEM_IsValidHandle(hNtfy, NTFY_SIGNATURE)); ++ ++ if (hNotification == NULL) ++ status = DSP_EHANDLE; ++ ++ /* Return DSP_ENOTIMPL if uNotifyType is not supported */ ++ if (DSP_SUCCEEDED(status)) { ++ if (!IsValidNotifyMask(uNotifyType)) ++ status = DSP_ENOTIMPL; ++ ++ } ++ ++ if (DSP_FAILED(status)) ++ return status; ++ ++ (void)SYNC_EnterCS(hNtfy->hSync); ++ ++ pNotify = (struct NOTIFICATION *)LST_First(hNtfy->notifyList); ++ while (pNotify != NULL) { ++ /* If there is more than one notification type, each ++ * type may require its own handler code. */ ++ ++ if (hNotification->handle == pNotify->hSync) { ++ /* found */ ++ break; ++ } ++ pNotify = (struct NOTIFICATION *)LST_Next(hNtfy->notifyList, ++ (struct LST_ELEM *)pNotify); ++ } ++ if (pNotify == NULL) { ++ /* Not registered */ ++ if (uEventMask == 0) { ++ status = DSP_EVALUE; ++ } else { ++ /* Allocate NOTIFICATION object, add to list */ ++ pNotify = MEM_Calloc(sizeof(struct NOTIFICATION), ++ MEM_PAGED); ++ if (pNotify == NULL) ++ status = DSP_EMEMORY; ++ ++ } ++ if (DSP_SUCCEEDED(status)) { ++ LST_InitElem((struct LST_ELEM *) pNotify); ++ /* If there is more than one notification type, each ++ * type may require its own handler code. */ ++ status = SYNC_OpenEvent(&pNotify->hSync, &syncAttrs); ++ hNotification->handle = pNotify->hSync; ++ ++ if (DSP_SUCCEEDED(status)) { ++ pNotify->uEventMask = uEventMask; ++ pNotify->uNotifyType = uNotifyType; ++ LST_PutTail(hNtfy->notifyList, ++ (struct LST_ELEM *)pNotify); ++ } else { ++ DeleteNotify(pNotify); ++ } ++ } ++ } else { ++ /* Found in list */ ++ if (uEventMask == 0) { ++ /* Remove from list and free */ ++ LST_RemoveElem(hNtfy->notifyList, ++ (struct LST_ELEM *)pNotify); ++ DeleteNotify(pNotify); ++ } else { ++ /* Update notification mask (type shouldn't change) */ ++ pNotify->uEventMask = uEventMask; ++ } ++ } ++ (void)SYNC_LeaveCS(hNtfy->hSync); ++ return status; ++} ++ ++/* ++ * ======== DeleteNotify ======== ++ * Purpose: ++ * Free the notification object. ++ */ ++static void DeleteNotify(struct NOTIFICATION *pNotify) ++{ ++ if (pNotify->hSync) ++ (void) SYNC_CloseEvent(pNotify->hSync); ++ ++ if (pNotify->pstrName) ++ MEM_Free(pNotify->pstrName); ++ ++ MEM_Free(pNotify); ++} ++ +diff --git a/drivers/dsp/bridge/services/reg.c b/drivers/dsp/bridge/services/reg.c +new file mode 100644 +index 0000000..0d85f41 +--- /dev/null ++++ b/drivers/dsp/bridge/services/reg.c +@@ -0,0 +1,196 @@ ++/* ++ * reg.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== regce.c ======== ++ * Purpose: ++ * Provide registry functions. ++ * ++ * Public Functions: ++ * REG_DeleteValue ++ * REG_EnumValue ++ * REG_Exit ++ * REG_GetValue ++ * REG_Init ++ * REG_SetValue ++ * ++ *! Revision History: ++ *! ================ ++ * ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++ ++/* ----------------------------------- Others */ ++#include ++ ++/* ----------------------------------- This */ ++#include ++#include ++ ++#if GT_TRACE ++struct GT_Mask REG_debugMask = { NULL, NULL }; /* GT trace var. */ ++#endif ++ ++/* ++ * ======== REG_DeleteValue ======== ++ * Deletes a registry entry value. NOTE: A registry entry value is not the ++ * same as * a registry key. ++ */ ++DSP_STATUS REG_DeleteValue(OPTIONAL IN HANDLE *phKey, IN CONST char *pstrSubkey, ++ IN CONST char *pstrValue) ++{ ++ DSP_STATUS status; ++ DBC_Require(pstrSubkey && pstrValue); ++ DBC_Require(phKey == NULL); ++ DBC_Require(strlen(pstrSubkey) < REG_MAXREGPATHLENGTH); ++ DBC_Require(strlen(pstrValue) < REG_MAXREGPATHLENGTH); ++ ++ GT_0trace(REG_debugMask, GT_ENTER, "REG_DeleteValue: entered\n"); ++ ++ /* Note that we don't use phKey */ ++ if (regsupDeleteValue(pstrSubkey, pstrValue) == DSP_SOK) ++ status = DSP_SOK; ++ else ++ status = DSP_EFAIL; ++ ++ return status; ++} ++ ++/* ++ * ======== REG_EnumValue ======== ++ * Enumerates a registry key and retrieve values stored under the key. ++ * We will assume the input pdwValueSize is smaller than ++ * REG_MAXREGPATHLENGTH for implementation purposes. ++ */ ++DSP_STATUS REG_EnumValue(IN HANDLE *phKey, IN u32 dwIndex, ++ IN CONST char *pstrKey, IN OUT char *pstrValue, ++ IN OUT u32 *pdwValueSize, IN OUT char *pstrData, ++ IN OUT u32 *pdwDataSize) ++{ ++ DSP_STATUS status; ++ ++ DBC_Require(pstrKey && pstrValue && pdwValueSize && pstrData && ++ pdwDataSize); ++ DBC_Require(*pdwValueSize <= REG_MAXREGPATHLENGTH); ++ DBC_Require(phKey == NULL); ++ DBC_Require(strlen(pstrKey) < REG_MAXREGPATHLENGTH); ++ ++ GT_0trace(REG_debugMask, GT_ENTER, "REG_EnumValue: entered\n"); ++ ++ status = regsupEnumValue(dwIndex, pstrKey, pstrValue, pdwValueSize, ++ pstrData, pdwDataSize); ++ ++ return status; ++} ++ ++/* ++ * ======== REG_Exit ======== ++ * Discontinue usage of the REG module. ++ */ ++void REG_Exit(void) ++{ ++ GT_0trace(REG_debugMask, GT_5CLASS, "REG_Exit\n"); ++ ++ regsupExit(); ++} ++ ++/* ++ * ======== REG_GetValue ======== ++ * Retrieve a value from the registry. ++ */ ++DSP_STATUS REG_GetValue(OPTIONAL IN HANDLE *phKey, IN CONST char *pstrSubkey, ++ IN CONST char *pstrValue, OUT u8 *pbData, ++ IN OUT u32 *pdwDataSize) ++{ ++ DSP_STATUS status; ++ ++ DBC_Require(pstrSubkey && pstrValue && pbData); ++ DBC_Require(phKey == NULL); ++ DBC_Require(strlen(pstrSubkey) < REG_MAXREGPATHLENGTH); ++ DBC_Require(strlen(pstrValue) < REG_MAXREGPATHLENGTH); ++ ++ GT_0trace(REG_debugMask, GT_ENTER, "REG_GetValue: entered\n"); ++ ++ /* We need to use regsup calls... */ ++ /* ...for now we don't need the key handle or */ ++ /* the subkey, all we need is the value to lookup. */ ++ if (regsupGetValue((char *)pstrValue, pbData, pdwDataSize) == DSP_SOK) ++ status = DSP_SOK; ++ else ++ status = DSP_EFAIL; ++ ++ return status; ++} ++ ++/* ++ * ======== REG_Init ======== ++ * Initialize the REG module's private state. ++ */ ++bool REG_Init(void) ++{ ++ bool fInit; ++ ++ GT_create(®_debugMask, "RG"); /* RG for ReG */ ++ ++ fInit = regsupInit(); ++ ++ GT_0trace(REG_debugMask, GT_5CLASS, "REG_Init\n"); ++ ++ return fInit; ++} ++ ++/* ++ * ======== REG_SetValue ======== ++ * Set a value in the registry. ++ */ ++DSP_STATUS REG_SetValue(OPTIONAL IN HANDLE *phKey, IN CONST char *pstrSubkey, ++ IN CONST char *pstrValue, IN CONST u32 dwType, ++ IN u8 *pbData, IN u32 dwDataSize) ++{ ++ DSP_STATUS status; ++ ++ DBC_Require(pstrValue && pbData); ++ DBC_Require(phKey == NULL); ++ DBC_Require(dwDataSize > 0); ++ DBC_Require(strlen(pstrValue) < REG_MAXREGPATHLENGTH); ++ ++ /* We need to use regsup calls... */ ++ /* ...for now we don't need the key handle or */ ++ /* the subkey, all we need is the value to lookup. */ ++ if (regsupSetValue((char *)pstrValue, pbData, dwDataSize) == DSP_SOK) ++ status = DSP_SOK; ++ else ++ status = DSP_EFAIL; ++ ++ return status; ++} ++ +diff --git a/drivers/dsp/bridge/services/regsup.c b/drivers/dsp/bridge/services/regsup.c +new file mode 100644 +index 0000000..5251b68 +--- /dev/null ++++ b/drivers/dsp/bridge/services/regsup.c +@@ -0,0 +1,368 @@ ++/* ++ * regsup.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== regsup.c ======== ++ * Purpose: ++ * Provide registry support functions. ++ * ++ *! Revision History: ++ *! ================ ++ *! 28-May-2002 map: Integrated PSI's dspimage update mechanism ++ *! 11-May-2002 gp: Turned PERF "on". ++ *! 21-May-2002 map: Fixed bug in SetValue - if resizing datasize, set ++ *! new size too ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++struct RegValueStruct { ++ char name[BRIDGE_MAX_NAME_SIZE]; /* Name of a given value entry */ ++ u32 dataSize; /* Size of the data */ ++ void *pData; /* Pointer to the actual data */ ++}; ++ ++struct RegKeyStruct { ++ /*The current number of value entries this key has*/ ++ u32 numValueEntries; ++ /* Array of value entries */ ++ struct RegValueStruct values[BRIDGE_MAX_NUM_REG_ENTRIES]; ++}; ++ ++ ++/* Pointer to the registry support key */ ++static struct RegKeyStruct *pRegKey; ++ ++#if GT_TRACE ++extern struct GT_Mask REG_debugMask; /* GT trace var. */ ++/* ++ * ======== printS ======== ++ * Purpose: ++ * Displays printable characters in pBuf, if any. ++ */ ++static inline void printS(void *pBuf) ++{ ++ int pos = 0; ++ if (*(REG_debugMask).flags & (GT_2CLASS)) { ++ while (*(u8 *)((pBuf)+pos) >= ' ' && ++ *(u8 *)((pBuf)+pos) <= '~') { ++ GT_1trace(REG_debugMask, GT_2CLASS, "%c", ++ *(u8 *)((pBuf) + pos++)); ++ } ++ ++ GT_0trace(REG_debugMask, GT_2CLASS, "\n"); ++ } ++} ++#else ++#define printS(pBuf) ++#endif ++ ++/* ++ * ======== regsupInit ======== ++ * Purpose: ++ * Initialize the Registry Support module's private state. ++ */ ++bool regsupInit(void) ++{ ++ if (pRegKey != NULL) ++ return true; ++ ++ /* Need to allocate and setup our registry. */ ++ pRegKey = MEM_Calloc(sizeof(struct RegKeyStruct), MEM_NONPAGED); ++ if (pRegKey == NULL) ++ return false; ++ ++ return true; ++} ++ ++/* ++ * ======== regsupExit ======== ++ * Purpose: ++ * Release all registry support allocations. ++ */ ++void regsupExit(void) ++{ ++ u32 i; ++ ++ /* Make sure data has actually been allocated. */ ++ if (pRegKey == NULL) { ++ /* Nothing initialized.return! */ ++ return; ++ } ++ ++ GT_1trace(REG_debugMask, GT_2CLASS, "pRegKey->numValueEntries %d\n", ++ pRegKey->numValueEntries); ++ ++ /* Now go through each entry and free all resources. */ ++ for (i = 0; ((i < BRIDGE_MAX_NUM_REG_ENTRIES) && ++ (i < pRegKey->numValueEntries)); i++) { ++ if (pRegKey->values[i].name[0] != '\0') { ++ /* We have a valid entry.free it up! */ ++ if (pRegKey->values[i].pData != NULL) { ++ GT_3trace(REG_debugMask, GT_2CLASS, ++ "E %d\t %s DATA %x ", i, ++ pRegKey->values[i].name, ++ *(u32 *)pRegKey->values[i].pData); ++ printS((u8 *)(pRegKey->values[i].pData)); ++ MEM_Free(pRegKey->values[i].pData); ++ } ++ pRegKey->values[i].pData = NULL; ++ pRegKey->values[i].dataSize = 0; ++ pRegKey->values[i].name[0] = '\0'; ++ } ++ } ++ ++ /* Now that all of the resources are freed up, free the main one! */ ++ MEM_Free(pRegKey); ++ ++ /* Don't forget to NULL out the global entry! */ ++ pRegKey = NULL; ++} ++ ++/* ++ * ======== regsupGetValue ======== ++ * Purpose: ++ * Get the value of the entry having the given name. ++ */ ++DSP_STATUS regsupGetValue(char *valName, void *pBuf, u32 *dataSize) ++{ ++ DSP_STATUS retVal = DSP_EFAIL; ++ u32 i; ++ ++ /* Need to search through the entries looking for the right one. */ ++ for (i = 0; i < pRegKey->numValueEntries; i++) { ++ /* See if the name matches. */ ++ if (strncmp(pRegKey->values[i].name, valName, ++ BRIDGE_MAX_NAME_SIZE) == 0) { ++ ++ /* We have a match! Copy out the data. */ ++ memcpy(pBuf, pRegKey->values[i].pData, ++ pRegKey->values[i].dataSize); ++ ++ /* Get the size for the caller. */ ++ *dataSize = pRegKey->values[i].dataSize; ++ ++ /* Set our status to good and exit. */ ++ retVal = DSP_SOK; ++ break; ++ } ++ } ++ ++ if (DSP_SUCCEEDED(retVal)) { ++ GT_2trace(REG_debugMask, GT_2CLASS, "G %s DATA %x ", valName, ++ *(u32 *)pBuf); ++ printS((u8 *)pBuf); ++ } else { ++ GT_1trace(REG_debugMask, GT_3CLASS, "G %s FAILED\n", valName); ++ } ++ ++ return retVal; ++} ++ ++/* ++ * ======== regsupSetValue ======== ++ * Purpose: ++ * Sets the value of the entry having the given name. ++ */ ++DSP_STATUS regsupSetValue(char *valName, void *pBuf, u32 dataSize) ++{ ++ DSP_STATUS retVal = DSP_EFAIL; ++ u32 i; ++ ++ GT_2trace(REG_debugMask, GT_2CLASS, "S %s DATA %x ", valName, ++ *(u32 *)pBuf); ++ printS((u8 *)pBuf); ++ ++ /* Need to search through the entries looking for the right one. */ ++ for (i = 0; i < pRegKey->numValueEntries; i++) { ++ /* See if the name matches. */ ++ if (strncmp(pRegKey->values[i].name, valName, ++ BRIDGE_MAX_NAME_SIZE) == 0) { ++ /* Make sure the new data size is the same. */ ++ if (dataSize != pRegKey->values[i].dataSize) { ++ /* The caller needs a different data size! */ ++ MEM_Free(pRegKey->values[i].pData); ++ pRegKey->values[i].pData = MEM_Alloc(dataSize, ++ MEM_NONPAGED); ++ if (pRegKey->values[i].pData == NULL) ++ break; ++ ++ } ++ ++ /* We have a match! Copy out the data. */ ++ memcpy(pRegKey->values[i].pData, pBuf, dataSize); ++ ++ /* Reset datasize - overwrite if new or same */ ++ pRegKey->values[i].dataSize = dataSize; ++ ++ /* Set our status to good and exit. */ ++ retVal = DSP_SOK; ++ break; ++ } ++ } ++ ++ /* See if we found a match or if this is a new entry */ ++ if (i == pRegKey->numValueEntries) { ++ /* No match, need to make a new entry */ ++ /* First check to see if we can make any more entries. */ ++ if (pRegKey->numValueEntries < BRIDGE_MAX_NUM_REG_ENTRIES) { ++ strncpy(pRegKey->values[pRegKey->numValueEntries].name, ++ valName, BRIDGE_MAX_NAME_SIZE); ++ pRegKey->values[pRegKey->numValueEntries].pData = ++ MEM_Alloc(dataSize, MEM_NONPAGED); ++ if (pRegKey->values[pRegKey->numValueEntries].pData != ++ NULL) { ++ memcpy(pRegKey-> ++ values[pRegKey->numValueEntries].pData, ++ pBuf, dataSize); ++ pRegKey-> ++ values[pRegKey->numValueEntries].dataSize = ++ dataSize; ++ pRegKey->numValueEntries++; ++ retVal = DSP_SOK; ++ } ++ } else { ++ GT_0trace(REG_debugMask, GT_7CLASS, ++ "MAX NUM REG ENTRIES REACHED\n"); ++ } ++ } ++ ++ return retVal; ++} ++ ++/* ++ * ======== regsupEnumValue ======== ++ * Purpose: ++ * Returns registry "values" and their "data" under a (sub)key. ++ */ ++DSP_STATUS regsupEnumValue(IN u32 dwIndex, IN CONST char *pstrKey, ++ IN OUT char *pstrValue, IN OUT u32 *pdwValueSize, ++ IN OUT char *pstrData, IN OUT u32 *pdwDataSize) ++{ ++ DSP_STATUS retVal = REG_E_INVALIDSUBKEY; ++ u32 i; ++ u32 dwKeyLen; ++ u32 count = 0; ++ ++ DBC_Require(pstrKey); ++ dwKeyLen = strlen(pstrKey); ++ ++ /* Need to search through the entries looking for the right one. */ ++ for (i = 0; i < pRegKey->numValueEntries; i++) { ++ /* See if the name matches. */ ++ if ((strncmp(pRegKey->values[i].name, pstrKey, ++ dwKeyLen) == 0) && count++ == dwIndex) { ++ /* We have a match! Copy out the data. */ ++ memcpy(pstrData, pRegKey->values[i].pData, ++ pRegKey->values[i].dataSize); ++ /* Get the size for the caller. */ ++ *pdwDataSize = pRegKey->values[i].dataSize; ++ *pdwValueSize = strlen(&(pRegKey-> ++ values[i].name[dwKeyLen])); ++ strncpy(pstrValue, ++ &(pRegKey->values[i].name[dwKeyLen]), ++ *pdwValueSize + 1); ++ GT_3trace(REG_debugMask, GT_2CLASS, ++ "E Key %s, Value %s, Data %x ", ++ pstrKey, pstrValue, *(u32 *)pstrData); ++ printS((u8 *)pstrData); ++ /* Set our status to good and exit. */ ++ retVal = DSP_SOK; ++ break; ++ } ++ } ++ ++ if (count && DSP_FAILED(retVal)) ++ retVal = REG_E_NOMOREITEMS; ++ ++ return retVal; ++} ++ ++/* ++ * ======== regsupDeleteValue ======== ++ */ ++DSP_STATUS regsupDeleteValue(IN CONST char *pstrSubkey, ++ IN CONST char *pstrValue) ++{ ++ DSP_STATUS retVal = DSP_EFAIL; ++ u32 i; ++ ++ for (i = 0; ((i < BRIDGE_MAX_NUM_REG_ENTRIES) && ++ (i < pRegKey->numValueEntries)); i++) { ++ /* See if the name matches... */ ++ if (strncmp(pRegKey->values[i].name, pstrValue, ++ BRIDGE_MAX_NAME_SIZE) == 0) { ++ /* We have a match! Delete this key. To delete a ++ * key, we free all resources associated with this ++ * key and, if we're not already the last entry in ++ * the array, we copy that entry into this deleted ++ * key. ++ */ ++ MEM_Free(pRegKey->values[i].pData); ++ if ((pRegKey->numValueEntries - 1) == i) { ++ /* we're deleting the last one */ ++ pRegKey->values[i].name[0] = '\0'; ++ pRegKey->values[i].dataSize = 0; ++ pRegKey->values[i].pData = NULL; ++ } else { ++ /* move the last one here */ ++ strncpy(pRegKey->values[i].name, pRegKey-> ++ values[pRegKey->numValueEntries - 1].name, ++ BRIDGE_MAX_NAME_SIZE); ++ pRegKey->values[i].dataSize = ++ pRegKey-> ++ values[pRegKey->numValueEntries-1].dataSize; ++ pRegKey->values[i].pData = ++ pRegKey-> ++ values[pRegKey->numValueEntries-1].pData; ++ /* don't have to do this, but for ++ * the paranoid... */ ++ pRegKey-> ++ values[pRegKey->numValueEntries-1].name[0] = ++ '\0'; ++ } ++ ++ /* another one bites the dust. */ ++ pRegKey->numValueEntries--; ++ ++ /* Set our status to good and exit... */ ++ retVal = DSP_SOK; ++ break; ++ } ++ } ++ return retVal; ++ ++} ++ +diff --git a/drivers/dsp/bridge/services/regsup.h b/drivers/dsp/bridge/services/regsup.h +new file mode 100644 +index 0000000..011be52 +--- /dev/null ++++ b/drivers/dsp/bridge/services/regsup.h +@@ -0,0 +1,58 @@ ++/* ++ * regsup.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== regsup.h ======== ++ * ++ *! Revision History ++ *! ================ ++ */ ++ ++#ifndef _REGSUP_H_ ++#define _REGSUP_H_ ++ ++#define BRIDGE_MAX_NAME_SIZE MAXREGPATHLENGTH ++#define BRIDGE_MAX_NUM_REG_ENTRIES 52 ++ ++/* Init function. MUST be called BEFORE any calls are */ ++/* made into this psuedo-registry!!! Returns TRUE/FALSE for SUCCESS/ERROR */ ++extern bool regsupInit(void); ++ ++/* Release all registry support allocations. */ ++extern void regsupExit(void); ++ ++/* ++ * ======== regsupDeleteValue ======== ++ */ ++extern DSP_STATUS regsupDeleteValue(IN CONST char *pstrSubkey, ++ IN CONST char *pstrValue); ++/* Get the value of the entry having the given name. Returns DSP_SOK */ ++/* if an entry was found and the value retrieved. Returns DSP_EFAIL ++ * otherwise.*/ ++extern DSP_STATUS regsupGetValue(char *valName, void *pBuf, u32 *dataSize); ++ ++/* Sets the value of the entry having the given name. Returns DSP_SOK */ ++/* if an entry was found and the value set. Returns DSP_EFAIL otherwise. */ ++extern DSP_STATUS regsupSetValue(char *valName, void *pBuf, u32 dataSize); ++ ++/* Returns registry "values" and their "data" under a (sub)key. */ ++extern DSP_STATUS regsupEnumValue(IN u32 dwIndex, IN CONST char *pstrKey, ++ IN OUT char *pstrValue, IN OUT u32 *pdwValueSize, ++ IN OUT char *pstrData, IN OUT u32 *pdwDataSize); ++ ++#endif ++ +diff --git a/drivers/dsp/bridge/services/services.c b/drivers/dsp/bridge/services/services.c +new file mode 100644 +index 0000000..346007e +--- /dev/null ++++ b/drivers/dsp/bridge/services/services.c +@@ -0,0 +1,193 @@ ++/* ++ * services.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== services.c ======== ++ * Purpose: ++ * Provide SERVICES loading. ++ * ++ * Public Functions: ++ * SERVICES_Exit ++ * SERVICES_Init ++ * ++ * ++ *! Revision History ++ *! ================ ++ *! 20-Nov-2000 rr: NTFY_Init/Exit added. ++ *! 06-Jul-2000 rr: PROC prefix changed to PRCS to accomodate RM. ++ *! 01-Feb-2000 kc: Created. ++ */ ++ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++/* ----------------------------------- Globals */ ++#if GT_TRACE ++static struct GT_Mask SERVICES_debugMask = { NULL, NULL }; /* GT trace var. */ ++#endif ++ ++static u32 cRefs; /* SERVICES module reference count */ ++ ++/* ++ * ======== SERVICES_Exit ======== ++ * Purpose: ++ * Discontinue usage of module; free resources when reference count ++ * reaches 0. ++ */ ++void SERVICES_Exit(void) ++{ ++ DBC_Require(cRefs > 0); ++ ++ GT_1trace(SERVICES_debugMask, GT_5CLASS, "SERVICES_Exit: cRefs 0x%x\n", ++ cRefs); ++ ++ cRefs--; ++ if (cRefs == 0) { ++ /* Uninitialize all SERVICES modules here */ ++ NTFY_Exit(); ++ UTIL_Exit(); ++ SYNC_Exit(); ++ CLK_Exit(); ++ REG_Exit(); ++ LST_Exit(); ++ KFILE_Exit(); ++ DPC_Exit(); ++ DBG_Exit(); ++ CSL_Exit(); ++ CFG_Exit(); ++ MEM_Exit(); ++ ++ GT_exit(); ++ } ++ ++ DBC_Ensure(cRefs >= 0); ++} ++ ++/* ++ * ======== SERVICES_Init ======== ++ * Purpose: ++ * Initializes SERVICES modules. ++ */ ++bool SERVICES_Init(void) ++{ ++ bool fInit = true; ++ bool fCFG, fCSL, fDBG, fDPC, fKFILE, fLST, fMEM; ++ bool fREG, fSYNC, fCLK, fUTIL, fNTFY; ++ ++ DBC_Require(cRefs >= 0); ++ ++ if (cRefs == 0) { ++ ++ GT_init(); ++ GT_create(&SERVICES_debugMask, "OS"); /* OS for OSal */ ++ ++ GT_0trace(SERVICES_debugMask, GT_ENTER, ++ "SERVICES_Init: entered\n"); ++ ++ /* Perform required initialization of SERVICES modules. */ ++ fMEM = MEM_Init(); ++ fREG = REG_Init(); ++ fCFG = CFG_Init(); ++ fCSL = CSL_Init(); ++ fDBG = DBG_Init(); ++ fDPC = DPC_Init(); ++ fKFILE = KFILE_Init(); ++ fLST = LST_Init(); ++ /* fREG = REG_Init(); */ ++ fSYNC = SYNC_Init(); ++ fCLK = CLK_Init(); ++ fUTIL = UTIL_Init(); ++ fNTFY = NTFY_Init(); ++ ++ fInit = fCFG && fCSL && fDBG && fDPC && fKFILE && ++ fLST && fMEM && fREG && fSYNC && fCLK && fUTIL; ++ ++ if (!fInit) { ++ if (fNTFY) ++ NTFY_Exit(); ++ ++ if (fUTIL) ++ UTIL_Exit(); ++ ++ if (fSYNC) ++ SYNC_Exit(); ++ ++ if (fCLK) ++ CLK_Exit(); ++ ++ if (fREG) ++ REG_Exit(); ++ ++ if (fLST) ++ LST_Exit(); ++ ++ if (fKFILE) ++ KFILE_Exit(); ++ ++ if (fDPC) ++ DPC_Exit(); ++ ++ if (fDBG) ++ DBG_Exit(); ++ ++ if (fCSL) ++ CSL_Exit(); ++ ++ if (fCFG) ++ CFG_Exit(); ++ ++ if (fMEM) ++ MEM_Exit(); ++ ++ } ++ } ++ ++ if (fInit) ++ cRefs++; ++ ++ GT_1trace(SERVICES_debugMask, GT_5CLASS, "SERVICES_Init: cRefs 0x%x\n", ++ cRefs); ++ ++ DBC_Ensure((fInit && (cRefs > 0)) || (!fInit && (cRefs >= 0))); ++ ++ return fInit; ++} ++ +diff --git a/drivers/dsp/bridge/services/sync.c b/drivers/dsp/bridge/services/sync.c +new file mode 100644 +index 0000000..7ab9347 +--- /dev/null ++++ b/drivers/dsp/bridge/services/sync.c +@@ -0,0 +1,602 @@ ++/* ++ * sync.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== sync.c ======== ++ * Purpose: ++ * Synchronization services. ++ * ++ * Public Functions: ++ * SYNC_CloseEvent ++ * SYNC_DeleteCS ++ * SYNC_EnterCS ++ * SYNC_Exit ++ * SYNC_Init ++ * SYNC_InitializeCS ++ * SYNC_LeaveCS ++ * SYNC_OpenEvent ++ * SYNC_ResetEvent ++ * SYNC_SetEvent ++ * SYNC_WaitOnEvent ++ * SYNC_WaitOnMultipleEvents ++ * ++ *! Revision History: ++ *! ================ ++ *! 05-Nov-2001 kc: Minor cosmetic changes. ++ *! 05-Oct-2000 jeh Added SYNC_WaitOnMultipleEvents(). ++ *! 10-Aug-2000 rr: SYNC_PostMessage added. ++ *! 10-Jul-2000 jeh Modified SYNC_OpenEvent() to handle NULL attrs. ++ *! 03-Feb-2000 rr: Module init/exit is handled by SERVICES Init/Exit. ++ *! GT Changes. ++ *! 01-Dec-1999 ag: Added optional named event creation in SYNC_OpenEvent(). ++ *! 22-Nov-1999 kc: Added changes from code review. ++ *! 22-Sep-1999 kc: Modified from sync95.c. ++ *! 05-Aug-1996 gp: Created. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include ++ ++/* ----------------------------------- Defines, Data Structures, Typedefs */ ++#define SIGNATURE 0x434e5953 /* "SYNC" (in reverse) */ ++ ++enum wait_state { ++ wo_waiting, ++ wo_signalled ++} ; ++ ++enum sync_state { ++ so_reset, ++ so_signalled ++} ; ++ ++struct WAIT_OBJECT { ++ enum wait_state state; ++ struct SYNC_OBJECT *signalling_event; ++ struct semaphore sem; ++}; ++ ++/* Generic SYNC object: */ ++struct SYNC_OBJECT { ++ u32 dwSignature; /* Used for object validation. */ ++ enum sync_state state; ++ spinlock_t sync_lock; ++ struct WAIT_OBJECT *pWaitObj; ++}; ++ ++struct SYNC_DPCCSOBJECT { ++ u32 dwSignature; /* used for object validation */ ++ spinlock_t sync_dpccs_lock; ++ s32 count; ++} ; ++ ++/* ----------------------------------- Globals */ ++#if GT_TRACE ++static struct GT_Mask SYNC_debugMask = { NULL, NULL }; /* GT trace variable */ ++#endif ++ ++static int test_and_set(volatile void *ptr, int val) ++{ ++ int ret = val; ++ asm volatile (" swp %0, %0, [%1]" : "+r" (ret) : "r"(ptr) : "memory"); ++ return ret; ++} ++ ++static void timeout_callback(unsigned long hWaitObj); ++ ++/* ++ * ======== SYNC_CloseEvent ======== ++ * Purpose: ++ * Close an existing SYNC event object. ++ */ ++DSP_STATUS SYNC_CloseEvent(struct SYNC_OBJECT *hEvent) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct SYNC_OBJECT *pEvent = (struct SYNC_OBJECT *)hEvent; ++ ++ DBC_Require(pEvent != NULL && pEvent->pWaitObj == NULL); ++ ++ GT_1trace(SYNC_debugMask, GT_ENTER, "SYNC_CloseEvent: hEvent 0x%x\n", ++ hEvent); ++ ++ if (MEM_IsValidHandle(hEvent, SIGNATURE)) { ++ if (pEvent->pWaitObj) { ++ status = DSP_EFAIL; ++ GT_0trace(SYNC_debugMask, GT_6CLASS, ++ "SYNC_CloseEvent: Wait object not NULL\n"); ++ } ++ MEM_FreeObject(pEvent); ++ ++ } else { ++ status = DSP_EHANDLE; ++ GT_1trace(SYNC_debugMask, GT_6CLASS, ++ "SYNC_CloseEvent: invalid " ++ "hEvent handle 0x%x\n", hEvent); ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== SYNC_Exit ======== ++ * Purpose: ++ * Cleanup SYNC module. ++ */ ++void SYNC_Exit(void) ++{ ++ GT_0trace(SYNC_debugMask, GT_5CLASS, "SYNC_Exit\n"); ++} ++ ++/* ++ * ======== SYNC_Init ======== ++ * Purpose: ++ * Initialize SYNC module. ++ */ ++bool SYNC_Init(void) ++{ ++ GT_create(&SYNC_debugMask, "SY"); /* SY for SYnc */ ++ ++ GT_0trace(SYNC_debugMask, GT_5CLASS, "SYNC_Init\n"); ++ ++ return true; ++} ++ ++/* ++ * ======== SYNC_OpenEvent ======== ++ * Purpose: ++ * Open a new synchronization event object. ++ */ ++DSP_STATUS SYNC_OpenEvent(OUT struct SYNC_OBJECT **phEvent, ++ IN OPTIONAL struct SYNC_ATTRS *pAttrs) ++{ ++ struct SYNC_OBJECT *pEvent = NULL; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(phEvent != NULL); ++ ++ GT_2trace(SYNC_debugMask, GT_ENTER, ++ "SYNC_OpenEvent: phEvent 0x%x, pAttrs " ++ "0x%x\n", phEvent, pAttrs); ++ ++ /* Allocate memory for sync object */ ++ MEM_AllocObject(pEvent, struct SYNC_OBJECT, SIGNATURE); ++ if (pEvent != NULL) { ++ pEvent->state = so_reset; ++ pEvent->pWaitObj = NULL; ++ spin_lock_init(&pEvent->sync_lock); ++ } else { ++ status = DSP_EMEMORY; ++ GT_0trace(SYNC_debugMask, GT_6CLASS, ++ "SYNC_OpenEvent: MEM_AllocObject failed\n"); ++ } ++ ++ *phEvent = pEvent; ++ ++ return status; ++} ++ ++/* ++ * ======== SYNC_ResetEvent ======== ++ * Purpose: ++ * Reset an event to non-signalled. ++ */ ++DSP_STATUS SYNC_ResetEvent(struct SYNC_OBJECT *hEvent) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct SYNC_OBJECT *pEvent = (struct SYNC_OBJECT *)hEvent; ++ ++ GT_1trace(SYNC_debugMask, GT_ENTER, "SYNC_ResetEvent: hEvent 0x%x\n", ++ hEvent); ++ ++ if (MEM_IsValidHandle(hEvent, SIGNATURE)) { ++ pEvent->state = so_reset; ++ status = DSP_SOK; ++ } else { ++ status = DSP_EHANDLE; ++ GT_1trace(SYNC_debugMask, GT_6CLASS, ++ "SYNC_ResetEvent: invalid hEvent " ++ "handle 0x%x\n", hEvent); ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== SYNC_SetEvent ======== ++ * Purpose: ++ * Set an event to signaled and unblock one waiting thread. ++ * ++ * This function is called from ISR, DPC and user context. Hence interrupts ++ * are disabled to ensure atomicity. ++ */ ++ ++DSP_STATUS SYNC_SetEvent(struct SYNC_OBJECT *hEvent) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct SYNC_OBJECT *pEvent = (struct SYNC_OBJECT *)hEvent; ++ unsigned long flags; ++ ++ GT_1trace(SYNC_debugMask, GT_6CLASS, "SYNC_SetEvent: hEvent 0x%x\n", ++ hEvent); ++ ++ if (MEM_IsValidHandle(hEvent, SIGNATURE)) { ++ spin_lock_irqsave(&hEvent->sync_lock, flags); ++ GT_1trace(SYNC_debugMask, GT_6CLASS, ++ "SYNC_SetEvent: pEvent->pWaitObj " ++ "= 0x%x \n", pEvent->pWaitObj); ++ if (pEvent->pWaitObj) ++ GT_1trace(SYNC_debugMask, GT_6CLASS, "SYNC_SetEvent: " ++ "pEvent->pWaitObj->state = 0x%x \n", ++ pEvent->pWaitObj->state); ++ if (pEvent->pWaitObj != NULL && ++ test_and_set(&pEvent->pWaitObj->state, ++ wo_signalled) == wo_waiting) { ++ ++ pEvent->state = so_reset; ++ pEvent->pWaitObj->signalling_event = pEvent; ++ up(&pEvent->pWaitObj->sem); ++ GT_1trace(SYNC_debugMask, GT_6CLASS, ++ "SYNC_SetEvent: Unlock " ++ "Semaphore for hEvent 0x%x\n", hEvent); ++ } else { ++ pEvent->state = so_signalled; ++ } ++ spin_unlock_irqrestore(&hEvent->sync_lock, flags); ++ } else { ++ status = DSP_EHANDLE; ++ GT_1trace(SYNC_debugMask, GT_6CLASS, ++ "SYNC_SetEvent: invalid hEvent " ++ "handle 0x%x\n", hEvent); ++ } ++ return status; ++} ++ ++/* ++ * ======== SYNC_WaitOnEvent ======== ++ * Purpose: ++ * Wait for an event to be signalled, up to the specified timeout. ++ * Note: dwTimeOut must be 0xffffffff to signal infinite wait. ++ */ ++DSP_STATUS SYNC_WaitOnEvent(struct SYNC_OBJECT *hEvent, u32 dwTimeout) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct SYNC_OBJECT *pEvent = (struct SYNC_OBJECT *)hEvent; ++ u32 temp; ++ ++ GT_2trace(SYNC_debugMask, GT_6CLASS, "SYNC_WaitOnEvent: hEvent 0x%x\n, " ++ "dwTimeOut 0x%x", hEvent, dwTimeout); ++ if (MEM_IsValidHandle(hEvent, SIGNATURE)) { ++ status = SYNC_WaitOnMultipleEvents(&pEvent, 1, dwTimeout, ++ &temp); ++ } else { ++ status = DSP_EHANDLE; ++ GT_1trace(SYNC_debugMask, GT_6CLASS, ++ "SYNC_WaitOnEvent: invalid hEvent" ++ "handle 0x%x\n", hEvent); ++ } ++ return status; ++} ++ ++/* ++ * ======== SYNC_WaitOnMultipleEvents ======== ++ * Purpose: ++ * Wait for any of an array of events to be signalled, up to the ++ * specified timeout. ++ */ ++DSP_STATUS SYNC_WaitOnMultipleEvents(struct SYNC_OBJECT **hSyncEvents, ++ u32 uCount, u32 dwTimeout, ++ OUT u32 *puIndex) ++{ ++ u32 i; ++ DSP_STATUS status = DSP_SOK; ++ u32 curr; ++ struct WAIT_OBJECT *Wp; ++ ++ DBC_Require(uCount > 0); ++ DBC_Require(hSyncEvents != NULL); ++ DBC_Require(puIndex != NULL); ++ ++ for (i = 0; i < uCount; i++) ++ DBC_Require(MEM_IsValidHandle(hSyncEvents[i], SIGNATURE)); ++ ++ GT_4trace(SYNC_debugMask, GT_6CLASS, ++ "SYNC_WaitOnMultipleEvents: hSyncEvents:" ++ "0x%x\tuCount: 0x%x" "\tdwTimeout: 0x%x\tpuIndex: 0x%x\n", ++ hSyncEvents, uCount, dwTimeout, puIndex); ++ ++ Wp = MEM_Calloc(sizeof(struct WAIT_OBJECT), MEM_NONPAGED); ++ if (Wp == NULL) ++ return DSP_EMEMORY; ++ ++ Wp->state = wo_waiting; ++ Wp->signalling_event = NULL; ++ init_MUTEX_LOCKED(&(Wp->sem)); ++ ++ for (curr = 0; curr < uCount; curr++) { ++ hSyncEvents[curr]->pWaitObj = Wp; ++ if (hSyncEvents[curr]->state == so_signalled) { ++ GT_0trace(SYNC_debugMask, GT_6CLASS, ++ "Detected signaled Event !!!\n"); ++ if (test_and_set(&(Wp->state), wo_signalled) == ++ wo_waiting) { ++ GT_0trace(SYNC_debugMask, GT_6CLASS, ++ "Setting Signal Event!!!\n"); ++ hSyncEvents[curr]->state = so_reset; ++ Wp->signalling_event = hSyncEvents[curr]; ++ } ++ curr++; /* Will try optimizing later */ ++ break; ++ } ++ } ++ ++ curr--; /* Will try optimizing later */ ++ if (Wp->state != wo_signalled && dwTimeout > 0) { ++ struct timer_list timeout; ++ if (dwTimeout != SYNC_INFINITE) { ++ init_timer(&timeout); ++ timeout.function = timeout_callback; ++ timeout.data = (unsigned long)Wp; ++ timeout.expires = jiffies + dwTimeout * HZ / 1000; ++ add_timer(&timeout); ++ } ++ if (down_interruptible(&(Wp->sem))) { ++ GT_0trace(SYNC_debugMask, GT_7CLASS, "SYNC: " ++ "WaitOnMultipleEvents Interrupted by signal\n"); ++ status = DSP_EFAIL; ++ } ++ if (dwTimeout != SYNC_INFINITE) { ++ if (in_interrupt()) { ++ if (!del_timer(&timeout)) { ++ GT_0trace(SYNC_debugMask, GT_7CLASS, ++ "SYNC: Timer expired\n"); ++ } ++ } else { ++ if (!del_timer_sync(&timeout)) { ++ GT_0trace(SYNC_debugMask, GT_7CLASS, ++ "SYNC: Timer expired\n"); ++ } ++ } ++ } ++ } ++ for (i = 0; i <= curr; i++) { ++ if (MEM_IsValidHandle(hSyncEvents[i], SIGNATURE)) { ++ /* Memory corruption here if hSyncEvents[i] is ++ * freed before following statememt. */ ++ hSyncEvents[i]->pWaitObj = NULL; ++ } ++ if (hSyncEvents[i] == Wp->signalling_event) ++ *puIndex = i; ++ ++ } ++ if (Wp->signalling_event == NULL && DSP_SUCCEEDED(status)) { ++ GT_0trace(SYNC_debugMask, GT_7CLASS, ++ "SYNC:Signaling Event NULL!!!(:-\n"); ++ status = DSP_ETIMEOUT; ++ } ++ if (Wp) ++ MEM_Free(Wp); ++ return status; ++} ++ ++static void timeout_callback(unsigned long hWaitObj) ++{ ++ struct WAIT_OBJECT *pWaitObj = (struct WAIT_OBJECT *)hWaitObj; ++ if (test_and_set(&pWaitObj->state, wo_signalled) == wo_waiting) ++ up(&pWaitObj->sem); ++ ++} ++ ++/* ++ * ======== SYNC_DeleteCS ======== ++ */ ++DSP_STATUS SYNC_DeleteCS(struct SYNC_CSOBJECT *hCSObj) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct SYNC_CSOBJECT *pCSObj = (struct SYNC_CSOBJECT *)hCSObj; ++ ++ GT_0trace(SYNC_debugMask, GT_ENTER, "SYNC_DeleteCS\n"); ++ ++ if (MEM_IsValidHandle(hCSObj, SIGNATURECS)) { ++ if (down_trylock(&pCSObj->sem) != 0) { ++ GT_1trace(SYNC_debugMask, GT_7CLASS, ++ "CS in use (locked) while " ++ "deleting! pCSObj=0x%X", pCSObj); ++ DBC_Assert(0); ++ } ++ MEM_FreeObject(hCSObj); ++ } else if (MEM_IsValidHandle(hCSObj, SIGNATUREDPCCS)) { ++ struct SYNC_DPCCSOBJECT *pDPCCSObj = ++ (struct SYNC_DPCCSOBJECT *)hCSObj; ++ if (pDPCCSObj->count != 1) { ++ GT_1trace(SYNC_debugMask, GT_7CLASS, ++ "DPC CS in use (locked) while " ++ "deleting! pCSObj=0x%X", pCSObj); ++ DBC_Assert(0); ++ } ++ MEM_FreeObject(pDPCCSObj); ++ } else { ++ status = DSP_EHANDLE; ++ GT_1trace(SYNC_debugMask, GT_6CLASS, ++ "SYNC_DeleteCS: invalid hCSObj " ++ "handle 0x%x\n", hCSObj); ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== SYNC_EnterCS ======== ++ */ ++DSP_STATUS SYNC_EnterCS(struct SYNC_CSOBJECT *hCSObj) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct SYNC_CSOBJECT *pCSObj = (struct SYNC_CSOBJECT *)hCSObj; ++ ++ GT_1trace(SYNC_debugMask, GT_ENTER, "SYNC_EnterCS: hCSObj %p\n", ++ hCSObj); ++ if (MEM_IsValidHandle(hCSObj, SIGNATURECS)) { ++ if (in_interrupt()) { ++ status = DSP_EFAIL; ++ GT_0trace(SYNC_debugMask, GT_7CLASS, ++ "SYNC_EnterCS called from " ++ "ISR/DPC or with ISR/DPC disabled!"); ++ DBC_Assert(0); ++ } else if (down_interruptible(&pCSObj->sem)) { ++ GT_1trace(SYNC_debugMask, GT_7CLASS, ++ "CS interrupted by signal! " ++ "pCSObj=0x%X", pCSObj); ++ status = DSP_EFAIL; ++ } ++ } else if (MEM_IsValidHandle(hCSObj, SIGNATUREDPCCS)) { ++ struct SYNC_DPCCSOBJECT *pDPCCSObj = ++ (struct SYNC_DPCCSOBJECT *)hCSObj; ++ GT_0trace(SYNC_debugMask, GT_ENTER, "SYNC_EnterCS DPC\n"); ++ spin_lock_bh(&pDPCCSObj->sync_dpccs_lock); ++ pDPCCSObj->count--; ++ if (pDPCCSObj->count != 0) { ++ /* FATAL ERROR : Failed to acquire DPC CS */ ++ GT_2trace(SYNC_debugMask, GT_7CLASS, ++ "SYNC_EnterCS DPCCS %x locked," ++ "count %d", pDPCCSObj, pDPCCSObj->count); ++ spin_unlock_bh(&pDPCCSObj->sync_dpccs_lock); ++ DBC_Assert(0); ++ } ++ } else { ++ status = DSP_EHANDLE; ++ GT_1trace(SYNC_debugMask, GT_6CLASS, ++ "SYNC_EnterCS: invalid hCSObj " ++ "handle 0x%x\n", hCSObj); ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== SYNC_InitializeCS ======== ++ */ ++DSP_STATUS SYNC_InitializeCS(OUT struct SYNC_CSOBJECT **phCSObj) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct SYNC_CSOBJECT *pCSObj = NULL; ++ ++ GT_0trace(SYNC_debugMask, GT_ENTER, "SYNC_InitializeCS\n"); ++ ++ /* Allocate memory for sync CS object */ ++ MEM_AllocObject(pCSObj, struct SYNC_CSOBJECT, SIGNATURECS); ++ if (pCSObj != NULL) { ++ init_MUTEX(&pCSObj->sem); ++ } else { ++ status = DSP_EMEMORY; ++ GT_0trace(SYNC_debugMask, GT_6CLASS, ++ "SYNC_InitializeCS: MEM_AllocObject" ++ "failed\n"); ++ } ++ /* return CS object */ ++ *phCSObj = pCSObj; ++ DBC_Assert(DSP_FAILED(status) || (pCSObj)); ++ return status; ++} ++ ++DSP_STATUS SYNC_InitializeDPCCS(OUT struct SYNC_CSOBJECT **phCSObj) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct SYNC_DPCCSOBJECT *pCSObj = NULL; ++ ++ DBC_Require(phCSObj); ++ ++ GT_0trace(SYNC_debugMask, GT_ENTER, "SYNC_InitializeDPCCS\n"); ++ ++ if (phCSObj) { ++ /* Allocate memory for sync CS object */ ++ MEM_AllocObject(pCSObj, struct SYNC_DPCCSOBJECT, ++ SIGNATUREDPCCS); ++ if (pCSObj != NULL) { ++ pCSObj->count = 1; ++ spin_lock_init(&pCSObj->sync_dpccs_lock); ++ } else { ++ status = DSP_EMEMORY; ++ GT_0trace(SYNC_debugMask, GT_6CLASS, ++ "SYNC_InitializeDPCCS: " ++ "MEM_AllocObject failed\n"); ++ } ++ ++ /* return CS object */ ++ *phCSObj = (struct SYNC_CSOBJECT *)pCSObj; ++ } else { ++ status = DSP_EPOINTER; ++ } ++ ++ GT_1trace(SYNC_debugMask, GT_ENTER, "SYNC_InitializeDPCCS " ++ "pCSObj %p\n", pCSObj); ++ DBC_Assert(DSP_FAILED(status) || (pCSObj)); ++ ++ return status; ++} ++ ++/* ++ * ======== SYNC_LeaveCS ======== ++ */ ++DSP_STATUS SYNC_LeaveCS(struct SYNC_CSOBJECT *hCSObj) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct SYNC_CSOBJECT *pCSObj = (struct SYNC_CSOBJECT *)hCSObj; ++ ++ GT_1trace(SYNC_debugMask, GT_ENTER, "SYNC_LeaveCS: hCSObj %p\n", ++ hCSObj); ++ ++ if (MEM_IsValidHandle(hCSObj, SIGNATURECS)) { ++ up(&pCSObj->sem); ++ } else if (MEM_IsValidHandle(hCSObj, SIGNATUREDPCCS)) { ++ struct SYNC_DPCCSOBJECT *pDPCCSObj = ++ (struct SYNC_DPCCSOBJECT *)hCSObj; ++ pDPCCSObj->count++; ++ if (pDPCCSObj->count != 1) { ++ /* FATAL ERROR : Invalid DPC CS count */ ++ GT_2trace(SYNC_debugMask, GT_7CLASS, ++ "SYNC_LeaveCS DPCCS %x, " ++ "Invalid count %d", pDPCCSObj, ++ pDPCCSObj->count); ++ spin_unlock_bh(&pDPCCSObj->sync_dpccs_lock); ++ DBC_Assert(0); ++ spin_lock_bh(&pDPCCSObj->sync_dpccs_lock); ++ } ++ spin_unlock_bh(&pDPCCSObj->sync_dpccs_lock); ++ GT_0trace(SYNC_debugMask, GT_ENTER, "SYNC_LeaveCS DPC\n"); ++ } else { ++ status = DSP_EHANDLE; ++ GT_1trace(SYNC_debugMask, GT_6CLASS, ++ "SYNC_LeaveCS: invalid hCSObj " ++ "handle 0x%x\n", hCSObj); ++ } ++ ++ return status; ++} +diff --git a/drivers/dsp/bridge/wmd/_cmm.h b/drivers/dsp/bridge/wmd/_cmm.h +new file mode 100644 +index 0000000..801b000 +--- /dev/null ++++ b/drivers/dsp/bridge/wmd/_cmm.h +@@ -0,0 +1,59 @@ ++/* ++ * _cmm.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== _cmm.h ======== ++ * Description: ++ * Private header file defining CMM manager objects and defines needed ++ * by IO manager to register shared memory regions when DSP base image ++ * is loaded(WMD_IO_OnLoaded). ++ * ++ * Public Functions: ++ * None. ++ * ++ * Notes: ++ * ++ *! Revision History: ++ *! ================ ++ *! 24-Aug-2001 ag Created. ++ */ ++ ++#ifndef _CMM_ ++#define _CMM_ ++ ++/* ++ * These target side symbols define the beginning and ending addresses ++ * of the section of shared memory used for shared memory manager CMM. ++ * They are defined in the *cfg.cmd file by cdb code. ++ */ ++#define SHM0_SHARED_BASE_SYM "_SHM0_BEG" ++#define SHM0_SHARED_END_SYM "_SHM0_END" ++#define SHM0_SHARED_RESERVED_BASE_SYM "_SHM0_RSVDSTRT" ++ ++/* ++ * Shared Memory Region #0(SHMSEG0) is used in the following way: ++ * ++ * |(_SHM0_BEG) | (_SHM0_RSVDSTRT) | (_SHM0_END) ++ * V V V ++ * ------------------------------------------------------------ ++ * | DSP-side allocations | GPP-side allocations | ++ * ------------------------------------------------------------ ++ * ++ * ++ */ ++ ++#endif /* _CMM_ */ +diff --git a/drivers/dsp/bridge/wmd/_deh.h b/drivers/dsp/bridge/wmd/_deh.h +new file mode 100644 +index 0000000..df281ad +--- /dev/null ++++ b/drivers/dsp/bridge/wmd/_deh.h +@@ -0,0 +1,46 @@ ++/* ++ * _deh.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== _deh.h ======== ++ * Description: ++ * Private header for DEH module. ++ * ++ *! Revision History: ++ *! ================ ++ *! 21-Sep-2001 kc: created. ++ */ ++ ++#ifndef _DEH_ ++#define _DEH_ ++ ++#include ++#include ++#include ++ ++#define SIGNATURE 0x5f484544 /* "DEH_" backwards */ ++ ++/* DEH Manager: only one created per board: */ ++struct DEH_MGR { ++ u32 dwSignature; /* Used for object validation. */ ++ struct WMD_DEV_CONTEXT *hWmdContext; /* WMD device context. */ ++ struct NTFY_OBJECT *hNtfy; /* NTFY object */ ++ struct DPC_OBJECT *hMmuFaultDpc; /* DPC object handle. */ ++ struct DSP_ERRORINFO errInfo; /* DSP exception info. */ ++} ; ++ ++#endif /* _DEH_ */ +diff --git a/drivers/dsp/bridge/wmd/_msg_sm.h b/drivers/dsp/bridge/wmd/_msg_sm.h +new file mode 100644 +index 0000000..fa5e9ee +--- /dev/null ++++ b/drivers/dsp/bridge/wmd/_msg_sm.h +@@ -0,0 +1,158 @@ ++/* ++ * _msg_sm.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== _msg_sm.h ======== ++ * Description: ++ * Private header file defining MSG manager objects and defines needed ++ * by IO manager. ++ * ++ * Public Functions: ++ * None. ++ * ++ * Notes: ++ * ++ *! Revision History: ++ *! ================ ++ *! 09-May-2001 jeh Code Review cleanup. ++ *! 08-Nov-2000 jeh Created. ++ */ ++ ++#ifndef _MSG_SM_ ++#define _MSG_SM_ ++ ++#include ++#include ++ ++/* ++ * These target side symbols define the beginning and ending addresses ++ * of the section of shared memory used for messages. They are ++ * defined in the *cfg.cmd file by cdb code. ++ */ ++#define MSG_SHARED_BUFFER_BASE_SYM "_MSG_BEG" ++#define MSG_SHARED_BUFFER_LIMIT_SYM "_MSG_END" ++ ++#ifndef _CHNL_WORDSIZE ++#define _CHNL_WORDSIZE 4 /* default _CHNL_WORDSIZE is 2 bytes/word */ ++#endif ++ ++/* ++ * ======== MSG ======== ++ * There is a control structure for messages to the DSP, and a control ++ * structure for messages from the DSP. The shared memory region for ++ * transferring messages is partitioned as follows: ++ * ++ * ---------------------------------------------------------- ++ * |Control | Messages from DSP | Control | Messages to DSP | ++ * ---------------------------------------------------------- ++ * ++ * MSG control structure for messages to the DSP is used in the following ++ * way: ++ * ++ * bufEmpty - This flag is set to FALSE by the GPP after it has output ++ * messages for the DSP. The DSP host driver sets it to ++ * TRUE after it has copied the messages. ++ * postSWI - Set to 1 by the GPP after it has written the messages, ++ * set the size, and set bufEmpty to FALSE. ++ * The DSP Host driver uses SWI_andn of the postSWI field ++ * when a host interrupt occurs. The host driver clears ++ * this after posting the SWI. ++ * size - Number of messages to be read by the DSP. ++ * ++ * For messages from the DSP: ++ * bufEmpty - This flag is set to FALSE by the DSP after it has output ++ * messages for the GPP. The DPC on the GPP sets it to ++ * TRUE after it has copied the messages. ++ * postSWI - Set to 1 the DPC on the GPP after copying the messages. ++ * size - Number of messages to be read by the GPP. ++ */ ++struct MSG { ++ u32 bufEmpty; /* to/from DSP buffer is empty */ ++ u32 postSWI; /* Set to "1" to post MSG SWI */ ++ u32 size; /* Number of messages to/from the DSP */ ++ u32 resvd; ++} ; ++ ++/* ++ * ======== MSG_MGR ======== ++ * The MSG_MGR maintains a list of all MSG_QUEUEs. Each NODE object can ++ * have MSG_QUEUE to hold all messages that come up from the corresponding ++ * node on the DSP. The MSG_MGR also has a shared queue of messages ++ * ready to go to the DSP. ++ */ ++struct MSG_MGR { ++ /* The first two fields must match those in msgobj.h */ ++ u32 dwSignature; ++ struct WMD_DRV_INTERFACE *pIntfFxns; /* Function interface to WMD. */ ++ ++ struct IO_MGR *hIOMgr; /* IO manager */ ++ struct LST_LIST *queueList; /* List of MSG_QUEUEs */ ++ struct SYNC_CSOBJECT *hSyncCS; /* For critical sections */ ++ /* Signalled when MsgFrame is available */ ++ struct SYNC_OBJECT *hSyncEvent; ++ struct LST_LIST *msgFreeList; /* Free MsgFrames ready to be filled */ ++ struct LST_LIST *msgUsedList; /* MsgFrames ready to go to DSP */ ++ u32 uMsgsPending; /* # of queued messages to go to DSP */ ++ u32 uMaxMsgs; /* Max # of msgs that fit in buffer */ ++ MSG_ONEXIT onExit; /* called when RMS_EXIT is received */ ++} ; ++ ++/* ++ * ======== MSG_QUEUE ======== ++ * Each NODE has a MSG_QUEUE for receiving messages from the ++ * corresponding node on the DSP. The MSG_QUEUE object maintains a list ++ * of messages that have been sent to the host, but not yet read (MSG_Get), ++ * and a list of free frames that can be filled when new messages arrive ++ * from the DSP. ++ * The MSG_QUEUE's hSynEvent gets posted when a message is ready. ++ */ ++struct MSG_QUEUE { ++ struct LST_ELEM listElem; ++ u32 dwSignature; ++ struct MSG_MGR *hMsgMgr; ++ u32 uMaxMsgs; /* Node message depth */ ++ u32 dwId; /* Node environment pointer */ ++ struct LST_LIST *msgFreeList; /* Free MsgFrames ready to be filled */ ++ /* Filled MsgFramess waiting to be read */ ++ struct LST_LIST *msgUsedList; ++ HANDLE hArg; /* Handle passed to mgr onExit callback */ ++ struct SYNC_OBJECT *hSyncEvent; /* Signalled when message is ready */ ++ struct SYNC_OBJECT *hSyncDone; /* For synchronizing cleanup */ ++ struct SYNC_OBJECT *hSyncDoneAck; /* For synchronizing cleanup */ ++ struct NTFY_OBJECT *hNtfy; /* For notification of message ready */ ++ bool fDone; /* TRUE <==> deleting the object */ ++ u32 refCount; /* Number of pending MSG_get/put calls */ ++}; ++ ++/* ++ * ======== MSG_DSPMSG ======== ++ */ ++struct MSG_DSPMSG { ++ struct DSP_MSG msg; ++ u32 dwId; /* Identifies the node the message goes to */ ++} ; ++ ++/* ++ * ======== MSG_FRAME ======== ++ */ ++struct MSG_FRAME { ++ struct LST_ELEM listElem; ++ struct MSG_DSPMSG msgData; ++} ; ++ ++#endif /* _MSG_SM_ */ ++ +diff --git a/drivers/dsp/bridge/wmd/_tiomap.h b/drivers/dsp/bridge/wmd/_tiomap.h +new file mode 100644 +index 0000000..815f695 +--- /dev/null ++++ b/drivers/dsp/bridge/wmd/_tiomap.h +@@ -0,0 +1,384 @@ ++/* ++ * _tiomap.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== _tiomap.h ======== ++ * Description: ++ * Definitions and types private to this WMD. ++ * ++ */ ++ ++#ifndef _TIOMAP_ ++#define _TIOMAP_ ++ ++#include ++#include ++#include ++#include /* for WMDIOCTL_EXTPROC defn */ ++#include ++#include ++ ++struct MAP_L4PERIPHERAL { ++ u32 physAddr; ++ u32 dspVirtAddr; ++} ; ++ ++#define ARM_MAILBOX_START 0xfffcf000 ++#define ARM_MAILBOX_LENGTH 0x800 ++ ++/* New Registers in OMAP3.1 */ ++ ++#define TESTBLOCK_ID_START 0xfffed400 ++#define TESTBLOCK_ID_LENGTH 0xff ++ ++/* ID Returned by OMAP1510 */ ++#define TBC_ID_VALUE 0xB47002F ++ ++#define SPACE_LENGTH 0x2000 ++#define API_CLKM_DPLL_DMA 0xfffec000 ++#define ARM_INTERRUPT_OFFSET 0xb00 ++ ++#define BIOS_24XX ++ ++#define L4_PERIPHERAL_NULL 0x0 ++#define DSPVA_PERIPHERAL_NULL 0x0 ++ ++#define MAX_LOCK_TLB_ENTRIES 15 ++ ++#define L4_PERIPHERAL_PRM 0x48306000 /*PRM L4 Peripheral */ ++#define DSPVA_PERIPHERAL_PRM 0x1181e000 ++#define L4_PERIPHERAL_SCM 0x48002000 /*SCM L4 Peripheral */ ++#define DSPVA_PERIPHERAL_SCM 0x1181f000 ++#define L4_PERIPHERAL_MMU 0x5D000000 /*MMU L4 Peripheral */ ++#define DSPVA_PERIPHERAL_MMU 0x11820000 ++#define L4_PERIPHERAL_CM 0x48004000 /* Core L4, Clock Management */ ++#define DSPVA_PERIPHERAL_CM 0x1181c000 ++#define L4_PERIPHERAL_PER 0x48005000 /* PER */ ++#define DSPVA_PERIPHERAL_PER 0x1181d000 ++ ++#define L4_PERIPHERAL_GPIO1 0x48310000 ++#define DSPVA_PERIPHERAL_GPIO1 0x11809000 ++#define L4_PERIPHERAL_GPIO2 0x49050000 ++#define DSPVA_PERIPHERAL_GPIO2 0x1180a000 ++#define L4_PERIPHERAL_GPIO3 0x49052000 ++#define DSPVA_PERIPHERAL_GPIO3 0x1180b000 ++#define L4_PERIPHERAL_GPIO4 0x49054000 ++#define DSPVA_PERIPHERAL_GPIO4 0x1180c000 ++#define L4_PERIPHERAL_GPIO5 0x49056000 ++#define DSPVA_PERIPHERAL_GPIO5 0x1180d000 ++ ++#define L4_PERIPHERAL_IVA2WDT 0x49030000 ++#define DSPVA_PERIPHERAL_IVA2WDT 0x1180e000 ++ ++#define L4_PERIPHERAL_DISPLAY 0x48050000 ++#define DSPVA_PERIPHERAL_DISPLAY 0x1180f000 ++ ++#define L4_PERIPHERAL_SSI 0x48058000 ++#define DSPVA_PERIPHERAL_SSI 0x11804000 ++#define L4_PERIPHERAL_GDD 0x48059000 ++#define DSPVA_PERIPHERAL_GDD 0x11805000 ++#define L4_PERIPHERAL_SS1 0x4805a000 ++#define DSPVA_PERIPHERAL_SS1 0x11806000 ++#define L4_PERIPHERAL_SS2 0x4805b000 ++#define DSPVA_PERIPHERAL_SS2 0x11807000 ++ ++#define L4_PERIPHERAL_CAMERA 0x480BC000 ++#define DSPVA_PERIPHERAL_CAMERA 0x11819000 ++ ++#define L4_PERIPHERAL_SDMA 0x48056000 ++#define DSPVA_PERIPHERAL_SDMA 0x11810000 /*0x1181d000 conflicts with PER */ ++ ++#define L4_PERIPHERAL_UART1 0x4806a000 ++#define DSPVA_PERIPHERAL_UART1 0x11811000 ++#define L4_PERIPHERAL_UART2 0x4806c000 ++#define DSPVA_PERIPHERAL_UART2 0x11812000 ++#define L4_PERIPHERAL_UART3 0x49020000 ++#define DSPVA_PERIPHERAL_UART3 0x11813000 ++ ++#define L4_PERIPHERAL_MCBSP1 0x48074000 ++#define DSPVA_PERIPHERAL_MCBSP1 0x11814000 ++#define L4_PERIPHERAL_MCBSP2 0x49022000 ++#define DSPVA_PERIPHERAL_MCBSP2 0x11815000 ++#define L4_PERIPHERAL_MCBSP3 0x49024000 ++#define DSPVA_PERIPHERAL_MCBSP3 0x11816000 ++#define L4_PERIPHERAL_MCBSP4 0x49026000 ++#define DSPVA_PERIPHERAL_MCBSP4 0x11817000 ++#define L4_PERIPHERAL_MCBSP5 0x48096000 ++#define DSPVA_PERIPHERAL_MCBSP5 0x11818000 ++ ++#define L4_PERIPHERAL_GPTIMER5 0x49038000 ++#define DSPVA_PERIPHERAL_GPTIMER5 0x11800000 ++#define L4_PERIPHERAL_GPTIMER6 0x4903a000 ++#define DSPVA_PERIPHERAL_GPTIMER6 0x11801000 ++#define L4_PERIPHERAL_GPTIMER7 0x4903c000 ++#define DSPVA_PERIPHERAL_GPTIMER7 0x11802000 ++#define L4_PERIPHERAL_GPTIMER8 0x4903e000 ++#define DSPVA_PERIPHERAL_GPTIMER8 0x11803000 ++ ++#define L4_PERIPHERAL_SPI1 0x48098000 ++#define DSPVA_PERIPHERAL_SPI1 0x1181a000 ++#define L4_PERIPHERAL_SPI2 0x4809a000 ++#define DSPVA_PERIPHERAL_SPI2 0x1181b000 ++ ++#define L4_PERIPHERAL_MBOX 0x48094000 ++#define DSPVA_PERIPHERAL_MBOX 0x11808000 ++ ++#define PM_GRPSEL_BASE 0x48307000 ++#define DSPVA_GRPSEL_BASE 0x11821000 ++ ++#define L4_PERIPHERAL_SIDETONE_MCBSP2 0x49028000 ++#define DSPVA_PERIPHERAL_SIDETONE_MCBSP2 0x11824000 ++#define L4_PERIPHERAL_SIDETONE_MCBSP3 0x4902a000 ++#define DSPVA_PERIPHERAL_SIDETONE_MCBSP3 0x11825000 ++ ++/* define a static array with L4 mappings */ ++static const struct MAP_L4PERIPHERAL L4PeripheralTable[] = { ++ {L4_PERIPHERAL_MBOX, DSPVA_PERIPHERAL_MBOX}, ++ {L4_PERIPHERAL_SCM, DSPVA_PERIPHERAL_SCM}, ++ {L4_PERIPHERAL_MMU, DSPVA_PERIPHERAL_MMU}, ++ {L4_PERIPHERAL_GPTIMER5, DSPVA_PERIPHERAL_GPTIMER5}, ++ {L4_PERIPHERAL_GPTIMER6, DSPVA_PERIPHERAL_GPTIMER6}, ++ {L4_PERIPHERAL_GPTIMER7, DSPVA_PERIPHERAL_GPTIMER7}, ++ {L4_PERIPHERAL_GPTIMER8, DSPVA_PERIPHERAL_GPTIMER8}, ++ {L4_PERIPHERAL_GPIO1, DSPVA_PERIPHERAL_GPIO1}, ++ {L4_PERIPHERAL_GPIO2, DSPVA_PERIPHERAL_GPIO2}, ++ {L4_PERIPHERAL_GPIO3, DSPVA_PERIPHERAL_GPIO3}, ++ {L4_PERIPHERAL_GPIO4, DSPVA_PERIPHERAL_GPIO4}, ++ {L4_PERIPHERAL_GPIO5, DSPVA_PERIPHERAL_GPIO5}, ++ {L4_PERIPHERAL_IVA2WDT, DSPVA_PERIPHERAL_IVA2WDT}, ++ {L4_PERIPHERAL_DISPLAY, DSPVA_PERIPHERAL_DISPLAY}, ++ {L4_PERIPHERAL_SSI, DSPVA_PERIPHERAL_SSI}, ++ {L4_PERIPHERAL_GDD, DSPVA_PERIPHERAL_GDD}, ++ {L4_PERIPHERAL_SS1, DSPVA_PERIPHERAL_SS1}, ++ {L4_PERIPHERAL_SS2, DSPVA_PERIPHERAL_SS2}, ++ {L4_PERIPHERAL_UART1, DSPVA_PERIPHERAL_UART1}, ++ {L4_PERIPHERAL_UART2, DSPVA_PERIPHERAL_UART2}, ++ {L4_PERIPHERAL_UART3, DSPVA_PERIPHERAL_UART3}, ++ {L4_PERIPHERAL_MCBSP1, DSPVA_PERIPHERAL_MCBSP1}, ++ {L4_PERIPHERAL_MCBSP2, DSPVA_PERIPHERAL_MCBSP2}, ++ {L4_PERIPHERAL_MCBSP3, DSPVA_PERIPHERAL_MCBSP3}, ++ {L4_PERIPHERAL_MCBSP4, DSPVA_PERIPHERAL_MCBSP4}, ++ {L4_PERIPHERAL_MCBSP5, DSPVA_PERIPHERAL_MCBSP5}, ++ {L4_PERIPHERAL_CAMERA, DSPVA_PERIPHERAL_CAMERA}, ++ {L4_PERIPHERAL_SPI1, DSPVA_PERIPHERAL_SPI1}, ++ {L4_PERIPHERAL_SPI2, DSPVA_PERIPHERAL_SPI2}, ++ {L4_PERIPHERAL_PRM, DSPVA_PERIPHERAL_PRM}, ++ {L4_PERIPHERAL_CM, DSPVA_PERIPHERAL_CM}, ++ {L4_PERIPHERAL_PER, DSPVA_PERIPHERAL_PER}, ++ {PM_GRPSEL_BASE, DSPVA_GRPSEL_BASE}, ++ {L4_PERIPHERAL_SIDETONE_MCBSP2, DSPVA_PERIPHERAL_SIDETONE_MCBSP2}, ++ {L4_PERIPHERAL_SIDETONE_MCBSP3, DSPVA_PERIPHERAL_SIDETONE_MCBSP3}, ++ {L4_PERIPHERAL_NULL, DSPVA_PERIPHERAL_NULL} ++}; ++ ++/* ++ * 15 10 0 ++ * --------------------------------- ++ * |0|0|1|0|0|0|c|c|c|i|i|i|i|i|i|i| ++ * --------------------------------- ++ * | (class) | (module specific) | ++ * ++ * where c -> Externel Clock Command: Clk & Autoidle Disable/Enable ++ * i -> External Clock ID Timers 5,6,7,8, McBSP1,2 and WDT3 ++ */ ++ ++/* MBX_PM_CLK_IDMASK: DSP External clock id mask. */ ++#define MBX_PM_CLK_IDMASK 0x7F ++ ++/* MBX_PM_CLK_CMDSHIFT: DSP External clock command shift. */ ++#define MBX_PM_CLK_CMDSHIFT 7 ++ ++/* MBX_PM_CLK_CMDMASK: DSP External clock command mask. */ ++#define MBX_PM_CLK_CMDMASK 7 ++ ++/* MBX_PM_MAX_RESOURCES: CORE 1 Clock resources. */ ++#define MBX_CORE1_RESOURCES 7 ++ ++/* MBX_PM_MAX_RESOURCES: CORE 2 Clock Resources. */ ++#define MBX_CORE2_RESOURCES 1 ++ ++/* MBX_PM_MAX_RESOURCES: TOTAL Clock Reosurces. */ ++#define MBX_PM_MAX_RESOURCES 11 ++ ++/* Power Management Commands */ ++enum BPWR_ExtClockCmd { ++ BPWR_DisableClock = 0, ++ BPWR_EnableClock, ++ BPWR_DisableAutoIdle, ++ BPWR_EnableAutoIdle ++} ; ++ ++/* OMAP242x specific resources */ ++enum BPWR_ExtClockId { ++ BPWR_GPTimer5 = 0x10, ++ BPWR_GPTimer6, ++ BPWR_GPTimer7, ++ BPWR_GPTimer8, ++ BPWR_WDTimer3, ++ BPWR_MCBSP1, ++ BPWR_MCBSP2, ++ BPWR_MCBSP3, ++ BPWR_MCBSP4, ++ BPWR_MCBSP5, ++ BPWR_SSI = 0x20 ++} ; ++ ++static const u32 BPWR_CLKID[] = { ++ (u32) BPWR_GPTimer5, ++ (u32) BPWR_GPTimer6, ++ (u32) BPWR_GPTimer7, ++ (u32) BPWR_GPTimer8, ++ (u32) BPWR_WDTimer3, ++ (u32) BPWR_MCBSP1, ++ (u32) BPWR_MCBSP2, ++ (u32) BPWR_MCBSP3, ++ (u32) BPWR_MCBSP4, ++ (u32) BPWR_MCBSP5, ++ (u32) BPWR_SSI ++}; ++ ++struct BPWR_Clk_t { ++ u32 clkId; ++ enum SERVICES_ClkId funClk; ++ enum SERVICES_ClkId intClk; ++} ; ++ ++static const struct BPWR_Clk_t BPWR_Clks[] = { ++ {(u32) BPWR_GPTimer5, SERVICESCLK_gpt5_fck, SERVICESCLK_gpt5_ick}, ++ {(u32) BPWR_GPTimer6, SERVICESCLK_gpt6_fck, SERVICESCLK_gpt6_ick}, ++ {(u32) BPWR_GPTimer7, SERVICESCLK_gpt7_fck, SERVICESCLK_gpt7_ick}, ++ {(u32) BPWR_GPTimer8, SERVICESCLK_gpt8_fck, SERVICESCLK_gpt8_ick}, ++ {(u32) BPWR_WDTimer3, SERVICESCLK_wdt3_fck, SERVICESCLK_wdt3_ick}, ++ {(u32) BPWR_MCBSP1, SERVICESCLK_mcbsp1_fck, SERVICESCLK_mcbsp1_ick}, ++ {(u32) BPWR_MCBSP2, SERVICESCLK_mcbsp2_fck, SERVICESCLK_mcbsp2_ick}, ++ {(u32) BPWR_MCBSP3, SERVICESCLK_mcbsp3_fck, SERVICESCLK_mcbsp3_ick}, ++ {(u32) BPWR_MCBSP4, SERVICESCLK_mcbsp4_fck, SERVICESCLK_mcbsp4_ick}, ++ {(u32) BPWR_MCBSP5, SERVICESCLK_mcbsp5_fck, SERVICESCLK_mcbsp5_ick}, ++ {(u32) BPWR_SSI, SERVICESCLK_ssi_fck, SERVICESCLK_ssi_ick} ++}; ++ ++/* Interrupt Register Offsets */ ++#define INTH_IT_REG_OFFSET 0x00 /* Interrupt register offset */ ++#define INTH_MASK_IT_REG_OFFSET 0x04 /* Mask Interrupt reg offset */ ++ ++#define DSP_MAILBOX1_INT 10 ++ ++/* ++ * INTH_InterruptKind_t ++ * Identify the kind of interrupt: either FIQ/IRQ ++ */ ++enum INTH_InterruptKind_t { ++ INTH_IRQ = 0, ++ INTH_FIQ = 1 ++} ; ++ ++enum INTH_SensitiveEdge_t { ++ FALLING_EDGE_SENSITIVE = 0, ++ LOW_LEVEL_SENSITIVE = 1 ++} ; ++ ++/* ++ * Bit definition of Interrupt Level Registers ++ */ ++ ++/* Mail Box defines */ ++#define MB_ARM2DSP1_REG_OFFSET 0x00 ++ ++#define MB_ARM2DSP1B_REG_OFFSET 0x04 ++ ++#define MB_DSP2ARM1B_REG_OFFSET 0x0C ++ ++#define MB_ARM2DSP1_FLAG_REG_OFFSET 0x18 ++ ++#define MB_ARM2DSP_FLAG 0x0001 ++ ++#define MBOX_ARM2DSP HW_MBOX_ID_0 ++#define MBOX_DSP2ARM HW_MBOX_ID_1 ++#define MBOX_ARM HW_MBOX_U0_ARM ++#define MBOX_DSP HW_MBOX_U1_DSP1 ++ ++#define ENABLE true ++#define DISABLE false ++ ++#define HIGH_LEVEL true ++#define LOW_LEVEL false ++ ++/* Macro's */ ++#define REG16(A) (*(REG_UWORD16 *)(A)) ++ ++#define ClearBit(reg, mask) (reg &= ~mask) ++#define SetBit(reg, mask) (reg |= mask) ++ ++#define SetGroupBits16(reg, position, width, value) \ ++ do {\ ++ reg &= ~((0xFFFF >> (16 - (width))) << (position)) ; \ ++ reg |= ((value & (0xFFFF >> (16 - (width)))) << (position)); \ ++ } while (0); ++ ++#define ClearBitIndex(reg, index) (reg &= ~(1 << (index))) ++ ++/* This mini driver's device context: */ ++struct WMD_DEV_CONTEXT { ++ struct DEV_OBJECT *hDevObject; /* Handle to WCD device object. */ ++ u32 dwDspBaseAddr; /* Arm's API to DSP virtual base addr */ ++ /* ++ * DSP External memory prog address as seen virtually by the OS on ++ * the host side. ++ */ ++ u32 dwDspExtBaseAddr; /* See the comment above */ ++ u32 dwAPIRegBase; /* API memory mapped registers */ ++ u32 dwDSPMmuBase; /* DSP MMU Mapped registers */ ++ u32 dwMailBoxBase; /* Mail box mapped registers */ ++ u32 dwAPIClkBase; /* CLK Registers */ ++ u32 dwDSPClkM2Base; /* DSP Clock Module m2 */ ++ u32 dwPublicRhea; /* Pub Rhea */ ++ u32 dwIntAddr; /* MB INTR reg */ ++ u32 dwTCEndianism; /* TC Endianism register */ ++ u32 dwTestBase; /* DSP MMU Mapped registers */ ++ u32 dwSelfLoop; /* Pointer to the selfloop */ ++ u32 dwDSPStartAdd; /* API Boot vector */ ++ u32 dwInternalSize; /* Internal memory size */ ++ ++ /* ++ * Processor specific info is set when prog loaded and read from DCD. ++ * [See WMD_BRD_Ctrl()] PROC info contains DSP-MMU TLB entries. ++ */ ++ /* DMMU TLB entries */ ++ struct WMDIOCTL_EXTPROC aTLBEntry[WMDIOCTL_NUMOFMMUTLB]; ++ u32 dwBrdState; /* Last known board state. */ ++ u32 ulIntMask; /* int mask */ ++ u16 ioBase; /* Board I/O base */ ++ u32 numTLBEntries; /* DSP MMU TLB entry counter */ ++ u32 fixedTLBEntries; /* Fixed DSPMMU TLB entry count */ ++ ++ /* TC Settings */ ++ bool tcWordSwapOn; /* Traffic Controller Word Swap */ ++ struct PgTableAttrs *pPtAttrs; ++ u32 uDspPerClks; ++} ; ++ ++ /* ++ * ======== WMD_TLB_DspVAToMpuPA ======== ++ * Given a DSP virtual address, traverse the page table and return ++ * a corresponding MPU physical address and size. ++ */ ++extern DSP_STATUS WMD_TLB_DspVAToMpuPA(struct WMD_DEV_CONTEXT *pDevContext, ++ IN u32 ulVirtAddr, ++ OUT u32 *ulPhysAddr, ++ OUT u32 *sizeTlb); ++ ++#endif /* _TIOMAP_ */ ++ +diff --git a/drivers/dsp/bridge/wmd/_tiomap_mmu.h b/drivers/dsp/bridge/wmd/_tiomap_mmu.h +new file mode 100644 +index 0000000..6b21047 +--- /dev/null ++++ b/drivers/dsp/bridge/wmd/_tiomap_mmu.h +@@ -0,0 +1,53 @@ ++/* ++ * _tiomap_mmu.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== _tiomap_mmu.h ======== ++ * Description: ++ * Definitions and types for the DSP MMU modules ++ * ++ *! Revision History ++ *! ================ ++ *! 19-Apr-2004 sb: Renamed HW types. Removed dspMmuTlbEntry ++ *! 05-Jan-2004 vp: Moved the file to a platform specific folder from common. ++ *! 21-Mar-2003 sb: Added macro definition TIHEL_LARGEPAGESIZE ++ *! 08-Oct-2002 rr: Created. ++ */ ++ ++#ifndef _TIOMAP_MMU_ ++#define _TIOMAP_MMU_ ++ ++#include "_tiomap.h" ++ ++/* ++ * ======== configureDspMmu ======== ++ * ++ * Make DSP MMu page table entries. ++ * Note: Not utilizing Coarse / Fine page tables. ++ * SECTION = 1MB, LARGE_PAGE = 64KB, SMALL_PAGE = 4KB, TINY_PAGE = 1KB. ++ * DSP Byte address 0x40_0000 is word addr 0x20_0000. ++ */ ++extern void configureDspMmu(struct WMD_DEV_CONTEXT *pDevContext, ++ u32 dataBasePhys, ++ u32 dspBaseVirt, ++ u32 sizeInBytes, ++ s32 nEntryStart, ++ enum HW_Endianism_t endianism, ++ enum HW_ElementSize_t elemSize, ++ enum HW_MMUMixedSize_t mixedSize); ++ ++#endif /* _TIOMAP_MMU_ */ +diff --git a/drivers/dsp/bridge/wmd/_tiomap_pwr.h b/drivers/dsp/bridge/wmd/_tiomap_pwr.h +new file mode 100644 +index 0000000..7ebd7b5 +--- /dev/null ++++ b/drivers/dsp/bridge/wmd/_tiomap_pwr.h +@@ -0,0 +1,102 @@ ++/* ++ * _tiomap_pwr.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== _tiomap_pwr.h ======== ++ * Description: ++ * Definitions and types for the DSP wake/sleep routines. ++ * ++ *! Revision History ++ *! ================ ++ *! 08-Oct-2002 rr: Created. ++ */ ++ ++#ifndef _TIOMAP_PWR_ ++#define _TIOMAP_PWR_ ++ ++/* ++ * ======== WakeDSP ========= ++ * Wakes up the DSP from DeepSleep ++ */ ++extern DSP_STATUS WakeDSP(struct WMD_DEV_CONTEXT *pDevContext, IN void *pArgs); ++ ++/* ++ * ======== SleepDSP ========= ++ * Places the DSP in DeepSleep. ++ */ ++extern DSP_STATUS SleepDSP(struct WMD_DEV_CONTEXT *pDevContext, ++ IN u32 dwCmd, IN void *pArgs); ++/* ++ * ========InterruptDSP======== ++ * Sends an interrupt to DSP unconditionally. ++ */ ++extern void InterruptDSP(struct WMD_DEV_CONTEXT *pDevContext, IN u16 wMbVal); ++ ++/* ++ * ======== WakeDSP ========= ++ * Wakes up the DSP from DeepSleep ++ */ ++extern DSP_STATUS DSPPeripheralClkCtrl(struct WMD_DEV_CONTEXT *pDevContext, ++ IN void *pArgs); ++/* ++ * ======== handle_hibernation_fromDSP ======== ++ * Handle Hibernation requested from DSP ++ */ ++DSP_STATUS handle_hibernation_fromDSP(struct WMD_DEV_CONTEXT *pDevContext); ++/* ++ * ======== PostScale_DSP ======== ++ * Handle Post Scale notification to DSP ++ */ ++DSP_STATUS PostScale_DSP(struct WMD_DEV_CONTEXT *pDevContext, IN void *pArgs); ++/* ++ * ======== PreScale_DSP ======== ++ * Handle Pre Scale notification to DSP ++ */ ++DSP_STATUS PreScale_DSP(struct WMD_DEV_CONTEXT *pDevContext, IN void *pArgs); ++/* ++ * ======== handle_constraints_set ======== ++ * Handle constraints request from DSP ++ */ ++DSP_STATUS handle_constraints_set(struct WMD_DEV_CONTEXT *pDevContext, ++ IN void *pArgs); ++/* ++ * ======== DSP_PeripheralClocks_Disable ======== ++ * This function disables all the peripheral clocks that ++ * were enabled by DSP. Call this function only when ++ * DSP is entering Hibernation or when DSP is in ++ * Error state ++ */ ++DSP_STATUS DSP_PeripheralClocks_Disable(struct WMD_DEV_CONTEXT *pDevContext, ++ IN void *pArgs); ++ ++/* ++ * ======== DSP_PeripheralClocks_Enable ======== ++ * This function enables all the peripheral clocks that ++ * were requested by DSP. ++ */ ++DSP_STATUS DSP_PeripheralClocks_Enable(struct WMD_DEV_CONTEXT *pDevContext, ++ IN void *pArgs); ++ ++/* ++ * ======== DSPClkWakeupEventCtrl ======== ++ * This function sets the group selction bits for while ++ * enabling/disabling. ++ */ ++void DSPClkWakeupEventCtrl(u32 ClkId, bool enable); ++ ++#endif /* _TIOMAP_PWR_ */ ++ +diff --git a/drivers/dsp/bridge/wmd/_tiomap_util.h b/drivers/dsp/bridge/wmd/_tiomap_util.h +new file mode 100644 +index 0000000..47e1e5d +--- /dev/null ++++ b/drivers/dsp/bridge/wmd/_tiomap_util.h +@@ -0,0 +1,46 @@ ++/* ++ * _tiomap_util.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== _tiomap_util.h ======== ++ * Description: ++ * Definitions and types for the utility routines. ++ * ++ *! Revision History ++ *! ================ ++ *! 08-Oct-2002 rr: Created. ++ */ ++ ++#ifndef _TIOMAP_UTIL_ ++#define _TIOMAP_UTIL_ ++ ++/* Time out Values in uSeconds*/ ++#define TIHELEN_ACKTIMEOUT 10000 ++ ++/* Time delay for HOM->SAM transition. */ ++#define WAIT_SAM 1000000 /* in usec (1000 millisec) */ ++ ++/* ++ * ======== WaitForStart ======== ++ * Wait for the singal from DSP that it has started, or time out. ++ * The argument dwSyncAddr is set to 1 before releasing the DSP. ++ * If the DSP starts running, it will clear this location. ++ */ ++extern bool WaitForStart(struct WMD_DEV_CONTEXT *pDevContext, u32 dwSyncAddr); ++ ++#endif /* _TIOMAP_UTIL_ */ ++ +diff --git a/drivers/dsp/bridge/wmd/chnl_sm.c b/drivers/dsp/bridge/wmd/chnl_sm.c +new file mode 100644 +index 0000000..e8ffb2f +--- /dev/null ++++ b/drivers/dsp/bridge/wmd/chnl_sm.c +@@ -0,0 +1,1100 @@ ++/* ++ * chnl_sm.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== chnl_sm.c ======== ++ * Description: ++ * Implements upper edge functions for WMD channel module. ++ * ++ * Public Functions: ++ * WMD_CHNL_AddIOReq ++ * WMD_CHNL_CancelIO ++ * WMD_CHNL_Close ++ * WMD_CHNL_Create ++ * WMD_CHNL_Destroy ++ * WMD_CHNL_FlushIO ++ * WMD_CHNL_GetInfo ++ * WMD_CHNL_GetIOC ++ * WMD_CHNL_GetMgrInfo ++ * WMD_CHNL_Idle ++ * WMD_CHNL_Open ++ * ++ * Notes: ++ * The lower edge functions must be implemented by the WMD writer, and ++ * are declared in chnl_sm.h. ++ * ++ * Care is taken in this code to prevent simulataneous access to channel ++ * queues from ++ * 1. Threads. ++ * 2. IO_DPC(), scheduled from the IO_ISR() as an event. ++ * ++ * This is done primarily by: ++ * - Semaphores. ++ * - state flags in the channel object; and ++ * - ensuring the IO_Dispatch() routine, which is called from both ++ * CHNL_AddIOReq() and the DPC(if implemented), is not re-entered. ++ * ++ * Channel Invariant: ++ * There is an important invariant condition which must be maintained per ++ * channel outside of WMD_CHNL_GetIOC() and IO_Dispatch(), violation of ++ * which may cause timeouts and/or failure offunction SYNC_WaitOnEvent. ++ * This invariant condition is: ++ * ++ * LST_Empty(pChnl->pIOCompletions) ==> pChnl->hSyncEvent is reset ++ * and ++ * !LST_Empty(pChnl->pIOCompletions) ==> pChnl->hSyncEvent is set. ++ * ++ *! Revision History: ++ *! ================ ++ *! 10-Feb-2004 sb: Consolidated the MAILBOX_IRQ macro at the top of the file. ++ *! 05-Jan-2004 vp: Updated for 2.6 kernel on 24xx platform. ++ *! 23-Apr-2003 sb: Fixed mailbox deadlock ++ *! 24-Feb-2003 vp: Code Review Updates. ++ *! 18-Oct-2002 vp: Ported to Linux platform ++ *! 29-Aug-2002 rr Changed the SYNC error code return to DSP error code return ++ * in WMD_CHNL_GetIOC. ++ *! 22-Jan-2002 ag Zero-copy support added. ++ *! CMM_CallocBuf() used for SM allocations. ++ *! 04-Feb-2001 ag DSP-DMA support added. ++ *! 22-Nov-2000 kc: Updated usage of PERF_RegisterStat. ++ *! 06-Nov-2000 jeh Move ISR_Install, DPC_Create from CHNL_Create to IO_Create. ++ *! 13-Oct-2000 jeh Added dwArg parameter to WMD_CHNL_AddIOReq(), added ++ *! WMD_CHNL_Idle and WMD_CHNL_RegisterNotify for DSPStream. ++ *! Remove #ifdef DEBUG from around channel cIOCs field. ++ *! 21-Sep-2000 rr: PreOMAP chnl class library acts like a IO class library. ++ *! 25-Sep-2000 ag: MEM_[Unmap]LinearAddress added for #ifdef CHNL_PREOMAP. ++ *! 07-Sep-2000 rr: Added new channel class for PreOMAP. ++ *! 11-Jul-2000 jeh Allow NULL user event in WMD_CHNL_Open(). ++ *! 06-Jul-2000 rr: Changed prefix PROC to PRCS for process module calls. ++ *! 20-Jan-2000 ag: Incorporated code review comments. ++ *! 05-Jan-2000 ag: Text format cleanup. ++ *! 07-Dec-1999 ag: Now setting ChnlMgr fSharedIRQ flag before ISR_Install(). ++ *! 01-Dec-1999 ag: WMD_CHNL_Open() now accepts named sync event. ++ *! 14-Nov-1999 ag: DPC_Schedule() uncommented. ++ *! 28-Oct-1999 ag: CHNL Attrs userEvent not supported. ++ *! SM addrs taken from COFF(IO) or host resource(SM). ++ *! 25-May-1999 jg: CHNL_IOCLASS boards now get their shared memory buffer ++ *! address and length from symbols defined in the currently ++ *! loaded COFF file. See _chn_sm.h. ++ *! 18-Jun-1997 gp: Moved waiting back to ring 0 to improve performance. ++ *! 22-Jan-1998 gp: Update User's pIOC struct in GetIOC at lower IRQL (NT). ++ *! 16-Jan-1998 gp: Commented out PERF stuff, since it is not all there in NT. ++ *! 13-Jan-1998 gp: Protect IOCTLs from IO_DPC by raising IRQL to DIRQL (NT). ++ *! 22-Oct-1997 gp: Call SYNC_OpenEvent in CHNL_Open, for NT support. ++ *! 18-Jun-1997 gp: Moved waiting back to ring 0 to improve performance. ++ *! 16-Jun-1997 gp: Added call into lower edge CHNL function to allow override ++ *! of the SHM window length reported by Windows CM. ++ *! 05-Jun-1997 gp: Removed unnecessary critical sections. ++ *! 18-Mar-1997 gp: Ensured CHNL_FlushIO on input leaves channel in READY state. ++ *! 06-Jan-1997 gp: ifdefed to support the IO variant of SHM channel class lib. ++ *! 21-Jan-1997 gp: CHNL_Close: set pChnl = NULL for DBC_Ensure(). ++ *! 14-Jan-1997 gp: Updated based on code review feedback. ++ *! 03-Jan-1997 gp: Added CHNL_E_WAITTIMEOUT error return code to CHNL_FlushIO() ++ *! 23-Oct-1996 gp: Tag channel with ring 0 process handle. ++ *! 13-Sep-1996 gp: Added performance statistics for channel. ++ *! 09-Sep-1996 gp: Added WMD_CHNL_GetMgrInfo(). ++ *! 04-Sep-1996 gp: Removed shared memory control struct offset: made zero. ++ *! 01-Aug-1996 gp: Implemented basic channel manager and channel create/delete. ++ *! 17-Jul-1996 gp: Started pseudo coding. ++ *! 11-Jul-1996 gp: Stubbed out. ++ */ ++ ++/* ----------------------------------- OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Mini-Driver */ ++#include ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++ ++/* ----------------------------------- Others */ ++#include ++ ++/* ----------------------------------- Define for This */ ++#define USERMODE_ADDR PAGE_OFFSET ++ ++#define MAILBOX_IRQ INT_MAIL_MPU_IRQ ++ ++/* ----------------------------------- Function Prototypes */ ++static struct LST_LIST *CreateChirpList(u32 uChirps); ++ ++static void FreeChirpList(struct LST_LIST *pList); ++ ++static struct CHNL_IRP *MakeNewChirp(void); ++ ++static DSP_STATUS SearchFreeChannel(struct CHNL_MGR *pChnlMgr, ++ OUT u32 *pdwChnl); ++ ++/* ++ * ======== WMD_CHNL_AddIOReq ======== ++ * Enqueue an I/O request for data transfer on a channel to the DSP. ++ * The direction (mode) is specified in the channel object. Note the DSP ++ * address is specified for channels opened in direct I/O mode. ++ */ ++DSP_STATUS WMD_CHNL_AddIOReq(struct CHNL_OBJECT *hChnl, void *pHostBuf, ++ u32 cBytes, u32 cBufSize, ++ OPTIONAL u32 dwDspAddr, u32 dwArg) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct CHNL_OBJECT *pChnl = (struct CHNL_OBJECT *)hChnl; ++ struct CHNL_IRP *pChirp = NULL; ++ u32 dwState; ++ bool fIsEOS; ++ struct CHNL_MGR *pChnlMgr = pChnl->pChnlMgr; ++ u8 *pHostSysBuf = NULL; ++ bool fSchedDPC = false; ++ u16 wMbVal = 0; ++ ++ DBG_Trace(DBG_ENTER, ++ "> WMD_CHNL_AddIOReq pChnl %p CHNL_IsOutput %x uChnlType " ++ "%x Id %d\n", pChnl, CHNL_IsOutput(pChnl->uMode), ++ pChnl->uChnlType, pChnl->uId); ++ ++ fIsEOS = (cBytes == 0) ? true : false; ++ ++ if (pChnl->uChnlType == CHNL_PCPY && pChnl->uId > 1 && pHostBuf) { ++ if (!(pHostBuf < (void *)USERMODE_ADDR)) { ++ pHostSysBuf = pHostBuf; ++ goto func_cont; ++ } ++ /* if addr in user mode, then copy to kernel space */ ++ pHostSysBuf = MEM_Alloc(cBufSize, MEM_NONPAGED); ++ if (pHostSysBuf == NULL) { ++ status = DSP_EMEMORY; ++ DBG_Trace(DBG_LEVEL7, ++ "No memory to allocate kernel buffer\n"); ++ goto func_cont; ++ } ++ if (CHNL_IsOutput(pChnl->uMode)) { ++ status = copy_from_user(pHostSysBuf, pHostBuf, ++ cBufSize); ++ if (status) { ++ DBG_Trace(DBG_LEVEL7, ++ "Error copying user buffer to " ++ "kernel, %d bytes remaining.\n", ++ status); ++ MEM_Free(pHostSysBuf); ++ pHostSysBuf = NULL; ++ status = DSP_EPOINTER; ++ } ++ } ++ } ++func_cont: ++ /* Validate args: */ ++ if (pHostBuf == NULL) { ++ status = DSP_EPOINTER; ++ } else if (!MEM_IsValidHandle(pChnl, CHNL_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ } else if (fIsEOS && CHNL_IsInput(pChnl->uMode)) { ++ status = CHNL_E_NOEOS; ++ } else { ++ /* Check the channel state: only queue chirp if channel state ++ * allows */ ++ dwState = pChnl->dwState; ++ if (dwState != CHNL_STATEREADY) { ++ if (dwState & CHNL_STATECANCEL) { ++ status = CHNL_E_CANCELLED; ++ } else if ((dwState & CHNL_STATEEOS) ++ && CHNL_IsOutput(pChnl->uMode)) { ++ status = CHNL_E_EOS; ++ } else { ++ /* No other possible states left: */ ++ DBC_Assert(0); ++ } ++ } ++ } ++ /* Mailbox IRQ is disabled to avoid race condition with DMA/ZCPY ++ * channels. DPCCS is held to avoid race conditions with PCPY channels. ++ * If DPC is scheduled in process context (IO_Schedule) and any ++ * non-mailbox interrupt occurs, that DPC will run and break CS. Hence ++ * we disable ALL DPCs. We will try to disable ONLY IO DPC later. */ ++ SYNC_EnterCS(pChnlMgr->hCSObj); ++ disable_irq(MAILBOX_IRQ); ++ if (pChnl->uChnlType == CHNL_PCPY) { ++ /* This is a processor-copy channel. */ ++ if (DSP_SUCCEEDED(status) && CHNL_IsOutput(pChnl->uMode)) { ++ /* Check buffer size on output channels for fit. */ ++ if (cBytes > IO_BufSize(pChnl->pChnlMgr->hIOMgr)) ++ status = CHNL_E_BUFSIZE; ++ ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Get a free chirp: */ ++ pChirp = (struct CHNL_IRP *)LST_GetHead(pChnl->pFreeList); ++ if (pChirp == NULL) ++ status = CHNL_E_NOIORPS; ++ ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Enqueue the chirp on the chnl's IORequest queue: */ ++ pChirp->pHostUserBuf = pChirp->pHostSysBuf = pHostBuf; ++ if (pChnl->uChnlType == CHNL_PCPY && pChnl->uId > 1) ++ pChirp->pHostSysBuf = pHostSysBuf; ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* Note: for dma chans dwDspAddr contains dsp address ++ * of SM buffer.*/ ++ DBC_Assert(pChnlMgr->uWordSize != 0); ++ /* DSP address */ ++ pChirp->uDspAddr = dwDspAddr / pChnlMgr->uWordSize; ++ pChirp->cBytes = cBytes; ++ pChirp->cBufSize = cBufSize; ++ /* Only valid for output channel */ ++ pChirp->dwArg = dwArg; ++ pChirp->status = (fIsEOS ? CHNL_IOCSTATEOS : ++ CHNL_IOCSTATCOMPLETE); ++ LST_PutTail(pChnl->pIORequests, (struct LST_ELEM *) ++ pChirp); ++ pChnl->cIOReqs++; ++ DBC_Assert(pChnl->cIOReqs <= pChnl->cChirps); ++ /* If end of stream, update the channel state to prevent ++ * more IOR's: */ ++ if (fIsEOS) ++ pChnl->dwState |= CHNL_STATEEOS; ++ ++ { ++ /* Legacy DSM Processor-Copy */ ++ DBC_Assert(pChnl->uChnlType == CHNL_PCPY); ++ /* Request IO from the DSP */ ++ IO_RequestChnl(pChnlMgr->hIOMgr, pChnl, ++ (CHNL_IsInput(pChnl->uMode) ? ++ IO_INPUT : IO_OUTPUT), &wMbVal); ++ fSchedDPC = true; ++ } ++ } ++ } ++ enable_irq(MAILBOX_IRQ); ++ SYNC_LeaveCS(pChnlMgr->hCSObj); ++ if (wMbVal != 0) ++ IO_IntrDSP2(pChnlMgr->hIOMgr, wMbVal); ++ ++ if (fSchedDPC == true) { ++ /* Schedule a DPC, to do the actual data transfer: */ ++ IO_Schedule(pChnlMgr->hIOMgr); ++ } ++ DBG_Trace(DBG_ENTER, "< WMD_CHNL_AddIOReq pChnl %p\n", pChnl); ++ return status; ++} ++ ++/* ++ * ======== WMD_CHNL_CancelIO ======== ++ * Return all I/O requests to the client which have not yet been ++ * transferred. The channel's I/O completion object is ++ * signalled, and all the I/O requests are queued as IOC's, with the ++ * status field set to CHNL_IOCSTATCANCEL. ++ * This call is typically used in abort situations, and is a prelude to ++ * CHNL_Close(); ++ */ ++DSP_STATUS WMD_CHNL_CancelIO(struct CHNL_OBJECT *hChnl) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct CHNL_OBJECT *pChnl = (struct CHNL_OBJECT *)hChnl; ++ u32 iChnl = -1; ++ CHNL_MODE uMode; ++ struct CHNL_IRP *pChirp; ++ struct CHNL_MGR *pChnlMgr = NULL; ++ ++ /* Check args: */ ++ if (MEM_IsValidHandle(pChnl, CHNL_SIGNATURE)) { ++ iChnl = pChnl->uId; ++ uMode = pChnl->uMode; ++ pChnlMgr = pChnl->pChnlMgr; ++ } else { ++ status = DSP_EHANDLE; ++ } ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ /* Mark this channel as cancelled, to prevent further IORequests or ++ * IORequests or dispatching. */ ++ SYNC_EnterCS(pChnlMgr->hCSObj); ++ pChnl->dwState |= CHNL_STATECANCEL; ++ if (LST_IsEmpty(pChnl->pIORequests)) ++ goto func_cont; ++ ++ if (pChnl->uChnlType == CHNL_PCPY) { ++ /* Indicate we have no more buffers available for transfer: */ ++ if (CHNL_IsInput(pChnl->uMode)) { ++ IO_CancelChnl(pChnlMgr->hIOMgr, iChnl); ++ } else { ++ /* Record that we no longer have output buffers ++ * available: */ ++ pChnlMgr->dwOutputMask &= ~(1 << iChnl); ++ } ++ } ++ /* Move all IOR's to IOC queue: */ ++ while (!LST_IsEmpty(pChnl->pIORequests)) { ++ pChirp = (struct CHNL_IRP *)LST_GetHead(pChnl->pIORequests); ++ if (pChirp) { ++ pChirp->cBytes = 0; ++ pChirp->status |= CHNL_IOCSTATCANCEL; ++ LST_PutTail(pChnl->pIOCompletions, ++ (struct LST_ELEM *)pChirp); ++ pChnl->cIOCs++; ++ pChnl->cIOReqs--; ++ DBC_Assert(pChnl->cIOReqs >= 0); ++ } ++ } ++func_cont: ++ SYNC_LeaveCS(pChnlMgr->hCSObj); ++func_end: ++ return status; ++} ++ ++/* ++ * ======== WMD_CHNL_Close ======== ++ * Purpose: ++ * Ensures all pending I/O on this channel is cancelled, discards all ++ * queued I/O completion notifications, then frees the resources allocated ++ * for this channel, and makes the corresponding logical channel id ++ * available for subsequent use. ++ */ ++DSP_STATUS WMD_CHNL_Close(struct CHNL_OBJECT *hChnl) ++{ ++ DSP_STATUS status; ++ struct CHNL_OBJECT *pChnl = (struct CHNL_OBJECT *)hChnl; ++ ++ /* Check args: */ ++ if (!MEM_IsValidHandle(pChnl, CHNL_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ goto func_cont; ++ } ++ { ++ /* Cancel IO: this ensures no further IO requests or ++ * notifications.*/ ++ status = WMD_CHNL_CancelIO(hChnl); ++ } ++func_cont: ++ if (DSP_SUCCEEDED(status)) { ++ /* Assert I/O on this channel is now cancelled: Protects ++ * from IO_DPC. */ ++ DBC_Assert((pChnl->dwState & CHNL_STATECANCEL)); ++ /* Invalidate channel object: Protects from ++ * CHNL_GetIOCompletion(). */ ++ pChnl->dwSignature = 0x0000; ++ /* Free the slot in the channel manager: */ ++ pChnl->pChnlMgr->apChannel[pChnl->uId] = NULL; ++ pChnl->pChnlMgr->cOpenChannels -= 1; ++ if (pChnl->hNtfy) { ++ NTFY_Delete(pChnl->hNtfy); ++ pChnl->hNtfy = NULL; ++ } ++ /* Reset channel event: (NOTE: hUserEvent freed in user ++ * context.). */ ++ if (pChnl->hSyncEvent) { ++ SYNC_ResetEvent(pChnl->hSyncEvent); ++ SYNC_CloseEvent(pChnl->hSyncEvent); ++ pChnl->hSyncEvent = NULL; ++ } ++ /* Free I/O request and I/O completion queues: */ ++ if (pChnl->pIOCompletions) { ++ FreeChirpList(pChnl->pIOCompletions); ++ pChnl->pIOCompletions = NULL; ++ pChnl->cIOCs = 0; ++ } ++ if (pChnl->pIORequests) { ++ FreeChirpList(pChnl->pIORequests); ++ pChnl->pIORequests = NULL; ++ pChnl->cIOReqs = 0; ++ } ++ if (pChnl->pFreeList) { ++ FreeChirpList(pChnl->pFreeList); ++ pChnl->pFreeList = NULL; ++ } ++ /* Release channel object. */ ++ MEM_FreeObject(pChnl); ++ pChnl = NULL; ++ } ++ DBC_Ensure(DSP_FAILED(status) || ++ !MEM_IsValidHandle(pChnl, CHNL_SIGNATURE)); ++ return status; ++} ++ ++/* ++ * ======== WMD_CHNL_Create ======== ++ * Create a channel manager object, responsible for opening new channels ++ * and closing old ones for a given board. ++ */ ++DSP_STATUS WMD_CHNL_Create(OUT struct CHNL_MGR **phChnlMgr, ++ struct DEV_OBJECT *hDevObject, ++ IN CONST struct CHNL_MGRATTRS *pMgrAttrs) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct CHNL_MGR *pChnlMgr = NULL; ++ s32 cChannels; ++#ifdef DEBUG ++ struct CHNL_MGR *hChnlMgr; ++#endif ++ /* Check DBC requirements: */ ++ DBC_Require(phChnlMgr != NULL); ++ DBC_Require(pMgrAttrs != NULL); ++ DBC_Require(pMgrAttrs->cChannels > 0); ++ DBC_Require(pMgrAttrs->cChannels <= CHNL_MAXCHANNELS); ++ DBC_Require(pMgrAttrs->uWordSize != 0); ++#ifdef DEBUG ++ /* This for the purposes of DBC_Require: */ ++ status = DEV_GetChnlMgr(hDevObject, &hChnlMgr); ++ DBC_Require(status != DSP_EHANDLE); ++ DBC_Require(hChnlMgr == NULL); ++#endif ++ if (DSP_SUCCEEDED(status)) { ++ /* Allocate channel manager object: */ ++ MEM_AllocObject(pChnlMgr, struct CHNL_MGR, CHNL_MGRSIGNATURE); ++ if (pChnlMgr) { ++ /* The cChannels attr must equal the # of supported ++ * chnls for each transport(# chnls for PCPY = DDMA = ++ * ZCPY): i.e. pMgrAttrs->cChannels = CHNL_MAXCHANNELS = ++ * DDMA_MAXDDMACHNLS = DDMA_MAXZCPYCHNLS. */ ++ DBC_Assert(pMgrAttrs->cChannels == CHNL_MAXCHANNELS); ++ cChannels = (CHNL_MAXCHANNELS + (CHNL_MAXCHANNELS * ++ CHNL_PCPY)); ++ /* Create array of channels: */ ++ pChnlMgr->apChannel = MEM_Calloc( ++ sizeof(struct CHNL_OBJECT *) * ++ cChannels, MEM_NONPAGED); ++ if (pChnlMgr->apChannel) { ++ /* Initialize CHNL_MGR object: */ ++ /* Shared memory driver. */ ++ pChnlMgr->dwType = CHNL_TYPESM; ++ pChnlMgr->uWordSize = pMgrAttrs->uWordSize; ++ /* total # chnls supported */ ++ pChnlMgr->cChannels = cChannels; ++ pChnlMgr->cOpenChannels = 0; ++ pChnlMgr->dwOutputMask = 0; ++ pChnlMgr->dwLastOutput = 0; ++ pChnlMgr->hDevObject = hDevObject; ++ if (DSP_SUCCEEDED(status)) { ++ status = SYNC_InitializeDPCCS ++ (&pChnlMgr->hCSObj); ++ } ++ } else { ++ status = DSP_EMEMORY; ++ } ++ } else { ++ status = DSP_EMEMORY; ++ } ++ } ++ if (DSP_FAILED(status)) { ++ WMD_CHNL_Destroy(pChnlMgr); ++ *phChnlMgr = NULL; ++ } else { ++ /* Return channel manager object to caller... */ ++ *phChnlMgr = pChnlMgr; ++ } ++ return status; ++} ++ ++/* ++ * ======== WMD_CHNL_Destroy ======== ++ * Purpose: ++ * Close all open channels, and destroy the channel manager. ++ */ ++DSP_STATUS WMD_CHNL_Destroy(struct CHNL_MGR *hChnlMgr) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct CHNL_MGR *pChnlMgr = hChnlMgr; ++ u32 iChnl; ++ ++ if (MEM_IsValidHandle(hChnlMgr, CHNL_MGRSIGNATURE)) { ++ /* Close all open channels: */ ++ for (iChnl = 0; iChnl < pChnlMgr->cChannels; iChnl++) { ++ if (DSP_SUCCEEDED ++ (WMD_CHNL_Close(pChnlMgr->apChannel[iChnl]))) { ++ DBC_Assert(pChnlMgr->apChannel[iChnl] == NULL); ++ } ++ } ++ /* release critical section */ ++ if (pChnlMgr->hCSObj) ++ SYNC_DeleteCS(pChnlMgr->hCSObj); ++ ++ /* Free channel manager object: */ ++ if (pChnlMgr->apChannel) ++ MEM_Free(pChnlMgr->apChannel); ++ ++ /* Set hChnlMgr to NULL in device object. */ ++ DEV_SetChnlMgr(pChnlMgr->hDevObject, NULL); ++ /* Free this Chnl Mgr object: */ ++ MEM_FreeObject(hChnlMgr); ++ } else { ++ status = DSP_EHANDLE; ++ } ++ return status; ++} ++ ++/* ++ * ======== WMD_CHNL_FlushIO ======== ++ * purpose: ++ * Flushes all the outstanding data requests on a channel. ++ */ ++DSP_STATUS WMD_CHNL_FlushIO(struct CHNL_OBJECT *hChnl, u32 dwTimeOut) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct CHNL_OBJECT *pChnl = (struct CHNL_OBJECT *)hChnl; ++ CHNL_MODE uMode = -1; ++ struct CHNL_MGR *pChnlMgr; ++ struct CHNL_IOC chnlIOC; ++ /* Check args: */ ++ if (MEM_IsValidHandle(pChnl, CHNL_SIGNATURE)) { ++ if ((dwTimeOut == CHNL_IOCNOWAIT) ++ && CHNL_IsOutput(pChnl->uMode)) { ++ status = DSP_EINVALIDARG; ++ } else { ++ uMode = pChnl->uMode; ++ pChnlMgr = pChnl->pChnlMgr; ++ } ++ } else { ++ status = DSP_EHANDLE; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Note: Currently, if another thread continues to add IO ++ * requests to this channel, this function will continue to ++ * flush all such queued IO requests. */ ++ if (CHNL_IsOutput(uMode) && (pChnl->uChnlType == CHNL_PCPY)) { ++ /* Wait for IO completions, up to the specified ++ * timeout: */ ++ while (!LST_IsEmpty(pChnl->pIORequests) && ++ DSP_SUCCEEDED(status)) { ++ status = WMD_CHNL_GetIOC(hChnl, dwTimeOut, ++ &chnlIOC); ++ if (DSP_FAILED(status)) ++ continue; ++ ++ if (chnlIOC.status & CHNL_IOCSTATTIMEOUT) ++ status = CHNL_E_WAITTIMEOUT; ++ ++ } ++ } else { ++ status = WMD_CHNL_CancelIO(hChnl); ++ /* Now, leave the channel in the ready state: */ ++ pChnl->dwState &= ~CHNL_STATECANCEL; ++ } ++ } ++ DBC_Ensure(DSP_FAILED(status) || LST_IsEmpty(pChnl->pIORequests)); ++ return status; ++} ++ ++/* ++ * ======== WMD_CHNL_GetInfo ======== ++ * Purpose: ++ * Retrieve information related to a channel. ++ */ ++DSP_STATUS WMD_CHNL_GetInfo(struct CHNL_OBJECT *hChnl, ++ OUT struct CHNL_INFO *pInfo) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct CHNL_OBJECT *pChnl = (struct CHNL_OBJECT *)hChnl; ++ if (pInfo != NULL) { ++ if (MEM_IsValidHandle(pChnl, CHNL_SIGNATURE)) { ++ /* Return the requested information: */ ++ pInfo->hChnlMgr = pChnl->pChnlMgr; ++ pInfo->hEvent = pChnl->hUserEvent; ++ pInfo->dwID = pChnl->uId; ++ pInfo->dwMode = pChnl->uMode; ++ pInfo->cPosition = pChnl->cBytesMoved; ++ pInfo->hProcess = pChnl->hProcess; ++ pInfo->hSyncEvent = pChnl->hSyncEvent; ++ pInfo->cIOCs = pChnl->cIOCs; ++ pInfo->cIOReqs = pChnl->cIOReqs; ++ pInfo->dwState = pChnl->dwState; ++ } else { ++ status = DSP_EHANDLE; ++ } ++ } else { ++ status = DSP_EPOINTER; ++ } ++ return status; ++} ++ ++/* ++ * ======== WMD_CHNL_GetIOC ======== ++ * Optionally wait for I/O completion on a channel. Dequeue an I/O ++ * completion record, which contains information about the completed ++ * I/O request. ++ * Note: Ensures Channel Invariant (see notes above). ++ */ ++DSP_STATUS WMD_CHNL_GetIOC(struct CHNL_OBJECT *hChnl, u32 dwTimeOut, ++ OUT struct CHNL_IOC *pIOC) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct CHNL_OBJECT *pChnl = (struct CHNL_OBJECT *)hChnl; ++ struct CHNL_IRP *pChirp; ++ DSP_STATUS statSync; ++ bool fDequeueIOC = true; ++ struct CHNL_IOC ioc = { NULL, 0, 0, 0, 0 }; ++ u8 *pHostSysBuf = NULL; ++ ++ DBG_Trace(DBG_ENTER, "> WMD_CHNL_GetIOC pChnl %p CHNL_IsOutput %x " ++ "uChnlType %x\n", pChnl, CHNL_IsOutput(pChnl->uMode), ++ pChnl->uChnlType); ++ /* Check args: */ ++ if (pIOC == NULL) { ++ status = DSP_EPOINTER; ++ } else if (!MEM_IsValidHandle(pChnl, CHNL_SIGNATURE)) { ++ status = DSP_EHANDLE; ++ } else if (dwTimeOut == CHNL_IOCNOWAIT) { ++ if (LST_IsEmpty(pChnl->pIOCompletions)) ++ status = CHNL_E_NOIOC; ++ ++ } ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ ioc.status = CHNL_IOCSTATCOMPLETE; ++ if (dwTimeOut != CHNL_IOCNOWAIT && LST_IsEmpty(pChnl->pIOCompletions)) { ++ if (dwTimeOut == CHNL_IOCINFINITE) ++ dwTimeOut = SYNC_INFINITE; ++ ++ statSync = SYNC_WaitOnEvent(pChnl->hSyncEvent, dwTimeOut); ++ if (statSync == DSP_ETIMEOUT) { ++ /* No response from DSP */ ++ ioc.status |= CHNL_IOCSTATTIMEOUT; ++ fDequeueIOC = false; ++ } else if (statSync == DSP_EFAIL) { ++ /* This can occur when the user mode thread is ++ * aborted (^C), or when _VWIN32_WaitSingleObject() ++ * fails due to unkown causes. */ ++ /* Even though Wait failed, there may be something in ++ * the Q: */ ++ if (LST_IsEmpty(pChnl->pIOCompletions)) { ++ ioc.status |= CHNL_IOCSTATCANCEL; ++ fDequeueIOC = false; ++ } ++ } ++ } ++ /* See comment in AddIOReq */ ++ SYNC_EnterCS(pChnl->pChnlMgr->hCSObj); ++ disable_irq(MAILBOX_IRQ); ++ if (fDequeueIOC) { ++ /* Dequeue IOC and set pIOC; */ ++ DBC_Assert(!LST_IsEmpty(pChnl->pIOCompletions)); ++ pChirp = (struct CHNL_IRP *)LST_GetHead(pChnl->pIOCompletions); ++ /* Update pIOC from channel state and chirp: */ ++ if (pChirp) { ++ pChnl->cIOCs--; ++ /* If this is a zero-copy channel, then set IOC's pBuf ++ * to the DSP's address. This DSP address will get ++ * translated to user's virtual addr later. */ ++ { ++ pHostSysBuf = pChirp->pHostSysBuf; ++ ioc.pBuf = pChirp->pHostUserBuf; ++ } ++ ioc.cBytes = pChirp->cBytes; ++ ioc.cBufSize = pChirp->cBufSize; ++ ioc.dwArg = pChirp->dwArg; ++ ioc.status |= pChirp->status; ++ /* Place the used chirp on the free list: */ ++ LST_PutTail(pChnl->pFreeList, (struct LST_ELEM *) ++ pChirp); ++ } else { ++ ioc.pBuf = NULL; ++ ioc.cBytes = 0; ++ } ++ } else { ++ ioc.pBuf = NULL; ++ ioc.cBytes = 0; ++ ioc.dwArg = 0; ++ ioc.cBufSize = 0; ++ } ++ /* Ensure invariant: If any IOC's are queued for this channel... */ ++ if (!LST_IsEmpty(pChnl->pIOCompletions)) { ++ /* Since DSPStream_Reclaim() does not take a timeout ++ * parameter, we pass the stream's timeout value to ++ * WMD_CHNL_GetIOC. We cannot determine whether or not ++ * we have waited in User mode. Since the stream's timeout ++ * value may be non-zero, we still have to set the event. ++ * Therefore, this optimization is taken out. ++ * ++ * if (dwTimeOut == CHNL_IOCNOWAIT) { ++ * ... ensure event is set.. ++ * SYNC_SetEvent(pChnl->hSyncEvent); ++ * } */ ++ SYNC_SetEvent(pChnl->hSyncEvent); ++ } else { ++ /* else, if list is empty, ensure event is reset. */ ++ SYNC_ResetEvent(pChnl->hSyncEvent); ++ } ++ enable_irq(MAILBOX_IRQ); ++ SYNC_LeaveCS(pChnl->pChnlMgr->hCSObj); ++ if (fDequeueIOC && (pChnl->uChnlType == CHNL_PCPY && pChnl->uId > 1)) { ++ if (!(ioc.pBuf < (void *) USERMODE_ADDR)) ++ goto func_cont; ++ ++ /* If the addr is in user mode, then copy it */ ++ if (!pHostSysBuf || !ioc.pBuf) { ++ status = DSP_EPOINTER; ++ DBG_Trace(DBG_LEVEL7, ++ "System buffer NULL in IO completion.\n"); ++ goto func_cont; ++ } ++ if (!CHNL_IsInput(pChnl->uMode)) ++ goto func_cont1; ++ ++ /*pHostUserBuf */ ++ status = copy_to_user(ioc.pBuf, pHostSysBuf, ioc.cBytes); ++#ifndef RES_CLEANUP_DISABLE ++ if (status) { ++ if (current->flags & PF_EXITING) { ++ DBG_Trace(DBG_LEVEL7, ++ "\n2current->flags == PF_EXITING, " ++ " current->flags;0x%x\n", ++ current->flags); ++ status = 0; ++ } else { ++ DBG_Trace(DBG_LEVEL7, ++ "\n2current->flags != PF_EXITING, " ++ " current->flags;0x%x\n", ++ current->flags); ++ } ++ } ++#endif ++ if (status) { ++ DBG_Trace(DBG_LEVEL7, ++ "Error copying kernel buffer to user, %d" ++ " bytes remaining. in_interupt %d\n", ++ status, in_interrupt()); ++ status = DSP_EPOINTER; ++ } ++func_cont1: ++ MEM_Free(pHostSysBuf); ++ } ++func_cont: ++ /* Update User's IOC block: */ ++ *pIOC = ioc; ++func_end: ++ DBG_Trace(DBG_ENTER, "< WMD_CHNL_GetIOC pChnl %p\n", pChnl); ++ return status; ++} ++ ++/* ++ * ======== WMD_CHNL_GetMgrInfo ======== ++ * Retrieve information related to the channel manager. ++ */ ++DSP_STATUS WMD_CHNL_GetMgrInfo(struct CHNL_MGR *hChnlMgr, u32 uChnlID, ++ OUT struct CHNL_MGRINFO *pMgrInfo) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct CHNL_MGR *pChnlMgr = (struct CHNL_MGR *)hChnlMgr; ++ ++ if (pMgrInfo != NULL) { ++ if (uChnlID <= CHNL_MAXCHANNELS) { ++ if (MEM_IsValidHandle(hChnlMgr, CHNL_MGRSIGNATURE)) { ++ /* Return the requested information: */ ++ pMgrInfo->hChnl = pChnlMgr->apChannel[uChnlID]; ++ pMgrInfo->cOpenChannels = pChnlMgr-> ++ cOpenChannels; ++ pMgrInfo->dwType = pChnlMgr->dwType; ++ /* total # of chnls */ ++ pMgrInfo->cChannels = pChnlMgr->cChannels; ++ } else { ++ status = DSP_EHANDLE; ++ } ++ } else { ++ status = CHNL_E_BADCHANID; ++ } ++ } else { ++ status = DSP_EPOINTER; ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== WMD_CHNL_Idle ======== ++ * Idles a particular channel. ++ */ ++DSP_STATUS WMD_CHNL_Idle(struct CHNL_OBJECT *hChnl, u32 dwTimeOut, ++ bool fFlush) ++{ ++ CHNL_MODE uMode; ++ struct CHNL_MGR *pChnlMgr; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(MEM_IsValidHandle(hChnl, CHNL_SIGNATURE)); ++ ++ uMode = hChnl->uMode; ++ pChnlMgr = hChnl->pChnlMgr; ++ ++ if (CHNL_IsOutput(uMode) && !fFlush) { ++ /* Wait for IO completions, up to the specified timeout: */ ++ status = WMD_CHNL_FlushIO(hChnl, dwTimeOut); ++ } else { ++ status = WMD_CHNL_CancelIO(hChnl); ++ ++ /* Reset the byte count and put channel back in ready state. */ ++ hChnl->cBytesMoved = 0; ++ hChnl->dwState &= ~CHNL_STATECANCEL; ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== WMD_CHNL_Open ======== ++ * Open a new half-duplex channel to the DSP board. ++ */ ++DSP_STATUS WMD_CHNL_Open(OUT struct CHNL_OBJECT **phChnl, ++ struct CHNL_MGR *hChnlMgr, CHNL_MODE uMode, ++ u32 uChnlId, CONST IN struct CHNL_ATTRS *pAttrs) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct CHNL_MGR *pChnlMgr = hChnlMgr; ++ struct CHNL_OBJECT *pChnl = NULL; ++ struct SYNC_ATTRS *pSyncAttrs = NULL; ++ struct SYNC_OBJECT *hSyncEvent = NULL; ++ /* Ensure DBC requirements: */ ++ DBC_Require(phChnl != NULL); ++ DBC_Require(pAttrs != NULL); ++ *phChnl = NULL; ++ /* Validate Args: */ ++ if (pAttrs->uIOReqs == 0) { ++ status = DSP_EINVALIDARG; ++ } else { ++ if (!MEM_IsValidHandle(hChnlMgr, CHNL_MGRSIGNATURE)) { ++ status = DSP_EHANDLE; ++ } else { ++ if (uChnlId != CHNL_PICKFREE) { ++ if (uChnlId >= pChnlMgr->cChannels) { ++ status = CHNL_E_BADCHANID; ++ } else if (pChnlMgr->apChannel[uChnlId] != ++ NULL) { ++ status = CHNL_E_CHANBUSY; ++ } ++ } else { ++ /* Check for free channel */ ++ status = SearchFreeChannel(pChnlMgr, &uChnlId); ++ } ++ } ++ } ++ if (DSP_FAILED(status)) ++ goto func_end; ++ ++ DBC_Assert(uChnlId < pChnlMgr->cChannels); ++ /* Create channel object: */ ++ MEM_AllocObject(pChnl, struct CHNL_OBJECT, 0x0000); ++ if (!pChnl) { ++ status = DSP_EMEMORY; ++ goto func_cont; ++ } ++ /* Protect queues from IO_DPC: */ ++ pChnl->dwState = CHNL_STATECANCEL; ++ /* Allocate initial IOR and IOC queues: */ ++ pChnl->pFreeList = CreateChirpList(pAttrs->uIOReqs); ++ pChnl->pIORequests = CreateChirpList(0); ++ pChnl->pIOCompletions = CreateChirpList(0); ++ pChnl->cChirps = pAttrs->uIOReqs; ++ pChnl->cIOCs = 0; ++ pChnl->cIOReqs = 0; ++ status = SYNC_OpenEvent(&hSyncEvent, pSyncAttrs); ++ if (DSP_SUCCEEDED(status)) { ++ status = NTFY_Create(&pChnl->hNtfy); ++ if (DSP_FAILED(status)) { ++ /* The only failure that could have occurred */ ++ status = DSP_EMEMORY; ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ if (pChnl->pIOCompletions && pChnl->pIORequests && ++ pChnl->pFreeList) { ++ /* Initialize CHNL object fields: */ ++ pChnl->pChnlMgr = pChnlMgr; ++ pChnl->uId = uChnlId; ++ pChnl->uMode = uMode; ++ pChnl->hUserEvent = hSyncEvent; /* for Linux */ ++ pChnl->hSyncEvent = hSyncEvent; ++ /* get the process handle */ ++ pChnl->hProcess = current->pid; ++ pChnl->pCBArg = 0; ++ pChnl->cBytesMoved = 0; ++ /* Default to proc-copy */ ++ pChnl->uChnlType = CHNL_PCPY; ++ } else { ++ status = DSP_EMEMORY; ++ } ++ } else { ++ status = DSP_EINVALIDARG; ++ } ++ if (DSP_FAILED(status)) { ++ /* Free memory */ ++ if (pChnl->pIOCompletions) { ++ FreeChirpList(pChnl->pIOCompletions); ++ pChnl->pIOCompletions = NULL; ++ pChnl->cIOCs = 0; ++ } ++ if (pChnl->pIORequests) { ++ FreeChirpList(pChnl->pIORequests); ++ pChnl->pIORequests = NULL; ++ } ++ if (pChnl->pFreeList) { ++ FreeChirpList(pChnl->pFreeList); ++ pChnl->pFreeList = NULL; ++ } ++ if (hSyncEvent) { ++ SYNC_CloseEvent(hSyncEvent); ++ hSyncEvent = NULL; ++ } ++ if (pChnl->hNtfy) { ++ NTFY_Delete(pChnl->hNtfy); ++ pChnl->hNtfy = NULL; ++ } ++ MEM_FreeObject(pChnl); ++ } ++func_cont: ++ if (DSP_SUCCEEDED(status)) { ++ /* Insert channel object in channel manager: */ ++ pChnlMgr->apChannel[pChnl->uId] = pChnl; ++ SYNC_EnterCS(pChnlMgr->hCSObj); ++ pChnlMgr->cOpenChannels++; ++ SYNC_LeaveCS(pChnlMgr->hCSObj); ++ /* Return result... */ ++ pChnl->dwSignature = CHNL_SIGNATURE; ++ pChnl->dwState = CHNL_STATEREADY; ++ *phChnl = pChnl; ++ } ++func_end: ++ DBC_Ensure((DSP_SUCCEEDED(status) && ++ MEM_IsValidHandle(pChnl, CHNL_SIGNATURE)) || ++ (*phChnl == NULL)); ++ return status; ++} ++ ++/* ++ * ======== WMD_CHNL_RegisterNotify ======== ++ * Registers for events on a particular channel. ++ */ ++DSP_STATUS WMD_CHNL_RegisterNotify(struct CHNL_OBJECT *hChnl, u32 uEventMask, ++ u32 uNotifyType, ++ struct DSP_NOTIFICATION *hNotification) ++{ ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Assert(!(uEventMask & ~(DSP_STREAMDONE | DSP_STREAMIOCOMPLETION))); ++ ++ status = NTFY_Register(hChnl->hNtfy, hNotification, uEventMask, ++ uNotifyType); ++ ++ return status; ++} ++ ++/* ++ * ======== CreateChirpList ======== ++ * Purpose: ++ * Initialize a queue of channel I/O Request/Completion packets. ++ * Parameters: ++ * uChirps: Number of Chirps to allocate. ++ * Returns: ++ * Pointer to queue of IRPs, or NULL. ++ * Requires: ++ * Ensures: ++ */ ++static struct LST_LIST *CreateChirpList(u32 uChirps) ++{ ++ struct LST_LIST *pChirpList; ++ struct CHNL_IRP *pChirp; ++ u32 i; ++ ++ pChirpList = LST_Create(); ++ ++ if (pChirpList) { ++ /* Make N chirps and place on queue. */ ++ for (i = 0; (i < uChirps) && ((pChirp = MakeNewChirp()) != ++ NULL); i++) { ++ LST_PutTail(pChirpList, (struct LST_ELEM *)pChirp); ++ } ++ ++ /* If we couldn't allocate all chirps, free those allocated: */ ++ if (i != uChirps) { ++ FreeChirpList(pChirpList); ++ pChirpList = NULL; ++ } ++ } ++ ++ return pChirpList; ++} ++ ++/* ++ * ======== FreeChirpList ======== ++ * Purpose: ++ * Free the queue of Chirps. ++ */ ++static void FreeChirpList(struct LST_LIST *pChirpList) ++{ ++ DBC_Require(pChirpList != NULL); ++ ++ while (!LST_IsEmpty(pChirpList)) ++ MEM_Free(LST_GetHead(pChirpList)); ++ ++ LST_Delete(pChirpList); ++} ++ ++/* ++ * ======== MakeNewChirp ======== ++ * Allocate the memory for a new channel IRP. ++ */ ++static struct CHNL_IRP *MakeNewChirp(void) ++{ ++ struct CHNL_IRP *pChirp; ++ ++ pChirp = (struct CHNL_IRP *)MEM_Calloc( ++ sizeof(struct CHNL_IRP), MEM_NONPAGED); ++ if (pChirp != NULL) { ++ /* LST_InitElem only resets the list's member values. */ ++ LST_InitElem(&pChirp->link); ++ } ++ ++ return pChirp; ++} ++ ++/* ++ * ======== SearchFreeChannel ======== ++ * Search for a free channel slot in the array of channel pointers. ++ */ ++static DSP_STATUS SearchFreeChannel(struct CHNL_MGR *pChnlMgr, ++ OUT u32 *pdwChnl) ++{ ++ DSP_STATUS status = CHNL_E_OUTOFSTREAMS; ++ u32 i; ++ ++ DBC_Require(MEM_IsValidHandle(pChnlMgr, CHNL_MGRSIGNATURE)); ++ ++ for (i = 0; i < pChnlMgr->cChannels; i++) { ++ if (pChnlMgr->apChannel[i] == NULL) { ++ status = DSP_SOK; ++ *pdwChnl = i; ++ break; ++ } ++ } ++ ++ return status; ++} +diff --git a/drivers/dsp/bridge/wmd/io_sm.c b/drivers/dsp/bridge/wmd/io_sm.c +new file mode 100644 +index 0000000..325f1f1 +--- /dev/null ++++ b/drivers/dsp/bridge/wmd/io_sm.c +@@ -0,0 +1,2011 @@ ++/* ++ * io_sm.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== io_sm.c ======== ++ * Description: ++ * IO dispatcher for a shared memory channel driver. ++ * ++ * Public Functions: ++ * WMD_IO_Create ++ * WMD_IO_Destroy ++ * WMD_IO_OnLoaded ++ * IO_AndSetValue ++ * IO_BufSize ++ * IO_CancelChnl ++ * IO_DPC ++ * IO_ISR ++ * IO_IVAISR ++ * IO_OrSetValue ++ * IO_ReadValue ++ * IO_ReadValueLong ++ * IO_RequestChnl ++ * IO_Schedule ++ * IO_WriteValue ++ * IO_WriteValueLong ++ * ++ * Channel Invariant: ++ * There is an important invariant condition which must be maintained per ++ * channel outside of WMD_CHNL_GetIOC() and IO_Dispatch(), violation of ++ * which may cause timeouts and/or failure of the WIN32_WaitSingleObject ++ * function (SYNC_WaitOnEvent). ++ * ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ------------------------------------ Hardware Abstraction Layer */ ++#include ++#include ++ ++/* ----------------------------------- Mini Driver */ ++#include ++#include ++#include ++#include <_tiomap.h> ++#include ++#include <_tiomap_pwr.h> ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Others */ ++#include ++#include ++#include ++#include "_cmm.h" ++ ++/* ----------------------------------- This */ ++#include ++#include "_msg_sm.h" ++#include ++ ++/* ----------------------------------- Defines, Data Structures, Typedefs */ ++#define OUTPUTNOTREADY 0xffff ++#define NOTENABLED 0xffff /* channel(s) not enabled */ ++ ++#define EXTEND "_EXT_END" ++ ++#define SwapWord(x) (x) ++#define ulPageAlignSize 0x10000 /* Page Align Size */ ++ ++#define MAX_PM_REQS 32 ++ ++/* IO Manager: only one created per board: */ ++struct IO_MGR { ++ /* These four fields must be the first fields in a IO_MGR_ struct: */ ++ u32 dwSignature; /* Used for object validation */ ++ struct WMD_DEV_CONTEXT *hWmdContext; /* WMD device context */ ++ struct WMD_DRV_INTERFACE *pIntfFxns; /* Function interface to WMD */ ++ struct DEV_OBJECT *hDevObject; /* Device this board represents */ ++ ++ /* These fields initialized in WMD_IO_Create(): */ ++ struct CHNL_MGR *hChnlMgr; ++ struct SHM *pSharedMem; /* Shared Memory control */ ++ u8 *pInput; /* Address of input channel */ ++ u8 *pOutput; /* Address of output channel */ ++ struct MSG_MGR *hMsgMgr; /* Message manager */ ++ struct MSG *pMsgInputCtrl; /* Msg control for from DSP messages */ ++ struct MSG *pMsgOutputCtrl; /* Msg control for to DSP messages */ ++ u8 *pMsgInput; /* Address of input messages */ ++ u8 *pMsgOutput; /* Address of output messages */ ++ u32 uSMBufSize; /* Size of a shared memory I/O channel */ ++ bool fSharedIRQ; /* Is this IRQ shared? */ ++ struct DPC_OBJECT *hDPC; /* DPC object handle */ ++ struct SYNC_CSOBJECT *hCSObj; /* Critical section object handle */ ++ u32 uWordSize; /* Size in bytes of DSP word */ ++ u16 wIntrVal; /* interrupt value */ ++ /* private extnd proc info; mmu setup */ ++ struct MGR_PROCESSOREXTINFO extProcInfo; ++ struct CMM_OBJECT *hCmmMgr; /* Shared Mem Mngr */ ++ struct work_struct io_workq; /*workqueue */ ++ u32 dQuePowerMbxVal[MAX_PM_REQS]; ++ u32 iQuePowerHead; ++ u32 iQuePowerTail; ++#ifndef DSP_TRACEBUF_DISABLED ++ u32 ulTraceBufferBegin; /* Trace message start address */ ++ u32 ulTraceBufferEnd; /* Trace message end address */ ++ u32 ulTraceBufferCurrent; /* Trace message current address */ ++ u32 ulGPPReadPointer; /* GPP Read pointer to Trace buffer */ ++ u8 *pMsg; ++ u32 ulGppVa; ++ u32 ulDspVa; ++#endif ++} ; ++ ++/* ----------------------------------- Function Prototypes */ ++static void IO_DispatchChnl(IN struct IO_MGR *pIOMgr, ++ IN OUT struct CHNL_OBJECT *pChnl, u32 iMode); ++static void IO_DispatchMsg(IN struct IO_MGR *pIOMgr, struct MSG_MGR *hMsgMgr); ++static void IO_DispatchPM(struct work_struct *work); ++static void NotifyChnlComplete(struct CHNL_OBJECT *pChnl, ++ struct CHNL_IRP *pChirp); ++static void InputChnl(struct IO_MGR *pIOMgr, struct CHNL_OBJECT *pChnl, ++ u32 iMode); ++static void OutputChnl(struct IO_MGR *pIOMgr, struct CHNL_OBJECT *pChnl, ++ u32 iMode); ++static void InputMsg(struct IO_MGR *pIOMgr, struct MSG_MGR *hMsgMgr); ++static void OutputMsg(struct IO_MGR *pIOMgr, struct MSG_MGR *hMsgMgr); ++static u32 FindReadyOutput(struct CHNL_MGR *pChnlMgr, ++ struct CHNL_OBJECT *pChnl, u32 dwMask); ++static u32 ReadData(struct WMD_DEV_CONTEXT *hDevContext, void *pDest, ++ void *pSrc, u32 uSize); ++static u32 WriteData(struct WMD_DEV_CONTEXT *hDevContext, void *pDest, ++ void *pSrc, u32 uSize); ++static struct workqueue_struct *bridge_workqueue; ++#ifndef DSP_TRACEBUF_DISABLED ++void PrintDSPDebugTrace(struct IO_MGR *hIOMgr); ++#endif ++ ++/* Bus Addr (cached kernel)*/ ++static DSP_STATUS registerSHMSegs(struct IO_MGR *hIOMgr, ++ struct COD_MANAGER *hCodMan, ++ u32 dwGPPBasePA); ++ ++#ifdef CONFIG_BRIDGE_DVFS ++/* The maximum number of OPPs that are supported */ ++extern s32 dsp_max_opps; ++/* The Vdd1 opp table information */ ++extern u32 vdd1_dsp_freq[6][4] ; ++#endif ++ ++#if GT_TRACE ++static struct GT_Mask dsp_trace_mask = { NULL, NULL }; /* GT trace variable */ ++#endif ++ ++/* ++ * ======== WMD_IO_Create ======== ++ * Create an IO manager object. ++ */ ++DSP_STATUS WMD_IO_Create(OUT struct IO_MGR **phIOMgr, ++ struct DEV_OBJECT *hDevObject, ++ IN CONST struct IO_ATTRS *pMgrAttrs) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct IO_MGR *pIOMgr = NULL; ++ struct SHM *pSharedMem = NULL; ++ struct WMD_DEV_CONTEXT *hWmdContext = NULL; ++ struct CFG_HOSTRES hostRes; ++ struct CFG_DEVNODE *hDevNode; ++ struct CHNL_MGR *hChnlMgr; ++ static int ref_count; ++ u32 devType; ++ /* Check DBC requirements: */ ++ DBC_Require(phIOMgr != NULL); ++ DBC_Require(pMgrAttrs != NULL); ++ DBC_Require(pMgrAttrs->uWordSize != 0); ++ /* This for the purposes of DBC_Require: */ ++ status = DEV_GetChnlMgr(hDevObject, &hChnlMgr); ++ DBC_Require(status != DSP_EHANDLE); ++ DBC_Require(hChnlMgr != NULL); ++ DBC_Require(hChnlMgr->hIOMgr == NULL); ++ /* Message manager will be created when a file is loaded, since ++ * size of message buffer in shared memory is configurable in ++ * the base image. */ ++ DEV_GetWMDContext(hDevObject, &hWmdContext); ++ DBC_Assert(hWmdContext); ++ DEV_GetDevType(hDevObject, &devType); ++ /* DSP shared memory area will get set properly when ++ * a program is loaded. They are unknown until a COFF file is ++ * loaded. I chose the value -1 because it was less likely to be ++ * a valid address than 0. */ ++ pSharedMem = (struct SHM *) -1; ++ if (DSP_FAILED(status)) ++ goto func_cont; ++ ++ /* ++ * Create a Single Threaded Work Queue ++ */ ++ ++ if (ref_count == 0) ++ bridge_workqueue = create_workqueue("bridge_work-queue"); ++ ++ if (bridge_workqueue <= 0) ++ DBG_Trace(DBG_LEVEL1, "Workque Create" ++ " failed 0x%d \n", bridge_workqueue); ++ ++ ++ /* Allocate IO manager object: */ ++ MEM_AllocObject(pIOMgr, struct IO_MGR, IO_MGRSIGNATURE); ++ if (pIOMgr == NULL) { ++ status = DSP_EMEMORY; ++ goto func_cont; ++ } ++ /*Intializing Work Element*/ ++ if (ref_count == 0) { ++ INIT_WORK(&pIOMgr->io_workq, (void *)IO_DispatchPM); ++ ref_count = 1; ++ } else ++ PREPARE_WORK(&pIOMgr->io_workq, (void *)IO_DispatchPM); ++ ++ /* Initialize CHNL_MGR object: */ ++#ifndef DSP_TRACEBUF_DISABLED ++ pIOMgr->pMsg = NULL; ++#endif ++ pIOMgr->hChnlMgr = hChnlMgr; ++ pIOMgr->uWordSize = pMgrAttrs->uWordSize; ++ pIOMgr->pSharedMem = pSharedMem; ++ if (DSP_SUCCEEDED(status)) ++ status = SYNC_InitializeCS(&pIOMgr->hCSObj); ++ ++ if (devType == DSP_UNIT) { ++ /* Create a DPC object: */ ++ status = DPC_Create(&pIOMgr->hDPC, IO_DPC, (void *)pIOMgr); ++ if (DSP_SUCCEEDED(status)) ++ status = DEV_GetDevNode(hDevObject, &hDevNode); ++ ++ pIOMgr->iQuePowerHead = 0; ++ pIOMgr->iQuePowerTail = 0; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ status = CFG_GetHostResources((struct CFG_DEVNODE *) ++ DRV_GetFirstDevExtension() , &hostRes); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ pIOMgr->hWmdContext = hWmdContext; ++ pIOMgr->fSharedIRQ = pMgrAttrs->fShared; ++ IO_DisableInterrupt(hWmdContext); ++ if (devType == DSP_UNIT) { ++ /* Plug the channel ISR:. */ ++ if ((request_irq(INT_MAIL_MPU_IRQ, IO_ISR, 0, ++ "DspBridge\tmailbox", (void *)pIOMgr)) == 0) ++ status = DSP_SOK; ++ else ++ status = DSP_EFAIL; ++ } ++ if (DSP_SUCCEEDED(status)) ++ DBG_Trace(DBG_LEVEL1, "ISR_IRQ Object 0x%x \n", ++ pIOMgr); ++ else ++ status = CHNL_E_ISR; ++ } else ++ status = CHNL_E_ISR; ++func_cont: ++ if (DSP_FAILED(status)) { ++ /* Cleanup: */ ++ WMD_IO_Destroy(pIOMgr); ++ *phIOMgr = NULL; ++ } else { ++ /* Return IO manager object to caller... */ ++ hChnlMgr->hIOMgr = pIOMgr; ++ *phIOMgr = pIOMgr; ++ } ++ return status; ++} ++ ++/* ++ * ======== WMD_IO_Destroy ======== ++ * Purpose: ++ * Disable interrupts, destroy the IO manager. ++ */ ++DSP_STATUS WMD_IO_Destroy(struct IO_MGR *hIOMgr) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct WMD_DEV_CONTEXT *hWmdContext; ++ if (MEM_IsValidHandle(hIOMgr, IO_MGRSIGNATURE)) { ++ /* Unplug IRQ: */ ++ /* Disable interrupts from the board: */ ++ if (DSP_SUCCEEDED(DEV_GetWMDContext(hIOMgr->hDevObject, ++ &hWmdContext))) ++ DBC_Assert(hWmdContext); ++ (void)CHNLSM_DisableInterrupt(hWmdContext); ++ destroy_workqueue(bridge_workqueue); ++ /* Linux function to uninstall ISR */ ++ free_irq(INT_MAIL_MPU_IRQ, (void *)hIOMgr); ++ (void)DPC_Destroy(hIOMgr->hDPC); ++#ifndef DSP_TRACEBUF_DISABLED ++ if (hIOMgr->pMsg) ++ MEM_Free(hIOMgr->pMsg); ++#endif ++ SYNC_DeleteCS(hIOMgr->hCSObj); /* Leak Fix. */ ++ /* Free this IO manager object: */ ++ MEM_FreeObject(hIOMgr); ++ } else ++ status = DSP_EHANDLE; ++ ++ return status; ++} ++ ++/* ++ * ======== WMD_IO_OnLoaded ======== ++ * Purpose: ++ * Called when a new program is loaded to get shared memory buffer ++ * parameters from COFF file. ulSharedBufferBase and ulSharedBufferLimit ++ * are in DSP address units. ++ */ ++DSP_STATUS WMD_IO_OnLoaded(struct IO_MGR *hIOMgr) ++{ ++ struct COD_MANAGER *hCodMan; ++ struct CHNL_MGR *hChnlMgr; ++ struct MSG_MGR *hMsgMgr; ++ u32 ulShmBase; ++ u32 ulShmBaseOffset; ++ u32 ulShmLimit; ++ u32 ulShmLength = -1; ++ u32 ulMemLength = -1; ++ u32 ulMsgBase; ++ u32 ulMsgLimit; ++ u32 ulMsgLength = -1; ++ u32 ulExtEnd; ++ u32 ulGppPa = 0; ++ u32 ulGppVa = 0; ++ u32 ulDspVa = 0; ++ u32 ulSegSize = 0; ++ u32 ulPadSize = 0; ++ u32 i; ++ DSP_STATUS status = DSP_SOK; ++ u32 uNumProcs = 0; ++ s32 ndx = 0; ++ /* DSP MMU setup table */ ++ struct WMDIOCTL_EXTPROC aEProc[WMDIOCTL_NUMOFMMUTLB]; ++ struct CFG_HOSTRES hostRes; ++ u32 mapAttrs; ++ u32 ulShm0End; ++ u32 ulDynExtBase; ++ u32 ulSeg1Size = 0; ++ u32 paCurr = 0; ++ u32 vaCurr = 0; ++ u32 gppVaCurr = 0; ++ u32 numBytes = 0; ++ u32 allBits = 0; ++ u32 pgSize[] = { HW_PAGE_SIZE_16MB, HW_PAGE_SIZE_1MB, ++ HW_PAGE_SIZE_64KB, HW_PAGE_SIZE_4KB }; ++ ++ status = DEV_GetCodMgr(hIOMgr->hDevObject, &hCodMan); ++ DBC_Assert(DSP_SUCCEEDED(status)); ++ hChnlMgr = hIOMgr->hChnlMgr; ++ /* The message manager is destroyed when the board is stopped. */ ++ DEV_GetMsgMgr(hIOMgr->hDevObject, &hIOMgr->hMsgMgr); ++ hMsgMgr = hIOMgr->hMsgMgr; ++ DBC_Assert(MEM_IsValidHandle(hChnlMgr, CHNL_MGRSIGNATURE)); ++ DBC_Assert(MEM_IsValidHandle(hMsgMgr, MSGMGR_SIGNATURE)); ++ if (hIOMgr->pSharedMem) ++ hIOMgr->pSharedMem = NULL; ++ ++ /* Get start and length of channel part of shared memory */ ++ status = COD_GetSymValue(hCodMan, CHNL_SHARED_BUFFER_BASE_SYM, ++ &ulShmBase); ++ if (DSP_FAILED(status)) { ++ status = CHNL_E_NOMEMMAP; ++ goto func_cont1; ++ } ++ status = COD_GetSymValue(hCodMan, CHNL_SHARED_BUFFER_LIMIT_SYM, ++ &ulShmLimit); ++ if (DSP_FAILED(status)) { ++ status = CHNL_E_NOMEMMAP; ++ goto func_cont1; ++ } ++ if (ulShmLimit <= ulShmBase) { ++ status = CHNL_E_INVALIDMEMBASE; ++ } else { ++ /* get total length in bytes */ ++ ulShmLength = (ulShmLimit - ulShmBase + 1) * hIOMgr->uWordSize; ++ /* Calculate size of a PROCCOPY shared memory region */ ++ DBG_Trace(DBG_LEVEL7, ++ "**(proc)PROCCOPY SHMMEM SIZE: 0x%x bytes\n", ++ (ulShmLength - sizeof(struct SHM))); ++ } ++func_cont1: ++ if (DSP_SUCCEEDED(status)) { ++ /* Get start and length of message part of shared memory */ ++ status = COD_GetSymValue(hCodMan, MSG_SHARED_BUFFER_BASE_SYM, ++ &ulMsgBase); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ status = COD_GetSymValue(hCodMan, MSG_SHARED_BUFFER_LIMIT_SYM, ++ &ulMsgLimit); ++ if (DSP_SUCCEEDED(status)) { ++ if (ulMsgLimit <= ulMsgBase) { ++ status = CHNL_E_INVALIDMEMBASE; ++ } else { ++ /* Length (bytes) of messaging part of shared ++ * memory */ ++ ulMsgLength = (ulMsgLimit - ulMsgBase + 1) * ++ hIOMgr->uWordSize; ++ /* Total length (bytes) of shared memory: ++ * chnl + msg */ ++ ulMemLength = ulShmLength + ulMsgLength; ++ } ++ } else { ++ status = CHNL_E_NOMEMMAP; ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++#ifndef DSP_TRACEBUF_DISABLED ++ status = COD_GetSymValue(hCodMan, DSP_TRACESEC_END, &ulShm0End); ++ DBG_Trace(DBG_LEVEL7, "_BRIDGE_TRACE_END value = %x \n", ++ ulShm0End); ++#else ++ status = COD_GetSymValue(hCodMan, SHM0_SHARED_END_SYM, ++ &ulShm0End); ++ DBG_Trace(DBG_LEVEL7, "_SHM0_END = %x \n", ulShm0End); ++#endif ++ if (DSP_FAILED(status)) ++ status = CHNL_E_NOMEMMAP; ++ ++ } ++ if (DSP_SUCCEEDED(status)) { ++ status = COD_GetSymValue(hCodMan, DYNEXTBASE, &ulDynExtBase); ++ if (DSP_FAILED(status)) ++ status = CHNL_E_NOMEMMAP; ++ ++ } ++ if (DSP_SUCCEEDED(status)) { ++ status = COD_GetSymValue(hCodMan, EXTEND, &ulExtEnd); ++ if (DSP_FAILED(status)) ++ status = CHNL_E_NOMEMMAP; ++ ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Get memory reserved in host resources */ ++ (void)MGR_EnumProcessorInfo(0, ++ (struct DSP_PROCESSORINFO *)&hIOMgr->extProcInfo, ++ sizeof(struct MGR_PROCESSOREXTINFO), &uNumProcs); ++ CFG_GetHostResources(( ++ struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), ++ &hostRes); ++ /* The first MMU TLB entry(TLB_0) in DCD is ShmBase. */ ++ ndx = 0; ++ ulGppPa = hostRes.dwMemPhys[1]; ++ ulGppVa = hostRes.dwMemBase[1]; ++ /* THIS IS THE VIRTUAL UNCACHED IOREMAPPED ADDRESS !!! */ ++ /* Why can't we directly take the DSPVA from the symbols? */ ++ ulDspVa = hIOMgr->extProcInfo.tyTlb[0].ulDspVirt; ++ ulSegSize = (ulShm0End - ulDspVa) * hIOMgr->uWordSize; ++ ulSeg1Size = (ulExtEnd - ulDynExtBase) * hIOMgr->uWordSize; ++ ulSeg1Size = (ulSeg1Size + 0xFFF) & (~0xFFFUL); /* 4K align*/ ++ ulSegSize = (ulSegSize + 0xFFFF) & (~0xFFFFUL); /* 64K align*/ ++ ulPadSize = ulPageAlignSize - ((ulGppPa + ulSeg1Size) % ++ ulPageAlignSize); ++ if (ulPadSize == ulPageAlignSize) ++ ulPadSize = 0x0; ++ ++ DBG_Trace(DBG_LEVEL7, "ulGppPa %x, ulGppVa %x, ulDspVa %x, " ++ "ulShm0End %x, ulDynExtBase %x, ulExtEnd %x, " ++ "ulSegSize %x ulSeg1Size %x \n", ulGppPa, ulGppVa, ++ ulDspVa, ulShm0End, ulDynExtBase, ulExtEnd, ulSegSize, ++ ulSeg1Size); ++ ++ if ((ulSegSize + ulSeg1Size + ulPadSize) > ++ hostRes.dwMemLength[1]) { ++ DBG_Trace(DBG_LEVEL7, "ulGppPa %x, ulGppVa %x, ulDspVa " ++ "%x, ulShm0End %x, ulDynExtBase %x, ulExtEnd " ++ "%x, ulSegSize %x, ulSeg1Size %x \n", ulGppPa, ++ ulGppVa, ulDspVa, ulShm0End, ulDynExtBase, ++ ulExtEnd, ulSegSize, ulSeg1Size); ++ DBG_Trace(DBG_LEVEL7, "Insufficient SHM Reserved 0x%x. " ++ "Required 0x%x\n", hostRes.dwMemLength[1], ++ ulSegSize + ulSeg1Size + ulPadSize); ++ status = DSP_EMEMORY; ++ } ++ } ++ if (DSP_FAILED(status)) ++ goto func_cont; ++ ++ paCurr = ulGppPa; ++ vaCurr = ulDynExtBase * hIOMgr->uWordSize; ++ gppVaCurr = ulGppVa; ++ numBytes = ulSeg1Size; ++ ++ /* ++ * Try to fit into TLB entries. If not possible, push them to page ++ * tables. It is quite possible that if sections are not on ++ * bigger page boundary, we may end up making several small pages. ++ * So, push them onto page tables, if that is the case. ++ */ ++ mapAttrs = 0x00000000; ++ mapAttrs = DSP_MAPLITTLEENDIAN; ++ mapAttrs |= DSP_MAPPHYSICALADDR; ++ mapAttrs |= DSP_MAPELEMSIZE32; ++ mapAttrs |= DSP_MAPDONOTLOCK; ++ ++ while (numBytes && DSP_SUCCEEDED(status)) { ++ /* To find the max. page size with which both PA & VA are ++ * aligned */ ++ allBits = paCurr | vaCurr; ++ DBG_Trace(DBG_LEVEL1, "allBits %x, paCurr %x, vaCurr %x, " ++ "numBytes %x\n", allBits, paCurr, vaCurr, numBytes); ++ for (i = 0; i < 4; i++) { ++ if ((numBytes >= pgSize[i]) && ((allBits & ++ (pgSize[i] - 1)) == 0)) { ++ status = hIOMgr->pIntfFxns->pfnBrdMemMap ++ (hIOMgr->hWmdContext, paCurr, vaCurr, ++ pgSize[i], mapAttrs); ++ DBC_Assert(DSP_SUCCEEDED(status)); ++ paCurr += pgSize[i]; ++ vaCurr += pgSize[i]; ++ gppVaCurr += pgSize[i]; ++ numBytes -= pgSize[i]; ++ /* Don't try smaller sizes. Hopefully we have ++ * reached an address aligned to a bigger page ++ * size*/ ++ break; ++ } ++ } ++ } ++ paCurr += ulPadSize; ++ vaCurr += ulPadSize; ++ gppVaCurr += ulPadSize; ++ ++ /* configure the TLB entries for the next cacheable segment */ ++ numBytes = ulSegSize; ++ vaCurr = ulDspVa * hIOMgr->uWordSize; ++ allBits = 0x0; ++ while (numBytes && DSP_SUCCEEDED(status)) { ++ /* To find the max. page size with which both PA & VA are ++ * aligned*/ ++ allBits = paCurr | vaCurr; ++ DBG_Trace(DBG_LEVEL1, "allBits for Seg1 %x, paCurr %x, " ++ "vaCurr %x, numBytes %x\n", allBits, paCurr, vaCurr, ++ numBytes); ++ for (i = 0; i < 4; i++) { ++ if (!(numBytes >= pgSize[i]) || ++ !((allBits & (pgSize[i]-1)) == 0)) ++ continue; ++ if (ndx < MAX_LOCK_TLB_ENTRIES) { ++ /* This is the physical address written to ++ * DSP MMU */ ++ aEProc[ndx].ulGppPa = paCurr; ++ /* THIS IS THE VIRTUAL UNCACHED IOREMAPPED ++ * ADDRESS!!! */ ++ aEProc[ndx].ulGppVa = gppVaCurr; ++ aEProc[ndx].ulDspVa = vaCurr / hIOMgr-> ++ uWordSize; ++ aEProc[ndx].ulSize = pgSize[i]; ++ aEProc[ndx].endianism = HW_LITTLE_ENDIAN; ++ aEProc[ndx].elemSize = HW_ELEM_SIZE_16BIT; ++ aEProc[ndx].mixedMode = HW_MMU_CPUES; ++ DBG_Trace(DBG_LEVEL1, "SHM MMU TLB entry PA %lx" ++ " VA %lx DSP_VA %lx Size %lx\n", ++ aEProc[ndx].ulGppPa, ++ aEProc[ndx].ulGppVa, ++ aEProc[ndx].ulDspVa * ++ hIOMgr->uWordSize, pgSize[i]); ++ ndx++; ++ } else { ++ status = hIOMgr->pIntfFxns->pfnBrdMemMap( ++ hIOMgr->hWmdContext, paCurr, vaCurr, pgSize[i], ++ mapAttrs); ++ DBG_Trace(DBG_LEVEL1, "SHM MMU PTE entry PA %lx" ++ " VA %lx DSP_VA %lx Size %lx\n", ++ aEProc[ndx].ulGppPa, ++ aEProc[ndx].ulGppVa, ++ aEProc[ndx].ulDspVa * ++ hIOMgr->uWordSize, pgSize[i]); ++ DBC_Assert(DSP_SUCCEEDED(status)); ++ } ++ paCurr += pgSize[i]; ++ vaCurr += pgSize[i]; ++ gppVaCurr += pgSize[i]; ++ numBytes -= pgSize[i]; ++ /* Don't try smaller sizes. Hopefully we have reached ++ an address aligned to a bigger page size*/ ++ break; ++ } ++ } ++ ++ /* Copy remaining entries from CDB. All entries are 1 MB and should not ++ * conflict with SHM entries on MPU or DSP side */ ++ for (i = 3; i < 7 && ndx < WMDIOCTL_NUMOFMMUTLB && ++ DSP_SUCCEEDED(status); i++) { ++ if (hIOMgr->extProcInfo.tyTlb[i].ulGppPhys == 0) ++ continue; ++ ++ if ((hIOMgr->extProcInfo.tyTlb[i].ulGppPhys > ulGppPa - 0x100000 ++ && hIOMgr->extProcInfo.tyTlb[i].ulGppPhys <= ++ ulGppPa + ulSegSize) ++ || (hIOMgr->extProcInfo.tyTlb[i].ulDspVirt > ulDspVa - ++ 0x100000 / hIOMgr->uWordSize && hIOMgr-> ++ extProcInfo.tyTlb[i].ulDspVirt ++ <= ulDspVa + ulSegSize / hIOMgr->uWordSize)) { ++ DBG_Trace(DBG_LEVEL7, "CDB MMU entry %d conflicts with " ++ "SHM.\n\tCDB: GppPa %x, DspVa %x.\n\tSHM: " ++ "GppPa %x, DspVa %x, Bytes %x.\n", i, ++ hIOMgr->extProcInfo.tyTlb[i].ulGppPhys, ++ hIOMgr->extProcInfo.tyTlb[i].ulDspVirt, ++ ulGppPa, ulDspVa, ulSegSize); ++ status = DSP_EFAIL; ++ } else { ++ if (ndx < MAX_LOCK_TLB_ENTRIES) { ++ aEProc[ndx].ulDspVa = hIOMgr->extProcInfo. ++ tyTlb[i].ulDspVirt; ++ aEProc[ndx].ulGppPa = hIOMgr->extProcInfo. ++ tyTlb[i].ulGppPhys; ++ aEProc[ndx].ulGppVa = 0; ++ /* Can't convert, so set to zero*/ ++ aEProc[ndx].ulSize = 0x100000; /* 1 MB*/ ++ DBG_Trace(DBG_LEVEL1, "SHM MMU entry PA %x " ++ "DSP_VA 0x%x\n", aEProc[ndx].ulGppPa, ++ aEProc[ndx].ulDspVa); ++ ndx++; ++ } else { ++ status = hIOMgr->pIntfFxns->pfnBrdMemMap ++ (hIOMgr->hWmdContext, ++ hIOMgr->extProcInfo.tyTlb[i].ulGppPhys, ++ hIOMgr->extProcInfo.tyTlb[i].ulDspVirt, ++ 0x100000, mapAttrs); ++ } ++ } ++ } ++ if (i < 7 && DSP_SUCCEEDED(status)) { ++ /* All CDB entries could not be made*/ ++ status = DSP_EFAIL; ++ } ++func_cont: ++ mapAttrs = 0x00000000; ++ mapAttrs = DSP_MAPLITTLEENDIAN; ++ mapAttrs |= DSP_MAPPHYSICALADDR; ++ mapAttrs |= DSP_MAPELEMSIZE32; ++ mapAttrs |= DSP_MAPDONOTLOCK; ++ ++ /* Map the L4 peripherals */ ++ i = 0; ++ while (L4PeripheralTable[i].physAddr && DSP_SUCCEEDED(status)) { ++ status = hIOMgr->pIntfFxns->pfnBrdMemMap ++ (hIOMgr->hWmdContext, L4PeripheralTable[i].physAddr, ++ L4PeripheralTable[i].dspVirtAddr, HW_PAGE_SIZE_4KB, ++ mapAttrs); ++ if (DSP_FAILED(status)) ++ break; ++ i++; ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ for (i = ndx; i < WMDIOCTL_NUMOFMMUTLB; i++) { ++ aEProc[i].ulDspVa = 0; ++ aEProc[i].ulGppPa = 0; ++ aEProc[i].ulGppVa = 0; ++ aEProc[i].ulSize = 0; ++ } ++ /* Set the SHM physical address entry (grayed out in CDB file) ++ * to the virtual uncached ioremapped address of SHM reserved ++ * on MPU */ ++ hIOMgr->extProcInfo.tyTlb[0].ulGppPhys = (ulGppVa + ulSeg1Size + ++ ulPadSize); ++ DBG_Trace(DBG_LEVEL1, "*********extProcInfo *********%x \n", ++ hIOMgr->extProcInfo.tyTlb[0].ulGppPhys); ++ /* Need SHM Phys addr. IO supports only one DSP for now: ++ * uNumProcs=1 */ ++ if ((hIOMgr->extProcInfo.tyTlb[0].ulGppPhys == 0) || ++ (uNumProcs != 1)) { ++ status = CHNL_E_NOMEMMAP; ++ DBC_Assert(false); ++ } else { ++ DBC_Assert(aEProc[0].ulDspVa <= ulShmBase); ++ /* ulShmBase may not be at ulDspVa address */ ++ ulShmBaseOffset = (ulShmBase - aEProc[0].ulDspVa) * ++ hIOMgr->uWordSize; ++ /* WMD_BRD_Ctrl() will set dev context dsp-mmu info. In ++ * _BRD_Start() the MMU will be re-programed with MMU ++ * DSPVa-GPPPa pair info while DSP is in a known ++ * (reset) state. */ ++ DBC_Assert(hIOMgr->pIntfFxns != NULL); ++ DBC_Assert(hIOMgr->hWmdContext != NULL); ++ status = hIOMgr->pIntfFxns->pfnDevCntrl(hIOMgr-> ++ hWmdContext, WMDIOCTL_SETMMUCONFIG, aEProc); ++ ulShmBase = hIOMgr->extProcInfo.tyTlb[0].ulGppPhys; ++ DBG_Trace(DBG_LEVEL1, "extProcInfo.tyTlb[0].ulGppPhys " ++ "%x \n ", hIOMgr->extProcInfo.tyTlb[0]. ++ ulGppPhys); ++ ulShmBase += ulShmBaseOffset; ++ ulShmBase = (u32)MEM_LinearAddress((void *)ulShmBase, ++ ulMemLength); ++ DBC_Assert(ulShmBase != 0); ++ if (DSP_SUCCEEDED(status)) { ++ status = registerSHMSegs(hIOMgr, hCodMan, ++ aEProc[0].ulGppPa); ++ /* Register SM */ ++ } ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ hIOMgr->pSharedMem = (struct SHM *)ulShmBase; ++ hIOMgr->pInput = (u8 *)hIOMgr->pSharedMem + ++ sizeof(struct SHM); ++ hIOMgr->pOutput = hIOMgr->pInput + (ulShmLength - ++ sizeof(struct SHM))/2; ++ hIOMgr->uSMBufSize = hIOMgr->pOutput - hIOMgr->pInput; ++ DBG_Trace(DBG_LEVEL3, ++ "hIOMgr: pInput %p pOutput %p ulShmLength %x\n", ++ hIOMgr->pInput, hIOMgr->pOutput, ulShmLength); ++ DBG_Trace(DBG_LEVEL3, ++ "pSharedMem %p uSMBufSize %x sizeof(SHM) %x\n", ++ hIOMgr->pSharedMem, hIOMgr->uSMBufSize, ++ sizeof(struct SHM)); ++ /* Set up Shared memory addresses for messaging. */ ++ hIOMgr->pMsgInputCtrl = (struct MSG *)((u8 *) ++ hIOMgr->pSharedMem + ++ ulShmLength); ++ hIOMgr->pMsgInput = (u8 *)hIOMgr->pMsgInputCtrl + ++ sizeof(struct MSG); ++ hIOMgr->pMsgOutputCtrl = (struct MSG *)((u8 *)hIOMgr-> ++ pMsgInputCtrl + ulMsgLength / 2); ++ hIOMgr->pMsgOutput = (u8 *)hIOMgr->pMsgOutputCtrl + ++ sizeof(struct MSG); ++ hMsgMgr->uMaxMsgs = ((u8 *)hIOMgr->pMsgOutputCtrl - ++ hIOMgr->pMsgInput) / ++ sizeof(struct MSG_DSPMSG); ++ DBG_Trace(DBG_LEVEL7, "IO MGR SHM details : pSharedMem 0x%x, " ++ "pInput 0x%x, pOutput 0x%x, pMsgInputCtrl 0x%x, " ++ "pMsgInput 0x%x, pMsgOutputCtrl 0x%x, pMsgOutput " ++ "0x%x \n", (u8 *)hIOMgr->pSharedMem, ++ (u8 *)hIOMgr->pInput, (u8 *)hIOMgr->pOutput, ++ (u8 *)hIOMgr->pMsgInputCtrl, ++ (u8 *)hIOMgr->pMsgInput, ++ (u8 *)hIOMgr->pMsgOutputCtrl, ++ (u8 *)hIOMgr->pMsgOutput); ++ DBG_Trace(DBG_LEVEL7, "** (proc) MAX MSGS IN SHARED MEMORY: " ++ "0x%x\n", hMsgMgr->uMaxMsgs); ++ memset((void *) hIOMgr->pSharedMem, 0, sizeof(struct SHM)); ++ } ++#ifndef DSP_TRACEBUF_DISABLED ++ if (DSP_SUCCEEDED(status)) { ++ /* Get the start address of trace buffer */ ++ if (DSP_SUCCEEDED(status)) { ++ status = COD_GetSymValue(hCodMan, SYS_PUTCBEG, ++ &hIOMgr->ulTraceBufferBegin); ++ if (DSP_FAILED(status)) ++ status = CHNL_E_NOMEMMAP; ++ ++ } ++ hIOMgr->ulGPPReadPointer = hIOMgr->ulTraceBufferBegin = ++ (ulGppVa + ulSeg1Size + ulPadSize) + ++ (hIOMgr->ulTraceBufferBegin - ulDspVa); ++ /* Get the end address of trace buffer */ ++ if (DSP_SUCCEEDED(status)) { ++ status = COD_GetSymValue(hCodMan, SYS_PUTCEND, ++ &hIOMgr->ulTraceBufferEnd); ++ if (DSP_FAILED(status)) ++ status = CHNL_E_NOMEMMAP; ++ ++ } ++ hIOMgr->ulTraceBufferEnd = (ulGppVa + ulSeg1Size + ulPadSize) + ++ (hIOMgr->ulTraceBufferEnd - ulDspVa); ++ /* Get the current address of DSP write pointer */ ++ if (DSP_SUCCEEDED(status)) { ++ status = COD_GetSymValue(hCodMan, ++ BRIDGE_SYS_PUTC_current, ++ &hIOMgr->ulTraceBufferCurrent); ++ if (DSP_FAILED(status)) ++ status = CHNL_E_NOMEMMAP; ++ ++ } ++ hIOMgr->ulTraceBufferCurrent = (ulGppVa + ulSeg1Size + ++ ulPadSize) + (hIOMgr-> ++ ulTraceBufferCurrent - ulDspVa); ++ /* Calculate the size of trace buffer */ ++ if (hIOMgr->pMsg) ++ MEM_Free(hIOMgr->pMsg); ++ hIOMgr->pMsg = MEM_Alloc(((hIOMgr->ulTraceBufferEnd - ++ hIOMgr->ulTraceBufferBegin) * ++ hIOMgr->uWordSize) + 2, MEM_NONPAGED); ++ if (!hIOMgr->pMsg) ++ status = DSP_EMEMORY; ++ ++ DBG_Trace(DBG_LEVEL1, "** hIOMgr->pMsg: 0x%x\n", hIOMgr->pMsg); ++ hIOMgr->ulDspVa = ulDspVa; ++ hIOMgr->ulGppVa = (ulGppVa + ulSeg1Size + ulPadSize); ++ } ++#endif ++ IO_EnableInterrupt(hIOMgr->hWmdContext); ++ return status; ++} ++ ++/* ++ * ======== IO_BufSize ======== ++ * Size of shared memory I/O channel. ++ */ ++u32 IO_BufSize(struct IO_MGR *hIOMgr) ++{ ++ DBC_Require(MEM_IsValidHandle(hIOMgr, IO_MGRSIGNATURE)); ++ ++ return hIOMgr->uSMBufSize; ++} ++ ++/* ++ * ======== IO_CancelChnl ======== ++ * Cancel IO on a given PCPY channel. ++ */ ++void IO_CancelChnl(struct IO_MGR *hIOMgr, u32 ulChnl) ++{ ++ struct IO_MGR *pIOMgr = (struct IO_MGR *)hIOMgr; ++ struct SHM *sm; ++ ++ DBC_Require(MEM_IsValidHandle(hIOMgr, IO_MGRSIGNATURE)); ++ sm = hIOMgr->pSharedMem; ++ ++ /* Inform DSP that we have no more buffers on this channel: */ ++ IO_AndValue(pIOMgr->hWmdContext, struct SHM, sm, hostFreeMask, ++ (~(1 << ulChnl))); ++ ++ CHNLSM_InterruptDSP2(pIOMgr->hWmdContext, MBX_PCPY_CLASS); ++} ++ ++/* ++ * ======== IO_DispatchChnl ======== ++ * Proc-copy chanl dispatch. ++ */ ++static void IO_DispatchChnl(IN struct IO_MGR *pIOMgr, ++ IN OUT struct CHNL_OBJECT *pChnl, u32 iMode) ++{ ++ DBC_Require(MEM_IsValidHandle(pIOMgr, IO_MGRSIGNATURE)); ++ ++ DBG_Trace(DBG_LEVEL3, "Entering IO_DispatchChnl \n"); ++ ++ /* See if there is any data available for transfer: */ ++ DBC_Assert(iMode == IO_SERVICE); ++ ++ /* Any channel will do for this mode: */ ++ InputChnl(pIOMgr, pChnl, iMode); ++ OutputChnl(pIOMgr, pChnl, iMode); ++} ++ ++/* ++ * ======== IO_DispatchMsg ======== ++ * Performs I/O dispatch on message queues. ++ */ ++static void IO_DispatchMsg(IN struct IO_MGR *pIOMgr, struct MSG_MGR *hMsgMgr) ++{ ++ DBC_Require(MEM_IsValidHandle(pIOMgr, IO_MGRSIGNATURE)); ++ ++ DBG_Trace(DBG_LEVEL3, "Entering IO_DispatchMsg \n"); ++ ++ /* We are performing both input and output processing. */ ++ InputMsg(pIOMgr, hMsgMgr); ++ OutputMsg(pIOMgr, hMsgMgr); ++} ++ ++/* ++ * ======== IO_DispatchPM ======== ++ * Performs I/O dispatch on PM related messages from DSP ++ */ ++static void IO_DispatchPM(struct work_struct *work) ++{ ++ struct IO_MGR *pIOMgr = ++ container_of(work, struct IO_MGR, io_workq); ++ DSP_STATUS status; ++ u32 pArg[2]; ++ ++ /*DBC_Require(MEM_IsValidHandle(pIOMgr, IO_MGRSIGNATURE));*/ ++ ++ DBG_Trace(DBG_LEVEL7, "IO_DispatchPM: Entering IO_DispatchPM : \n"); ++ ++ /* Perform Power message processing here */ ++ while (pIOMgr->iQuePowerHead != pIOMgr->iQuePowerTail) { ++ pArg[0] = *(u32 *)&(pIOMgr->dQuePowerMbxVal[pIOMgr-> ++ iQuePowerTail]); ++ DBG_Trace(DBG_LEVEL7, "IO_DispatchPM - pArg[0] - 0x%x: \n", ++ pArg[0]); ++ /* Send the command to the WMD clk/pwr manager to handle */ ++ if (pArg[0] == MBX_PM_HIBERNATE_EN) { ++ DBG_Trace(DBG_LEVEL7, "IO_DispatchPM : Hibernate " ++ "command\n"); ++ status = pIOMgr->pIntfFxns->pfnDevCntrl(pIOMgr-> ++ hWmdContext, WMDIOCTL_PWR_HIBERNATE, pArg); ++ if (DSP_FAILED(status)) { ++ DBG_Trace(DBG_LEVEL7, "IO_DispatchPM : " ++ "Hibernation command failed\n"); ++ } ++ } else if (pArg[0] == MBX_PM_OPP_REQ) { ++ pArg[1] = pIOMgr->pSharedMem->oppRequest.rqstOppPt; ++ DBG_Trace(DBG_LEVEL7, "IO_DispatchPM : Value of OPP " ++ "value =0x%x \n", pArg[1]); ++ status = pIOMgr->pIntfFxns->pfnDevCntrl(pIOMgr-> ++ hWmdContext, WMDIOCTL_CONSTRAINT_REQUEST, ++ pArg); ++ if (DSP_FAILED(status)) { ++ DBG_Trace(DBG_LEVEL7, "IO_DispatchPM : Failed " ++ "to set constraint = 0x%x \n", ++ pArg[1]); ++ } ++ ++ } else { ++ DBG_Trace(DBG_LEVEL7, "IO_DispatchPM - clock control - " ++ "value of msg = 0x%x: \n", pArg[0]); ++ status = pIOMgr->pIntfFxns->pfnDevCntrl(pIOMgr-> ++ hWmdContext, WMDIOCTL_CLK_CTRL, pArg); ++ if (DSP_FAILED(status)) { ++ DBG_Trace(DBG_LEVEL7, "IO_DispatchPM : Failed " ++ "to control the DSP clk = 0x%x \n", ++ *pArg); ++ } ++ } ++ /* increment the tail count here */ ++ pIOMgr->iQuePowerTail++; ++ if (pIOMgr->iQuePowerTail >= MAX_PM_REQS) ++ pIOMgr->iQuePowerTail = 0; ++ ++ } ++ ++} ++ ++/* ++ * ======== IO_DPC ======== ++ * Deferred procedure call for shared memory channel driver ISR. Carries ++ * out the dispatch of I/O as a non-preemptible event.It can only be ++ * pre-empted by an ISR. ++ */ ++void IO_DPC(IN OUT void *pRefData) ++{ ++ struct IO_MGR *pIOMgr = (struct IO_MGR *)pRefData; ++ struct CHNL_MGR *pChnlMgr; ++ struct MSG_MGR *pMsgMgr; ++ struct DEH_MGR *hDehMgr; ++ ++ DBC_Require(MEM_IsValidHandle(pIOMgr, IO_MGRSIGNATURE)); ++ pChnlMgr = pIOMgr->hChnlMgr; ++ DEV_GetMsgMgr(pIOMgr->hDevObject, &pMsgMgr); ++ DEV_GetDehMgr(pIOMgr->hDevObject, &hDehMgr); ++ DBC_Require(MEM_IsValidHandle(pChnlMgr, CHNL_MGRSIGNATURE)); ++ DBG_Trace(DBG_LEVEL7, "Entering IO_DPC(0x%x)\n", pRefData); ++ /* Check value of interrupt register to ensure it is a valid error */ ++ if ((pIOMgr->wIntrVal > DEH_BASE) && (pIOMgr->wIntrVal < DEH_LIMIT)) { ++ /* notify DSP/BIOS exception */ ++ if (hDehMgr) ++ WMD_DEH_Notify(hDehMgr, DSP_SYSERROR, pIOMgr->wIntrVal); ++ ++ } ++ IO_DispatchChnl(pIOMgr, NULL, IO_SERVICE); ++#ifdef CHNL_MESSAGES ++ if (pMsgMgr) { ++ DBC_Require(MEM_IsValidHandle(pMsgMgr, MSGMGR_SIGNATURE)); ++ IO_DispatchMsg(pIOMgr, pMsgMgr); ++ } ++#endif ++#ifndef DSP_TRACEBUF_DISABLED ++ if (pIOMgr->wIntrVal & MBX_DBG_CLASS) { ++ /* notify DSP Trace message */ ++ if (pIOMgr->wIntrVal & MBX_DBG_SYSPRINTF) ++ PrintDSPDebugTrace(pIOMgr); ++ } ++#endif ++ ++#ifndef DSP_TRACEBUF_DISABLED ++ PrintDSPDebugTrace(pIOMgr); ++#endif ++} ++ ++ ++/* ++ * ======== IO_ISR ======== ++ * Main interrupt handler for the shared memory IO manager. ++ * Calls the WMD's CHNL_ISR to determine if this interrupt is ours, then ++ * schedules a DPC to dispatch I/O. ++ */ ++irqreturn_t IO_ISR(int irq, IN void *pRefData) ++{ ++ struct IO_MGR *hIOMgr = (struct IO_MGR *)pRefData; ++ bool fSchedDPC; ++ DBC_Require(irq == INT_MAIL_MPU_IRQ); ++ DBC_Require(MEM_IsValidHandle(hIOMgr, IO_MGRSIGNATURE)); ++ DBG_Trace(DBG_LEVEL3, "Entering IO_ISR(0x%x)\n", pRefData); ++ ++ /* Call WMD's CHNLSM_ISR() to see if interrupt is ours, and process. */ ++ if (IO_CALLISR(hIOMgr->hWmdContext, &fSchedDPC, &hIOMgr->wIntrVal)) { ++ { ++ DBG_Trace(DBG_LEVEL3, "IO_ISR %x\n", hIOMgr->wIntrVal); ++ if (hIOMgr->wIntrVal & MBX_PM_CLASS) { ++ hIOMgr->dQuePowerMbxVal[hIOMgr->iQuePowerHead] = ++ hIOMgr->wIntrVal; ++ hIOMgr->iQuePowerHead++; ++ if (hIOMgr->iQuePowerHead >= MAX_PM_REQS) ++ hIOMgr->iQuePowerHead = 0; ++ ++ queue_work(bridge_workqueue, &hIOMgr->io_workq); ++ } ++ if (hIOMgr->wIntrVal == MBX_DEH_RESET) { ++ DBG_Trace(DBG_LEVEL6, "*** DSP RESET ***\n"); ++ hIOMgr->wIntrVal = 0; ++ } else if (fSchedDPC) { ++ /* PROC-COPY defer i/o */ ++ DPC_Schedule(hIOMgr->hDPC); ++ } ++ } ++ } else ++ /* Ensure that, if WMD didn't claim it, the IRQ is shared. */ ++ DBC_Ensure(hIOMgr->fSharedIRQ); ++ return IRQ_HANDLED; ++} ++ ++/* ++ * ======== IO_RequestChnl ======== ++ * Purpose: ++ * Request chanenel I/O from the DSP. Sets flags in shared memory, then ++ * interrupts the DSP. ++ */ ++void IO_RequestChnl(struct IO_MGR *pIOMgr, struct CHNL_OBJECT *pChnl, ++ u32 iMode, OUT u16 *pwMbVal) ++{ ++ struct CHNL_MGR *pChnlMgr; ++ struct SHM *sm; ++ DBC_Require(pChnl != NULL); ++ DBC_Require(pwMbVal != NULL); ++ pChnlMgr = pIOMgr->hChnlMgr; ++ sm = pIOMgr->pSharedMem; ++ if (iMode == IO_INPUT) { ++ /* Assertion fires if CHNL_AddIOReq() called on a stream ++ * which was cancelled, or attached to a dead board: */ ++ DBC_Assert((pChnl->dwState == CHNL_STATEREADY) || ++ (pChnl->dwState == CHNL_STATEEOS)); ++ /* Indicate to the DSP we have a buffer available for input: */ ++ IO_OrValue(pIOMgr->hWmdContext, struct SHM, sm, hostFreeMask, ++ (1 << pChnl->uId)); ++ *pwMbVal = MBX_PCPY_CLASS; ++ } else if (iMode == IO_OUTPUT) { ++ /* This assertion fails if CHNL_AddIOReq() was called on a ++ * stream which was cancelled, or attached to a dead board: */ ++ DBC_Assert((pChnl->dwState & ~CHNL_STATEEOS) == ++ CHNL_STATEREADY); ++ /* Record the fact that we have a buffer available for ++ * output: */ ++ pChnlMgr->dwOutputMask |= (1 << pChnl->uId); ++ } else { ++ DBC_Assert(iMode); /* Shouldn't get here. */ ++ } ++} ++ ++/* ++ * ======== IO_Schedule ======== ++ * Schedule DPC for IO. ++ */ ++void IO_Schedule(struct IO_MGR *pIOMgr) ++{ ++ DBC_Require(MEM_IsValidHandle(pIOMgr, IO_MGRSIGNATURE)); ++ ++ DPC_Schedule(pIOMgr->hDPC); ++} ++ ++/* ++ * ======== FindReadyOutput ======== ++ * Search for a host output channel which is ready to send. If this is ++ * called as a result of servicing the DPC, then implement a round ++ * robin search; otherwise, this was called by a client thread (via ++ * IO_Dispatch()), so just start searching from the current channel id. ++ */ ++static u32 FindReadyOutput(struct CHNL_MGR *pChnlMgr, ++ struct CHNL_OBJECT *pChnl, u32 dwMask) ++{ ++ u32 uRetval = OUTPUTNOTREADY; ++ u32 id, startId; ++ u32 shift; ++ ++ id = (pChnl != NULL ? pChnl->uId : (pChnlMgr->dwLastOutput + 1)); ++ id = ((id == CHNL_MAXCHANNELS) ? 0 : id); ++ DBC_Assert(id < CHNL_MAXCHANNELS); ++ if (dwMask) { ++ shift = (1 << id); ++ startId = id; ++ do { ++ if (dwMask & shift) { ++ uRetval = id; ++ if (pChnl == NULL) ++ pChnlMgr->dwLastOutput = id; ++ ++ break; ++ } ++ id = id + 1; ++ id = ((id == CHNL_MAXCHANNELS) ? 0 : id); ++ shift = (1 << id); ++ } while (id != startId); ++ } ++ DBC_Ensure((uRetval == OUTPUTNOTREADY) || (uRetval < CHNL_MAXCHANNELS)); ++ return uRetval; ++} ++ ++/* ++ * ======== InputChnl ======== ++ * Dispatch a buffer on an input channel. ++ */ ++static void InputChnl(struct IO_MGR *pIOMgr, struct CHNL_OBJECT *pChnl, ++ u32 iMode) ++{ ++ struct CHNL_MGR *pChnlMgr; ++ struct SHM *sm; ++ u32 chnlId; ++ u32 uBytes; ++ struct CHNL_IRP *pChirp = NULL; ++ u32 dwArg; ++ bool fClearChnl = false; ++ bool fNotifyClient = false; ++ ++ sm = pIOMgr->pSharedMem; ++ pChnlMgr = pIOMgr->hChnlMgr; ++ ++ DBG_Trace(DBG_LEVEL3, "> InputChnl\n"); ++ ++ /* Attempt to perform input.... */ ++ if (!IO_GetValue(pIOMgr->hWmdContext, struct SHM, sm, inputFull)) ++ goto func_end; ++ ++ uBytes = IO_GetValue(pIOMgr->hWmdContext, struct SHM, sm, inputSize) * ++ pChnlMgr->uWordSize; ++ chnlId = IO_GetValue(pIOMgr->hWmdContext, struct SHM, sm, inputId); ++ dwArg = IO_GetLong(pIOMgr->hWmdContext, struct SHM, sm, arg); ++ if (!(chnlId >= 0) || !(chnlId < CHNL_MAXCHANNELS)) { ++ /* Shouldn't be here: would indicate corrupted SHM. */ ++ DBC_Assert(chnlId); ++ goto func_end; ++ } ++ pChnl = pChnlMgr->apChannel[chnlId]; ++ if ((pChnl != NULL) && CHNL_IsInput(pChnl->uMode)) { ++ if ((pChnl->dwState & ~CHNL_STATEEOS) == CHNL_STATEREADY) { ++ if (!pChnl->pIORequests) ++ goto func_end; ++ /* Get the I/O request, and attempt a transfer: */ ++ pChirp = (struct CHNL_IRP *)LST_GetHead(pChnl-> ++ pIORequests); ++ if (pChirp) { ++ pChnl->cIOReqs--; ++ DBC_Assert(pChnl->cIOReqs >= 0); ++ /* Ensure we don't overflow the client's ++ * buffer: */ ++ uBytes = min(uBytes, pChirp->cBytes); ++ /* Transfer buffer from DSP side: */ ++ uBytes = ReadData(pIOMgr->hWmdContext, ++ pChirp->pHostSysBuf, ++ pIOMgr->pInput, uBytes); ++ pChnl->cBytesMoved += uBytes; ++ pChirp->cBytes = uBytes; ++ pChirp->dwArg = dwArg; ++ pChirp->status = CHNL_IOCSTATCOMPLETE; ++ DBG_Trace(DBG_LEVEL7, "Input Chnl:status= 0x%x " ++ "\n", *((RMS_WORD *)(pChirp-> ++ pHostSysBuf))); ++ if (uBytes == 0) { ++ /* This assertion fails if the DSP ++ * sends EOS more than once on this ++ * channel: */ ++ DBC_Assert(!(pChnl->dwState & ++ CHNL_STATEEOS)); ++ /* Zero bytes indicates EOS. Update ++ * IOC status for this chirp, and also ++ * the channel state: */ ++ pChirp->status |= CHNL_IOCSTATEOS; ++ pChnl->dwState |= CHNL_STATEEOS; ++ /* Notify that end of stream has ++ * occurred */ ++ NTFY_Notify(pChnl->hNtfy, ++ DSP_STREAMDONE); ++ DBG_Trace(DBG_LEVEL7, "Input Chnl NTFY " ++ "chnl = 0x%x\n", pChnl); ++ } ++ /* Tell DSP if no more I/O buffers available: */ ++ if (!pChnl->pIORequests) ++ goto func_end; ++ if (LST_IsEmpty(pChnl->pIORequests)) { ++ IO_AndValue(pIOMgr->hWmdContext, ++ struct SHM, sm, hostFreeMask, ++ ~(1 << pChnl->uId)); ++ } ++ fClearChnl = true; ++ fNotifyClient = true; ++ } else { ++ /* Input full for this channel, but we have no ++ * buffers available. The channel must be ++ * "idling". Clear out the physical input ++ * channel. */ ++ fClearChnl = true; ++ } ++ } else { ++ /* Input channel cancelled: clear input channel. */ ++ fClearChnl = true; ++ } ++ } else { ++ /* DPC fired after host closed channel: clear input channel. */ ++ fClearChnl = true; ++ } ++ if (fClearChnl) { ++ /* Indicate to the DSP we have read the input: */ ++ IO_SetValue(pIOMgr->hWmdContext, struct SHM, sm, inputFull, 0); ++ CHNLSM_InterruptDSP2(pIOMgr->hWmdContext, MBX_PCPY_CLASS); ++ } ++ if (fNotifyClient) { ++ /* Notify client with IO completion record: */ ++ NotifyChnlComplete(pChnl, pChirp); ++ } ++func_end: ++ DBG_Trace(DBG_LEVEL3, "< InputChnl\n"); ++} ++ ++/* ++ * ======== InputMsg ======== ++ * Copies messages from shared memory to the message queues. ++ */ ++static void InputMsg(struct IO_MGR *pIOMgr, struct MSG_MGR *hMsgMgr) ++{ ++ u32 uMsgs; ++ u32 i; ++ u8 *pMsgInput; ++ struct MSG_QUEUE *hMsgQueue; ++ struct MSG_FRAME *pMsg; ++ struct MSG_DSPMSG msg; ++ struct MSG *pCtrl; ++ u32 fInputEmpty; ++ u32 addr; ++ ++ pCtrl = pIOMgr->pMsgInputCtrl; ++ /* Get the number of input messages to be read. */ ++ fInputEmpty = IO_GetValue(pIOMgr->hWmdContext, struct MSG, pCtrl, ++ bufEmpty); ++ uMsgs = IO_GetValue(pIOMgr->hWmdContext, struct MSG, pCtrl, size); ++ if (fInputEmpty || uMsgs >= hMsgMgr->uMaxMsgs) ++ return; ++ ++ pMsgInput = pIOMgr->pMsgInput; ++ for (i = 0; i < uMsgs; i++) { ++ /* Read the next message */ ++ addr = (u32)&(((struct MSG_DSPMSG *)pMsgInput)->msg.dwCmd); ++ msg.msg.dwCmd = ReadExt32BitDspData(pIOMgr->hWmdContext, addr); ++ addr = (u32)&(((struct MSG_DSPMSG *)pMsgInput)->msg.dwArg1); ++ msg.msg.dwArg1 = ReadExt32BitDspData(pIOMgr->hWmdContext, addr); ++ addr = (u32)&(((struct MSG_DSPMSG *)pMsgInput)->msg.dwArg2); ++ msg.msg.dwArg2 = ReadExt32BitDspData(pIOMgr->hWmdContext, addr); ++ addr = (u32)&(((struct MSG_DSPMSG *)pMsgInput)->dwId); ++ msg.dwId = ReadExt32BitDspData(pIOMgr->hWmdContext, addr); ++ pMsgInput += sizeof(struct MSG_DSPMSG); ++ if (!hMsgMgr->queueList) ++ goto func_end; ++ ++ /* Determine which queue to put the message in */ ++ hMsgQueue = (struct MSG_QUEUE *)LST_First(hMsgMgr->queueList); ++ DBG_Trace(DBG_LEVEL7, "InputMsg RECVD: dwCmd=0x%x dwArg1=0x%x " ++ "dwArg2=0x%x dwId=0x%x \n", msg.msg.dwCmd, ++ msg.msg.dwArg1, msg.msg.dwArg2, msg.dwId); ++ /* Interrupt may occur before shared memory and message ++ * input locations have been set up. If all nodes were ++ * cleaned up, hMsgMgr->uMaxMsgs should be 0. */ ++ if (hMsgQueue && uMsgs > hMsgMgr->uMaxMsgs) ++ goto func_end; ++ ++ while (hMsgQueue != NULL) { ++ if (msg.dwId == hMsgQueue->dwId) { ++ /* Found it */ ++ if (msg.msg.dwCmd == RMS_EXITACK) { ++ /* The exit message does not get ++ * queued */ ++ /* Call the node exit notification */ ++ /* Node handle */ /* status */ ++ (*hMsgMgr->onExit)((HANDLE)hMsgQueue-> ++ hArg, msg.msg.dwArg1); ++ } else { ++ /* Not an exit acknowledgement, queue ++ * the message */ ++ if (!hMsgQueue->msgFreeList) ++ goto func_end; ++ pMsg = (struct MSG_FRAME *)LST_GetHead ++ (hMsgQueue->msgFreeList); ++ if (hMsgQueue->msgUsedList && pMsg) { ++ pMsg->msgData = msg; ++ LST_PutTail(hMsgQueue-> ++ msgUsedList, ++ (struct LST_ELEM *)pMsg); ++ NTFY_Notify(hMsgQueue->hNtfy, ++ DSP_NODEMESSAGEREADY); ++ SYNC_SetEvent(hMsgQueue-> ++ hSyncEvent); ++ } else { ++ /* No free frame to copy the ++ * message into */ ++ DBG_Trace(DBG_LEVEL7, "NO FREE " ++ "MSG FRAMES, DISCARDING" ++ " MESSAGE\n"); ++ } ++ } ++ break; ++ } ++ ++ if (!hMsgMgr->queueList || !hMsgQueue) ++ goto func_end; ++ hMsgQueue = (struct MSG_QUEUE *)LST_Next(hMsgMgr-> ++ queueList, (struct LST_ELEM *)hMsgQueue); ++ } ++ } ++ /* Set the post SWI flag */ ++ if (uMsgs > 0) { ++ /* Tell the DSP we've read the messages */ ++ IO_SetValue(pIOMgr->hWmdContext, struct MSG, pCtrl, bufEmpty, ++ true); ++ IO_SetValue(pIOMgr->hWmdContext, struct MSG, pCtrl, postSWI, ++ true); ++ CHNLSM_InterruptDSP2(pIOMgr->hWmdContext, MBX_PCPY_CLASS); ++ } ++func_end: ++ return; ++ ++} ++ ++/* ++ * ======== NotifyChnlComplete ======== ++ * Purpose: ++ * Signal the channel event, notifying the client that I/O has completed. ++ */ ++static void NotifyChnlComplete(struct CHNL_OBJECT *pChnl, ++ struct CHNL_IRP *pChirp) ++{ ++ bool fSignalEvent; ++ ++ DBC_Require(MEM_IsValidHandle(pChnl, CHNL_SIGNATURE)); ++ DBC_Require(pChnl->hSyncEvent != NULL); ++ /* Note: we signal the channel event only if the queue of IO ++ * completions is empty. If it is not empty, the event is sure to be ++ * signalled by the only IO completion list consumer: ++ * WMD_CHNL_GetIOC(). */ ++ fSignalEvent = LST_IsEmpty(pChnl->pIOCompletions); ++ /* Enqueue the IO completion info for the client: */ ++ LST_PutTail(pChnl->pIOCompletions, (struct LST_ELEM *) pChirp); ++ pChnl->cIOCs++; ++ DBC_Assert(pChnl->cIOCs <= pChnl->cChirps); ++ /* Signal the channel event (if not already set) that IO is complete: */ ++ if (fSignalEvent) ++ SYNC_SetEvent(pChnl->hSyncEvent); ++ ++ /* Notify that IO is complete */ ++ NTFY_Notify(pChnl->hNtfy, DSP_STREAMIOCOMPLETION); ++} ++ ++/* ++ * ======== OutputChnl ======== ++ * Purpose: ++ * Dispatch a buffer on an output channel. ++ */ ++static void OutputChnl(struct IO_MGR *pIOMgr, struct CHNL_OBJECT *pChnl, ++ u32 iMode) ++{ ++ struct CHNL_MGR *pChnlMgr; ++ struct SHM *sm; ++ u32 chnlId; ++ struct CHNL_IRP *pChirp; ++ u32 dwDspFMask; ++ ++ pChnlMgr = pIOMgr->hChnlMgr; ++ sm = pIOMgr->pSharedMem; ++ DBG_Trace(DBG_LEVEL3, "> OutputChnl\n"); ++ /* Attempt to perform output: */ ++ if (IO_GetValue(pIOMgr->hWmdContext, struct SHM, sm, outputFull)) ++ goto func_end; ++ ++ if (pChnl && !((pChnl->dwState & ~CHNL_STATEEOS) == CHNL_STATEREADY)) ++ goto func_end; ++ ++ /* Look to see if both a PC and DSP output channel are ready: */ ++ dwDspFMask = IO_GetValue(pIOMgr->hWmdContext, struct SHM, sm, ++ dspFreeMask); ++ chnlId = FindReadyOutput(pChnlMgr, pChnl, (pChnlMgr->dwOutputMask & ++ dwDspFMask)); ++ if (chnlId == OUTPUTNOTREADY) ++ goto func_end; ++ ++ pChnl = pChnlMgr->apChannel[chnlId]; ++ if (!pChnl || !pChnl->pIORequests) { ++ /* Shouldn't get here: */ ++ goto func_end; ++ } ++ /* Get the I/O request, and attempt a transfer: */ ++ pChirp = (struct CHNL_IRP *)LST_GetHead(pChnl->pIORequests); ++ if (!pChirp) ++ goto func_end; ++ ++ pChnl->cIOReqs--; ++ if (pChnl->cIOReqs < 0 || !pChnl->pIORequests) ++ goto func_end; ++ ++ /* Record fact that no more I/O buffers available: */ ++ if (LST_IsEmpty(pChnl->pIORequests)) ++ pChnlMgr->dwOutputMask &= ~(1 << chnlId); ++ ++ /* Transfer buffer to DSP side: */ ++ pChirp->cBytes = WriteData(pIOMgr->hWmdContext, pIOMgr->pOutput, ++ pChirp->pHostSysBuf, min(pIOMgr->uSMBufSize, pChirp-> ++ cBytes)); ++ pChnl->cBytesMoved += pChirp->cBytes; ++ /* Write all 32 bits of arg */ ++ IO_SetLong(pIOMgr->hWmdContext, struct SHM, sm, arg, pChirp->dwArg); ++#if _CHNL_WORDSIZE == 2 ++ IO_SetValue(pIOMgr->hWmdContext, struct SHM, sm, outputId, ++ (u16)chnlId); ++ IO_SetValue(pIOMgr->hWmdContext, struct SHM, sm, outputSize, ++ (u16)(pChirp->cBytes + (pChnlMgr->uWordSize-1)) / ++ (u16)pChnlMgr->uWordSize); ++#else ++ IO_SetValue(pIOMgr->hWmdContext, struct SHM, sm, outputId, chnlId); ++ IO_SetValue(pIOMgr->hWmdContext, struct SHM, sm, outputSize, ++ (pChirp->cBytes + (pChnlMgr->uWordSize - 1)) / pChnlMgr-> ++ uWordSize); ++#endif ++ IO_SetValue(pIOMgr->hWmdContext, struct SHM, sm, outputFull, 1); ++ /* Indicate to the DSP we have written the output: */ ++ CHNLSM_InterruptDSP2(pIOMgr->hWmdContext, MBX_PCPY_CLASS); ++ /* Notify client with IO completion record (keep EOS) */ ++ pChirp->status &= CHNL_IOCSTATEOS; ++ NotifyChnlComplete(pChnl, pChirp); ++ /* Notify if stream is done. */ ++ if (pChirp->status & CHNL_IOCSTATEOS) ++ NTFY_Notify(pChnl->hNtfy, DSP_STREAMDONE); ++ ++func_end: ++ DBG_Trace(DBG_LEVEL3, "< OutputChnl\n"); ++} ++/* ++ * ======== OutputMsg ======== ++ * Copies messages from the message queues to the shared memory. ++ */ ++static void OutputMsg(struct IO_MGR *pIOMgr, struct MSG_MGR *hMsgMgr) ++{ ++ u32 uMsgs = 0; ++ u32 i; ++ u8 *pMsgOutput; ++ struct MSG_FRAME *pMsg; ++ struct MSG *pCtrl; ++ u32 fOutputEmpty; ++ u32 val; ++ u32 addr; ++ ++ pCtrl = pIOMgr->pMsgOutputCtrl; ++ ++ /* Check if output has been cleared */ ++ fOutputEmpty = IO_GetValue(pIOMgr->hWmdContext, struct MSG, pCtrl, ++ bufEmpty); ++ if (fOutputEmpty) { ++ uMsgs = (hMsgMgr->uMsgsPending > hMsgMgr->uMaxMsgs) ? ++ hMsgMgr->uMaxMsgs : hMsgMgr->uMsgsPending; ++ pMsgOutput = pIOMgr->pMsgOutput; ++ /* Copy uMsgs messages into shared memory */ ++ for (i = 0; i < uMsgs; i++) { ++ if (!hMsgMgr->msgUsedList) { ++ DBG_Trace(DBG_LEVEL3, "msgUsedList is NULL\n"); ++ pMsg = NULL; ++ goto func_end; ++ } else ++ pMsg = (struct MSG_FRAME *)LST_GetHead( ++ hMsgMgr->msgUsedList); ++ if (pMsg != NULL) { ++ val = (pMsg->msgData).dwId; ++ addr = (u32)&(((struct MSG_DSPMSG *) ++ pMsgOutput)->dwId); ++ WriteExt32BitDspData(pIOMgr->hWmdContext, addr, ++ val); ++ val = (pMsg->msgData).msg.dwCmd; ++ addr = (u32)&((((struct MSG_DSPMSG *) ++ pMsgOutput)->msg).dwCmd); ++ WriteExt32BitDspData(pIOMgr->hWmdContext, addr, ++ val); ++ val = (pMsg->msgData).msg.dwArg1; ++ addr = ++ (u32)&((((struct MSG_DSPMSG *) ++ pMsgOutput)->msg).dwArg1); ++ WriteExt32BitDspData(pIOMgr->hWmdContext, addr, ++ val); ++ val = (pMsg->msgData).msg.dwArg2; ++ addr = ++ (u32)&((((struct MSG_DSPMSG *) ++ pMsgOutput)->msg).dwArg2); ++ WriteExt32BitDspData(pIOMgr->hWmdContext, addr, ++ val); ++ pMsgOutput += sizeof(struct MSG_DSPMSG); ++ if (!hMsgMgr->msgFreeList) ++ goto func_end; ++ LST_PutTail(hMsgMgr->msgFreeList, ++ (struct LST_ELEM *) pMsg); ++ SYNC_SetEvent(hMsgMgr->hSyncEvent); ++ } else { ++ DBG_Trace(DBG_LEVEL3, "pMsg is NULL\n"); ++ } ++ } ++ ++ if (uMsgs > 0) { ++ hMsgMgr->uMsgsPending -= uMsgs; ++#if _CHNL_WORDSIZE == 2 ++ IO_SetValue(pIOMgr->hWmdContext, struct MSG, pCtrl, ++ size, (u16)uMsgs); ++#else ++ IO_SetValue(pIOMgr->hWmdContext, struct MSG, pCtrl, ++ size, uMsgs); ++#endif ++ IO_SetValue(pIOMgr->hWmdContext, struct MSG, pCtrl, ++ bufEmpty, false); ++ /* Set the post SWI flag */ ++ IO_SetValue(pIOMgr->hWmdContext, struct MSG, pCtrl, ++ postSWI, true); ++ /* Tell the DSP we have written the output. */ ++ CHNLSM_InterruptDSP2(pIOMgr->hWmdContext, MBX_PCPY_CLASS); ++ } ++ } ++func_end: ++ return; ++ ++} ++ ++/* ++ * ======== registerSHMSegs ======== ++ * purpose: ++ * Registers GPP SM segment with CMM. ++ */ ++static DSP_STATUS registerSHMSegs(struct IO_MGR *hIOMgr, ++ struct COD_MANAGER *hCodMan, ++ u32 dwGPPBasePA) ++{ ++ DSP_STATUS status = DSP_SOK; ++ u32 ulShm0_Base = 0; ++ u32 ulShm0_End = 0; ++ u32 ulShm0_RsrvdStart = 0; ++ u32 ulRsrvdSize = 0; ++ u32 ulGppPhys; ++ u32 ulDspVirt; ++ u32 ulShmSegId0 = 0; ++ u32 dwOffset, dwGPPBaseVA, ulDSPSize; ++ ++ /* Read address and size info for first SM region.*/ ++ /* Get start of 1st SM Heap region */ ++ status = COD_GetSymValue(hCodMan, SHM0_SHARED_BASE_SYM, &ulShm0_Base); ++ DBC_Assert(ulShm0_Base != 0); ++ /* Get end of 1st SM Heap region */ ++ if (DSP_SUCCEEDED(status)) { ++ /* Get start and length of message part of shared memory */ ++ status = COD_GetSymValue(hCodMan, SHM0_SHARED_END_SYM, ++ &ulShm0_End); ++ DBC_Assert(ulShm0_End != 0); ++ } ++ /* start of Gpp reserved region */ ++ if (DSP_SUCCEEDED(status)) { ++ /* Get start and length of message part of shared memory */ ++ status = COD_GetSymValue(hCodMan, SHM0_SHARED_RESERVED_BASE_SYM, ++ &ulShm0_RsrvdStart); ++ DBG_Trace(DBG_LEVEL1, "***ulShm0_RsrvdStart 0x%x \n", ++ ulShm0_RsrvdStart); ++ DBC_Assert(ulShm0_RsrvdStart != 0); ++ } ++ /* Register with CMM */ ++ if (DSP_SUCCEEDED(status)) { ++ status = DEV_GetCmmMgr(hIOMgr->hDevObject, &hIOMgr->hCmmMgr); ++ if (DSP_SUCCEEDED(status)) { ++ status = CMM_UnRegisterGPPSMSeg(hIOMgr->hCmmMgr, ++ CMM_ALLSEGMENTS); ++ if (DSP_FAILED(status)) { ++ DBG_Trace(DBG_LEVEL7, "ERROR - Unable to " ++ "Un-Register SM segments \n"); ++ } ++ } else { ++ DBG_Trace(DBG_LEVEL7, "ERROR - Unable to get CMM " ++ "Handle \n"); ++ } ++ } ++ /* Register new SM region(s) */ ++ if (DSP_SUCCEEDED(status) && (ulShm0_End - ulShm0_Base) > 0) { ++ /* calc size (bytes) of SM the GPP can alloc from */ ++ ulRsrvdSize = (ulShm0_End - ulShm0_RsrvdStart + 1) * hIOMgr-> ++ uWordSize; ++ DBC_Assert(ulRsrvdSize > 0); ++ /* calc size of SM DSP can alloc from */ ++ ulDSPSize = (ulShm0_RsrvdStart - ulShm0_Base) * hIOMgr-> ++ uWordSize; ++ DBC_Assert(ulDSPSize > 0); ++ /* First TLB entry reserved for Bridge SM use.*/ ++ ulGppPhys = hIOMgr->extProcInfo.tyTlb[0].ulGppPhys; ++ /* get size in bytes */ ++ ulDspVirt = hIOMgr->extProcInfo.tyTlb[0].ulDspVirt * hIOMgr-> ++ uWordSize; ++ /* Calc byte offset used to convert GPP phys <-> DSP byte ++ * address.*/ ++ if (dwGPPBasePA > ulDspVirt) ++ dwOffset = dwGPPBasePA - ulDspVirt; ++ else ++ dwOffset = ulDspVirt - dwGPPBasePA; ++ ++ DBC_Assert(ulShm0_RsrvdStart * hIOMgr->uWordSize >= ulDspVirt); ++ /* calc Gpp phys base of SM region */ ++ /* Linux - this is actually uncached kernel virtual address*/ ++ dwGPPBaseVA = ulGppPhys + ulShm0_RsrvdStart * hIOMgr->uWordSize ++ - ulDspVirt; ++ /* calc Gpp phys base of SM region */ ++ /* Linux - this is the physical address*/ ++ dwGPPBasePA = dwGPPBasePA + ulShm0_RsrvdStart * hIOMgr-> ++ uWordSize - ulDspVirt; ++ /* Register SM Segment 0.*/ ++ status = CMM_RegisterGPPSMSeg(hIOMgr->hCmmMgr, dwGPPBasePA, ++ ulRsrvdSize, dwOffset, (dwGPPBasePA > ulDspVirt) ? ++ CMM_ADDTODSPPA : CMM_SUBFROMDSPPA, ++ (u32)(ulShm0_Base * hIOMgr->uWordSize), ++ ulDSPSize, &ulShmSegId0, dwGPPBaseVA); ++ if (DSP_FAILED(status)) { ++ DBG_Trace(DBG_LEVEL7, "ERROR - Failed to register SM " ++ "Seg 0 \n"); ++ } ++ /* first SM region is segId = 1 */ ++ DBC_Assert(ulShmSegId0 == 1); ++ } ++ return status; ++} ++ ++/* ++ * ======== ReadData ======== ++ * Copies buffers from the shared memory to the host buffer. ++ */ ++static u32 ReadData(struct WMD_DEV_CONTEXT *hDevContext, void *pDest, ++ void *pSrc, u32 uSize) ++{ ++ memcpy(pDest, pSrc, uSize); ++ return uSize; ++} ++ ++/* ++ * ======== WriteData ======== ++ * Copies buffers from the host side buffer to the shared memory. ++ */ ++static u32 WriteData(struct WMD_DEV_CONTEXT *hDevContext, void *pDest, ++ void *pSrc, u32 uSize) ++{ ++ memcpy(pDest, pSrc, uSize); ++ return uSize; ++} ++ ++/* ZCPY IO routines. */ ++void IO_IntrDSP2(IN struct IO_MGR *pIOMgr, IN u16 wMbVal) ++{ ++ CHNLSM_InterruptDSP2(pIOMgr->hWmdContext, wMbVal); ++} ++ ++/* ++ * ======== IO_SHMcontrol ======== ++ * Sets the requested SHM setting. ++ */ ++DSP_STATUS IO_SHMsetting(IN struct IO_MGR *hIOMgr, IN enum SHM_DESCTYPE desc, ++ IN void *pArgs) ++{ ++#ifdef CONFIG_BRIDGE_DVFS ++ u32 i; ++ struct dspbridge_platform_data *pdata = ++ omap_dspbridge_dev->dev.platform_data; ++ ++ switch (desc) { ++ case SHM_CURROPP: ++ /* Update the shared memory with requested OPP information */ ++ if (pArgs != NULL) ++ hIOMgr->pSharedMem->oppTableStruct.currOppPt = ++ *(u32 *)pArgs; ++ else ++ return DSP_EFAIL; ++ break; ++ case SHM_OPPINFO: ++ /* Update the shared memory with the voltage, frequency, ++ min and max frequency values for an OPP */ ++ for (i = 0; i <= dsp_max_opps; i++) { ++ hIOMgr->pSharedMem->oppTableStruct.oppPoint[i].voltage = ++ vdd1_dsp_freq[i][0]; ++ DBG_Trace(DBG_LEVEL5, "OPP shared memory -voltage: " ++ "%d\n", hIOMgr->pSharedMem->oppTableStruct. ++ oppPoint[i].voltage); ++ hIOMgr->pSharedMem->oppTableStruct.oppPoint[i]. ++ frequency = vdd1_dsp_freq[i][1]; ++ DBG_Trace(DBG_LEVEL5, "OPP shared memory -frequency: " ++ "%d\n", hIOMgr->pSharedMem->oppTableStruct. ++ oppPoint[i].frequency); ++ hIOMgr->pSharedMem->oppTableStruct.oppPoint[i].minFreq = ++ vdd1_dsp_freq[i][2]; ++ DBG_Trace(DBG_LEVEL5, "OPP shared memory -min value: " ++ "%d\n", hIOMgr->pSharedMem->oppTableStruct. ++ oppPoint[i].minFreq); ++ hIOMgr->pSharedMem->oppTableStruct.oppPoint[i].maxFreq = ++ vdd1_dsp_freq[i][3]; ++ DBG_Trace(DBG_LEVEL5, "OPP shared memory -max value: " ++ "%d\n", hIOMgr->pSharedMem->oppTableStruct. ++ oppPoint[i].maxFreq); ++ } ++ hIOMgr->pSharedMem->oppTableStruct.numOppPts = dsp_max_opps; ++ DBG_Trace(DBG_LEVEL5, "OPP shared memory - max OPP number: " ++ "%d\n", hIOMgr->pSharedMem->oppTableStruct.numOppPts); ++ /* Update the current OPP number */ ++ if (pdata->dsp_get_opp) ++ i = (*pdata->dsp_get_opp)(); ++ hIOMgr->pSharedMem->oppTableStruct.currOppPt = i; ++ DBG_Trace(DBG_LEVEL7, "OPP value programmed to shared memory: " ++ "%d\n", i); ++ break; ++ case SHM_GETOPP: ++ /* Get the OPP that DSP has requested */ ++ *(u32 *)pArgs = hIOMgr->pSharedMem->oppRequest.rqstOppPt; ++ break; ++ default: ++ break; ++ ++ queue_work(bridge_workqueue, ++ &(hIOMgr->io_workq)); ++ } ++#endif ++ return DSP_SOK; ++} ++ ++/* ++ * ======== WMD_IO_GetProcLoad ======== ++ * Gets the Processor's Load information ++ */ ++DSP_STATUS WMD_IO_GetProcLoad(IN struct IO_MGR *hIOMgr, ++ OUT struct DSP_PROCLOADSTAT *pProcStat) ++{ ++ pProcStat->uCurrLoad = hIOMgr->pSharedMem->loadMonInfo.currDspLoad; ++ pProcStat->uPredictedLoad = hIOMgr->pSharedMem->loadMonInfo.predDspLoad; ++ pProcStat->uCurrDspFreq = hIOMgr->pSharedMem->loadMonInfo.currDspFreq; ++ pProcStat->uPredictedFreq = hIOMgr->pSharedMem->loadMonInfo.predDspFreq; ++ ++ DBG_Trace(DBG_LEVEL4, "Curr Load =%d, Pred Load = %d, Curr Freq = %d, " ++ "Pred Freq = %d\n", pProcStat->uCurrLoad, ++ pProcStat->uPredictedLoad, pProcStat->uCurrDspFreq, ++ pProcStat->uPredictedFreq); ++ return DSP_SOK; ++} ++ ++#ifndef DSP_TRACEBUF_DISABLED ++void PrintDSPDebugTrace(struct IO_MGR *hIOMgr) ++{ ++ u32 ulNewMessageLength = 0, ulGPPCurPointer; ++ ++ GT_0trace(dsp_trace_mask, GT_ENTER, "Entering PrintDSPDebugTrace\n"); ++ ++ while (true) { ++ /* Get the DSP current pointer */ ++ ulGPPCurPointer = *(u32 *) (hIOMgr->ulTraceBufferCurrent); ++ ulGPPCurPointer = hIOMgr->ulGppVa + (ulGPPCurPointer - ++ hIOMgr->ulDspVa); ++ ++ /* No new debug messages available yet */ ++ if (ulGPPCurPointer == hIOMgr->ulGPPReadPointer) ++ break; ++ ++ /* Continuous data */ ++ else if (ulGPPCurPointer > hIOMgr->ulGPPReadPointer) { ++ ulNewMessageLength = ulGPPCurPointer - hIOMgr-> ++ ulGPPReadPointer; ++ ++ memcpy(hIOMgr->pMsg, (char *)hIOMgr->ulGPPReadPointer, ++ ulNewMessageLength); ++ hIOMgr->pMsg[ulNewMessageLength] = '\0'; ++ /* Advance the GPP trace pointer to DSP current ++ * pointer */ ++ hIOMgr->ulGPPReadPointer += ulNewMessageLength; ++ /* Print the trace messages */ ++ GT_0trace(dsp_trace_mask, GT_1CLASS, hIOMgr->pMsg); ++ } ++ /* Handle trace buffer wraparound */ ++ else if (ulGPPCurPointer < hIOMgr->ulGPPReadPointer) { ++ memcpy(hIOMgr->pMsg, (char *)hIOMgr->ulGPPReadPointer, ++ hIOMgr->ulTraceBufferEnd - ++ hIOMgr->ulGPPReadPointer); ++ ulNewMessageLength = ulGPPCurPointer - ++ hIOMgr->ulTraceBufferBegin; ++ memcpy(&hIOMgr->pMsg[hIOMgr->ulTraceBufferEnd - ++ hIOMgr->ulGPPReadPointer], ++ (char *)hIOMgr->ulTraceBufferBegin, ++ ulNewMessageLength); ++ hIOMgr->pMsg[hIOMgr->ulTraceBufferEnd - ++ hIOMgr->ulGPPReadPointer + ++ ulNewMessageLength] = '\0'; ++ /* Advance the GPP trace pointer to DSP current ++ * pointer */ ++ hIOMgr->ulGPPReadPointer = hIOMgr->ulTraceBufferBegin + ++ ulNewMessageLength; ++ /* Print the trace messages */ ++ GT_0trace(dsp_trace_mask, GT_1CLASS, hIOMgr->pMsg); ++ } ++ } ++} ++#endif ++ ++/* ++ * ======== PackTraceBuffer ======== ++ * Removes extra nulls from the trace buffer returned from the DSP. ++ * Works even on buffers that already are packed (null removed); but has ++ * one bug in that case -- loses the last character (replaces with '\0'). ++ * Continues through conversion for full set of nBytes input characters. ++ * Parameters: ++ * lpBuf: Pointer to input/output buffer ++ * nBytes: Number of characters in the buffer ++ * ulNumWords: Number of DSP words in the buffer. Indicates potential ++ * number of extra carriage returns to generate. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Unable to allocate memory. ++ * Requires: ++ * lpBuf must be a fully allocated writable block of at least nBytes. ++ * There are no more than ulNumWords extra characters needed (the number of ++ * linefeeds minus the number of NULLS in the input buffer). ++ */ ++#if (defined(DEBUG) || defined(DDSP_DEBUG_PRODUCT)) && GT_TRACE ++static DSP_STATUS PackTraceBuffer(char *lpBuf, u32 nBytes, u32 ulNumWords) ++{ ++ DSP_STATUS status = DSP_SOK; ++ char *lpTmpBuf; ++ char *lpBufStart; ++ char *lpTmpStart; ++ u32 nCnt; ++ char thisChar; ++ ++ /* tmp workspace, 1 KB longer than input buf */ ++ lpTmpBuf = MEM_Calloc((nBytes + ulNumWords), MEM_PAGED); ++ if (lpTmpBuf == NULL) { ++ DBG_Trace(DBG_LEVEL7, "PackTrace buffer:OutofMemory \n"); ++ status = DSP_EMEMORY; ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ lpBufStart = lpBuf; ++ lpTmpStart = lpTmpBuf; ++ for (nCnt = nBytes; nCnt > 0; nCnt--) { ++ thisChar = *lpBuf++; ++ switch (thisChar) { ++ case '\0': /* Skip null bytes */ ++ break; ++ case '\n': /* Convert \n to \r\n */ ++ /* NOTE: do not reverse order; Some OS */ ++ /* editors control doesn't understand "\n\r" */ ++ *lpTmpBuf++ = '\r'; ++ *lpTmpBuf++ = '\n'; ++ break; ++ default: /* Copy in the actual ascii byte */ ++ *lpTmpBuf++ = thisChar; ++ break; ++ } ++ } ++ *lpTmpBuf = '\0'; /* Make sure tmp buf is null terminated */ ++ /* Cut output down to input buf size */ ++ strncpy(lpBufStart, lpTmpStart, nBytes); ++ /*Make sure output is null terminated */ ++ lpBufStart[nBytes - 1] = '\0'; ++ MEM_Free(lpTmpStart); ++ } ++ ++ return status; ++} ++#endif /* (defined(DEBUG) || defined(DDSP_DEBUG_PRODUCT)) && GT_TRACE */ ++ ++/* ++ * ======== PrintDspTraceBuffer ======== ++ * Prints the trace buffer returned from the DSP (if DBG_Trace is enabled). ++ * Parameters: ++ * hDehMgr: Handle to DEH manager object ++ * number of extra carriage returns to generate. ++ * Returns: ++ * DSP_SOK: Success. ++ * DSP_EMEMORY: Unable to allocate memory. ++ * Requires: ++ * hDehMgr muse be valid. Checked in WMD_DEH_Notify. ++ */ ++DSP_STATUS PrintDspTraceBuffer(struct WMD_DEV_CONTEXT *hWmdContext) ++{ ++ DSP_STATUS status = DSP_SOK; ++ ++#if (defined(DEBUG) || defined(DDSP_DEBUG_PRODUCT)) && GT_TRACE ++ struct COD_MANAGER *hCodMgr; ++ u32 ulTraceEnd; ++ u32 ulTraceBegin; ++ u32 ulNumBytes = 0; ++ u32 ulNumWords = 0; ++ u32 ulWordSize = 2; ++ CONST u32 uMaxSize = 512; ++ char *pszBuf; ++ u16 *lpszBuf; ++ ++ struct WMD_DEV_CONTEXT *pWmdContext = (struct WMD_DEV_CONTEXT *) ++ hWmdContext; ++ struct WMD_DRV_INTERFACE *pIntfFxns; ++ struct DEV_OBJECT *pDevObject = (struct DEV_OBJECT *) ++ pWmdContext->hDevObject; ++ ++ status = DEV_GetCodMgr(pDevObject, &hCodMgr); ++ if (DSP_FAILED(status)) ++ GT_0trace(dsp_trace_mask, GT_2CLASS, ++ "PrintDspTraceBuffer: Failed on DEV_GetCodMgr.\n"); ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* Look for SYS_PUTCBEG/SYS_PUTCEND: */ ++ status = COD_GetSymValue(hCodMgr, COD_TRACEBEG, &ulTraceBegin); ++ GT_1trace(dsp_trace_mask, GT_2CLASS, ++ "PrintDspTraceBuffer: ulTraceBegin Value 0x%x\n", ++ ulTraceBegin); ++ if (DSP_FAILED(status)) ++ GT_0trace(dsp_trace_mask, GT_2CLASS, ++ "PrintDspTraceBuffer: Failed on " ++ "COD_GetSymValue.\n"); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ status = COD_GetSymValue(hCodMgr, COD_TRACEEND, &ulTraceEnd); ++ GT_1trace(dsp_trace_mask, GT_2CLASS, ++ "PrintDspTraceBuffer: ulTraceEnd Value 0x%x\n", ++ ulTraceEnd); ++ if (DSP_FAILED(status)) ++ GT_0trace(dsp_trace_mask, GT_2CLASS, ++ "PrintDspTraceBuffer: Failed on " ++ "COD_GetSymValue.\n"); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ ulNumBytes = (ulTraceEnd - ulTraceBegin) * ulWordSize; ++ /* If the chip type is 55 then the addresses will be ++ * byte addresses; convert them to word addresses. */ ++ if (ulNumBytes > uMaxSize) ++ ulNumBytes = uMaxSize; ++ ++ /* make sure the data we request fits evenly */ ++ ulNumBytes = (ulNumBytes / ulWordSize) * ulWordSize; ++ GT_1trace(dsp_trace_mask, GT_2CLASS, "PrintDspTraceBuffer: " ++ "ulNumBytes 0x%x\n", ulNumBytes); ++ ulNumWords = ulNumBytes * ulWordSize; ++ GT_1trace(dsp_trace_mask, GT_2CLASS, "PrintDspTraceBuffer: " ++ "ulNumWords 0x%x\n", ulNumWords); ++ status = DEV_GetIntfFxns(pDevObject, &pIntfFxns); ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ pszBuf = MEM_Calloc(uMaxSize, MEM_NONPAGED); ++ lpszBuf = MEM_Calloc(ulNumBytes * 2, MEM_NONPAGED); ++ if (pszBuf != NULL) { ++ /* Read bytes from the DSP trace buffer... */ ++ status = (*pIntfFxns->pfnBrdRead)(hWmdContext, ++ (u8 *)pszBuf, (u32)ulTraceBegin, ++ ulNumBytes, 0); ++ if (DSP_FAILED(status)) ++ GT_0trace(dsp_trace_mask, GT_2CLASS, ++ "PrintDspTraceBuffer: " ++ "Failed to Read Trace Buffer.\n"); ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* Pack and do newline conversion */ ++ GT_0trace(dsp_trace_mask, GT_2CLASS, ++ "PrintDspTraceBuffer: " ++ "before pack and unpack.\n"); ++ PackTraceBuffer(pszBuf, ulNumBytes, ulNumWords); ++ GT_1trace(dsp_trace_mask, GT_1CLASS, ++ "DSP Trace Buffer:\n%s\n", pszBuf); ++ } ++ MEM_Free(pszBuf); ++ MEM_Free(lpszBuf); ++ } else { ++ GT_0trace(dsp_trace_mask, GT_2CLASS, ++ "PrintDspTraceBuffer: Failed to " ++ "allocate trace buffer.\n"); ++ status = DSP_EMEMORY; ++ } ++ } ++#endif ++ return status; ++} ++ ++void IO_SM_init(void) ++{ ++ ++ GT_create(&dsp_trace_mask, "DT"); /* DSP Trace Mask */ ++ ++} +diff --git a/drivers/dsp/bridge/wmd/mmu_fault.c b/drivers/dsp/bridge/wmd/mmu_fault.c +new file mode 100644 +index 0000000..5585cdb +--- /dev/null ++++ b/drivers/dsp/bridge/wmd/mmu_fault.c +@@ -0,0 +1,172 @@ ++/* ++ * mmu_fault.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== mmu_fault.c ======== ++ * Description: ++ * Implements DSP MMU fault handling functions. ++ * ++ *! Revision History: ++ *! ================ ++ *! 26-Dec-2004 hn: Support for IVA MMU exception. ++ *! 06-Mar-2003 sb: Print MMU fault address. Cosmetic changes. ++ *! 16-Feb-2003 vp: Fixed warning in MMU_FaultIsr ++ *! 05-Jan-2004 vp: Updated support for 24xx silicon ++ *! 19-Feb-2003 vp: Code review updates. ++ *! - Cosmetic changes. ++ *! 18-Oct-2002 sb: Ported to Linux platform. ++ *! 10-Sep-2001 kc: created. ++ */ ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Link Driver */ ++#include ++ ++/* ------------------------------------ Hardware Abstraction Layer */ ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include "_deh.h" ++#include ++#include "_tiomap_mmu.h" ++#include "_tiomap.h" ++#include "mmu_fault.h" ++ ++static u32 dmmuEventMask; ++u32 faultAddr; ++ ++static bool MMU_CheckIfFault(struct WMD_DEV_CONTEXT *pDevContext); ++ ++/* ++ * ======== MMU_FaultDpc ======== ++ * Deferred procedure call to handle DSP MMU fault. ++ */ ++void MMU_FaultDpc(IN void *pRefData) ++{ ++ struct DEH_MGR *hDehMgr = (struct DEH_MGR *)pRefData; ++ struct DEH_MGR *pDehMgr = (struct DEH_MGR *)hDehMgr; ++ ++ DBG_Trace(DBG_LEVEL1, "MMU_FaultDpc Enter: 0x%x\n", pRefData); ++ ++ if (pDehMgr) ++ WMD_DEH_Notify(hDehMgr, DSP_MMUFAULT, 0L); ++ ++ DBG_Trace(DBG_LEVEL1, "MMU_FaultDpc Exit: 0x%x\n", pRefData); ++} ++ ++/* ++ * ======== MMU_FaultIsr ======== ++ * ISR to be triggered by a DSP MMU fault interrupt. ++ */ ++irqreturn_t MMU_FaultIsr(int irq, IN void *pRefData) ++{ ++ struct DEH_MGR *pDehMgr = (struct DEH_MGR *)pRefData; ++ struct WMD_DEV_CONTEXT *pDevContext; ++ struct CFG_HOSTRES resources; ++ DSP_STATUS status = DSP_SOK; ++ ++ ++ DBG_Trace(DBG_LEVEL1, "Entering DEH_DspMmuIsr: 0x%x\n", pRefData); ++ DBC_Require(irq == INT_DSP_MMU_IRQ); ++ DBC_Require(MEM_IsValidHandle(pDehMgr, SIGNATURE)); ++ ++ if (MEM_IsValidHandle(pDehMgr, SIGNATURE)) { ++ ++ pDevContext = (struct WMD_DEV_CONTEXT *)pDehMgr->hWmdContext; ++ status = CFG_GetHostResources( ++ (struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), ++ &resources); ++ if (DSP_FAILED(status)) ++ DBG_Trace(DBG_LEVEL7, ++ "**Failed to get Host Resources " ++ "in MMU ISR **\n"); ++ if (MMU_CheckIfFault(pDevContext)) { ++ printk(KERN_INFO "***** DSPMMU FAULT ***** IRQStatus " ++ "0x%x\n", dmmuEventMask); ++ printk(KERN_INFO "***** DSPMMU FAULT ***** faultAddr " ++ "0x%x\n", faultAddr); ++ /* Disable the MMU events, else once we clear it will ++ * start to raise INTs again */ ++ /* ++ * Schedule a DPC directly. In the future, it may be ++ * necessary to check if DSP MMU fault is intended for ++ * Bridge. ++ */ ++ DPC_Schedule(pDehMgr->hMmuFaultDpc); ++ /* Reset errInfo structure before use. */ ++ pDehMgr->errInfo.dwErrMask = DSP_MMUFAULT; ++ pDehMgr->errInfo.dwVal1 = faultAddr >> 16; ++ pDehMgr->errInfo.dwVal2 = faultAddr & 0xFFFF; ++ pDehMgr->errInfo.dwVal3 = 0L; ++ /* Disable the MMU events, else once we clear it will ++ * start to raise INTs again */ ++ HW_MMU_EventDisable(resources.dwDmmuBase, ++ HW_MMU_TRANSLATION_FAULT); ++ } else { ++ DBG_Trace(DBG_LEVEL7, ++ "***** MMU FAULT ***** faultcode 0x%x\n", ++ dmmuEventMask); ++ HW_MMU_EventDisable(resources.dwDmmuBase, ++ HW_MMU_ALL_INTERRUPTS); ++ } ++ } ++ return IRQ_HANDLED; ++} ++ ++ ++/* ++ * ======== MMU_CheckIfFault ======== ++ * Check to see if MMU Fault is valid TLB miss from DSP ++ * Note: This function is called from an ISR ++ */ ++static bool MMU_CheckIfFault(struct WMD_DEV_CONTEXT *pDevContext) ++{ ++ ++ ++ bool retVal = false; ++ DSP_STATUS status = DSP_SOK; ++ HW_STATUS hwStatus; ++ struct CFG_HOSTRES resources; ++ status = CFG_GetHostResources( ++ (struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), &resources); ++ if (DSP_FAILED(status)) ++ DBG_Trace(DBG_LEVEL7, "**Failed to get Host Resources in " ++ "MMU_CheckIfFault **\n"); ++ ++ hwStatus = HW_MMU_EventStatus(resources.dwDmmuBase, &dmmuEventMask); ++ if (dmmuEventMask == HW_MMU_TRANSLATION_FAULT) { ++ HW_MMU_FaultAddrRead(resources.dwDmmuBase, &faultAddr); ++ DBG_Trace(DBG_LEVEL1, "WMD_DEH_Notify: DSP_MMUFAULT, fault " ++ "address = 0x%x\n", faultAddr); ++ retVal = true; ++ } ++ return retVal; ++} +diff --git a/drivers/dsp/bridge/wmd/mmu_fault.h b/drivers/dsp/bridge/wmd/mmu_fault.h +new file mode 100644 +index 0000000..be59333 +--- /dev/null ++++ b/drivers/dsp/bridge/wmd/mmu_fault.h +@@ -0,0 +1,45 @@ ++/* ++ * mmu_fault.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== mmu_fault.h ======== ++ * Description: ++ * Defines DSP MMU fault handling functions. ++ * ++ *! Revision History: ++ *! ================ ++ *! 26-Dec-2004 hn: IVA MMU handlers. ++ *! 10-Sep-2001 kc: created. ++ */ ++ ++#ifndef MMU_FAULT_ ++#define MMU_FAULT_ ++ ++/* ++ * ======== MMU_FaultDpc ======== ++ * Deferred procedure call to handle DSP MMU fault. ++ */ ++ void MMU_FaultDpc(IN void *pRefData); ++ ++/* ++ * ======== MMU_FaultIsr ======== ++ * ISR to be triggered by a DSP MMU fault interrupt. ++ */ ++irqreturn_t MMU_FaultIsr(int irq, IN void *pRefData); ++ ++#endif /* MMU_FAULT_ */ ++ +diff --git a/drivers/dsp/bridge/wmd/msg_sm.c b/drivers/dsp/bridge/wmd/msg_sm.c +new file mode 100644 +index 0000000..b9b2bec +--- /dev/null ++++ b/drivers/dsp/bridge/wmd/msg_sm.c +@@ -0,0 +1,643 @@ ++/* ++ * msg_sm.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== msg_sm.c ======== ++ * Description: ++ * Implements upper edge functions for WMD message module. ++ * ++ * Public Functions: ++ * WMD_MSG_Create ++ * WMD_MSG_CreateQueue ++ * WMD_MSG_Delete ++ * WMD_MSG_DeleteQueue ++ * WMD_MSG_Get ++ * WMD_MSG_Put ++ * WMD_MSG_RegisterNotify ++ * WMD_MSG_SetQueueId ++ * ++ *! Revision History: ++ *! ================= ++ *! 24-Jul-2002 jeh Release critical section in WMD_MSG_Put() before ++ *! scheduling DPC. ++ *! 09-May-2001 jeh Free MSG queue NTFY object, remove unnecessary set/ ++ *! reset of events. ++ *! 10-Jan-2001 jeh Set/Reset message manager and message queue events ++ *! correctly. ++ *! 04-Dec-2000 jeh Bug fixes. ++ *! 12-Sep-2000 jeh Created. ++ */ ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++ ++/* ----------------------------------- Others */ ++#include ++ ++/* ----------------------------------- This */ ++#include <_msg_sm.h> ++#include ++ ++/* ----------------------------------- Defines, Data Structures, Typedefs */ ++#define MSGQ_SIGNATURE 0x5147534d /* "QGSM" */ ++ ++/* ----------------------------------- Function Prototypes */ ++static DSP_STATUS AddNewMsg(struct LST_LIST *msgList); ++static void DeleteMsgMgr(struct MSG_MGR *hMsgMgr); ++static void DeleteMsgQueue(struct MSG_QUEUE *hMsgQueue, u32 uNumToDSP); ++static void FreeMsgList(struct LST_LIST *msgList); ++ ++/* ++ * ======== WMD_MSG_Create ======== ++ * Create an object to manage message queues. Only one of these objects ++ * can exist per device object. ++ */ ++DSP_STATUS WMD_MSG_Create(OUT struct MSG_MGR **phMsgMgr, ++ struct DEV_OBJECT *hDevObject, MSG_ONEXIT msgCallback) ++{ ++ struct MSG_MGR *pMsgMgr; ++ struct IO_MGR *hIOMgr; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(phMsgMgr != NULL); ++ DBC_Require(msgCallback != NULL); ++ DBC_Require(hDevObject != NULL); ++ DEV_GetIOMgr(hDevObject, &hIOMgr); ++ DBC_Assert(hIOMgr != NULL); ++ *phMsgMgr = NULL; ++ /* Allocate MSG manager object */ ++ MEM_AllocObject(pMsgMgr, struct MSG_MGR, MSGMGR_SIGNATURE); ++ ++ if (pMsgMgr) { ++ pMsgMgr->onExit = msgCallback; ++ pMsgMgr->hIOMgr = hIOMgr; ++ /* List of MSG_QUEUEs */ ++ pMsgMgr->queueList = LST_Create(); ++ /* Queues of message frames for messages to the DSP. Message ++ * frames will only be added to the free queue when a ++ * MSG_QUEUE object is created. */ ++ pMsgMgr->msgFreeList = LST_Create(); ++ pMsgMgr->msgUsedList = LST_Create(); ++ if (pMsgMgr->queueList == NULL || ++ pMsgMgr->msgFreeList == NULL || ++ pMsgMgr->msgUsedList == NULL) ++ status = DSP_EMEMORY; ++ if (DSP_SUCCEEDED(status)) ++ status = SYNC_InitializeDPCCS(&pMsgMgr->hSyncCS); ++ ++ /* Create an event to be used by WMD_MSG_Put() in waiting ++ * for an available free frame from the message manager. */ ++ if (DSP_SUCCEEDED(status)) ++ status = SYNC_OpenEvent(&pMsgMgr->hSyncEvent, NULL); ++ ++ if (DSP_SUCCEEDED(status)) ++ *phMsgMgr = pMsgMgr; ++ else ++ DeleteMsgMgr(pMsgMgr); ++ ++ } else { ++ status = DSP_EMEMORY; ++ } ++ return status; ++} ++ ++/* ++ * ======== WMD_MSG_CreateQueue ======== ++ * Create a MSG_QUEUE for sending/receiving messages to/from a node ++ * on the DSP. ++ */ ++DSP_STATUS WMD_MSG_CreateQueue(struct MSG_MGR *hMsgMgr, ++ OUT struct MSG_QUEUE **phMsgQueue, ++ u32 dwId, u32 uMaxMsgs, HANDLE hArg) ++{ ++ u32 i; ++ u32 uNumAllocated = 0; ++ struct MSG_QUEUE *pMsgQ; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(MEM_IsValidHandle(hMsgMgr, MSGMGR_SIGNATURE)); ++ DBC_Require(phMsgQueue != NULL); ++ ++ *phMsgQueue = NULL; ++ /* Allocate MSG_QUEUE object */ ++ MEM_AllocObject(pMsgQ, struct MSG_QUEUE, MSGQ_SIGNATURE); ++ if (!pMsgQ) { ++ status = DSP_EMEMORY; ++ goto func_end; ++ } ++ LST_InitElem((struct LST_ELEM *) pMsgQ); ++ pMsgQ->uMaxMsgs = uMaxMsgs; ++ pMsgQ->hMsgMgr = hMsgMgr; ++ pMsgQ->hArg = hArg; /* Node handle */ ++ pMsgQ->dwId = dwId; /* Node env (not valid yet) */ ++ /* Queues of Message frames for messages from the DSP */ ++ pMsgQ->msgFreeList = LST_Create(); ++ pMsgQ->msgUsedList = LST_Create(); ++ if (pMsgQ->msgFreeList == NULL || pMsgQ->msgUsedList == NULL) ++ status = DSP_EMEMORY; ++ ++ /* Create event that will be signalled when a message from ++ * the DSP is available. */ ++ if (DSP_SUCCEEDED(status)) ++ status = SYNC_OpenEvent(&pMsgQ->hSyncEvent, NULL); ++ ++ /* Create a notification list for message ready notification. */ ++ if (DSP_SUCCEEDED(status)) ++ status = NTFY_Create(&pMsgQ->hNtfy); ++ ++ /* Create events that will be used to synchronize cleanup ++ * when the object is deleted. hSyncDone will be set to ++ * unblock threads in MSG_Put() or MSG_Get(). hSyncDoneAck ++ * will be set by the unblocked thread to signal that it ++ * is unblocked and will no longer reference the object. */ ++ if (DSP_SUCCEEDED(status)) ++ status = SYNC_OpenEvent(&pMsgQ->hSyncDone, NULL); ++ ++ if (DSP_SUCCEEDED(status)) ++ status = SYNC_OpenEvent(&pMsgQ->hSyncDoneAck, NULL); ++ ++ if (DSP_SUCCEEDED(status)) { ++ if (!hMsgMgr->msgFreeList) { ++ status = DSP_EHANDLE; ++ goto func_end; ++ } ++ /* Enter critical section */ ++ (void)SYNC_EnterCS(hMsgMgr->hSyncCS); ++ /* Initialize message frames and put in appropriate queues */ ++ for (i = 0; i < uMaxMsgs && DSP_SUCCEEDED(status); i++) { ++ status = AddNewMsg(hMsgMgr->msgFreeList); ++ if (DSP_SUCCEEDED(status)) { ++ uNumAllocated++; ++ status = AddNewMsg(pMsgQ->msgFreeList); ++ } ++ } ++ if (DSP_FAILED(status)) { ++ /* Stay inside CS to prevent others from taking any ++ * of the newly allocated message frames. */ ++ DeleteMsgQueue(pMsgQ, uNumAllocated); ++ } else { ++ LST_PutTail(hMsgMgr->queueList, ++ (struct LST_ELEM *)pMsgQ); ++ *phMsgQueue = pMsgQ; ++ /* Signal that free frames are now available */ ++ if (!LST_IsEmpty(hMsgMgr->msgFreeList)) ++ SYNC_SetEvent(hMsgMgr->hSyncEvent); ++ ++ } ++ /* Exit critical section */ ++ (void)SYNC_LeaveCS(hMsgMgr->hSyncCS); ++ } else { ++ DeleteMsgQueue(pMsgQ, 0); ++ } ++func_end: ++ return status; ++} ++ ++/* ++ * ======== WMD_MSG_Delete ======== ++ * Delete a MSG manager allocated in WMD_MSG_Create(). ++ */ ++void WMD_MSG_Delete(struct MSG_MGR *hMsgMgr) ++{ ++ DBC_Require(MEM_IsValidHandle(hMsgMgr, MSGMGR_SIGNATURE)); ++ ++ DeleteMsgMgr(hMsgMgr); ++} ++ ++/* ++ * ======== WMD_MSG_DeleteQueue ======== ++ * Delete a MSG queue allocated in WMD_MSG_CreateQueue. ++ */ ++void WMD_MSG_DeleteQueue(struct MSG_QUEUE *hMsgQueue) ++{ ++ struct MSG_MGR *hMsgMgr = hMsgQueue->hMsgMgr; ++ u32 refCount; ++ ++ DBC_Require(MEM_IsValidHandle(hMsgQueue, MSGQ_SIGNATURE)); ++ hMsgQueue->fDone = true; ++ /* Unblock all threads blocked in MSG_Get() or MSG_Put(). */ ++ refCount = hMsgQueue->refCount; ++ while (refCount) { ++ /* Unblock thread */ ++ SYNC_SetEvent(hMsgQueue->hSyncDone); ++ /* Wait for acknowledgement */ ++ SYNC_WaitOnEvent(hMsgQueue->hSyncDoneAck, SYNC_INFINITE); ++ refCount = hMsgQueue->refCount; ++ } ++ /* Remove message queue from hMsgMgr->queueList */ ++ (void)SYNC_EnterCS(hMsgMgr->hSyncCS); ++ LST_RemoveElem(hMsgMgr->queueList, (struct LST_ELEM *)hMsgQueue); ++ /* Free the message queue object */ ++ DeleteMsgQueue(hMsgQueue, hMsgQueue->uMaxMsgs); ++ if (!hMsgMgr->msgFreeList) ++ goto func_cont; ++ if (LST_IsEmpty(hMsgMgr->msgFreeList)) ++ SYNC_ResetEvent(hMsgMgr->hSyncEvent); ++func_cont: ++ (void)SYNC_LeaveCS(hMsgMgr->hSyncCS); ++} ++ ++/* ++ * ======== WMD_MSG_Get ======== ++ * Get a message from a MSG queue. ++ */ ++DSP_STATUS WMD_MSG_Get(struct MSG_QUEUE *hMsgQueue, ++ struct DSP_MSG *pMsg, u32 uTimeout) ++{ ++ struct MSG_FRAME *pMsgFrame; ++ struct MSG_MGR *hMsgMgr; ++ bool fGotMsg = false; ++ struct SYNC_OBJECT *hSyncs[2]; ++ u32 uIndex; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(MEM_IsValidHandle(hMsgQueue, MSGQ_SIGNATURE)); ++ DBC_Require(pMsg != NULL); ++ ++ hMsgMgr = hMsgQueue->hMsgMgr; ++ if (!hMsgQueue->msgUsedList) { ++ status = DSP_EHANDLE; ++ goto func_end; ++ } ++ ++ /* Enter critical section */ ++ (void)SYNC_EnterCS(hMsgMgr->hSyncCS); ++ /* If a message is already there, get it */ ++ if (!LST_IsEmpty(hMsgQueue->msgUsedList)) { ++ pMsgFrame = (struct MSG_FRAME *)LST_GetHead(hMsgQueue-> ++ msgUsedList); ++ if (pMsgFrame != NULL) { ++ *pMsg = pMsgFrame->msgData.msg; ++ LST_PutTail(hMsgQueue->msgFreeList, ++ (struct LST_ELEM *)pMsgFrame); ++ if (LST_IsEmpty(hMsgQueue->msgUsedList)) ++ SYNC_ResetEvent(hMsgQueue->hSyncEvent); ++ ++ fGotMsg = true; ++ } ++ } else { ++ if (hMsgQueue->fDone) ++ status = DSP_EFAIL; ++ else ++ hMsgQueue->refCount++; ++ ++ } ++ /* Exit critical section */ ++ (void)SYNC_LeaveCS(hMsgMgr->hSyncCS); ++ if (DSP_SUCCEEDED(status) && !fGotMsg) { ++ /* Wait til message is available, timeout, or done. We don't ++ * have to schedule the DPC, since the DSP will send messages ++ * when they are available. */ ++ hSyncs[0] = hMsgQueue->hSyncEvent; ++ hSyncs[1] = hMsgQueue->hSyncDone; ++ status = SYNC_WaitOnMultipleEvents(hSyncs, 2, uTimeout, ++ &uIndex); ++ /* Enter critical section */ ++ (void)SYNC_EnterCS(hMsgMgr->hSyncCS); ++ if (hMsgQueue->fDone) { ++ hMsgQueue->refCount--; ++ /* Exit critical section */ ++ (void)SYNC_LeaveCS(hMsgMgr->hSyncCS); ++ /* Signal that we're not going to access hMsgQueue ++ * anymore, so it can be deleted. */ ++ (void)SYNC_SetEvent(hMsgQueue->hSyncDoneAck); ++ status = DSP_EFAIL; ++ } else { ++ if (DSP_SUCCEEDED(status)) { ++ DBC_Assert(!LST_IsEmpty(hMsgQueue-> ++ msgUsedList)); ++ /* Get msg from used list */ ++ pMsgFrame = (struct MSG_FRAME *) ++ LST_GetHead(hMsgQueue->msgUsedList); ++ /* Copy message into pMsg and put frame on the ++ * free list */ ++ if (pMsgFrame != NULL) { ++ *pMsg = pMsgFrame->msgData.msg; ++ LST_PutTail(hMsgQueue->msgFreeList, ++ (struct LST_ELEM *)pMsgFrame); ++ } ++ } ++ hMsgQueue->refCount--; ++ /* Reset the event if there are still queued messages */ ++ if (!LST_IsEmpty(hMsgQueue->msgUsedList)) ++ SYNC_SetEvent(hMsgQueue->hSyncEvent); ++ ++ /* Exit critical section */ ++ (void)SYNC_LeaveCS(hMsgMgr->hSyncCS); ++ } ++ } ++func_end: ++ return status; ++} ++ ++/* ++ * ======== WMD_MSG_Put ======== ++ * Put a message onto a MSG queue. ++ */ ++DSP_STATUS WMD_MSG_Put(struct MSG_QUEUE *hMsgQueue, ++ IN CONST struct DSP_MSG *pMsg, u32 uTimeout) ++{ ++ struct MSG_FRAME *pMsgFrame; ++ struct MSG_MGR *hMsgMgr; ++ bool fPutMsg = false; ++ struct SYNC_OBJECT *hSyncs[2]; ++ u32 uIndex; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(MEM_IsValidHandle(hMsgQueue, MSGQ_SIGNATURE)); ++ DBC_Require(pMsg != NULL); ++ ++ hMsgMgr = hMsgQueue->hMsgMgr; ++ ++ if (!hMsgMgr->msgFreeList) { ++ status = DSP_EHANDLE; ++ goto func_end; ++ } ++ ++ ++ (void) SYNC_EnterCS(hMsgMgr->hSyncCS); ++ ++ /* If a message frame is available, use it */ ++ if (!LST_IsEmpty(hMsgMgr->msgFreeList)) { ++ pMsgFrame = (struct MSG_FRAME *)LST_GetHead(hMsgMgr-> ++ msgFreeList); ++ if (pMsgFrame != NULL) { ++ pMsgFrame->msgData.msg = *pMsg; ++ pMsgFrame->msgData.dwId = hMsgQueue->dwId; ++ LST_PutTail(hMsgMgr->msgUsedList, (struct LST_ELEM *) ++ pMsgFrame); ++ hMsgMgr->uMsgsPending++; ++ fPutMsg = true; ++ } ++ if (LST_IsEmpty(hMsgMgr->msgFreeList)) ++ SYNC_ResetEvent(hMsgMgr->hSyncEvent); ++ ++ /* Release critical section before scheduling DPC */ ++ (void)SYNC_LeaveCS(hMsgMgr->hSyncCS); ++ /* Schedule a DPC, to do the actual data transfer: */ ++ IO_Schedule(hMsgMgr->hIOMgr); ++ } else { ++ if (hMsgQueue->fDone) ++ status = DSP_EFAIL; ++ else ++ hMsgQueue->refCount++; ++ ++ (void)SYNC_LeaveCS(hMsgMgr->hSyncCS); ++ } ++ if (DSP_SUCCEEDED(status) && !fPutMsg) { ++ /* Wait til a free message frame is available, timeout, ++ * or done */ ++ hSyncs[0] = hMsgMgr->hSyncEvent; ++ hSyncs[1] = hMsgQueue->hSyncDone; ++ status = SYNC_WaitOnMultipleEvents(hSyncs, 2, uTimeout, ++ &uIndex); ++ /* Enter critical section */ ++ (void)SYNC_EnterCS(hMsgMgr->hSyncCS); ++ if (hMsgQueue->fDone) { ++ hMsgQueue->refCount--; ++ /* Exit critical section */ ++ (void)SYNC_LeaveCS(hMsgMgr->hSyncCS); ++ /* Signal that we're not going to access hMsgQueue ++ * anymore, so it can be deleted. */ ++ (void)SYNC_SetEvent(hMsgQueue->hSyncDoneAck); ++ status = DSP_EFAIL; ++ } else { ++ if (DSP_SUCCEEDED(status)) { ++ if (LST_IsEmpty(hMsgMgr->msgFreeList)) { ++ status = DSP_EPOINTER; ++ goto func_cont; ++ } ++ /* Get msg from free list */ ++ pMsgFrame = (struct MSG_FRAME *) ++ LST_GetHead(hMsgMgr->msgFreeList); ++ /* Copy message into pMsg and put frame on the ++ * used list */ ++ if (pMsgFrame != NULL) { ++ pMsgFrame->msgData.msg = *pMsg; ++ pMsgFrame->msgData.dwId = ++ hMsgQueue->dwId; ++ LST_PutTail(hMsgMgr->msgUsedList, ++ (struct LST_ELEM *) ++ pMsgFrame); ++ hMsgMgr->uMsgsPending++; ++ /* Schedule a DPC, to do the actual ++ * data transfer: */ ++ IO_Schedule(hMsgMgr->hIOMgr); ++ } ++ } ++ hMsgQueue->refCount--; ++ /* Reset event if there are still frames available */ ++ if (!LST_IsEmpty(hMsgMgr->msgFreeList)) ++ SYNC_SetEvent(hMsgMgr->hSyncEvent); ++func_cont: ++ /* Exit critical section */ ++ (void) SYNC_LeaveCS(hMsgMgr->hSyncCS); ++ } ++ } ++func_end: ++ return status; ++} ++ ++/* ++ * ======== WMD_MSG_RegisterNotify ======== ++ */ ++DSP_STATUS WMD_MSG_RegisterNotify(struct MSG_QUEUE *hMsgQueue, u32 uEventMask, ++ u32 uNotifyType, ++ struct DSP_NOTIFICATION *hNotification) ++{ ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(MEM_IsValidHandle(hMsgQueue, MSGQ_SIGNATURE)); ++ DBC_Require(hNotification != NULL); ++ DBC_Require(uEventMask == DSP_NODEMESSAGEREADY || uEventMask == 0); ++ DBC_Require(uNotifyType == DSP_SIGNALEVENT); ++ ++ status = NTFY_Register(hMsgQueue->hNtfy, hNotification, uEventMask, ++ uNotifyType); ++ ++ if (status == DSP_EVALUE) { ++ /* Not registered. Ok, since we couldn't have known. Node ++ * notifications are split between node state change handled ++ * by NODE, and message ready handled by MSG. */ ++ status = DSP_SOK; ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== WMD_MSG_SetQueueId ======== ++ */ ++void WMD_MSG_SetQueueId(struct MSG_QUEUE *hMsgQueue, u32 dwId) ++{ ++ DBC_Require(MEM_IsValidHandle(hMsgQueue, MSGQ_SIGNATURE)); ++ /* DBC_Require(dwId != 0); */ ++ ++ /* ++ * A message queue must be created when a node is allocated, ++ * so that NODE_RegisterNotify() can be called before the node ++ * is created. Since we don't know the node environment until the ++ * node is created, we need this function to set hMsgQueue->dwId ++ * to the node environment, after the node is created. ++ */ ++ hMsgQueue->dwId = dwId; ++} ++ ++/* ++ * ======== AddNewMsg ======== ++ * Must be called in message manager critical section. ++ */ ++static DSP_STATUS AddNewMsg(struct LST_LIST *msgList) ++{ ++ struct MSG_FRAME *pMsg; ++ DSP_STATUS status = DSP_SOK; ++ ++ pMsg = (struct MSG_FRAME *)MEM_Calloc(sizeof(struct MSG_FRAME), ++ MEM_PAGED); ++ if (pMsg != NULL) { ++ LST_InitElem((struct LST_ELEM *) pMsg); ++ LST_PutTail(msgList, (struct LST_ELEM *) pMsg); ++ } else { ++ status = DSP_EMEMORY; ++ } ++ ++ return status; ++} ++ ++/* ++ * ======== DeleteMsgMgr ======== ++ */ ++static void DeleteMsgMgr(struct MSG_MGR *hMsgMgr) ++{ ++ DBC_Require(MEM_IsValidHandle(hMsgMgr, MSGMGR_SIGNATURE)); ++ ++ if (hMsgMgr->queueList) { ++ if (LST_IsEmpty(hMsgMgr->queueList)) { ++ LST_Delete(hMsgMgr->queueList); ++ hMsgMgr->queueList = NULL; ++ } ++ } ++ ++ if (hMsgMgr->msgFreeList) { ++ FreeMsgList(hMsgMgr->msgFreeList); ++ hMsgMgr->msgFreeList = NULL; ++ } ++ ++ if (hMsgMgr->msgUsedList) { ++ FreeMsgList(hMsgMgr->msgUsedList); ++ hMsgMgr->msgUsedList = NULL; ++ } ++ ++ if (hMsgMgr->hSyncEvent) ++ SYNC_CloseEvent(hMsgMgr->hSyncEvent); ++ ++ if (hMsgMgr->hSyncCS) ++ SYNC_DeleteCS(hMsgMgr->hSyncCS); ++ ++ MEM_FreeObject(hMsgMgr); ++} ++ ++/* ++ * ======== DeleteMsgQueue ======== ++ */ ++static void DeleteMsgQueue(struct MSG_QUEUE *hMsgQueue, u32 uNumToDSP) ++{ ++ struct MSG_MGR *hMsgMgr; ++ struct MSG_FRAME *pMsg; ++ u32 i; ++ ++ if (!MEM_IsValidHandle(hMsgQueue, MSGQ_SIGNATURE) ++ || !hMsgQueue->hMsgMgr || !hMsgQueue->hMsgMgr->msgFreeList) ++ goto func_end; ++ hMsgMgr = hMsgQueue->hMsgMgr; ++ ++ ++ /* Pull off uNumToDSP message frames from Msg manager and free */ ++ for (i = 0; i < uNumToDSP; i++) { ++ ++ if (!LST_IsEmpty(hMsgMgr->msgFreeList)) { ++ pMsg = (struct MSG_FRAME *)LST_GetHead(hMsgMgr-> ++ msgFreeList); ++ MEM_Free(pMsg); ++ } else { ++ /* Cannot free all of the message frames */ ++ break; ++ } ++ } ++ ++ if (hMsgQueue->msgFreeList) { ++ FreeMsgList(hMsgQueue->msgFreeList); ++ hMsgQueue->msgFreeList = NULL; ++ } ++ ++ if (hMsgQueue->msgUsedList) { ++ FreeMsgList(hMsgQueue->msgUsedList); ++ hMsgQueue->msgUsedList = NULL; ++ } ++ ++ ++ if (hMsgQueue->hNtfy) ++ NTFY_Delete(hMsgQueue->hNtfy); ++ ++ if (hMsgQueue->hSyncEvent) ++ SYNC_CloseEvent(hMsgQueue->hSyncEvent); ++ ++ if (hMsgQueue->hSyncDone) ++ SYNC_CloseEvent(hMsgQueue->hSyncDone); ++ ++ if (hMsgQueue->hSyncDoneAck) ++ SYNC_CloseEvent(hMsgQueue->hSyncDoneAck); ++ ++ MEM_FreeObject(hMsgQueue); ++func_end: ++ return; ++ ++} ++ ++/* ++ * ======== FreeMsgList ======== ++ */ ++static void FreeMsgList(struct LST_LIST *msgList) ++{ ++ struct MSG_FRAME *pMsg; ++ ++ if (!msgList) ++ goto func_end; ++ ++ while ((pMsg = (struct MSG_FRAME *)LST_GetHead(msgList)) != NULL) ++ MEM_Free(pMsg); ++ ++ DBC_Assert(LST_IsEmpty(msgList)); ++ ++ LST_Delete(msgList); ++func_end: ++ return; ++} ++ +diff --git a/drivers/dsp/bridge/wmd/tiomap3430.c b/drivers/dsp/bridge/wmd/tiomap3430.c +new file mode 100644 +index 0000000..2ab585d +--- /dev/null ++++ b/drivers/dsp/bridge/wmd/tiomap3430.c +@@ -0,0 +1,2149 @@ ++/* ++ * tiomap.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== tiomap.c ======== ++ * Processor Manager Driver for TI OMAP3430 EVM. ++ * ++ * Public Function: ++ * WMD_DRV_Entry ++ * ++ *! Revision History: ++ *! ================ ++ * 26-March-2008 HK and AL: Added WMD_DEV_WalkTbl funciton. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ------------------------------------ Hardware Abstraction Layer */ ++#include ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Link Driver */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Local */ ++#include "_tiomap.h" ++#include "_tiomap_pwr.h" ++#include "_tiomap_mmu.h" ++#include "_tiomap_util.h" ++#include "tiomap_io.h" ++ ++ ++/* Offset in shared mem to write to in order to synchronize start with DSP */ ++#define SHMSYNCOFFSET 4 /* GPP byte offset */ ++ ++#define BUFFERSIZE 1024 ++ ++#define MMU_SECTION_ADDR_MASK 0xFFF00000 ++#define MMU_SSECTION_ADDR_MASK 0xFF000000 ++#define MMU_LARGE_PAGE_MASK 0xFFFF0000 ++#define MMU_SMALL_PAGE_MASK 0xFFFFF000 ++#define PAGES_II_LVL_TABLE 512 ++#define phys_to_page(phys) pfn_to_page((phys) >> PAGE_SHIFT) ++ ++#define MMU_GFLUSH 0x60 ++ ++/* Forward Declarations: */ ++static DSP_STATUS WMD_BRD_Monitor(struct WMD_DEV_CONTEXT *pDevContext); ++static DSP_STATUS WMD_BRD_Read(struct WMD_DEV_CONTEXT *pDevContext, ++ OUT u8 *pbHostBuf, ++ u32 dwDSPAddr, u32 ulNumBytes, u32 ulMemType); ++static DSP_STATUS WMD_BRD_Start(struct WMD_DEV_CONTEXT *pDevContext, ++ u32 dwDSPAddr); ++static DSP_STATUS WMD_BRD_Status(struct WMD_DEV_CONTEXT *pDevContext, ++ OUT BRD_STATUS *pdwState); ++static DSP_STATUS WMD_BRD_Stop(struct WMD_DEV_CONTEXT *pDevContext); ++static DSP_STATUS WMD_BRD_Write(struct WMD_DEV_CONTEXT *pDevContext, ++ IN u8 *pbHostBuf, ++ u32 dwDSPAddr, u32 ulNumBytes, u32 ulMemType); ++static DSP_STATUS WMD_BRD_SetState(struct WMD_DEV_CONTEXT *hDevContext, ++ u32 ulBrdState); ++static DSP_STATUS WMD_BRD_MemCopy(struct WMD_DEV_CONTEXT *hDevContext, ++ u32 ulDspDestAddr, u32 ulDspSrcAddr, ++ u32 ulNumBytes, u32 ulMemType); ++static DSP_STATUS WMD_BRD_MemWrite(struct WMD_DEV_CONTEXT *pDevContext, ++ IN u8 *pbHostBuf, u32 dwDSPAddr, ++ u32 ulNumBytes, u32 ulMemType); ++static DSP_STATUS WMD_BRD_MemMap(struct WMD_DEV_CONTEXT *hDevContext, ++ u32 ulMpuAddr, u32 ulVirtAddr, u32 ulNumBytes, ++ u32 ulMapAttr); ++static DSP_STATUS WMD_BRD_MemUnMap(struct WMD_DEV_CONTEXT *hDevContext, ++ u32 ulVirtAddr, u32 ulNumBytes); ++static DSP_STATUS WMD_DEV_Create(OUT struct WMD_DEV_CONTEXT **ppDevContext, ++ struct DEV_OBJECT *hDevObject, ++ IN CONST struct CFG_HOSTRES *pConfig, ++ IN CONST struct CFG_DSPRES *pDspConfig); ++static DSP_STATUS WMD_DEV_Ctrl(struct WMD_DEV_CONTEXT *pDevContext, u32 dwCmd, ++ IN OUT void *pArgs); ++static DSP_STATUS WMD_DEV_Destroy(struct WMD_DEV_CONTEXT *pDevContext); ++static u32 user_va2pa(struct mm_struct *mm, u32 address); ++static DSP_STATUS PteUpdate(struct WMD_DEV_CONTEXT *hDevContext, u32 pa, ++ u32 va, u32 size, ++ struct HW_MMUMapAttrs_t *mapAttrs); ++static DSP_STATUS PteSet(struct PgTableAttrs *pt, u32 pa, u32 va, ++ u32 size, struct HW_MMUMapAttrs_t *attrs); ++static DSP_STATUS MemMapVmalloc(struct WMD_DEV_CONTEXT *hDevContext, ++ u32 ulMpuAddr, u32 ulVirtAddr, ++ u32 ulNumBytes, struct HW_MMUMapAttrs_t *hwAttrs); ++static DSP_STATUS run_IdleBoot(u32 prcm_base, u32 cm_base, ++ u32 sysctrl_base); ++void GetHWRegs(u32 prcm_base, u32 cm_base); ++ ++/* ----------------------------------- Globals */ ++ ++/* Attributes of L2 page tables for DSP MMU */ ++struct PageInfo { ++ u32 numEntries; /* Number of valid PTEs in the L2 PT */ ++} ; ++ ++/* Attributes used to manage the DSP MMU page tables */ ++struct PgTableAttrs { ++ struct SYNC_CSOBJECT *hCSObj; /* Critical section object handle */ ++ ++ u32 L1BasePa; /* Physical address of the L1 PT */ ++ u32 L1BaseVa; /* Virtual address of the L1 PT */ ++ u32 L1size; /* Size of the L1 PT */ ++ u32 L1TblAllocPa; ++ /* Physical address of Allocated mem for L1 table. May not be aligned */ ++ u32 L1TblAllocVa; ++ /* Virtual address of Allocated mem for L1 table. May not be aligned */ ++ u32 L1TblAllocSz; ++ /* Size of consistent memory allocated for L1 table. ++ * May not be aligned */ ++ ++ u32 L2BasePa; /* Physical address of the L2 PT */ ++ u32 L2BaseVa; /* Virtual address of the L2 PT */ ++ u32 L2size; /* Size of the L2 PT */ ++ u32 L2TblAllocPa; ++ /* Physical address of Allocated mem for L2 table. May not be aligned */ ++ u32 L2TblAllocVa; ++ /* Virtual address of Allocated mem for L2 table. May not be aligned */ ++ u32 L2TblAllocSz; ++ /* Size of consistent memory allocated for L2 table. ++ * May not be aligned */ ++ ++ u32 L2NumPages; /* Number of allocated L2 PT */ ++ struct PageInfo *pgInfo; /* Array [L2NumPages] of L2 PT info structs */ ++} ; ++ ++/* ++ * If dsp_debug is true, do not branch to the DSP entry point and wait for DSP ++ * to boot ++ */ ++extern s32 dsp_debug; ++ ++ ++/* ++ * This mini driver's function interface table. ++ */ ++static struct WMD_DRV_INTERFACE drvInterfaceFxns = { ++ WCD_MAJOR_VERSION, /* WCD ver. for which this mini driver is built. */ ++ WCD_MINOR_VERSION, ++ WMD_DEV_Create, ++ WMD_DEV_Destroy, ++ WMD_DEV_Ctrl, ++ WMD_BRD_Monitor, ++ WMD_BRD_Start, ++ WMD_BRD_Stop, ++ WMD_BRD_Status, ++ WMD_BRD_Read, ++ WMD_BRD_Write, ++ WMD_BRD_SetState, ++ WMD_BRD_MemCopy, ++ WMD_BRD_MemWrite, ++ WMD_BRD_MemMap, ++ WMD_BRD_MemUnMap, ++ /* The following CHNL functions are provided by chnl_io.lib: */ ++ WMD_CHNL_Create, ++ WMD_CHNL_Destroy, ++ WMD_CHNL_Open, ++ WMD_CHNL_Close, ++ WMD_CHNL_AddIOReq, ++ WMD_CHNL_GetIOC, ++ WMD_CHNL_CancelIO, ++ WMD_CHNL_FlushIO, ++ WMD_CHNL_GetInfo, ++ WMD_CHNL_GetMgrInfo, ++ WMD_CHNL_Idle, ++ WMD_CHNL_RegisterNotify, ++ /* The following DEH functions are provided by tihelen_ue_deh.c */ ++ WMD_DEH_Create, ++ WMD_DEH_Destroy, ++ WMD_DEH_Notify, ++ WMD_DEH_RegisterNotify, ++ WMD_DEH_GetInfo, ++ /* The following IO functions are provided by chnl_io.lib: */ ++ WMD_IO_Create, ++ WMD_IO_Destroy, ++ WMD_IO_OnLoaded, ++ WMD_IO_GetProcLoad, ++ /* The following MSG functions are provided by chnl_io.lib: */ ++ WMD_MSG_Create, ++ WMD_MSG_CreateQueue, ++ WMD_MSG_Delete, ++ WMD_MSG_DeleteQueue, ++ WMD_MSG_Get, ++ WMD_MSG_Put, ++ WMD_MSG_RegisterNotify, ++ WMD_MSG_SetQueueId, ++}; ++ ++static inline void tlb_flush_all(const u32 base) ++{ ++ __raw_writeb(__raw_readb(base + MMU_GFLUSH) | 1, base + MMU_GFLUSH); ++} ++ ++static inline void flush_all(struct WMD_DEV_CONTEXT *pDevContext) ++{ ++ struct CFG_HOSTRES resources; ++ u32 temp = 0; ++ ++ CFG_GetHostResources((struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), &resources); ++ HW_PWRST_IVA2RegGet(resources.dwPrmBase, &temp); ++ ++ if ((temp & HW_PWR_STATE_ON) == HW_PWR_STATE_OFF || ++ (temp & HW_PWR_STATE_ON) == HW_PWR_STATE_RET) { ++ CLK_Enable(SERVICESCLK_iva2_ck); ++ WakeDSP(pDevContext, NULL); ++ tlb_flush_all(pDevContext->dwDSPMmuBase); ++ CLK_Disable(SERVICESCLK_iva2_ck); ++ } else ++ tlb_flush_all(pDevContext->dwDSPMmuBase); ++} ++ ++static void bad_page_dump(u32 pa, struct page *pg) ++{ ++ pr_emerg("DSPBRIDGE: MAP function: COUNT 0 FOR PA 0x%x\n", pa); ++ pr_emerg("Bad page state in process '%s'\n" ++ "page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n" ++ "Backtrace:\n", ++ current->comm, pg, (int)(2*sizeof(unsigned long)), ++ (unsigned long)pg->flags, pg->mapping, ++ page_mapcount(pg), page_count(pg)); ++ BUG(); ++} ++ ++/* ++ * ======== WMD_DRV_Entry ======== ++ * purpose: ++ * Mini Driver entry point. ++ */ ++void WMD_DRV_Entry(OUT struct WMD_DRV_INTERFACE **ppDrvInterface, ++ IN CONST char *pstrWMDFileName) ++{ ++ ++ DBC_Require(pstrWMDFileName != NULL); ++ DBG_Trace(DBG_ENTER, "In the WMD_DRV_Entry \n"); ++ ++ IO_SM_init(); /* Initialization of io_sm module */ ++ ++ if (strcmp(pstrWMDFileName, "UMA") == 0) ++ *ppDrvInterface = &drvInterfaceFxns; ++ else ++ DBG_Trace(DBG_LEVEL7, "WMD_DRV_Entry Unknown WMD file name"); ++ ++} ++ ++/* ++ * ======== WMD_BRD_Monitor ======== ++ * purpose: ++ * This WMD_BRD_Monitor puts DSP into a Loadable state. ++ * i.e Application can load and start the device. ++ * ++ * Preconditions: ++ * Device in 'OFF' state. ++ */ ++static DSP_STATUS WMD_BRD_Monitor(struct WMD_DEV_CONTEXT *hDevContext) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct WMD_DEV_CONTEXT *pDevContext = hDevContext; ++ struct CFG_HOSTRES resources; ++ u32 temp; ++ enum HW_PwrState_t pwrState; ++ ++ DBG_Trace(DBG_ENTER, "Board in the monitor state \n"); ++ status = CFG_GetHostResources( ++ (struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), &resources); ++ if (DSP_FAILED(status)) ++ goto error_return; ++ ++ GetHWRegs(resources.dwPrmBase, resources.dwCmBase); ++ HW_PWRST_IVA2RegGet(resources.dwPrmBase, &temp); ++ if ((temp & 0x03) != 0x03 || (temp & 0x03) != 0x02) { ++ /* IVA2 is not in ON state */ ++ /* Read and set PM_PWSTCTRL_IVA2 to ON */ ++ HW_PWR_IVA2PowerStateSet(resources.dwPrmBase, ++ HW_PWR_DOMAIN_DSP, ++ HW_PWR_STATE_ON); ++ /* Set the SW supervised state transition */ ++ HW_PWR_CLKCTRL_IVA2RegSet(resources.dwCmBase, ++ HW_SW_SUP_WAKEUP); ++ /* Wait until the state has moved to ON */ ++ HW_PWR_IVA2StateGet(resources.dwPrmBase, HW_PWR_DOMAIN_DSP, ++ &pwrState); ++ /* Disable Automatic transition */ ++ HW_PWR_CLKCTRL_IVA2RegSet(resources.dwCmBase, HW_AUTOTRANS_DIS); ++ } ++ DBG_Trace(DBG_LEVEL6, "WMD_BRD_Monitor - Middle ****** \n"); ++ GetHWRegs(resources.dwPrmBase, resources.dwCmBase); ++ status = run_IdleBoot(resources.dwPrmBase, resources.dwCmBase, ++ resources.dwSysCtrlBase); ++ if (DSP_SUCCEEDED(status)) { ++ /* set the device state to IDLE */ ++ pDevContext->dwBrdState = BRD_IDLE; ++ ++ } ++error_return: ++ DBG_Trace(DBG_LEVEL6, "WMD_BRD_Monitor - End ****** \n"); ++ GetHWRegs(resources.dwPrmBase, resources.dwCmBase); ++ return status; ++} ++ ++/* ++ * ======== WMD_BRD_Read ======== ++ * purpose: ++ * Reads buffers for DSP memory. ++ */ ++static DSP_STATUS WMD_BRD_Read(struct WMD_DEV_CONTEXT *hDevContext, ++ OUT u8 *pbHostBuf, u32 dwDSPAddr, ++ u32 ulNumBytes, u32 ulMemType) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct WMD_DEV_CONTEXT *pDevContext = hDevContext; ++ u32 offset; ++ u32 dspBaseAddr = hDevContext->dwDspBaseAddr; ++ ++ DBG_Trace(DBG_ENTER, "WMD_BRD_Read, pDevContext: 0x%x\n\t\tpbHostBuf:" ++ " 0x%x\n\t\tdwDSPAddr: 0x%x\n\t\tulNumBytes: 0x%x\n\t\t" ++ "ulMemType: 0x%x\n", pDevContext, pbHostBuf, ++ dwDSPAddr, ulNumBytes, ulMemType); ++ if (dwDSPAddr < pDevContext->dwDSPStartAdd) { ++ DBG_Trace(DBG_LEVEL7, ++ "WMD_BRD_Read: DSP address < start address \n "); ++ status = DSP_EFAIL; ++ return status; ++ } ++ /* change here to account for the 3 bands of the DSP internal memory */ ++ if ((dwDSPAddr - pDevContext->dwDSPStartAdd) < ++ pDevContext->dwInternalSize) { ++ offset = dwDSPAddr - pDevContext->dwDSPStartAdd; ++ } else { ++ DBG_Trace(DBG_LEVEL1, ++ "**** Reading From external memory **** \n "); ++ status = ReadExtDspData(pDevContext, pbHostBuf, dwDSPAddr, ++ ulNumBytes, ulMemType); ++ return status; ++ } ++ /* copy the data from DSP memory, */ ++ memcpy(pbHostBuf, (void *)(dspBaseAddr + offset), ulNumBytes); ++ return status; ++} ++ ++/* ++ * ======== WMD_BRD_SetState ======== ++ * purpose: ++ * This routine updates the Board status. ++ */ ++static DSP_STATUS WMD_BRD_SetState(struct WMD_DEV_CONTEXT *hDevContext, ++ u32 ulBrdState) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct WMD_DEV_CONTEXT *pDevContext = hDevContext; ++ ++ DBG_Trace(DBG_ENTER, "WMD_BRD_SetState: Board State: 0x%x \n", ++ ulBrdState); ++ pDevContext->dwBrdState = ulBrdState; ++ return status; ++} ++ ++/* ++ * ======== WMD_BRD_Start ======== ++ * purpose: ++ * Initializes DSP MMU and Starts DSP. ++ * ++ * Preconditions: ++ * a) DSP domain is 'ACTIVE'. ++ * b) DSP_RST1 is asserted. ++ * b) DSP_RST2 is released. ++ */ ++static DSP_STATUS WMD_BRD_Start(struct WMD_DEV_CONTEXT *hDevContext, ++ u32 dwDSPAddr) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct WMD_DEV_CONTEXT *pDevContext = hDevContext; ++ u32 dwSyncAddr = 0; ++ u32 ulShmBase; /* Gpp Phys SM base addr(byte) */ ++ u32 ulShmBaseVirt; /* Dsp Virt SM base addr */ ++ u32 ulTLBBaseVirt; /* Base of MMU TLB entry */ ++ u32 ulShmOffsetVirt; /* offset of ulShmBaseVirt from ulTLBBaseVirt */ ++ s32 iEntryNdx; ++ s32 itmpEntryNdx = 0; /* DSP-MMU TLB entry base address */ ++ struct CFG_HOSTRES resources; ++ u32 temp; ++ u32 ulDspClkRate; ++ u32 ulDspClkAddr; ++ u32 ulBiosGpTimer; ++ u32 uClkCmd; ++ struct IO_MGR *hIOMgr; ++ u32 ulLoadMonitorTimer; ++ u32 extClkId = 0; ++ u32 tmpIndex; ++ u32 clkIdIndex = MBX_PM_MAX_RESOURCES; ++ ++ DBG_Trace(DBG_ENTER, "Entering WMD_BRD_Start:\n hDevContext: 0x%x\n\t " ++ "dwDSPAddr: 0x%x\n", hDevContext, dwDSPAddr); ++ ++ /* The device context contains all the mmu setup info from when the ++ * last dsp base image was loaded. The first entry is always ++ * SHMMEM base. */ ++ /* Get SHM_BEG - convert to byte address */ ++ (void) DEV_GetSymbol(pDevContext->hDevObject, SHMBASENAME, ++ &ulShmBaseVirt); ++ ulShmBaseVirt *= DSPWORDSIZE; ++ DBC_Assert(ulShmBaseVirt != 0); ++ /* DSP Virtual address */ ++ ulTLBBaseVirt = pDevContext->aTLBEntry[0].ulDspVa; ++ DBC_Assert(ulTLBBaseVirt <= ulShmBaseVirt); ++ ulShmOffsetVirt = ulShmBaseVirt - (ulTLBBaseVirt * DSPWORDSIZE); ++ /* Kernel logical address */ ++ ulShmBase = pDevContext->aTLBEntry[0].ulGppVa + ulShmOffsetVirt; ++ ++ DBC_Assert(ulShmBase != 0); ++ /* 2nd wd is used as sync field */ ++ dwSyncAddr = ulShmBase + SHMSYNCOFFSET; ++ /* Write a signature into the SHM base + offset; this will ++ * get cleared when the DSP program starts. */ ++ if ((ulShmBaseVirt == 0) || (ulShmBase == 0)) { ++ DBG_Trace(DBG_LEVEL6, "WMD_BRD_Start: Illegal SM base\n"); ++ status = DSP_EFAIL; ++ } else ++ *((volatile u32 *)dwSyncAddr) = 0xffffffff; ++ ++ if (DSP_SUCCEEDED(status)) { ++ status = CFG_GetHostResources( ++ (struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), ++ &resources); ++ /* Assert RST1 i.e only the RST only for DSP megacell */ ++ /* HW_RST_Reset(resources.dwPrcmBase, HW_RST1_IVA2);*/ ++ if (DSP_SUCCEEDED(status)) { ++ HW_RST_Reset(resources.dwPrmBase, HW_RST1_IVA2); ++ if (dsp_debug) { ++ /* Set the bootmode to self loop */ ++ DBG_Trace(DBG_LEVEL7, ++ "Set boot mode to self loop" ++ " for IVA2 Device\n"); ++ HW_DSPSS_BootModeSet(resources.dwSysCtrlBase, ++ HW_DSPSYSC_SELFLOOPBOOT, dwDSPAddr); ++ } else { ++ /* Set the bootmode to '0' - direct boot */ ++ DBG_Trace(DBG_LEVEL7, ++ "Set boot mode to direct" ++ " boot for IVA2 Device \n"); ++ HW_DSPSS_BootModeSet(resources.dwSysCtrlBase, ++ HW_DSPSYSC_DIRECTBOOT, dwDSPAddr); ++ } ++ } ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Reset and Unreset the RST2, so that BOOTADDR is copied to ++ * IVA2 SYSC register */ ++ HW_RST_Reset(resources.dwPrmBase, HW_RST2_IVA2); ++ udelay(100); ++ HW_RST_UnReset(resources.dwPrmBase, HW_RST2_IVA2); ++ udelay(100); ++ DBG_Trace(DBG_LEVEL6, "WMD_BRD_Start 0 ****** \n"); ++ GetHWRegs(resources.dwPrmBase, resources.dwCmBase); ++ /* Disbale the DSP MMU */ ++ HW_MMU_Disable(resources.dwDmmuBase); ++ /* Disable TWL */ ++ HW_MMU_TWLDisable(resources.dwDmmuBase); ++ ++ /* Only make TLB entry if both addresses are non-zero */ ++ for (iEntryNdx = 0; iEntryNdx < WMDIOCTL_NUMOFMMUTLB; ++ iEntryNdx++) { ++ if ((pDevContext->aTLBEntry[iEntryNdx].ulGppPa != 0) && ++ (pDevContext->aTLBEntry[iEntryNdx].ulDspVa != 0)) { ++ DBG_Trace(DBG_LEVEL4, "** (proc) MMU %d GppPa:" ++ " 0x%x DspVa 0x%x Size 0x%x\n", ++ itmpEntryNdx, ++ pDevContext->aTLBEntry[iEntryNdx].ulGppPa, ++ pDevContext->aTLBEntry[iEntryNdx].ulDspVa, ++ pDevContext->aTLBEntry[iEntryNdx].ulSize); ++ configureDspMmu(pDevContext, ++ pDevContext->aTLBEntry[iEntryNdx].ulGppPa, ++ pDevContext->aTLBEntry[iEntryNdx].ulDspVa * ++ DSPWORDSIZE, ++ pDevContext->aTLBEntry[iEntryNdx].ulSize, ++ itmpEntryNdx, ++ pDevContext->aTLBEntry[iEntryNdx].endianism, ++ pDevContext->aTLBEntry[iEntryNdx].elemSize, ++ pDevContext->aTLBEntry[iEntryNdx]. ++ mixedMode); ++ itmpEntryNdx++; ++ } ++ } /* end for */ ++ } ++ ++ /* Lock the above TLB entries and get the BIOS and load monitor timer ++ * information*/ ++ if (DSP_SUCCEEDED(status)) { ++ HW_MMU_NumLockedSet(resources.dwDmmuBase, itmpEntryNdx); ++ HW_MMU_VictimNumSet(resources.dwDmmuBase, itmpEntryNdx); ++ HW_MMU_TTBSet(resources.dwDmmuBase, ++ pDevContext->pPtAttrs->L1BasePa); ++ HW_MMU_TWLEnable(resources.dwDmmuBase); ++ /* Enable the SmartIdle and AutoIdle bit for MMU_SYSCONFIG */ ++ ++ temp = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwDmmuBase) + 0x10)); ++ temp = (temp & 0xFFFFFFEF) | 0x11; ++ *((REG_UWORD32 *) ((u32) (resources.dwDmmuBase) + 0x10)) = ++ (u32) temp; ++ ++ /* Let the DSP MMU run */ ++ HW_MMU_Enable(resources.dwDmmuBase); ++ ++ /* Enable the BIOS clock */ ++ (void)DEV_GetSymbol(pDevContext->hDevObject, ++ BRIDGEINIT_BIOSGPTIMER, ++ &ulBiosGpTimer); ++ DBG_Trace(DBG_LEVEL7, "BIOS GPTimer : 0x%x\n", ulBiosGpTimer); ++ (void)DEV_GetSymbol(pDevContext->hDevObject, ++ BRIDGEINIT_LOADMON_GPTIMER, ++ &ulLoadMonitorTimer); ++ DBG_Trace(DBG_LEVEL7, "Load Monitor Timer : 0x%x\n", ++ ulLoadMonitorTimer); ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ if (ulLoadMonitorTimer != 0xFFFF) { ++ uClkCmd = (BPWR_DisableClock << MBX_PM_CLK_CMDSHIFT) | ++ ulLoadMonitorTimer; ++ DBG_Trace(DBG_LEVEL7, ++ "encoded LoadMonitor cmd for Disable: 0x%x\n", ++ uClkCmd); ++ DSPPeripheralClkCtrl(pDevContext, &uClkCmd); ++ ++ extClkId = uClkCmd & MBX_PM_CLK_IDMASK; ++ for (tmpIndex = 0; tmpIndex < MBX_PM_MAX_RESOURCES; ++ tmpIndex++) { ++ if (extClkId == BPWR_CLKID[tmpIndex]) { ++ clkIdIndex = tmpIndex; ++ break; ++ } ++ } ++ ++ if (clkIdIndex < MBX_PM_MAX_RESOURCES) ++ status = CLK_Set_32KHz( ++ BPWR_Clks[clkIdIndex].funClk); ++ else ++ status = DSP_EFAIL; ++ ++ if (DSP_FAILED(status)) { ++ DBG_Trace(DBG_LEVEL7, " Error while setting" ++ "LM Timer to 32KHz\n"); ++ } ++ uClkCmd = (BPWR_EnableClock << MBX_PM_CLK_CMDSHIFT) | ++ ulLoadMonitorTimer; ++ DBG_Trace(DBG_LEVEL7, ++ "encoded LoadMonitor cmd for Enable : 0x%x\n", ++ uClkCmd); ++ DSPPeripheralClkCtrl(pDevContext, &uClkCmd); ++ ++ } else { ++ DBG_Trace(DBG_LEVEL7, ++ "Not able to get the symbol for Load " ++ "Monitor Timer\n"); ++ } ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ if (ulBiosGpTimer != 0xFFFF) { ++ uClkCmd = (BPWR_DisableClock << MBX_PM_CLK_CMDSHIFT) | ++ ulBiosGpTimer; ++ DBG_Trace(DBG_LEVEL7, "encoded BIOS GPTimer cmd for" ++ "Disable: 0x%x\n", uClkCmd); ++ DSPPeripheralClkCtrl(pDevContext, &uClkCmd); ++ ++ extClkId = uClkCmd & MBX_PM_CLK_IDMASK; ++ ++ for (tmpIndex = 0; tmpIndex < MBX_PM_MAX_RESOURCES; ++ tmpIndex++) { ++ if (extClkId == BPWR_CLKID[tmpIndex]) { ++ clkIdIndex = tmpIndex; ++ break; ++ } ++ } ++ ++ if (clkIdIndex < MBX_PM_MAX_RESOURCES) ++ status = CLK_Set_32KHz( ++ BPWR_Clks[clkIdIndex].funClk); ++ else ++ status = DSP_EFAIL; ++ ++ if (DSP_FAILED(status)) { ++ DBG_Trace(DBG_LEVEL7, ++ " Error while setting BIOS Timer to 32KHz\n"); ++ } ++ ++ uClkCmd = (BPWR_EnableClock << MBX_PM_CLK_CMDSHIFT) | ++ ulBiosGpTimer; ++ DBG_Trace(DBG_LEVEL7, "encoded BIOS GPTimer cmd :" ++ "0x%x\n", uClkCmd); ++ DSPPeripheralClkCtrl(pDevContext, &uClkCmd); ++ ++ } else { ++ DBG_Trace(DBG_LEVEL7, ++ "Not able to get the symbol for BIOS Timer\n"); ++ } ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* Set the DSP clock rate */ ++ (void)DEV_GetSymbol(pDevContext->hDevObject, ++ "_BRIDGEINIT_DSP_FREQ", &ulDspClkAddr); ++ /*Set Autoidle Mode for IVA2 PLL */ ++ temp = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwCmBase) + 0x34)); ++ temp = (temp & 0xFFFFFFFE) | 0x1; ++ *((REG_UWORD32 *) ((u32) (resources.dwCmBase) + 0x34)) = ++ (u32) temp; ++ DBG_Trace(DBG_LEVEL5, "WMD_BRD_Start: _BRIDGE_DSP_FREQ Addr:" ++ "0x%x \n", ulDspClkAddr); ++ if ((unsigned int *)ulDspClkAddr != NULL) { ++ /* Get the clock rate */ ++ status = CLK_GetRate(SERVICESCLK_iva2_ck, ++ &ulDspClkRate); ++ DBG_Trace(DBG_LEVEL5, ++ "WMD_BRD_Start: DSP clock rate (KHZ): 0x%x \n", ++ ulDspClkRate); ++ (void)WMD_BRD_Write(pDevContext, (u8 *)&ulDspClkRate, ++ ulDspClkAddr, sizeof(u32), 0); ++ } ++/*PM_IVA2GRPSEL_PER = 0xC0;*/ ++ temp = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwPerPmBase) + 0xA8)); ++ temp = (temp & 0xFFFFFF30) | 0xC0; ++ *((REG_UWORD32 *) ((u32) (resources.dwPerPmBase) + 0xA8)) = ++ (u32) temp; ++ ++/*PM_MPUGRPSEL_PER &= 0xFFFFFF3F;*/ ++ temp = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwPerPmBase) + 0xA4)); ++ temp = (temp & 0xFFFFFF3F); ++ *((REG_UWORD32 *) ((u32) (resources.dwPerPmBase) + 0xA4)) = ++ (u32) temp; ++/*CM_SLEEPDEP_PER |= 0x04;*/ ++ temp = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwPerBase) + 0x44)); ++ temp = (temp & 0xFFFFFFFB) | 0x04; ++ *((REG_UWORD32 *) ((u32) (resources.dwPerBase) + 0x44)) = ++ (u32) temp; ++ ++/*CM_CLKSTCTRL_IVA2 = 0x00000003 -To Allow automatic transitions*/ ++ temp = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwCmBase) + 0x48)); ++ temp = (temp & 0xFFFFFFFC) | 0x03; ++ *((REG_UWORD32 *) ((u32) (resources.dwCmBase) + 0x48)) = ++ (u32) temp; ++ ++ ++ /* Enable Mailbox events and also drain any pending ++ * stale messages */ ++ (void)CHNLSM_EnableInterrupt(pDevContext); ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ HW_RSTCTRL_RegGet(resources.dwPrmBase, HW_RST1_IVA2, &temp); ++ DBG_Trace(DBG_LEVEL7, "BRD_Start: RM_RSTCTRL_DSP = 0x%x \n", ++ temp); ++ HW_RSTST_RegGet(resources.dwPrmBase, HW_RST1_IVA2, &temp); ++ DBG_Trace(DBG_LEVEL7, "BRD_Start0: RM_RSTST_DSP = 0x%x \n", ++ temp); ++ ++ /* Let DSP go */ ++ DBG_Trace(DBG_LEVEL7, "Unreset, WMD_BRD_Start\n"); ++ /* Enable DSP MMU Interrupts */ ++ HW_MMU_EventEnable(resources.dwDmmuBase, ++ HW_MMU_ALL_INTERRUPTS); ++ /* release the RST1, DSP starts executing now .. */ ++ HW_RST_UnReset(resources.dwPrmBase, HW_RST1_IVA2); ++ ++ HW_RSTST_RegGet(resources.dwPrmBase, HW_RST1_IVA2, &temp); ++ DBG_Trace(DBG_LEVEL7, "BRD_Start: RM_RSTST_DSP = 0x%x \n", ++ temp); ++ HW_RSTCTRL_RegGet(resources.dwPrmBase, HW_RST1_IVA2, &temp); ++ DBG_Trace(DBG_LEVEL5, "WMD_BRD_Start: CM_RSTCTRL_DSP: 0x%x \n", ++ temp); ++ DBG_Trace(DBG_LEVEL7, "Driver waiting for Sync @ 0x%x \n", ++ dwSyncAddr); ++ DBG_Trace(DBG_LEVEL7, "DSP c_int00 Address = 0x%x \n", ++ dwDSPAddr); ++ if (dsp_debug) ++ while (*((volatile u16 *)dwSyncAddr)) ++ ;; ++ } ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* Wait for DSP to clear word in shared memory */ ++ /* Read the Location */ ++ if (!WaitForStart(pDevContext, dwSyncAddr)) { ++ status = WMD_E_TIMEOUT; ++ DBG_Trace(DBG_LEVEL7, ++ "WMD_BRD_Start Failed to Synchronize\n"); ++ } ++ status = DEV_GetIOMgr(pDevContext->hDevObject, &hIOMgr); ++ if (DSP_SUCCEEDED(status)) { ++ IO_SHMsetting(hIOMgr, SHM_OPPINFO, NULL); ++ DBG_Trace(DBG_LEVEL7, ++ "WMD_BRD_Start: OPP information initialzed\n"); ++ /* Write the synchronization bit to indicate the ++ * completion of OPP table update to DSP ++ */ ++ *((volatile u32 *)dwSyncAddr) = 0XCAFECAFE; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* update board state */ ++ pDevContext->dwBrdState = BRD_RUNNING; ++ /* (void)CHNLSM_EnableInterrupt(pDevContext);*/ ++ DBG_Trace(DBG_LEVEL7, "Device Started \n "); ++ } else { ++ pDevContext->dwBrdState = BRD_UNKNOWN; ++ DBG_Trace(DBG_LEVEL7, "Device not Started \n "); ++ } ++ } ++ return status; ++} ++ ++/* ++ * ======== WMD_BRD_Stop ======== ++ * purpose: ++ * Puts DSP in self loop. ++ * ++ * Preconditions : ++ * a) None ++ */ ++static DSP_STATUS WMD_BRD_Stop(struct WMD_DEV_CONTEXT *hDevContext) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct WMD_DEV_CONTEXT *pDevContext = hDevContext; ++ struct CFG_HOSTRES resources; ++ struct PgTableAttrs *pPtAttrs; ++ u32 dspPwrState; ++ DSP_STATUS clk_status; ++ ++ DBG_Trace(DBG_ENTER, "Entering WMD_BRD_Stop:\nhDevContext: 0x%x\n", ++ hDevContext); ++ ++ /* Disable the mail box interrupts */ ++ (void)CHNLSM_DisableInterrupt(pDevContext); ++ ++ if (pDevContext->dwBrdState == BRD_STOPPED) ++ return status; ++ ++ /* as per TRM, it is advised to first drive the IVA2 to 'Standby' mode, ++ * before turning off the clocks.. This is to ensure that there are no ++ * pending L3 or other transactons from IVA2 */ ++ status = CFG_GetHostResources( ++ (struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), ++ &resources); ++ if (DSP_FAILED(status)) { ++ DBG_Trace(DBG_LEVEL7, ++ "WMD_BRD_Stop: Get Host resources failed \n"); ++ DBG_Trace(DBG_LEVEL1, "Device Stopp failed \n "); ++ return DSP_EFAIL; ++ } ++ ++ HW_PWRST_IVA2RegGet(resources.dwPrmBase, &dspPwrState); ++ if (dspPwrState != HW_PWR_STATE_OFF) { ++ ++ CHNLSM_InterruptDSP2(pDevContext, MBX_PM_DSPIDLE); ++ ++ mdelay(10); ++ ++ GetHWRegs(resources.dwPrmBase, resources.dwCmBase); ++ ++ run_IdleBoot(resources.dwPrmBase, resources.dwCmBase, ++ resources.dwSysCtrlBase); ++ ++ udelay(50); ++ ++ clk_status = CLK_Disable(SERVICESCLK_iva2_ck); ++ if (DSP_FAILED(clk_status)) { ++ DBG_Trace(DBG_LEVEL6, ++ "\n WMD_BRD_Stop: CLK_Disable failed " ++ "for iva2_fck\n"); ++ } ++ /* IVA2 is not in OFF state */ ++ /* Set PM_PWSTCTRL_IVA2 to OFF */ ++ HW_PWR_IVA2PowerStateSet(resources.dwPrmBase, ++ HW_PWR_DOMAIN_DSP, ++ HW_PWR_STATE_OFF); ++ /* Set the SW supervised state transition for Sleep */ ++ HW_PWR_CLKCTRL_IVA2RegSet(resources.dwCmBase, ++ HW_SW_SUP_SLEEP); ++ } else { ++ clk_status = CLK_Disable(SERVICESCLK_iva2_ck); ++ if (DSP_FAILED(clk_status)) { ++ DBG_Trace(DBG_LEVEL6, ++ "\n WMD_BRD_Stop: Else loop CLK_Disable failed" ++ " for iva2_fck\n"); ++ } ++ } ++ udelay(10); ++ /* Release the Ext Base virtual Address as the next DSP Program ++ * may have a different load address */ ++ if (pDevContext->dwDspExtBaseAddr) ++ pDevContext->dwDspExtBaseAddr = 0; ++ ++ pDevContext->dwBrdState = BRD_STOPPED; /* update board state */ ++ DBG_Trace(DBG_LEVEL1, "Device Stopped \n "); ++ /* This is a good place to clear the MMU page tables as well */ ++ if (pDevContext->pPtAttrs) { ++ pPtAttrs = pDevContext->pPtAttrs; ++ memset((u8 *) pPtAttrs->L1BaseVa, 0x00, pPtAttrs->L1size); ++ memset((u8 *) pPtAttrs->L2BaseVa, 0x00, pPtAttrs->L2size); ++ memset((u8 *) pPtAttrs->pgInfo, 0x00, ++ (pPtAttrs->L2NumPages * sizeof(struct PageInfo))); ++ } ++ ++ DBG_Trace(DBG_LEVEL6, "WMD_BRD_Stop - End ****** \n"); ++ ++ return status; ++} ++ ++ ++/* ++ * ======== WMD_BRD_Delete ======== ++ * purpose: ++ * Puts DSP in Low power mode ++ * ++ * Preconditions : ++ * a) None ++ */ ++static DSP_STATUS WMD_BRD_Delete(struct WMD_DEV_CONTEXT *hDevContext) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct WMD_DEV_CONTEXT *pDevContext = hDevContext; ++ struct CFG_HOSTRES resources; ++ struct PgTableAttrs *pPtAttrs; ++ DSP_STATUS clk_status; ++ ++ DBG_Trace(DBG_ENTER, "Entering WMD_BRD_Delete:\nhDevContext: 0x%x\n", ++ hDevContext); ++ ++ /* Disable the mail box interrupts */ ++ (void) CHNLSM_DisableInterrupt(pDevContext); ++ ++ if (pDevContext->dwBrdState == BRD_STOPPED) ++ return status; ++ ++ /* as per TRM, it is advised to first drive ++ * the IVA2 to 'Standby' mode, before turning off the clocks.. This is ++ * to ensure that there are no pending L3 or other transactons from ++ * IVA2 */ ++ status = CFG_GetHostResources( ++ (struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), &resources); ++ if (DSP_FAILED(status)) { ++ DBG_Trace(DBG_LEVEL7, ++ "WMD_BRD_Stop: Get Host resources failed \n"); ++ DBG_Trace(DBG_LEVEL1, "Device Delete failed \n "); ++ return DSP_EFAIL; ++ } ++ status = SleepDSP(pDevContext, PWR_EMERGENCYDEEPSLEEP, NULL); ++ clk_status = CLK_Disable(SERVICESCLK_iva2_ck); ++ if (DSP_FAILED(clk_status)) { ++ DBG_Trace(DBG_LEVEL6, "\n WMD_BRD_Stop: CLK_Disable failed for" ++ " iva2_fck\n"); ++ } ++ /* Release the Ext Base virtual Address as the next DSP Program ++ * may have a different load address */ ++ if (pDevContext->dwDspExtBaseAddr) ++ pDevContext->dwDspExtBaseAddr = 0; ++ ++ pDevContext->dwBrdState = BRD_STOPPED; /* update board state */ ++ DBG_Trace(DBG_LEVEL1, "Device Stopped \n "); ++ /* This is a good place to clear the MMU page tables as well */ ++ if (pDevContext->pPtAttrs) { ++ pPtAttrs = pDevContext->pPtAttrs; ++ memset((u8 *)pPtAttrs->L1BaseVa, 0x00, pPtAttrs->L1size); ++ memset((u8 *)pPtAttrs->L2BaseVa, 0x00, pPtAttrs->L2size); ++ memset((u8 *)pPtAttrs->pgInfo, 0x00, ++ (pPtAttrs->L2NumPages * sizeof(struct PageInfo))); ++ } ++ DBG_Trace(DBG_LEVEL6, "WMD_BRD_Stop - End ****** \n"); ++ return status; ++} ++ ++ ++/* ++ * ======== WMD_BRD_Status ======== ++ * Returns the board status. ++ */ ++static DSP_STATUS WMD_BRD_Status(struct WMD_DEV_CONTEXT *hDevContext, ++ OUT BRD_STATUS *pdwState) ++{ ++ struct WMD_DEV_CONTEXT *pDevContext = hDevContext; ++ *pdwState = pDevContext->dwBrdState; ++ return DSP_SOK; ++} ++ ++/* ++ * ======== WMD_BRD_Write ======== ++ * Copies the buffers to DSP internal or external memory. ++ */ ++static DSP_STATUS WMD_BRD_Write(struct WMD_DEV_CONTEXT *hDevContext, ++ IN u8 *pbHostBuf, u32 dwDSPAddr, ++ u32 ulNumBytes, u32 ulMemType) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct WMD_DEV_CONTEXT *pDevContext = hDevContext; ++ ++ DBG_Trace(DBG_ENTER, "WMD_BRD_Write, pDevContext: 0x%x\n\t\t " ++ "pbHostBuf: 0x%x\n\t\tdwDSPAddr: 0x%x\n\t\tulNumBytes: " ++ "0x%x\n \t\t ulMemtype: 0x%x\n", pDevContext, pbHostBuf, ++ dwDSPAddr, ulNumBytes, ulMemType); ++ if (dwDSPAddr < pDevContext->dwDSPStartAdd) { ++ DBG_Trace(DBG_LEVEL7, ++ "WMD_BRD_Write: DSP address < start address \n "); ++ status = DSP_EFAIL; ++ return status; ++ } ++ if ((dwDSPAddr - pDevContext->dwDSPStartAdd) < ++ pDevContext->dwInternalSize) { ++ status = WriteDspData(hDevContext, pbHostBuf, dwDSPAddr, ++ ulNumBytes, ulMemType); ++ } else { ++ status = WriteExtDspData(pDevContext, pbHostBuf, dwDSPAddr, ++ ulNumBytes, ulMemType, false); ++ } ++ ++ DBG_Trace(DBG_ENTER, "WMD_BRD_Write, memcopy : DspLogicAddr=0x%x \n", ++ pDevContext->dwDspBaseAddr); ++ return status; ++} ++ ++/* ++ * ======== WMD_DEV_Create ======== ++ * Creates a driver object. Puts DSP in self loop. ++ */ ++static DSP_STATUS WMD_DEV_Create(OUT struct WMD_DEV_CONTEXT **ppDevContext, ++ struct DEV_OBJECT *hDevObject, ++ IN CONST struct CFG_HOSTRES *pConfig, ++ IN CONST struct CFG_DSPRES *pDspConfig) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct WMD_DEV_CONTEXT *pDevContext = NULL; ++ s32 iEntryNdx; ++ s32 tcWordSwap; ++ u32 tcWordSwapSize = sizeof(tcWordSwap); ++ struct CFG_HOSTRES resources; ++ struct PgTableAttrs *pPtAttrs; ++ u32 pg_tbl_pa; ++ u32 pg_tbl_va; ++ u32 align_size; ++ ++ DBG_Trace(DBG_ENTER, "WMD_DEV_Create, ppDevContext: 0x%x\n\t\t " ++ "hDevObject: 0x%x\n\t\tpConfig: 0x%x\n\t\tpDspConfig: 0x%x\n", ++ ppDevContext, hDevObject, pConfig, pDspConfig); ++ /* Allocate and initialize a data structure to contain the mini driver ++ * state, which becomes the context for later calls into this WMD. */ ++ pDevContext = MEM_Calloc(sizeof(struct WMD_DEV_CONTEXT), MEM_NONPAGED); ++ if (!pDevContext) { ++ DBG_Trace(DBG_ENTER, "Failed to allocate mem \n"); ++ status = DSP_EMEMORY; ++ goto func_end; ++ } ++ status = CFG_GetHostResources( ++ (struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), &resources); ++ if (DSP_FAILED(status)) { ++ DBG_Trace(DBG_ENTER, "Failed to get host resources \n"); ++ status = DSP_EMEMORY; ++ goto func_end; ++ } ++ ++ pDevContext->dwDSPStartAdd = (u32)OMAP_GEM_BASE; ++ pDevContext->dwSelfLoop = (u32)NULL; ++ pDevContext->uDspPerClks = 0; ++ pDevContext->dwInternalSize = OMAP_DSP_SIZE; ++ /* Clear dev context MMU table entries. ++ * These get set on WMD_BRD_IOCTL() call after program loaded. */ ++ for (iEntryNdx = 0; iEntryNdx < WMDIOCTL_NUMOFMMUTLB; iEntryNdx++) { ++ pDevContext->aTLBEntry[iEntryNdx].ulGppPa = ++ pDevContext->aTLBEntry[iEntryNdx].ulDspVa = 0; ++ } ++ pDevContext->numTLBEntries = 0; ++ pDevContext->dwDspBaseAddr = (u32)MEM_LinearAddress((void *) ++ (pConfig->dwMemBase[3]), pConfig->dwMemLength[3]); ++ if (!pDevContext->dwDspBaseAddr) { ++ status = DSP_EFAIL; ++ DBG_Trace(DBG_LEVEL7, ++ "WMD_DEV_Create: failed to Map the API memory\n"); ++ } ++ pPtAttrs = MEM_Calloc(sizeof(struct PgTableAttrs), MEM_NONPAGED); ++ if (pPtAttrs != NULL) { ++ /* Assuming that we use only DSP's memory map ++ * until 0x4000:0000 , we would need only 1024 ++ * L1 enties i.e L1 size = 4K */ ++ pPtAttrs->L1size = 0x1000; ++ align_size = pPtAttrs->L1size; ++ /* Align sizes are expected to be power of 2 */ ++ /* we like to get aligned on L1 table size */ ++ pg_tbl_va = (u32)MEM_AllocPhysMem(pPtAttrs->L1size, ++ align_size, &pg_tbl_pa); ++ /* Check if the PA is aligned for us */ ++ if ((pg_tbl_pa) & (align_size-1)) { ++ /* PA not aligned to page table size , ++ * try with more allocation and align */ ++ MEM_FreePhysMem((void *)pg_tbl_va, pg_tbl_pa, pPtAttrs->L1size); ++ /* we like to get aligned on L1 table size */ ++ pg_tbl_va = (u32) MEM_AllocPhysMem((pPtAttrs->L1size)*2, ++ align_size, &pg_tbl_pa); ++ /* We should be able to get aligned table now */ ++ pPtAttrs->L1TblAllocPa = pg_tbl_pa; ++ pPtAttrs->L1TblAllocVa = pg_tbl_va; ++ pPtAttrs->L1TblAllocSz = pPtAttrs->L1size * 2; ++ /* Align the PA to the next 'align' boundary */ ++ pPtAttrs->L1BasePa = ((pg_tbl_pa) + (align_size-1)) & ++ (~(align_size-1)); ++ pPtAttrs->L1BaseVa = pg_tbl_va + (pPtAttrs->L1BasePa - ++ pg_tbl_pa); ++ } else { ++ /* We got aligned PA, cool */ ++ pPtAttrs->L1TblAllocPa = pg_tbl_pa; ++ pPtAttrs->L1TblAllocVa = pg_tbl_va; ++ pPtAttrs->L1TblAllocSz = pPtAttrs->L1size; ++ pPtAttrs->L1BasePa = pg_tbl_pa; ++ pPtAttrs->L1BaseVa = pg_tbl_va; ++ } ++ if (pPtAttrs->L1BaseVa) ++ memset((u8 *)pPtAttrs->L1BaseVa, 0x00, pPtAttrs->L1size); ++ ++ /* number of L2 page tables = DMM pool used + SHMMEM +EXTMEM + ++ * L4 pages */ ++ pPtAttrs->L2NumPages = ((DMMPOOLSIZE >> 20) + 6); ++ pPtAttrs->L2size = HW_MMU_COARSE_PAGE_SIZE * ++ pPtAttrs->L2NumPages; ++ align_size = 4; /* Make it u32 aligned */ ++ /* we like to get aligned on L1 table size */ ++ pg_tbl_va = (u32)MEM_AllocPhysMem(pPtAttrs->L2size, ++ align_size, &pg_tbl_pa); ++ pPtAttrs->L2TblAllocPa = pg_tbl_pa; ++ pPtAttrs->L2TblAllocVa = pg_tbl_va; ++ pPtAttrs->L2TblAllocSz = pPtAttrs->L2size; ++ pPtAttrs->L2BasePa = pg_tbl_pa; ++ pPtAttrs->L2BaseVa = pg_tbl_va; ++ ++ if (pPtAttrs->L2BaseVa) ++ memset((u8 *)pPtAttrs->L2BaseVa, 0x00, pPtAttrs->L2size); ++ ++ pPtAttrs->pgInfo = MEM_Calloc(pPtAttrs->L2NumPages * ++ sizeof(struct PageInfo), MEM_NONPAGED); ++ DBG_Trace(DBG_LEVEL1, "L1 pa %x, va %x, size %x\n L2 pa %x, va " ++ "%x, size %x\n", pPtAttrs->L1BasePa, ++ pPtAttrs->L1BaseVa, pPtAttrs->L1size, ++ pPtAttrs->L2BasePa, pPtAttrs->L2BaseVa, ++ pPtAttrs->L2size); ++ DBG_Trace(DBG_LEVEL1, "pPtAttrs %x L2 NumPages %x pgInfo %x\n", ++ pPtAttrs, pPtAttrs->L2NumPages, pPtAttrs->pgInfo); ++ } ++ if ((pPtAttrs != NULL) && (pPtAttrs->L1BaseVa != 0) && ++ (pPtAttrs->L2BaseVa != 0) && (pPtAttrs->pgInfo != NULL)) ++ pDevContext->pPtAttrs = pPtAttrs; ++ else ++ status = DSP_EMEMORY; ++ ++ if (DSP_SUCCEEDED(status)) ++ status = SYNC_InitializeCS(&pPtAttrs->hCSObj); ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* Set the Endianism Register */ /* Need to set this */ ++ /* Retrieve the TC u16 SWAP Option */ ++ status = REG_GetValue(NULL, CURRENTCONFIG, TCWORDSWAP, ++ (u8 *)&tcWordSwap, &tcWordSwapSize); ++ /* Save the value */ ++ pDevContext->tcWordSwapOn = tcWordSwap; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ /* Set the Clock Divisor for the DSP module */ ++ DBG_Trace(DBG_LEVEL7, "WMD_DEV_create:Reset mail box and " ++ "enable the clock \n"); ++ status = CLK_Enable(SERVICESCLK_mailbox_ick); ++ if (DSP_FAILED(status)) { ++ DBG_Trace(DBG_LEVEL7, ++ "WMD_DEV_create:Reset mail box and " ++ "enable the clock Fail\n"); ++ } ++ udelay(5); ++ /* 24xx-Linux MMU address is obtained from the host ++ * resources struct */ ++ pDevContext->dwDSPMmuBase = resources.dwDmmuBase; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ pDevContext->hDevObject = hDevObject; ++ pDevContext->ulIntMask = 0; ++ /* Store current board state. */ ++ pDevContext->dwBrdState = BRD_STOPPED; ++ /* Return this ptr to our device state to the WCD for storage:*/ ++ *ppDevContext = pDevContext; ++ DBG_Trace(DBG_ENTER, "Device Created \n"); ++ } else { ++ if (pPtAttrs != NULL) { ++ if (pPtAttrs->hCSObj) ++ SYNC_DeleteCS(pPtAttrs->hCSObj); ++ ++ if (pPtAttrs->pgInfo) ++ MEM_Free(pPtAttrs->pgInfo); ++ ++ if (pPtAttrs->L2TblAllocVa) { ++ MEM_FreePhysMem((void *)pPtAttrs->L2TblAllocVa, ++ pPtAttrs->L2TblAllocPa, ++ pPtAttrs->L2TblAllocSz); ++ } ++ if (pPtAttrs->L1TblAllocVa) { ++ MEM_FreePhysMem((void *)pPtAttrs->L1TblAllocVa, ++ pPtAttrs->L1TblAllocPa, ++ pPtAttrs->L1TblAllocSz); ++ } ++ } ++ if (pPtAttrs) ++ MEM_Free(pPtAttrs); ++ ++ if (pDevContext) ++ MEM_Free(pDevContext); ++ ++ DBG_Trace(DBG_LEVEL7, ++ "WMD_DEV_Create Error Device not created\n"); ++ } ++func_end: ++ return status; ++} ++ ++/* ++ * ======== WMD_DEV_Ctrl ======== ++ * Receives device specific commands. ++ */ ++static DSP_STATUS WMD_DEV_Ctrl(struct WMD_DEV_CONTEXT *pDevContext, u32 dwCmd, ++ IN OUT void *pArgs) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct WMDIOCTL_EXTPROC *paExtProc = (struct WMDIOCTL_EXTPROC *)pArgs; ++ s32 ndx; ++ ++ DBG_Trace(DBG_ENTER, "WMD_DEV_Ctrl, pDevContext: 0x%x\n\t\t dwCmd: " ++ "0x%x\n\t\tpArgs: 0x%x\n", pDevContext, dwCmd, pArgs); ++ switch (dwCmd) { ++ case WMDIOCTL_CHNLREAD: ++ break; ++ case WMDIOCTL_CHNLWRITE: ++ break; ++ case WMDIOCTL_SETMMUCONFIG: ++ /* store away dsp-mmu setup values for later use */ ++ for (ndx = 0; ndx < WMDIOCTL_NUMOFMMUTLB; ndx++, paExtProc++) ++ pDevContext->aTLBEntry[ndx] = *paExtProc; ++ ++ break; ++ case WMDIOCTL_DEEPSLEEP: ++ case WMDIOCTL_EMERGENCYSLEEP: ++ /* Currently only DSP Idle is supported Need to update for ++ * later releases */ ++ DBG_Trace(DBG_LEVEL5, "WMDIOCTL_DEEPSLEEP\n"); ++ status = SleepDSP(pDevContext, PWR_DEEPSLEEP, pArgs); ++ break; ++ case WMDIOCTL_WAKEUP: ++ DBG_Trace(DBG_LEVEL5, "WMDIOCTL_WAKEUP\n"); ++ status = WakeDSP(pDevContext, pArgs); ++ break; ++ case WMDIOCTL_CLK_CTRL: ++ DBG_Trace(DBG_LEVEL5, "WMDIOCTL_CLK_CTRL\n"); ++ status = DSP_SOK; ++ /* Looking For Baseport Fix for Clocks */ ++ status = DSPPeripheralClkCtrl(pDevContext, pArgs); ++ break; ++ case WMDIOCTL_PWR_HIBERNATE: ++ DBG_Trace(DBG_LEVEL5, "WMDIOCTL_PWR_HIBERNATE\n"); ++ status = handle_hibernation_fromDSP(pDevContext); ++ break; ++ case WMDIOCTL_PRESCALE_NOTIFY: ++ DBG_Trace(DBG_LEVEL5, "WMDIOCTL_PRESCALE_NOTIFY\n"); ++ status = PreScale_DSP(pDevContext, pArgs); ++ break; ++ case WMDIOCTL_POSTSCALE_NOTIFY: ++ DBG_Trace(DBG_LEVEL5, "WMDIOCTL_POSTSCALE_NOTIFY\n"); ++ status = PostScale_DSP(pDevContext, pArgs); ++ break; ++ case WMDIOCTL_CONSTRAINT_REQUEST: ++ DBG_Trace(DBG_LEVEL5, "WMDIOCTL_CONSTRAINT_REQUEST\n"); ++ status = handle_constraints_set(pDevContext, pArgs); ++ break; ++ default: ++ status = DSP_EFAIL; ++ DBG_Trace(DBG_LEVEL7, "Error in WMD_BRD_Ioctl \n"); ++ break; ++ } ++ return status; ++} ++ ++/* ++ * ======== WMD_DEV_Destroy ======== ++ * Destroys the driver object. ++ */ ++static DSP_STATUS WMD_DEV_Destroy(struct WMD_DEV_CONTEXT *hDevContext) ++{ ++ struct PgTableAttrs *pPtAttrs; ++ DSP_STATUS status = DSP_SOK; ++ struct WMD_DEV_CONTEXT *pDevContext = (struct WMD_DEV_CONTEXT *) ++ hDevContext; ++ DBG_Trace(DBG_ENTER, "Entering WMD_DEV_Destroy:n hDevContext ::0x%x\n", ++ hDevContext); ++ /* first put the device to stop state */ ++ WMD_BRD_Delete(pDevContext); ++ if (pDevContext && pDevContext->pPtAttrs) { ++ pPtAttrs = pDevContext->pPtAttrs; ++ if (pPtAttrs->hCSObj) ++ SYNC_DeleteCS(pPtAttrs->hCSObj); ++ ++ if (pPtAttrs->pgInfo) ++ MEM_Free(pPtAttrs->pgInfo); ++ ++ if (pPtAttrs->L2TblAllocVa) { ++ MEM_FreePhysMem((void *)pPtAttrs->L2TblAllocVa, ++ pPtAttrs->L2TblAllocPa, pPtAttrs-> ++ L2TblAllocSz); ++ } ++ if (pPtAttrs->L1TblAllocVa) { ++ MEM_FreePhysMem((void *)pPtAttrs->L1TblAllocVa, ++ pPtAttrs->L1TblAllocPa, pPtAttrs-> ++ L1TblAllocSz); ++ } ++ if (pPtAttrs) ++ MEM_Free(pPtAttrs); ++ ++ } ++ /* Free the driver's device context: */ ++ MEM_Free((void *) hDevContext); ++ return status; ++} ++ ++static DSP_STATUS WMD_BRD_MemCopy(struct WMD_DEV_CONTEXT *hDevContext, ++ u32 ulDspDestAddr, u32 ulDspSrcAddr, ++ u32 ulNumBytes, u32 ulMemType) ++{ ++ DSP_STATUS status = DSP_SOK; ++ u32 srcAddr = ulDspSrcAddr; ++ u32 destAddr = ulDspDestAddr; ++ u32 copyBytes = 0; ++ u32 totalBytes = ulNumBytes; ++ u8 hostBuf[BUFFERSIZE]; ++ struct WMD_DEV_CONTEXT *pDevContext = hDevContext; ++ while ((totalBytes > 0) && DSP_SUCCEEDED(status)) { ++ copyBytes = totalBytes > BUFFERSIZE ? BUFFERSIZE : totalBytes; ++ /* Read from External memory */ ++ status = ReadExtDspData(hDevContext, hostBuf, srcAddr, ++ copyBytes, ulMemType); ++ if (DSP_SUCCEEDED(status)) { ++ if (destAddr < (pDevContext->dwDSPStartAdd + ++ pDevContext->dwInternalSize)) { ++ /* Write to Internal memory */ ++ status = WriteDspData(hDevContext, hostBuf, ++ destAddr, copyBytes, ulMemType); ++ } else { ++ /* Write to External memory */ ++ status = WriteExtDspData(hDevContext, hostBuf, ++ destAddr, copyBytes, ulMemType, false); ++ } ++ } ++ totalBytes -= copyBytes; ++ srcAddr += copyBytes; ++ destAddr += copyBytes; ++ } ++ return status; ++} ++ ++/* Mem Write does not halt the DSP to write unlike WMD_BRD_Write */ ++static DSP_STATUS WMD_BRD_MemWrite(struct WMD_DEV_CONTEXT *hDevContext, ++ IN u8 *pbHostBuf, u32 dwDSPAddr, ++ u32 ulNumBytes, u32 ulMemType) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct WMD_DEV_CONTEXT *pDevContext = hDevContext; ++ u32 ulRemainBytes = 0; ++ u32 ulBytes = 0; ++ ulRemainBytes = ulNumBytes; ++ while (ulRemainBytes > 0 && DSP_SUCCEEDED(status)) { ++ ulBytes = ++ ulRemainBytes > BUFFERSIZE ? BUFFERSIZE : ulRemainBytes; ++ if (dwDSPAddr < (pDevContext->dwDSPStartAdd + ++ pDevContext->dwInternalSize)) { ++ status = WriteDspData(hDevContext, pbHostBuf, dwDSPAddr, ++ ulBytes, ulMemType); ++ } else { ++ status = WriteExtDspData(hDevContext, pbHostBuf, ++ dwDSPAddr, ulBytes, ulMemType, true); ++ } ++ ulRemainBytes -= ulBytes; ++ dwDSPAddr += ulBytes; ++ pbHostBuf = pbHostBuf + ulBytes; ++ } ++ return status; ++} ++ ++/* ++ * ======== WMD_BRD_MemMap ======== ++ * This function maps MPU buffer to the DSP address space. It performs ++ * linear to physical address translation if required. It translates each ++ * page since linear addresses can be physically non-contiguous ++ * All address & size arguments are assumed to be page aligned (in proc.c) ++ * ++ * TODO: Disable MMU while updating the page tables (but that'll stall DSP) ++ */ ++static DSP_STATUS WMD_BRD_MemMap(struct WMD_DEV_CONTEXT *hDevContext, ++ u32 ulMpuAddr, u32 ulVirtAddr, ++ u32 ulNumBytes, u32 ulMapAttr) ++{ ++ u32 attrs; ++ DSP_STATUS status = DSP_SOK; ++ struct WMD_DEV_CONTEXT *pDevContext = hDevContext; ++ struct HW_MMUMapAttrs_t hwAttrs; ++ struct vm_area_struct *vma; ++ struct mm_struct *mm = current->mm; ++ u32 write = 0; ++ u32 numUsrPgs = 0; ++ struct page *mappedPage, *pg; ++ s32 pgNum; ++ u32 va = ulVirtAddr; ++ struct task_struct *curr_task = current; ++ u32 pgI = 0; ++ u32 mpuAddr, pa; ++ ++ DBG_Trace(DBG_ENTER, "> WMD_BRD_MemMap hDevContext %x, pa %x, va %x, " ++ "size %x, ulMapAttr %x\n", hDevContext, ulMpuAddr, ulVirtAddr, ++ ulNumBytes, ulMapAttr); ++ if (ulNumBytes == 0) ++ return DSP_EINVALIDARG; ++ ++ if (ulMapAttr != 0) { ++ attrs = ulMapAttr; ++ } else { ++ /* Assign default attributes */ ++ attrs = DSP_MAPVIRTUALADDR | DSP_MAPELEMSIZE16; ++ } ++ /* Take mapping properties */ ++ if (attrs & DSP_MAPBIGENDIAN) ++ hwAttrs.endianism = HW_BIG_ENDIAN; ++ else ++ hwAttrs.endianism = HW_LITTLE_ENDIAN; ++ ++ hwAttrs.mixedSize = (enum HW_MMUMixedSize_t) ++ ((attrs & DSP_MAPMIXEDELEMSIZE) >> 2); ++ /* Ignore elementSize if mixedSize is enabled */ ++ if (hwAttrs.mixedSize == 0) { ++ if (attrs & DSP_MAPELEMSIZE8) { ++ /* Size is 8 bit */ ++ hwAttrs.elementSize = HW_ELEM_SIZE_8BIT; ++ } else if (attrs & DSP_MAPELEMSIZE16) { ++ /* Size is 16 bit */ ++ hwAttrs.elementSize = HW_ELEM_SIZE_16BIT; ++ } else if (attrs & DSP_MAPELEMSIZE32) { ++ /* Size is 32 bit */ ++ hwAttrs.elementSize = HW_ELEM_SIZE_32BIT; ++ } else if (attrs & DSP_MAPELEMSIZE64) { ++ /* Size is 64 bit */ ++ hwAttrs.elementSize = HW_ELEM_SIZE_64BIT; ++ } else { ++ /* ++ * Mixedsize isn't enabled, so size can't be ++ * zero here ++ */ ++ DBG_Trace(DBG_LEVEL7, ++ "WMD_BRD_MemMap: MMU element size is zero\n"); ++ return DSP_EINVALIDARG; ++ } ++ } ++ if (attrs & DSP_MAPDONOTLOCK) ++ hwAttrs.donotlockmpupage = 1; ++ else ++ hwAttrs.donotlockmpupage = 0; ++ ++ if (attrs & DSP_MAPVMALLOCADDR) { ++ return MemMapVmalloc(hDevContext, ulMpuAddr, ulVirtAddr, ++ ulNumBytes, &hwAttrs); ++ } ++ /* ++ * Do OS-specific user-va to pa translation. ++ * Combine physically contiguous regions to reduce TLBs. ++ * Pass the translated pa to PteUpdate. ++ */ ++ if ((attrs & DSP_MAPPHYSICALADDR)) { ++ status = PteUpdate(pDevContext, ulMpuAddr, ulVirtAddr, ++ ulNumBytes, &hwAttrs); ++ goto func_cont; ++ } ++ ++ /* ++ * Important Note: ulMpuAddr is mapped from user application process ++ * to current process - it must lie completely within the current ++ * virtual memory address space in order to be of use to us here! ++ */ ++ down_read(&mm->mmap_sem); ++ vma = find_vma(mm, ulMpuAddr); ++ if (vma) ++ DBG_Trace(DBG_LEVEL6, "VMAfor UserBuf: ulMpuAddr=%x, " ++ "ulNumBytes=%x, vm_start=%x vm_end=%x vm_flags=%x \n", ++ ulMpuAddr, ulNumBytes, vma->vm_start, ++ vma->vm_end, vma->vm_flags); ++ ++ /* ++ * It is observed that under some circumstances, the user buffer is ++ * spread across several VMAs. So loop through and check if the entire ++ * user buffer is covered ++ */ ++ while ((vma) && (ulMpuAddr + ulNumBytes > vma->vm_end)) { ++ /* jump to the next VMA region */ ++ vma = find_vma(mm, vma->vm_end + 1); ++ DBG_Trace(DBG_LEVEL6, "VMAfor UserBuf ulMpuAddr=%x, " ++ "ulNumBytes=%x, vm_start=%x vm_end=%x vm_flags=%x\n", ++ ulMpuAddr, ulNumBytes, vma->vm_start, ++ vma->vm_end, vma->vm_flags); ++ } ++ if (!vma) { ++ DBG_Trace(DBG_LEVEL7, "Failed to get the VMA region for " ++ "MPU Buffer !!! \n"); ++ status = DSP_EINVALIDARG; ++ up_read(&mm->mmap_sem); ++ goto func_cont; ++ } ++ ++ if (vma->vm_flags & VM_IO) { ++ numUsrPgs = ulNumBytes / PG_SIZE_4K; ++ mpuAddr = ulMpuAddr; ++ DBG_Trace(DBG_LEVEL4, "WMD_BRD_MemMap:numOfActualTabEntries=%d," ++ "ulNumBytes= %d\n", numUsrPgs, ulNumBytes); ++ /* Get the physical addresses for user buffer */ ++ for (pgI = 0; pgI < numUsrPgs; pgI++) { ++ pa = user_va2pa(mm, mpuAddr); ++ if (!pa) { ++ status = DSP_EFAIL; ++ pr_err("DSPBRIDGE: VM_IO mapping physical" ++ "address is invalid\n"); ++ break; ++ } ++ if (pfn_valid(__phys_to_pfn(pa))) { ++ pg = phys_to_page(pa); ++ get_page(pg); ++ if (page_count(pg) < 1) { ++ pr_err("Bad page in VM_IO buffer\n"); ++ bad_page_dump(pa, pg); ++ } ++ } ++ status = PteSet(pDevContext->pPtAttrs, pa, ++ va, HW_PAGE_SIZE_4KB, &hwAttrs); ++ if (DSP_FAILED(status)) { ++ DBG_Trace(DBG_LEVEL7, ++ "WMD_BRD_MemMap: FAILED IN VM_IO" ++ "PTESET \n"); ++ break; ++ } ++ va += HW_PAGE_SIZE_4KB; ++ mpuAddr += HW_PAGE_SIZE_4KB; ++ pa += HW_PAGE_SIZE_4KB; ++ } ++ } else { ++ numUsrPgs = ulNumBytes / PG_SIZE_4K; ++ if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) ++ write = 1; ++ ++ for (pgI = 0; pgI < numUsrPgs; pgI++) { ++ pgNum = get_user_pages(curr_task, mm, ulMpuAddr, 1, ++ write, 1, &mappedPage, NULL); ++ if (pgNum > 0) { ++ if (page_count(mappedPage) < 1) { ++ pr_err("Bad page count after doing" ++ "get_user_pages on" ++ "user buffer\n"); ++ bad_page_dump(page_to_phys(mappedPage), ++ mappedPage); ++ } ++ status = PteSet(pDevContext->pPtAttrs, ++ page_to_phys(mappedPage), va, ++ HW_PAGE_SIZE_4KB, &hwAttrs); ++ if (DSP_FAILED(status)) { ++ DBG_Trace(DBG_LEVEL7, ++ "WMD_BRD_MemMap: FAILED IN PTESET \n"); ++ break; ++ } ++ va += HW_PAGE_SIZE_4KB; ++ ulMpuAddr += HW_PAGE_SIZE_4KB; ++ } else { ++ pr_err("DSPBRIDGE: get_user_pages FAILED," ++ "MPU addr = 0x%x," ++ "vma->vm_flags = 0x%lx," ++ "get_user_pages Err" ++ "Value = %d, Buffer" ++ "size=0x%x\n", ulMpuAddr, ++ vma->vm_flags, pgNum, ++ ulNumBytes); ++ status = DSP_EFAIL; ++ break; ++ } ++ } ++ } ++ up_read(&mm->mmap_sem); ++func_cont: ++ /* Don't propogate Linux or HW status to upper layers */ ++ if (DSP_SUCCEEDED(status)) { ++ status = DSP_SOK; ++ } else { ++ DBG_Trace(DBG_LEVEL7, "< WMD_BRD_MemMap status %x\n", status); ++ /* ++ * Roll out the mapped pages incase it failed in middle of ++ * mapping ++ */ ++ if (pgI) { ++ WMD_BRD_MemUnMap(pDevContext, ulVirtAddr, ++ (pgI * PG_SIZE_4K)); ++ } ++ status = DSP_EFAIL; ++ } ++ /* ++ * In any case, flush the TLB ++ * This is called from here instead from PteUpdate to avoid unnecessary ++ * repetition while mapping non-contiguous physical regions of a virtual ++ * region ++ */ ++ flush_all(pDevContext); ++ DBG_Trace(DBG_ENTER, "< WMD_BRD_MemMap status %x\n", status); ++ return status; ++} ++ ++/* ++ * ======== WMD_BRD_MemUnMap ======== ++ * Invalidate the PTEs for the DSP VA block to be unmapped. ++ * ++ * PTEs of a mapped memory block are contiguous in any page table ++ * So, instead of looking up the PTE address for every 4K block, ++ * we clear consecutive PTEs until we unmap all the bytes ++ */ ++static DSP_STATUS WMD_BRD_MemUnMap(struct WMD_DEV_CONTEXT *hDevContext, ++ u32 ulVirtAddr, u32 ulNumBytes) ++{ ++ u32 L1BaseVa; ++ u32 L2BaseVa; ++ u32 L2BasePa; ++ u32 L2PageNum; ++ u32 pteVal; ++ u32 pteSize; ++ u32 pteCount; ++ u32 pteAddrL1; ++ u32 pteAddrL2 = 0; ++ u32 remBytes; ++ u32 remBytesL2; ++ u32 vaCurr; ++ struct page *pg = NULL; ++ DSP_STATUS status = DSP_SOK; ++ struct WMD_DEV_CONTEXT *pDevContext = hDevContext; ++ struct PgTableAttrs *pt = pDevContext->pPtAttrs; ++ u32 pacount = 0; ++ u32 *pPhysAddrPageTbl = NULL; ++ u32 temp; ++ u32 patemp = 0; ++ u32 pAddr; ++ u32 numof4KPages = 0; ++ ++ DBG_Trace(DBG_ENTER, "> WMD_BRD_MemUnMap hDevContext %x, va %x, " ++ "NumBytes %x\n", hDevContext, ulVirtAddr, ulNumBytes); ++ pPhysAddrPageTbl = DMM_GetPhysicalAddrTable(); ++ vaCurr = ulVirtAddr; ++ remBytes = ulNumBytes; ++ remBytesL2 = 0; ++ L1BaseVa = pt->L1BaseVa; ++ pteAddrL1 = HW_MMU_PteAddrL1(L1BaseVa, vaCurr); ++ DBG_Trace(DBG_ENTER, "WMD_BRD_MemUnMap L1BaseVa %x, pteAddrL1 %x " ++ "vaCurr %x remBytes %x\n", L1BaseVa, pteAddrL1, ++ vaCurr, remBytes); ++ while (remBytes && (DSP_SUCCEEDED(status))) { ++ u32 vaCurrOrig = vaCurr; ++ /* Find whether the L1 PTE points to a valid L2 PT */ ++ pteAddrL1 = HW_MMU_PteAddrL1(L1BaseVa, vaCurr); ++ pteVal = *(u32 *)pteAddrL1; ++ pteSize = HW_MMU_PteSizeL1(pteVal); ++ if (pteSize == HW_MMU_COARSE_PAGE_SIZE) { ++ /* ++ * Get the L2 PA from the L1 PTE, and find ++ * corresponding L2 VA ++ */ ++ L2BasePa = HW_MMU_PteCoarseL1(pteVal); ++ L2BaseVa = L2BasePa - pt->L2BasePa + pt->L2BaseVa; ++ L2PageNum = (L2BasePa - pt->L2BasePa) / ++ HW_MMU_COARSE_PAGE_SIZE; ++ /* ++ * Find the L2 PTE address from which we will start ++ * clearing, the number of PTEs to be cleared on this ++ * page, and the size of VA space that needs to be ++ * cleared on this L2 page ++ */ ++ pteAddrL2 = HW_MMU_PteAddrL2(L2BaseVa, vaCurr); ++ pteCount = pteAddrL2 & (HW_MMU_COARSE_PAGE_SIZE - 1); ++ pteCount = (HW_MMU_COARSE_PAGE_SIZE - pteCount) / ++ sizeof(u32); ++ if (remBytes < (pteCount * PG_SIZE_4K)) ++ pteCount = remBytes / PG_SIZE_4K; ++ ++ remBytesL2 = pteCount * PG_SIZE_4K; ++ DBG_Trace(DBG_LEVEL1, "WMD_BRD_MemUnMap L2BasePa %x, " ++ "L2BaseVa %x pteAddrL2 %x, remBytesL2 %x\n", ++ L2BasePa, L2BaseVa, pteAddrL2, remBytesL2); ++ /* ++ * Unmap the VA space on this L2 PT. A quicker way ++ * would be to clear pteCount entries starting from ++ * pteAddrL2. However, below code checks that we don't ++ * clear invalid entries or less than 64KB for a 64KB ++ * entry. Similar checking is done for L1 PTEs too ++ * below ++ */ ++ while (remBytesL2 && (DSP_SUCCEEDED(status))) { ++ pteVal = *(u32 *)pteAddrL2; ++ pteSize = HW_MMU_PteSizeL2(pteVal); ++ /* vaCurr aligned to pteSize? */ ++ if ((pteSize != 0) && (remBytesL2 >= pteSize) && ++ !(vaCurr & (pteSize - 1))) { ++ /* Collect Physical addresses from VA */ ++ pAddr = (pteVal & ~(pteSize - 1)); ++ if (pteSize == HW_PAGE_SIZE_64KB) ++ numof4KPages = 16; ++ else ++ numof4KPages = 1; ++ temp = 0; ++ while (temp++ < numof4KPages) { ++ pPhysAddrPageTbl[pacount++] = ++ pAddr; ++ pAddr += HW_PAGE_SIZE_4KB; ++ } ++ if (HW_MMU_PteClear(pteAddrL2, ++ vaCurr, pteSize) == RET_OK) { ++ status = DSP_SOK; ++ remBytesL2 -= pteSize; ++ vaCurr += pteSize; ++ pteAddrL2 += (pteSize >> 12) * ++ sizeof(u32); ++ } else { ++ status = DSP_EFAIL; ++ goto EXIT_LOOP; ++ } ++ } else { ++ status = DSP_EFAIL; ++ } ++ } ++ SYNC_EnterCS(pt->hCSObj); ++ if (remBytesL2 == 0) { ++ pt->pgInfo[L2PageNum].numEntries -= pteCount; ++ if (pt->pgInfo[L2PageNum].numEntries == 0) { ++ /* ++ * Clear the L1 PTE pointing to the ++ * L2 PT ++ */ ++ if (RET_OK == HW_MMU_PteClear(L1BaseVa, ++ vaCurrOrig, HW_MMU_COARSE_PAGE_SIZE)) ++ status = DSP_SOK; ++ else { ++ status = DSP_EFAIL; ++ SYNC_LeaveCS(pt->hCSObj); ++ goto EXIT_LOOP; ++ } ++ } ++ remBytes -= pteCount * PG_SIZE_4K; ++ } else { ++ status = DSP_EFAIL; ++ } ++ DBG_Trace(DBG_LEVEL1, "WMD_BRD_MemUnMap L2PageNum %x, " ++ "numEntries %x, pteCount %x, status: 0x%x\n", ++ L2PageNum, pt->pgInfo[L2PageNum].numEntries, ++ pteCount, status); ++ SYNC_LeaveCS(pt->hCSObj); ++ } else ++ /* vaCurr aligned to pteSize? */ ++ /* pteSize = 1 MB or 16 MB */ ++ if ((pteSize != 0) && (remBytes >= pteSize) && ++ !(vaCurr & (pteSize - 1))) { ++ if (pteSize == HW_PAGE_SIZE_1MB) ++ numof4KPages = 256; ++ else ++ numof4KPages = 4096; ++ temp = 0; ++ /* Collect Physical addresses from VA */ ++ pAddr = (pteVal & ~(pteSize - 1)); ++ while (temp++ < numof4KPages) { ++ pPhysAddrPageTbl[pacount++] = pAddr; ++ pAddr += HW_PAGE_SIZE_4KB; ++ } ++ if (HW_MMU_PteClear(L1BaseVa, vaCurr, pteSize) ++ == RET_OK) { ++ status = DSP_SOK; ++ remBytes -= pteSize; ++ vaCurr += pteSize; ++ } else { ++ status = DSP_EFAIL; ++ goto EXIT_LOOP; ++ } ++ } else { ++ status = DSP_EFAIL; ++ } ++ } ++ /* ++ * It is better to flush the TLB here, so that any stale old entries ++ * get flushed ++ */ ++EXIT_LOOP: ++ flush_all(pDevContext); ++ for (temp = 0; temp < pacount; temp++) { ++ patemp = pPhysAddrPageTbl[temp]; ++ if (pfn_valid(__phys_to_pfn(patemp))) { ++ pg = phys_to_page(patemp); ++ if (page_count(pg) < 1) { ++ pr_info("DSPBRIDGE:UNMAP function: COUNT 0" ++ "FOR PA 0x%x, size = 0x%x\n", ++ patemp, ulNumBytes); ++ bad_page_dump(patemp, pg); ++ } ++ SetPageDirty(pg); ++ page_cache_release(pg); ++ } ++ } ++ DBG_Trace(DBG_LEVEL1, "WMD_BRD_MemUnMap vaCurr %x, pteAddrL1 %x " ++ "pteAddrL2 %x\n", vaCurr, pteAddrL1, pteAddrL2); ++ DBG_Trace(DBG_ENTER, "< WMD_BRD_MemUnMap status %x remBytes %x, " ++ "remBytesL2 %x\n", status, remBytes, remBytesL2); ++ return status; ++} ++ ++/* ++ * ======== user_va2pa ======== ++ * Purpose: ++ * This function walks through the Linux page tables to convert a userland ++ * virtual address to physical address ++ */ ++static u32 user_va2pa(struct mm_struct *mm, u32 address) ++{ ++ pgd_t *pgd; ++ pmd_t *pmd; ++ pte_t *ptep, pte; ++ ++ pgd = pgd_offset(mm, address); ++ if (!(pgd_none(*pgd) || pgd_bad(*pgd))) { ++ pmd = pmd_offset(pgd, address); ++ if (!(pmd_none(*pmd) || pmd_bad(*pmd))) { ++ ptep = pte_offset_map(pmd, address); ++ if (ptep) { ++ pte = *ptep; ++ if (pte_present(pte)) ++ return pte & PAGE_MASK; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++ ++/* ++ * ======== PteUpdate ======== ++ * This function calculates the optimum page-aligned addresses and sizes ++ * Caller must pass page-aligned values ++ */ ++static DSP_STATUS PteUpdate(struct WMD_DEV_CONTEXT *hDevContext, u32 pa, ++ u32 va, u32 size, ++ struct HW_MMUMapAttrs_t *mapAttrs) ++{ ++ u32 i; ++ u32 allBits; ++ u32 paCurr = pa; ++ u32 vaCurr = va; ++ u32 numBytes = size; ++ struct WMD_DEV_CONTEXT *pDevContext = hDevContext; ++ DSP_STATUS status = DSP_SOK; ++ u32 pgSize[] = { HW_PAGE_SIZE_16MB, HW_PAGE_SIZE_1MB, ++ HW_PAGE_SIZE_64KB, HW_PAGE_SIZE_4KB }; ++ DBG_Trace(DBG_ENTER, "> PteUpdate hDevContext %x, pa %x, va %x, " ++ "size %x, mapAttrs %x\n", hDevContext, pa, va, size, mapAttrs); ++ while (numBytes && DSP_SUCCEEDED(status)) { ++ /* To find the max. page size with which both PA & VA are ++ * aligned */ ++ allBits = paCurr | vaCurr; ++ DBG_Trace(DBG_LEVEL1, "allBits %x, paCurr %x, vaCurr %x, " ++ "numBytes %x ", allBits, paCurr, vaCurr, numBytes); ++ for (i = 0; i < 4; i++) { ++ if ((numBytes >= pgSize[i]) && ((allBits & ++ (pgSize[i] - 1)) == 0)) { ++ DBG_Trace(DBG_LEVEL1, "pgSize %x\n", pgSize[i]); ++ status = PteSet(pDevContext->pPtAttrs, paCurr, ++ vaCurr, pgSize[i], mapAttrs); ++ paCurr += pgSize[i]; ++ vaCurr += pgSize[i]; ++ numBytes -= pgSize[i]; ++ /* Don't try smaller sizes. Hopefully we have ++ * reached an address aligned to a bigger page ++ * size */ ++ break; ++ } ++ } ++ } ++ DBG_Trace(DBG_ENTER, "< PteUpdate status %x numBytes %x\n", status, ++ numBytes); ++ return status; ++} ++ ++/* ++ * ======== PteSet ======== ++ * This function calculates PTE address (MPU virtual) to be updated ++ * It also manages the L2 page tables ++ */ ++static DSP_STATUS PteSet(struct PgTableAttrs *pt, u32 pa, u32 va, ++ u32 size, struct HW_MMUMapAttrs_t *attrs) ++{ ++ u32 i; ++ u32 pteVal; ++ u32 pteAddrL1; ++ u32 pteSize; ++ u32 pgTblVa; /* Base address of the PT that will be updated */ ++ u32 L1BaseVa; ++ /* Compiler warns that the next three variables might be used ++ * uninitialized in this function. Doesn't seem so. Working around, ++ * anyways. */ ++ u32 L2BaseVa = 0; ++ u32 L2BasePa = 0; ++ u32 L2PageNum = 0; ++ DSP_STATUS status = DSP_SOK; ++ DBG_Trace(DBG_ENTER, "> PteSet pPgTableAttrs %x, pa %x, va %x, " ++ "size %x, attrs %x\n", pt, pa, va, size, attrs); ++ L1BaseVa = pt->L1BaseVa; ++ pgTblVa = L1BaseVa; ++ if ((size == HW_PAGE_SIZE_64KB) || (size == HW_PAGE_SIZE_4KB)) { ++ /* Find whether the L1 PTE points to a valid L2 PT */ ++ pteAddrL1 = HW_MMU_PteAddrL1(L1BaseVa, va); ++ if (pteAddrL1 <= (pt->L1BaseVa + pt->L1size)) { ++ pteVal = *(u32 *)pteAddrL1; ++ pteSize = HW_MMU_PteSizeL1(pteVal); ++ } else { ++ return DSP_EFAIL; ++ } ++ SYNC_EnterCS(pt->hCSObj); ++ if (pteSize == HW_MMU_COARSE_PAGE_SIZE) { ++ /* Get the L2 PA from the L1 PTE, and find ++ * corresponding L2 VA */ ++ L2BasePa = HW_MMU_PteCoarseL1(pteVal); ++ L2BaseVa = L2BasePa - pt->L2BasePa + pt->L2BaseVa; ++ L2PageNum = (L2BasePa - pt->L2BasePa) / ++ HW_MMU_COARSE_PAGE_SIZE; ++ } else if (pteSize == 0) { ++ /* L1 PTE is invalid. Allocate a L2 PT and ++ * point the L1 PTE to it */ ++ /* Find a free L2 PT. */ ++ for (i = 0; (i < pt->L2NumPages) && ++ (pt->pgInfo[i].numEntries != 0); i++) ++ ;; ++ if (i < pt->L2NumPages) { ++ L2PageNum = i; ++ L2BasePa = pt->L2BasePa + (L2PageNum * ++ HW_MMU_COARSE_PAGE_SIZE); ++ L2BaseVa = pt->L2BaseVa + (L2PageNum * ++ HW_MMU_COARSE_PAGE_SIZE); ++ /* Endianness attributes are ignored for ++ * HW_MMU_COARSE_PAGE_SIZE */ ++ status = HW_MMU_PteSet(L1BaseVa, L2BasePa, va, ++ HW_MMU_COARSE_PAGE_SIZE, attrs); ++ } else { ++ status = DSP_EMEMORY; ++ } ++ } else { ++ /* Found valid L1 PTE of another size. ++ * Should not overwrite it. */ ++ status = DSP_EFAIL; ++ } ++ if (DSP_SUCCEEDED(status)) { ++ pgTblVa = L2BaseVa; ++ if (size == HW_PAGE_SIZE_64KB) ++ pt->pgInfo[L2PageNum].numEntries += 16; ++ else ++ pt->pgInfo[L2PageNum].numEntries++; ++ DBG_Trace(DBG_LEVEL1, "L2 BaseVa %x, BasePa %x, " ++ "PageNum %x numEntries %x\n", L2BaseVa, ++ L2BasePa, L2PageNum, ++ pt->pgInfo[L2PageNum].numEntries); ++ } ++ SYNC_LeaveCS(pt->hCSObj); ++ } ++ if (DSP_SUCCEEDED(status)) { ++ DBG_Trace(DBG_LEVEL1, "PTE pgTblVa %x, pa %x, va %x, size %x\n", ++ pgTblVa, pa, va, size); ++ DBG_Trace(DBG_LEVEL1, "PTE endianism %x, elementSize %x, " ++ "mixedSize %x\n", attrs->endianism, ++ attrs->elementSize, attrs->mixedSize); ++ status = HW_MMU_PteSet(pgTblVa, pa, va, size, attrs); ++ } ++ DBG_Trace(DBG_ENTER, "< PteSet status %x\n", status); ++ return status; ++} ++ ++/* Memory map kernel VA -- memory allocated with vmalloc */ ++static DSP_STATUS MemMapVmalloc(struct WMD_DEV_CONTEXT *pDevContext, ++ u32 ulMpuAddr, u32 ulVirtAddr, u32 ulNumBytes, ++ struct HW_MMUMapAttrs_t *hwAttrs) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct page *pPage[1]; ++ u32 i; ++ u32 paCurr; ++ u32 paNext; ++ u32 vaCurr; ++ u32 sizeCurr; ++ u32 numPages; ++ u32 pa; ++ u32 numOf4KPages; ++ u32 temp = 0; ++ ++ DBG_Trace(DBG_ENTER, "> MemMapVmalloc hDevContext %x, pa %x, va %x, " ++ "size %x\n", pDevContext, ulMpuAddr, ulVirtAddr, ulNumBytes); ++ ++ /* ++ * Do Kernel va to pa translation. ++ * Combine physically contiguous regions to reduce TLBs. ++ * Pass the translated pa to PteUpdate. ++ */ ++ numPages = ulNumBytes / PAGE_SIZE; /* PAGE_SIZE = OS page size */ ++ i = 0; ++ vaCurr = ulMpuAddr; ++ pPage[0] = vmalloc_to_page((void *)vaCurr); ++ paNext = page_to_phys(pPage[0]); ++ while (DSP_SUCCEEDED(status) && (i < numPages)) { ++ /* ++ * Reuse paNext from the previous iteraion to avoid ++ * an extra va2pa call ++ */ ++ paCurr = paNext; ++ sizeCurr = PAGE_SIZE; ++ /* ++ * If the next page is physically contiguous, ++ * map it with the current one by increasing ++ * the size of the region to be mapped ++ */ ++ while (++i < numPages) { ++ pPage[0] = vmalloc_to_page((void *)(vaCurr + sizeCurr)); ++ paNext = page_to_phys(pPage[0]); ++ DBG_Trace(DBG_LEVEL5, "Xlate Vmalloc VA=0x%x , " ++ "PA=0x%x \n", (vaCurr + sizeCurr), paNext); ++ if (paNext == (paCurr + sizeCurr)) ++ sizeCurr += PAGE_SIZE; ++ else ++ break; ++ ++ } ++ if (paNext == 0) { ++ status = DSP_EMEMORY; ++ break; ++ } ++ pa = paCurr; ++ numOf4KPages = sizeCurr / HW_PAGE_SIZE_4KB; ++ while (temp++ < numOf4KPages) { ++ get_page(phys_to_page(pa)); ++ pa += HW_PAGE_SIZE_4KB; ++ } ++ status = PteUpdate(pDevContext, paCurr, ulVirtAddr + ++ (vaCurr - ulMpuAddr), sizeCurr, hwAttrs); ++ vaCurr += sizeCurr; ++ } ++ /* Don't propogate Linux or HW status to upper layers */ ++ if (DSP_SUCCEEDED(status)) { ++ status = DSP_SOK; ++ DBG_Trace(DBG_LEVEL7, "< WMD_BRD_MemMap succeeded %x\n", ++ status); ++ } else { ++ DBG_Trace(DBG_LEVEL7, "< WMD_BRD_MemMap status %x\n", status); ++ status = DSP_EFAIL; ++ } ++ /* ++ * In any case, flush the TLB ++ * This is called from here instead from PteUpdate to avoid unnecessary ++ * repetition while mapping non-contiguous physical regions of a virtual ++ * region ++ */ ++ flush_all(pDevContext); ++ DBG_Trace(DBG_LEVEL7, "< WMD_BRD_MemMap at end status %x\n", status); ++ return status; ++} ++ ++static DSP_STATUS run_IdleBoot(u32 prm_base, u32 cm_base, ++ u32 sysctrl_base) ++{ ++ u32 temp; ++ DSP_STATUS status = DSP_SOK; ++ enum HW_PwrState_t pwrState; ++ ++ /* Read PM_PWSTST_IVA2 */ ++ HW_PWRST_IVA2RegGet(prm_base, &temp); ++ if ((temp & 0x03) != 0x03 || (temp & 0x03) != 0x02) { ++ /* IVA2 is not in ON state */ ++ /* Set PM_PWSTCTRL_IVA2 to ON */ ++ HW_PWR_IVA2PowerStateSet(prm_base, HW_PWR_DOMAIN_DSP, ++ HW_PWR_STATE_ON); ++ /* Set the SW supervised state transition */ ++ HW_PWR_CLKCTRL_IVA2RegSet(cm_base, HW_SW_SUP_WAKEUP); ++ /* Wait until the state has moved to ON */ ++ HW_PWR_IVA2StateGet(prm_base, HW_PWR_DOMAIN_DSP, &pwrState); ++ } ++ CLK_Disable(SERVICESCLK_iva2_ck); ++ udelay(10); ++ /* Assert IVA2-RST1 and IVA2-RST2 */ ++ *((REG_UWORD32 *)((u32)(prm_base) + 0x50)) = (u32)0x07; ++ udelay(30); ++ /* set the SYSC for Idle Boot */ ++ *((REG_UWORD32 *)((u32)(sysctrl_base) + 0x404)) = (u32)0x01; ++ temp = (u32) *((REG_UWORD32 *) ++ ((u32) (cm_base) + 0x34)); ++ temp = (temp & 0xFFFFFFFE) | 0x1; ++ *((REG_UWORD32 *) ((u32) (cm_base) + 0x34)) = ++ (u32) temp; ++ temp = (u32) *((REG_UWORD32 *) ++ ((u32) (cm_base) + 0x4)); ++ temp = (temp & 0xFFFFFC8) | 0x37; ++ *((REG_UWORD32 *) ((u32) (cm_base) + 0x4)) = ++ (u32) temp; ++ CLK_Enable(SERVICESCLK_iva2_ck); ++ udelay(20); ++ GetHWRegs(prm_base, cm_base); ++ /* Release Reset1 and Reset2 */ ++ *((REG_UWORD32 *)((u32)(prm_base) + 0x50)) = (u32)0x05; ++ udelay(20); ++ *((REG_UWORD32 *)((u32)(prm_base) + 0x50)) = (u32)0x04; ++ udelay(30); ++ return status; ++} ++ ++ ++void GetHWRegs(u32 prm_base, u32 cm_base) ++{ ++ u32 temp; ++ temp = (u32)*((REG_UWORD32 *)((u32)(cm_base) + 0x00)); ++ DBG_Trace(DBG_LEVEL6, "CM_FCLKEN_IVA2 = 0x%x \n", temp); ++ temp = (u32)*((REG_UWORD32 *)((u32)(cm_base) + 0x10)); ++ DBG_Trace(DBG_LEVEL6, "CM_ICLKEN1_IVA2 = 0x%x \n", temp); ++ temp = (u32)*((REG_UWORD32 *)((u32)(cm_base) + 0x20)); ++ DBG_Trace(DBG_LEVEL6, "CM_IDLEST_IVA2 = 0x%x \n", temp); ++ temp = (u32)*((REG_UWORD32 *)((u32)(cm_base) + 0x48)); ++ DBG_Trace(DBG_LEVEL6, "CM_CLKSTCTRL_IVA2 = 0x%x \n", temp); ++ temp = (u32)*((REG_UWORD32 *)((u32)(cm_base) + 0x4c)); ++ DBG_Trace(DBG_LEVEL6, "CM_CLKSTST_IVA2 = 0x%x \n", temp); ++ temp = (u32)*((REG_UWORD32 *)((u32)(prm_base) + 0x50)); ++ DBG_Trace(DBG_LEVEL6, "RM_RSTCTRL_IVA2 = 0x%x \n", temp); ++ temp = (u32)*((REG_UWORD32 *)((u32)(prm_base) + 0x58)); ++ DBG_Trace(DBG_LEVEL6, "RM_RSTST_IVA2 = 0x%x \n", temp); ++ temp = (u32)*((REG_UWORD32 *)((u32)(prm_base) + 0xE0)); ++ DBG_Trace(DBG_LEVEL6, "PM_PWSTCTRL_IVA2 = 0x%x \n", temp); ++ temp = (u32)*((REG_UWORD32 *)((u32)(prm_base) + 0xE4)); ++ DBG_Trace(DBG_LEVEL6, "PM_PWSTST_IVA2 = 0x%x \n", temp); ++ temp = (u32)*((REG_UWORD32 *)((u32)(cm_base) + 0xA10)); ++ DBG_Trace(DBG_LEVEL6, "CM_ICLKEN1_CORE = 0x%x \n", temp); ++} ++ ++/* ++ * ======== configureDspMmu ======== ++ * Make DSP MMU page table entries. ++ */ ++void configureDspMmu(struct WMD_DEV_CONTEXT *pDevContext, u32 dataBasePhys, ++ u32 dspBaseVirt, u32 sizeInBytes, s32 nEntryStart, ++ enum HW_Endianism_t endianism, ++ enum HW_ElementSize_t elemSize, ++ enum HW_MMUMixedSize_t mixedSize) ++{ ++ struct CFG_HOSTRES resources; ++ struct HW_MMUMapAttrs_t mapAttrs = { endianism, elemSize, mixedSize }; ++ DSP_STATUS status = DSP_SOK; ++ ++ DBC_Require(sizeInBytes > 0); ++ DBG_Trace(DBG_LEVEL1, ++ "configureDspMmu entry %x pa %x, va %x, bytes %x ", ++ nEntryStart, dataBasePhys, dspBaseVirt, sizeInBytes); ++ ++ DBG_Trace(DBG_LEVEL1, "endianism %x, elemSize %x, mixedSize %x\n", ++ endianism, elemSize, mixedSize); ++ status = CFG_GetHostResources( ++ (struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), &resources); ++ status = HW_MMU_TLBAdd(pDevContext->dwDSPMmuBase, dataBasePhys, ++ dspBaseVirt, sizeInBytes, nEntryStart, ++ &mapAttrs, HW_SET, HW_SET); ++} ++ ++/* ++ * ======== WaitForStart ======== ++ * Wait for the singal from DSP that it has started, or time out. ++ */ ++bool WaitForStart(struct WMD_DEV_CONTEXT *pDevContext, u32 dwSyncAddr) ++{ ++ u16 usCount = TIHELEN_ACKTIMEOUT; ++ ++ /* Wait for response from board */ ++ while (*((volatile u16 *)dwSyncAddr) && --usCount) ++ udelay(10); ++ ++ /* If timed out: return FALSE */ ++ if (!usCount) { ++ DBG_Trace(DBG_LEVEL7, "Timed out Waiting for DSP to Start\n"); ++ return FALSE; ++ } ++ return TRUE; ++} +diff --git a/drivers/dsp/bridge/wmd/tiomap3430_pwr.c b/drivers/dsp/bridge/wmd/tiomap3430_pwr.c +new file mode 100644 +index 0000000..cbf6925 +--- /dev/null ++++ b/drivers/dsp/bridge/wmd/tiomap3430_pwr.c +@@ -0,0 +1,731 @@ ++/* ++ * tiomap_pwr.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2007-2008 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++/* ++ * ======== _tiomap_pwr.c ======== ++ * Description: ++ * Implementation of DSP wake/sleep routines. ++ * ++ *! Revision History ++ *! ================ ++ *! 01-Nov-2007 HK: Added Off mode(Hibernation) support and DVFS support ++ *! 05-Jan-2004 vp: Moved the file to platform specific folder and commented the ++ *! code. ++ *! 27-Mar-2003 vp: Added support for DSP boot idle mode. ++ *! 06-Dec-2002 cring: Added Palm support. ++ *! 08-Oct-2002 rr: Created. ++ */ ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++#include ++#include ++ ++/* ------------------------------------ Hardware Abstraction Layer */ ++#include ++#include ++#include ++#include ++ ++#include ++ ++/* ----------------------------------- specific to this file */ ++#include "_tiomap.h" ++#include "_tiomap_pwr.h" ++#include "_tiomap_util.h" ++#include ++#include ++ ++#ifdef CONFIG_PM ++#include ++#endif ++extern struct MAILBOX_CONTEXT mboxsetting; ++static unsigned short enable_off_mode = 0; ++/* ++ * ======== handle_constraints_set ======== ++ * Sets new DSP constraint ++ */ ++DSP_STATUS handle_constraints_set(struct WMD_DEV_CONTEXT *pDevContext, ++ IN void *pArgs) ++{ ++#ifdef CONFIG_BRIDGE_DVFS ++ u32 *pConstraintVal; ++ DSP_STATUS status = DSP_SOK; ++ struct CFG_HOSTRES resources; ++ struct dspbridge_platform_data *pdata = ++ omap_dspbridge_dev->dev.platform_data; ++ status = CFG_GetHostResources( ++ (struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), &resources); ++ ++ pConstraintVal = (u32 *)(pArgs); ++ /* Read the target value requested by DSP */ ++ DBG_Trace(DBG_LEVEL7, "handle_constraints_set:" ++ "opp requested = 0x%x\n", (u32)*(pConstraintVal+1)); ++ status = HW_MBOX_saveSettings(resources.dwMboxBase); ++ ++ /* Set the new opp value */ ++ if (pdata->dsp_set_min_opp) ++ (*pdata->dsp_set_min_opp)((u32)*(pConstraintVal+1)); ++ return DSP_SOK; ++#endif /* #ifdef CONFIG_BRIDGE_DVFS */ ++ return DSP_SOK; ++} ++ ++/* ++ * ======== handle_hibernation_fromDSP ======== ++ * Handle Hibernation requested from DSP ++ */ ++DSP_STATUS handle_hibernation_fromDSP(struct WMD_DEV_CONTEXT *pDevContext) ++{ ++ DSP_STATUS status = DSP_SOK; ++#ifdef CONFIG_PM ++ u16 usCount = TIHELEN_ACKTIMEOUT; ++ struct CFG_HOSTRES resources; ++ enum HW_PwrState_t pwrState; ++#ifdef CONFIG_BRIDGE_DVFS ++ u32 opplevel; ++ struct IO_MGR *hIOMgr; ++ struct dspbridge_platform_data *pdata = ++ omap_dspbridge_dev->dev.platform_data; ++#endif ++ ++ status = CFG_GetHostResources( ++ (struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), &resources); ++ if (DSP_FAILED(status)) ++ return status; ++ ++ HW_PWR_IVA2StateGet(resources.dwPrmBase, HW_PWR_DOMAIN_DSP, ++ &pwrState); ++ /* Wait for DSP to move into Off state, how much time should ++ * we wait? */ ++ while ((pwrState != HW_PWR_STATE_OFF) && --usCount) { ++ udelay(500); ++ HW_PWR_IVA2StateGet(resources.dwPrmBase, HW_PWR_DOMAIN_DSP, ++ &pwrState); ++ } ++ if (usCount == 0) { ++ DBG_Trace(DBG_LEVEL7, "Timed out Waiting for DSP Off mode \n"); ++ status = WMD_E_TIMEOUT; ++ return status; ++ } else { ++ ++ /* Save mailbox settings */ ++ status = HW_MBOX_saveSettings(resources.dwMboxBase); ++ DBG_Trace(DBG_LEVEL6, "MailBoxSettings: SYSCONFIG = 0x%x\n", ++ mboxsetting.sysconfig); ++ DBG_Trace(DBG_LEVEL6, "MailBoxSettings: IRQENABLE0 = 0x%x\n", ++ mboxsetting.irqEnable0); ++ DBG_Trace(DBG_LEVEL6, "MailBoxSettings: IRQENABLE1 = 0x%x\n", ++ mboxsetting.irqEnable1); ++ /* Turn off DSP Peripheral clocks and DSP Load monitor timer */ ++ status = DSP_PeripheralClocks_Disable(pDevContext, NULL); ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* Update the Bridger Driver state */ ++ pDevContext->dwBrdState = BRD_DSP_HIBERNATION; ++#ifdef CONFIG_BRIDGE_DVFS ++ status = DEV_GetIOMgr(pDevContext->hDevObject, &hIOMgr); ++ if (DSP_FAILED(status)) ++ return status; ++ IO_SHMsetting(hIOMgr, SHM_GETOPP, &opplevel); ++ /* Set the OPP to low level before moving to OFF mode */ ++ if (opplevel != VDD1_OPP1) { ++ DBG_Trace(DBG_LEVEL5, ++ "Tiomap_pwr.c - DSP requested" ++ " OPP = %d, MPU requesting low" ++ " OPP %d instead\n", opplevel, ++ VDD1_OPP1); ++ if (pdata->dsp_set_min_opp) ++ (*pdata->dsp_set_min_opp)(VDD1_OPP1); ++ status = DSP_SOK; ++ } ++#endif /* CONFIG_BRIDGE_DVFS */ ++ } else { ++ DBG_Trace(DBG_LEVEL7, ++ "handle_hibernation_fromDSP- FAILED\n"); ++ } ++ } ++#endif ++ return status; ++} ++ ++/* ++ * ======== SleepDSP ======== ++ * Put DSP in low power consuming state. ++ */ ++DSP_STATUS SleepDSP(struct WMD_DEV_CONTEXT *pDevContext, IN u32 dwCmd, ++ IN void *pArgs) ++{ ++ DSP_STATUS status = DSP_SOK; ++#ifdef CONFIG_PM ++ struct CFG_HOSTRES resources; ++ u16 usCount = TIHELEN_ACKTIMEOUT; ++ enum HW_PwrState_t pwrState; ++ enum HW_PwrState_t targetPwrState; ++ ++ status = CFG_GetHostResources( ++ (struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), &resources); ++ if (DSP_FAILED(status)) ++ return status; ++ DBG_Trace(DBG_LEVEL7, "SleepDSP- Enter function \n"); ++ ++ /* next, check if sleep code is valid... */ ++ if ((dwCmd != PWR_DEEPSLEEP) && (dwCmd != PWR_EMERGENCYDEEPSLEEP)) { ++ DBG_Trace(DBG_LEVEL7, "SleepDSP- Illegal sleep command\n"); ++ return DSP_EINVALIDARG; ++ } ++ switch (pDevContext->dwBrdState) { ++ case BRD_RUNNING: ++ status = HW_MBOX_saveSettings(resources.dwMboxBase); ++ if (enable_off_mode) { ++ CHNLSM_InterruptDSP2(pDevContext, ++ MBX_PM_DSPHIBERNATE); ++ DBG_Trace(DBG_LEVEL7, ++ "SleepDSP - Sent hibernate " ++ "command to DSP\n"); ++ targetPwrState = HW_PWR_STATE_OFF; ++ } else { ++ CHNLSM_InterruptDSP2(pDevContext, ++ MBX_PM_DSPRETENTION); ++ targetPwrState = HW_PWR_STATE_RET; ++ } ++ break; ++ case BRD_RETENTION: ++ status = HW_MBOX_saveSettings(resources.dwMboxBase); ++ if (enable_off_mode) { ++ CHNLSM_InterruptDSP2(pDevContext, ++ MBX_PM_DSPHIBERNATE); ++ targetPwrState = HW_PWR_STATE_OFF; ++ } else ++ return DSP_SOK; ++ break; ++ case BRD_HIBERNATION: ++ case BRD_DSP_HIBERNATION: ++ status = HW_MBOX_saveSettings(resources.dwMboxBase); ++ /* Already in Hibernation, so just return */ ++ DBG_Trace(DBG_LEVEL7, "SleepDSP- DSP already in " ++ "hibernation\n"); ++ return DSP_SOK; ++ case BRD_STOPPED: ++ DBG_Trace(DBG_LEVEL7, ++ "SleepDSP- Board in STOP state \n"); ++ return DSP_SALREADYASLEEP; ++ default: ++ DBG_Trace(DBG_LEVEL7, ++ "SleepDSP- Bridge in Illegal state\n"); ++ return DSP_EFAIL; ++ } ++ /* Get the PRCM DSP power domain status */ ++ HW_PWR_IVA2StateGet(resources.dwPrmBase, HW_PWR_DOMAIN_DSP, ++ &pwrState); ++ /* Wait for DSP to move into Standby state, how much time ++ * should we wait?*/ ++ while ((pwrState != targetPwrState) && --usCount) { ++ udelay(500); ++ HW_PWR_IVA2StateGet(resources.dwPrmBase, HW_PWR_DOMAIN_DSP, ++ &pwrState); ++ } ++ if (usCount == 0) { ++ DBG_Trace(DBG_LEVEL7, "SleepDSP: Timed out Waiting for DSP" ++ " STANDBY %x \n", pwrState); ++ return WMD_E_TIMEOUT; ++ } else { ++ DBG_Trace(DBG_LEVEL7, "SleepDSP: DSP STANDBY Pwr state %x \n", ++ pwrState); ++ /* Update the Bridger Driver state */ ++ if (enable_off_mode) ++ pDevContext->dwBrdState = BRD_HIBERNATION; ++ else ++ pDevContext->dwBrdState = BRD_RETENTION; ++ /* Turn off DSP Peripheral clocks */ ++ status = DSP_PeripheralClocks_Disable(pDevContext, NULL); ++ if (DSP_FAILED(status)) ++ DBG_Trace(DBG_LEVEL7, "SleepDSP- FAILED\n"); ++ } ++#endif ++ return status; ++} ++ ++ ++/* ++ * ======== WakeDSP ======== ++ * Wake up DSP from sleep. ++ */ ++DSP_STATUS WakeDSP(struct WMD_DEV_CONTEXT *pDevContext, IN void *pArgs) ++{ ++ DSP_STATUS status = DSP_SOK; ++#ifdef CONFIG_PM ++ struct CFG_HOSTRES resources; ++ enum HW_PwrState_t pwrState; ++ u32 temp; ++ ++ status = CFG_GetHostResources( ++ (struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), &resources); ++ if (DSP_FAILED(status)) ++ return status; ++ /* check the BRD/WMD state, if it is not 'SLEEP' then return failure */ ++ if (pDevContext->dwBrdState == BRD_RUNNING || ++ pDevContext->dwBrdState == BRD_STOPPED || ++ pDevContext->dwBrdState == BRD_DSP_HIBERNATION) { ++ /* The Device is in 'RET' or 'OFF' state and WMD state is not ++ * 'SLEEP', this means state inconsistency, so return */ ++ status = DSP_SOK; ++ return status; ++ } ++ /* Enable the DSP peripheral clocks and load monitor timer ++ * before waking the DSP */ ++ DBG_Trace(DBG_LEVEL6, "WakeDSP: enable DSP Peripheral Clks = 0x%x \n", ++ pDevContext->uDspPerClks); ++ status = DSP_PeripheralClocks_Enable(pDevContext, NULL); ++ ++ /* Enabling Dppll in lock mode */ ++ temp = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwCmBase) + 0x34)); ++ temp = (temp & 0xFFFFFFFE) | 0x1; ++ *((REG_UWORD32 *) ((u32) (resources.dwCmBase) + 0x34)) = ++ (u32) temp; ++ temp = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwCmBase) + 0x4)); ++ temp = (temp & 0xFFFFFC8) | 0x37; ++ ++ *((REG_UWORD32 *) ((u32) (resources.dwCmBase) + 0x4)) = ++ (u32) temp; ++ ++ udelay(10); ++ if (DSP_SUCCEEDED(status)) { ++ /* Send a message to DSP to wake up */ ++ CHNLSM_InterruptDSP2(pDevContext, MBX_PM_DSPWAKEUP); ++ HW_PWR_IVA2StateGet(resources.dwPrmBase, HW_PWR_DOMAIN_DSP, ++ &pwrState); ++ DBG_Trace(DBG_LEVEL7, ++ "\nWakeDSP: Power State After sending Interrupt " ++ "to DSP %x\n", pwrState); ++ /* set the device state to RUNNIG */ ++ pDevContext->dwBrdState = BRD_RUNNING; ++ } else { ++ DBG_Trace(DBG_LEVEL6, "WakeDSP: FAILED\n"); ++ } ++#endif ++ return status; ++} ++ ++/* ++ * ======== DSPPeripheralClkCtrl ======== ++ * Enable/Disable the DSP peripheral clocks as needed.. ++ */ ++DSP_STATUS DSPPeripheralClkCtrl(struct WMD_DEV_CONTEXT *pDevContext, ++ IN void *pArgs) ++{ ++ u32 extClk = 0; ++ u32 extClkId = 0; ++ u32 extClkCmd = 0; ++ u32 clkIdIndex = MBX_PM_MAX_RESOURCES; ++ u32 tmpIndex; ++ u32 dspPerClksBefore; ++ DSP_STATUS status = DSP_SOK; ++ DSP_STATUS status1 = DSP_SOK; ++ ++ DBG_Trace(DBG_ENTER, "Entering DSPPeripheralClkCtrl \n"); ++ dspPerClksBefore = pDevContext->uDspPerClks; ++ DBG_Trace(DBG_ENTER, "DSPPeripheralClkCtrl : uDspPerClks = 0x%x \n", ++ dspPerClksBefore); ++ ++ extClk = (u32)*((u32 *)pArgs); ++ ++ DBG_Trace(DBG_LEVEL3, "DSPPeripheralClkCtrl : extClk+Cmd = 0x%x \n", ++ extClk); ++ ++ extClkId = extClk & MBX_PM_CLK_IDMASK; ++ ++ /* process the power message -- TODO, keep it in a separate function */ ++ for (tmpIndex = 0; tmpIndex < MBX_PM_MAX_RESOURCES; tmpIndex++) { ++ if (extClkId == BPWR_CLKID[tmpIndex]) { ++ clkIdIndex = tmpIndex; ++ break; ++ } ++ } ++ /* TODO -- Assert may be a too hard restriction here.. May be we should ++ * just return with failure when the CLK ID does not match */ ++ /* DBC_Assert(clkIdIndex < MBX_PM_MAX_RESOURCES);*/ ++ if (clkIdIndex == MBX_PM_MAX_RESOURCES) { ++ DBG_Trace(DBG_LEVEL7, ++ "DSPPeripheralClkCtrl : Could n't get clock Id for" ++ "clkid 0x%x \n", clkIdIndex); ++ /* return with a more meaningfull error code */ ++ return DSP_EFAIL; ++ } ++ extClkCmd = (extClk >> MBX_PM_CLK_CMDSHIFT) & MBX_PM_CLK_CMDMASK; ++ switch (extClkCmd) { ++ case BPWR_DisableClock: ++ /* Call BP to disable the needed clock */ ++ DBG_Trace(DBG_LEVEL3, ++ "DSPPeripheralClkCtrl : Disable CLK for \n"); ++ status1 = CLK_Disable(BPWR_Clks[clkIdIndex].intClk); ++ status = CLK_Disable(BPWR_Clks[clkIdIndex].funClk); ++ DSPClkWakeupEventCtrl(BPWR_Clks[clkIdIndex].clkId, false); ++ if ((DSP_SUCCEEDED(status)) && (DSP_SUCCEEDED(status1))) { ++ (pDevContext->uDspPerClks) &= ++ (~((u32) (1 << clkIdIndex))); ++ } else { ++ DBG_Trace(DBG_LEVEL7, "DSPPeripheralClkCtrl : Failed " ++ "to disable clk\n"); ++ } ++ break; ++ case BPWR_EnableClock: ++ DBG_Trace(DBG_LEVEL3, ++ "DSPPeripheralClkCtrl : Enable CLK for \n"); ++ status1 = CLK_Enable(BPWR_Clks[clkIdIndex].intClk); ++ status = CLK_Enable(BPWR_Clks[clkIdIndex].funClk); ++ DSPClkWakeupEventCtrl(BPWR_Clks[clkIdIndex].clkId, true); ++ if ((DSP_SUCCEEDED(status)) && (DSP_SUCCEEDED(status1))) { ++ (pDevContext->uDspPerClks) |= (1 << clkIdIndex); ++ } else { ++ DBG_Trace(DBG_LEVEL7, ++ "DSPPeripheralClkCtrl:Failed to Enable clk\n"); ++ } ++ break; ++ default: ++ DBG_Trace(DBG_LEVEL3, ++ "DSPPeripheralClkCtrl : Unsupported CMD \n"); ++ /* unsupported cmd */ ++ /* TODO -- provide support for AUTOIDLE Enable/Disable ++ * commands */ ++ } ++ return status; ++} ++ ++/* ++ * ========PreScale_DSP======== ++ * Sends prescale notification to DSP ++ * ++ */ ++DSP_STATUS PreScale_DSP(struct WMD_DEV_CONTEXT *pDevContext, IN void *pArgs) ++{ ++#ifdef CONFIG_BRIDGE_DVFS ++ u32 level; ++ u32 voltage_domain; ++ ++ voltage_domain = *((u32 *)pArgs); ++ level = *((u32 *)pArgs + 1); ++ ++ DBG_Trace(DBG_LEVEL7, "PreScale_DSP: voltage_domain = %x, level = " ++ "0x%x\n", voltage_domain, level); ++ if ((pDevContext->dwBrdState == BRD_HIBERNATION) || ++ (pDevContext->dwBrdState == BRD_RETENTION) || ++ (pDevContext->dwBrdState == BRD_DSP_HIBERNATION)) { ++ DBG_Trace(DBG_LEVEL7, "PreScale_DSP: IVA in sleep. " ++ "No notification to DSP\n"); ++ return DSP_SOK; ++ } else if ((pDevContext->dwBrdState == BRD_RUNNING)) { ++ /* Send a prenotificatio to DSP */ ++ DBG_Trace(DBG_LEVEL7, ++ "PreScale_DSP: Sent notification to DSP\n"); ++ CHNLSM_InterruptDSP2(pDevContext, MBX_PM_SETPOINT_PRENOTIFY); ++ return DSP_SOK; ++ } else { ++ DBG_Trace(DBG_LEVEL7, "PreScale_DSP: Failed - DSP BRD" ++ " state in wrong state"); ++ return DSP_EFAIL; ++ } ++#endif /* #ifdef CONFIG_BRIDGE_DVFS */ ++ return DSP_SOK; ++} ++ ++/* ++ * ========PostScale_DSP======== ++ * Sends postscale notification to DSP ++ * ++ */ ++DSP_STATUS PostScale_DSP(struct WMD_DEV_CONTEXT *pDevContext, IN void *pArgs) ++{ ++#ifdef CONFIG_BRIDGE_DVFS ++ u32 level; ++ u32 voltage_domain; ++ struct IO_MGR *hIOMgr; ++ DSP_STATUS status = DSP_SOK; ++ ++ status = DEV_GetIOMgr(pDevContext->hDevObject, &hIOMgr); ++ ++ voltage_domain = *((u32 *)pArgs); ++ level = *((u32 *)pArgs + 1); ++ DBG_Trace(DBG_LEVEL7, ++ "PostScale_DSP: voltage_domain = %x, level = 0x%x\n", ++ voltage_domain, level); ++ if ((pDevContext->dwBrdState == BRD_HIBERNATION) || ++ (pDevContext->dwBrdState == BRD_RETENTION) || ++ (pDevContext->dwBrdState == BRD_DSP_HIBERNATION)) { ++ /* Update the OPP value in shared memory */ ++ IO_SHMsetting(hIOMgr, SHM_CURROPP, &level); ++ DBG_Trace(DBG_LEVEL7, ++ "PostScale_DSP: IVA in sleep. Wrote to shared " ++ "memory \n"); ++ return DSP_SOK; ++ } else if ((pDevContext->dwBrdState == BRD_RUNNING)) { ++ /* Update the OPP value in shared memory */ ++ IO_SHMsetting(hIOMgr, SHM_CURROPP, &level); ++ /* Send a post notification to DSP */ ++ CHNLSM_InterruptDSP2(pDevContext, MBX_PM_SETPOINT_POSTNOTIFY); ++ DBG_Trace(DBG_LEVEL7, ++ "PostScale_DSP: Wrote to shared memory Sent post" ++ " notification to DSP\n"); ++ return DSP_SOK; ++ } else { ++ DBG_Trace(DBG_LEVEL7, "PostScale_DSP: Failed - DSP BRD state " ++ "in wrong state"); ++ return DSP_EFAIL; ++ } ++#endif /* #ifdef CONFIG_BRIDGE_DVFS */ ++ return DSP_SOK; ++} ++ ++/* ++ * ========DSP_PeripheralClocks_Disable======== ++ * Disables all the peripheral clocks that were requested by DSP ++ */ ++DSP_STATUS DSP_PeripheralClocks_Disable(struct WMD_DEV_CONTEXT *pDevContext, ++ IN void *pArgs) ++{ ++ ++ u32 clkIdx; ++ DSP_STATUS status = DSP_SOK; ++ ++ for (clkIdx = 0; clkIdx < MBX_PM_MAX_RESOURCES; clkIdx++) { ++ if (((pDevContext->uDspPerClks) >> clkIdx) & 0x01) { ++ /* Disables the interface clock of the peripheral */ ++ status = CLK_Disable(BPWR_Clks[clkIdx].intClk); ++ if (DSP_FAILED(status)) { ++ DBG_Trace(DBG_LEVEL7, ++ "Failed to Enable the DSP Peripheral" ++ "Clk 0x%x \n", BPWR_Clks[clkIdx]); ++ } ++ /* Disables the functional clock of the periphearl */ ++ status = CLK_Disable(BPWR_Clks[clkIdx].funClk); ++ if (DSP_FAILED(status)) { ++ DBG_Trace(DBG_LEVEL7, ++ "Failed to Enable the DSP Peripheral" ++ "Clk 0x%x \n", BPWR_Clks[clkIdx]); ++ } ++ } ++ } ++ return status; ++} ++ ++/* ++ * ========DSP_PeripheralClocks_Enable======== ++ * Enables all the peripheral clocks that were requested by DSP ++ */ ++DSP_STATUS DSP_PeripheralClocks_Enable(struct WMD_DEV_CONTEXT *pDevContext, ++ IN void *pArgs) ++{ ++ u32 clkIdx; ++ DSP_STATUS int_clk_status = DSP_EFAIL, fun_clk_status = DSP_EFAIL; ++ ++ for (clkIdx = 0; clkIdx < MBX_PM_MAX_RESOURCES; clkIdx++) { ++ if (((pDevContext->uDspPerClks) >> clkIdx) & 0x01) { ++ /* Enable the interface clock of the peripheral */ ++ int_clk_status = CLK_Enable(BPWR_Clks[clkIdx].intClk); ++ /* Enable the functional clock of the periphearl */ ++ fun_clk_status = CLK_Enable(BPWR_Clks[clkIdx].funClk); ++ } ++ } ++ if ((int_clk_status | fun_clk_status) != DSP_SOK) ++ return DSP_EFAIL; ++ return DSP_SOK; ++} ++ ++void DSPClkWakeupEventCtrl(u32 ClkId, bool enable) ++{ ++ struct CFG_HOSTRES resources; ++ DSP_STATUS status = DSP_SOK; ++ u32 iva2_grpsel; ++ u32 mpu_grpsel; ++ ++ status = CFG_GetHostResources( ++ (struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), &resources); ++ if (DSP_FAILED(status)) ++ return; ++ ++ switch (ClkId) { ++ case BPWR_GPTimer5: ++ iva2_grpsel = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwPerPmBase) + 0xA8)); ++ mpu_grpsel = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwPerPmBase) + 0xA4)); ++ if (enable) { ++ iva2_grpsel |= OMAP3430_GRPSEL_GPT5; ++ mpu_grpsel &= ~OMAP3430_GRPSEL_GPT5; ++ } else { ++ mpu_grpsel |= OMAP3430_GRPSEL_GPT5; ++ iva2_grpsel &= ~OMAP3430_GRPSEL_GPT5; ++ } ++ *((REG_UWORD32 *) ((u32) (resources.dwPerPmBase) + 0xA8)) ++ = iva2_grpsel; ++ *((REG_UWORD32 *) ((u32) (resources.dwPerPmBase) + 0xA4)) ++ = mpu_grpsel; ++ break; ++ case BPWR_GPTimer6: ++ iva2_grpsel = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwPerPmBase) + 0xA8)); ++ mpu_grpsel = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwPerPmBase) + 0xA4)); ++ if (enable) { ++ iva2_grpsel |= OMAP3430_GRPSEL_GPT6; ++ mpu_grpsel &= ~OMAP3430_GRPSEL_GPT6; ++ } else { ++ mpu_grpsel |= OMAP3430_GRPSEL_GPT6; ++ iva2_grpsel &= ~OMAP3430_GRPSEL_GPT6; ++ } ++ *((REG_UWORD32 *) ((u32) (resources.dwPerPmBase) + 0xA8)) ++ = iva2_grpsel; ++ *((REG_UWORD32 *) ((u32) (resources.dwPerPmBase) + 0xA4)) ++ = mpu_grpsel; ++ break; ++ case BPWR_GPTimer7: ++ iva2_grpsel = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwPerPmBase) + 0xA8)); ++ mpu_grpsel = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwPerPmBase) + 0xA4)); ++ if (enable) { ++ iva2_grpsel |= OMAP3430_GRPSEL_GPT7; ++ mpu_grpsel &= ~OMAP3430_GRPSEL_GPT7; ++ } else { ++ mpu_grpsel |= OMAP3430_GRPSEL_GPT7; ++ iva2_grpsel &= ~OMAP3430_GRPSEL_GPT7; ++ } ++ *((REG_UWORD32 *) ((u32) (resources.dwPerPmBase) + 0xA8)) ++ = iva2_grpsel; ++ *((REG_UWORD32 *) ((u32) (resources.dwPerPmBase) + 0xA4)) ++ = mpu_grpsel; ++ break; ++ case BPWR_GPTimer8: ++ iva2_grpsel = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwPerPmBase) + 0xA8)); ++ mpu_grpsel = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwPerPmBase) + 0xA4)); ++ if (enable) { ++ iva2_grpsel |= OMAP3430_GRPSEL_GPT8; ++ mpu_grpsel &= ~OMAP3430_GRPSEL_GPT8; ++ } else { ++ mpu_grpsel |= OMAP3430_GRPSEL_GPT8; ++ iva2_grpsel &= ~OMAP3430_GRPSEL_GPT8; ++ } ++ *((REG_UWORD32 *) ((u32) (resources.dwPerPmBase) + 0xA8)) ++ = iva2_grpsel; ++ *((REG_UWORD32 *) ((u32) (resources.dwPerPmBase) + 0xA4)) ++ = mpu_grpsel; ++ break; ++ case BPWR_MCBSP1: ++ iva2_grpsel = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwCorePmBase) + 0xA8)); ++ mpu_grpsel = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwCorePmBase) + 0xA4)); ++ if (enable) { ++ iva2_grpsel |= OMAP3430_GRPSEL_MCBSP1; ++ mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP1; ++ } else { ++ mpu_grpsel |= OMAP3430_GRPSEL_MCBSP1; ++ iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP1; ++ } ++ *((REG_UWORD32 *) ((u32) (resources.dwCorePmBase) + 0xA8)) ++ = iva2_grpsel; ++ *((REG_UWORD32 *) ((u32) (resources.dwCorePmBase) + 0xA4)) ++ = mpu_grpsel; ++ break; ++ case BPWR_MCBSP2: ++ iva2_grpsel = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwPerPmBase) + 0xA8)); ++ mpu_grpsel = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwPerPmBase) + 0xA4)); ++ if (enable) { ++ iva2_grpsel |= OMAP3430_GRPSEL_MCBSP2; ++ mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP2; ++ } else { ++ mpu_grpsel |= OMAP3430_GRPSEL_MCBSP2; ++ iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP2; ++ } ++ *((REG_UWORD32 *) ((u32) (resources.dwPerPmBase) + 0xA8)) ++ = iva2_grpsel; ++ *((REG_UWORD32 *) ((u32) (resources.dwPerPmBase) + 0xA4)) ++ = mpu_grpsel; ++ break; ++ case BPWR_MCBSP3: ++ iva2_grpsel = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwPerPmBase) + 0xA8)); ++ mpu_grpsel = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwPerPmBase) + 0xA4)); ++ if (enable) { ++ iva2_grpsel |= OMAP3430_GRPSEL_MCBSP3; ++ mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP3; ++ } else { ++ mpu_grpsel |= OMAP3430_GRPSEL_MCBSP3; ++ iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP3; ++ } ++ *((REG_UWORD32 *) ((u32) (resources.dwPerPmBase) + 0xA8)) ++ = iva2_grpsel; ++ *((REG_UWORD32 *) ((u32) (resources.dwPerPmBase) + 0xA4)) ++ = mpu_grpsel; ++ break; ++ case BPWR_MCBSP4: ++ iva2_grpsel = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwPerPmBase) + 0xA8)); ++ mpu_grpsel = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwPerPmBase) + 0xA4)); ++ if (enable) { ++ iva2_grpsel |= OMAP3430_GRPSEL_MCBSP4; ++ mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP4; ++ } else { ++ mpu_grpsel |= OMAP3430_GRPSEL_MCBSP4; ++ iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP4; ++ } ++ *((REG_UWORD32 *) ((u32) (resources.dwPerPmBase) + 0xA8)) ++ = iva2_grpsel; ++ *((REG_UWORD32 *) ((u32) (resources.dwPerPmBase) + 0xA4)) ++ = mpu_grpsel; ++ break; ++ case BPWR_MCBSP5: ++ iva2_grpsel = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwCorePmBase) + 0xA8)); ++ mpu_grpsel = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwCorePmBase) + 0xA4)); ++ if (enable) { ++ iva2_grpsel |= OMAP3430_GRPSEL_MCBSP5; ++ mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP5; ++ } else { ++ mpu_grpsel |= OMAP3430_GRPSEL_MCBSP5; ++ iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP5; ++ } ++ *((REG_UWORD32 *) ((u32) (resources.dwCorePmBase) + 0xA8)) ++ = iva2_grpsel; ++ *((REG_UWORD32 *) ((u32) (resources.dwCorePmBase) + 0xA4)) ++ = mpu_grpsel; ++ break; ++ } ++} +diff --git a/drivers/dsp/bridge/wmd/tiomap_io.c b/drivers/dsp/bridge/wmd/tiomap_io.c +new file mode 100644 +index 0000000..6121e8f +--- /dev/null ++++ b/drivers/dsp/bridge/wmd/tiomap_io.c +@@ -0,0 +1,427 @@ ++/* ++ * tiomap_io.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== _tiomap_io.c ======== ++ * Description: ++ * Implementation for the io read/write routines. ++ * ++ *! Revision History ++ *! ================ ++ *! 16-Feb-2004 vp: Fixed warning in WriteDspData function. ++ *! 16-Apr-2003 vp: Added support for TC word swap ++ *! 26-Feb-2003 vp: Fixed issue with EXT_BEG and EXT_END address. ++ *! 24-Feb-2003 vp: Ported to Linux platform ++ *! 08-Oct-2002 rr: Created. ++ */ ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++ ++/* ----------------------------------- specific to this file */ ++#include "_tiomap.h" ++#include "_tiomap_pwr.h" ++#include "tiomap_io.h" ++ ++static u32 ulExtBase; ++static u32 ulExtEnd; ++ ++static u32 ulShm0End; ++static u32 ulDynExtBase; ++static u32 ulTraceSecBeg; ++static u32 ulTraceSecEnd; ++static u32 ulShmBaseVirt; ++ ++bool bSymbolsReloaded = true; ++ ++/* ++ * ======== ReadExtDspData ======== ++ * Copies DSP external memory buffers to the host side buffers. ++ */ ++DSP_STATUS ReadExtDspData(struct WMD_DEV_CONTEXT *hDevContext, ++ OUT u8 *pbHostBuf, u32 dwDSPAddr, ++ u32 ulNumBytes, u32 ulMemType) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct WMD_DEV_CONTEXT *pDevContext = hDevContext; ++ u32 offset; ++ u32 ulTLBBaseVirt = 0; ++ u32 ulShmOffsetVirt = 0; ++ u32 dwExtProgVirtMem; ++ u32 dwBaseAddr = pDevContext->dwDspExtBaseAddr; ++ bool bTraceRead = false; ++ ++ DBG_Trace(DBG_ENTER, "ReadExtDspData," ++ "hDevContext: 0x%x\n\t\tpbHostBuf: 0x%x" ++ "\n\t\tdwDSPAddr: 0x%x\n\t\tulNumBytes: 0x%x\n\t\t" ++ "ulMemType: 0x%x\n", pDevContext, pbHostBuf, dwDSPAddr, ++ ulNumBytes, ulMemType); ++ ++ if (!ulShmBaseVirt) { ++ status = DEV_GetSymbol(pDevContext->hDevObject, ++ SHMBASENAME, &ulShmBaseVirt); ++ } ++ DBC_Assert(ulShmBaseVirt != 0); ++ ++ /* Check if it is a read of Trace section */ ++ if (!ulTraceSecBeg) { ++ status = DEV_GetSymbol(pDevContext->hDevObject, ++ DSP_TRACESEC_BEG, &ulTraceSecBeg); ++ } ++ DBC_Assert(ulTraceSecBeg != 0); ++ ++ if (DSP_SUCCEEDED(status) && !ulTraceSecEnd) { ++ status = DEV_GetSymbol(pDevContext->hDevObject, ++ DSP_TRACESEC_END, &ulTraceSecEnd); ++ } ++ DBC_Assert(ulTraceSecEnd != 0); ++ ++ if (DSP_SUCCEEDED(status)) { ++ if ((dwDSPAddr <= ulTraceSecEnd) && ++ (dwDSPAddr >= ulTraceSecBeg)) { ++ DBG_Trace(DBG_LEVEL5, "Reading from DSP Trace" ++ "section 0x%x \n", dwDSPAddr); ++ bTraceRead = true; ++ } ++ } ++ ++ /* If reading from TRACE, force remap/unmap */ ++ if ((bTraceRead) && dwBaseAddr) { ++ dwBaseAddr = 0; ++ pDevContext->dwDspExtBaseAddr = 0; ++ } ++ ++ if (!dwBaseAddr) { ++ /* Initialize ulExtBase and ulExtEnd */ ++ ulExtBase = 0; ++ ulExtEnd = 0; ++ ++ /* Get DYNEXT_BEG, EXT_BEG and EXT_END.*/ ++ if (DSP_SUCCEEDED(status) && !ulDynExtBase) { ++ status = DEV_GetSymbol(pDevContext->hDevObject, ++ DYNEXTBASE, &ulDynExtBase); ++ } ++ DBC_Assert(ulDynExtBase != 0); ++ ++ if (DSP_SUCCEEDED(status)) { ++ status = DEV_GetSymbol(pDevContext->hDevObject, ++ EXTBASE, &ulExtBase); ++ } ++ DBC_Assert(ulExtBase != 0); ++ ++ if (DSP_SUCCEEDED(status)) { ++ status = DEV_GetSymbol(pDevContext->hDevObject, ++ EXTEND, &ulExtEnd); ++ } ++ DBC_Assert(ulExtEnd != 0); ++ ++ /* Trace buffer is right after the SHM SEG0, ++ * so set the base address to SHMBASE */ ++ if (bTraceRead) { ++ ulExtBase = ulShmBaseVirt; ++ ulExtEnd = ulTraceSecEnd; ++ } ++ ++ DBC_Assert(ulExtEnd != 0); ++ DBC_Assert(ulExtEnd > ulExtBase); ++ ++ if (ulExtEnd < ulExtBase) ++ status = DSP_EFAIL; ++ ++ if (DSP_SUCCEEDED(status)) { ++ ulTLBBaseVirt = ++ pDevContext->aTLBEntry[0].ulDspVa * DSPWORDSIZE; ++ DBC_Assert(ulTLBBaseVirt <= ulShmBaseVirt); ++ dwExtProgVirtMem = pDevContext->aTLBEntry[0].ulGppVa; ++ ++ if (bTraceRead) { ++ DBG_Trace(DBG_LEVEL7, "ReadExtDspData: " ++ "GPP VA pointing to SHMMEMBASE 0x%x \n", ++ dwExtProgVirtMem); ++ } else { ++ ulShmOffsetVirt = ulShmBaseVirt - ulTLBBaseVirt; ++ ulShmOffsetVirt += PG_ALIGN_HIGH(ulExtEnd - ++ ulDynExtBase + 1, ++ HW_PAGE_SIZE_64KB); ++ dwExtProgVirtMem -= ulShmOffsetVirt; ++ dwExtProgVirtMem += (ulExtBase - ulDynExtBase); ++ DBG_Trace(DBG_LEVEL7, "ReadExtDspData: " ++ "GPP VA pointing to EXTMEMBASE 0x%x \n", ++ dwExtProgVirtMem); ++ pDevContext->dwDspExtBaseAddr = ++ dwExtProgVirtMem; ++ ++ /* This dwDspExtBaseAddr will get cleared only when the board is ++ * stopped. */ ++ if (!pDevContext->dwDspExtBaseAddr) { ++ status = DSP_EFAIL; ++ DBG_Trace(DBG_LEVEL7, "ReadExtDspData: " ++ "failed to Map the program memory\n"); ++ } ++ } ++ ++ dwBaseAddr = dwExtProgVirtMem; ++ } ++ } ++ ++ if (!dwBaseAddr || !ulExtBase || !ulExtEnd) { ++ DBG_Trace(DBG_LEVEL7, ++ "Symbols missing for Ext Prog reading \n"); ++ status = DSP_EFAIL; ++ } ++ ++ offset = dwDSPAddr - ulExtBase; ++ ++ if (DSP_SUCCEEDED(status)) ++ memcpy(pbHostBuf, (u8 *)dwBaseAddr+offset, ulNumBytes); ++ ++ return status; ++} ++/* ++ * ======== WriteDspData ======== ++ * purpose: ++ * Copies buffers to the DSP internal/external memory. ++ */ ++DSP_STATUS WriteDspData(struct WMD_DEV_CONTEXT *hDevContext, IN u8 *pbHostBuf, ++ u32 dwDSPAddr, u32 ulNumBytes, u32 ulMemType) ++{ ++ u32 offset; ++ u32 dwBaseAddr = hDevContext->dwDspBaseAddr; ++ struct CFG_HOSTRES resources; ++ DSP_STATUS status; ++ u32 base1, base2, base3; ++ base1 = OMAP_DSP_MEM1_SIZE; ++ base2 = OMAP_DSP_MEM2_BASE - OMAP_DSP_MEM1_BASE; ++ base3 = OMAP_DSP_MEM3_BASE - OMAP_DSP_MEM1_BASE; ++ DBG_Trace(DBG_ENTER, "Entered WriteDspData \n"); ++ ++ status = CFG_GetHostResources( ++ (struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), &resources); ++ ++ offset = dwDSPAddr - hDevContext->dwDSPStartAdd; ++ if (offset < base1) { ++ dwBaseAddr = MEM_LinearAddress(resources.dwMemBase[2], ++ resources.dwMemLength[2]); ++ } else if (offset > base1 && offset < base2+OMAP_DSP_MEM2_SIZE) { ++ dwBaseAddr = MEM_LinearAddress(resources.dwMemBase[3], ++ resources.dwMemLength[3]); ++ offset = offset - base2; ++ } else if (offset >= base2+OMAP_DSP_MEM2_SIZE && ++ offset < base3 + OMAP_DSP_MEM3_SIZE) { ++ dwBaseAddr = MEM_LinearAddress(resources.dwMemBase[4], ++ resources.dwMemLength[4]); ++ offset = offset - base3; ++ } else{ ++ status = DSP_EFAIL; ++ return status; ++ } ++ if (ulNumBytes) ++ memcpy((u8 *) (dwBaseAddr+offset), pbHostBuf, ulNumBytes); ++ else ++ *((u32 *) pbHostBuf) = dwBaseAddr+offset; ++ ++ return status; ++} ++ ++/* ++ * ======== WriteExtDspData ======== ++ * purpose: ++ * Copies buffers to the external memory. ++ * ++ */ ++DSP_STATUS WriteExtDspData(struct WMD_DEV_CONTEXT *pDevContext, ++ IN u8 *pbHostBuf, u32 dwDSPAddr, u32 ulNumBytes, ++ u32 ulMemType, bool bDynamicLoad) ++{ ++ u32 dwBaseAddr = pDevContext->dwDspExtBaseAddr; ++ u32 dwOffset = 0; ++ u8 bTempByte1, bTempByte2; ++ u8 remainByte[4]; ++ s32 i; ++ DSP_STATUS retVal = DSP_SOK; ++ u32 dwExtProgVirtMem; ++ u32 ulTLBBaseVirt = 0; ++ u32 ulShmOffsetVirt = 0; ++ struct CFG_HOSTRES hostRes; ++ bool bTraceLoad = false; ++ bTempByte1 = 0x0; ++ bTempByte2 = 0x0; ++ ++ DBG_Trace(DBG_ENTER, "Entered WriteExtDspData dwDSPAddr 0x%x " ++ "ulNumBytes 0x%x \n", dwDSPAddr, ulNumBytes); ++ if (bSymbolsReloaded) { ++ /* Check if it is a load to Trace section */ ++ retVal = DEV_GetSymbol(pDevContext->hDevObject, ++ DSP_TRACESEC_BEG, &ulTraceSecBeg); ++ if (DSP_SUCCEEDED(retVal)) ++ retVal = DEV_GetSymbol(pDevContext->hDevObject, ++ DSP_TRACESEC_END, &ulTraceSecEnd); ++ } ++ if (DSP_SUCCEEDED(retVal)) { ++ if ((dwDSPAddr <= ulTraceSecEnd) && ++ (dwDSPAddr >= ulTraceSecBeg)) { ++ DBG_Trace(DBG_LEVEL5, "Writing to DSP Trace " ++ "section 0x%x \n", dwDSPAddr); ++ bTraceLoad = true; ++ } ++ } ++ ++ /* If dynamic, force remap/unmap */ ++ if ((bDynamicLoad || bTraceLoad) && dwBaseAddr) { ++ dwBaseAddr = 0; ++ MEM_UnmapLinearAddress((void *)pDevContext->dwDspExtBaseAddr); ++ pDevContext->dwDspExtBaseAddr = 0x0; ++ } ++ if (!dwBaseAddr) { ++ if (bSymbolsReloaded) ++ /* Get SHM_BEG EXT_BEG and EXT_END. */ ++ retVal = DEV_GetSymbol(pDevContext->hDevObject, ++ SHMBASENAME, &ulShmBaseVirt); ++ DBC_Assert(ulShmBaseVirt != 0); ++ if (bDynamicLoad) { ++ if (DSP_SUCCEEDED(retVal)) { ++ if (bSymbolsReloaded) ++ retVal = DEV_GetSymbol(pDevContext-> ++ hDevObject, DYNEXTBASE, ++ &ulExtBase); ++ } ++ DBC_Assert(ulExtBase != 0); ++ if (DSP_SUCCEEDED(retVal)) { ++ /* DR OMAPS00013235 : DLModules array may be ++ * in EXTMEM. It is expected that DYNEXTMEM and ++ * EXTMEM are contiguous, so checking for the ++ * upper bound at EXTEND should be Ok. */ ++ if (bSymbolsReloaded) ++ retVal = DEV_GetSymbol(pDevContext-> ++ hDevObject, EXTEND, &ulExtEnd); ++ } ++ } else { ++ if (bSymbolsReloaded) { ++ if (DSP_SUCCEEDED(retVal)) ++ retVal = DEV_GetSymbol(pDevContext-> ++ hDevObject, EXTBASE, ++ &ulExtBase); ++ DBC_Assert(ulExtBase != 0); ++ if (DSP_SUCCEEDED(retVal)) ++ retVal = DEV_GetSymbol(pDevContext-> ++ hDevObject, EXTEND, &ulExtEnd); ++ } ++ } ++ /* Trace buffer it right after the SHM SEG0, so set the ++ * base address to SHMBASE */ ++ if (bTraceLoad) ++ ulExtBase = ulShmBaseVirt; ++ ++ DBC_Assert(ulExtEnd != 0); ++ DBC_Assert(ulExtEnd > ulExtBase); ++ if (ulExtEnd < ulExtBase) ++ retVal = DSP_EFAIL; ++ ++ if (DSP_SUCCEEDED(retVal)) { ++ ulTLBBaseVirt = pDevContext->aTLBEntry[0].ulDspVa * ++ DSPWORDSIZE; ++ DBC_Assert(ulTLBBaseVirt <= ulShmBaseVirt); ++ ++ if (bSymbolsReloaded) { ++ if (DSP_SUCCEEDED(retVal)) { ++ retVal = DEV_GetSymbol(pDevContext-> ++ hDevObject, DSP_TRACESEC_END, ++ &ulShm0End); ++ } ++ if (DSP_SUCCEEDED(retVal)) { ++ retVal = DEV_GetSymbol(pDevContext-> ++ hDevObject, DYNEXTBASE, ++ &ulDynExtBase); ++ } ++ } ++ ulShmOffsetVirt = ulShmBaseVirt - ulTLBBaseVirt; ++ if (bTraceLoad) { ++ dwExtProgVirtMem = pDevContext->aTLBEntry[0]. ++ ulGppVa; ++ } else { ++ CFG_GetHostResources( ++ (struct CFG_DEVNODE *) ++ DRV_GetFirstDevExtension(), &hostRes); ++ dwExtProgVirtMem = hostRes.dwMemBase[1]; ++ dwExtProgVirtMem += (ulExtBase - ulDynExtBase); ++ } ++ DBG_Trace(DBG_LEVEL7, "WriteExtDspData: GPP VA " ++ "pointing to EXTMEMBASE 0x%x \n", ++ dwExtProgVirtMem); ++ ++ pDevContext->dwDspExtBaseAddr = ++ (u32)MEM_LinearAddress((void *) ++ TO_VIRTUAL_UNCACHED(dwExtProgVirtMem), ulExtEnd ++ - ulExtBase); ++ dwBaseAddr += pDevContext->dwDspExtBaseAddr; ++ /* This dwDspExtBaseAddr will get cleared only when ++ * the board is stopped. */ ++ if (!pDevContext->dwDspExtBaseAddr) { ++ retVal = DSP_EFAIL; ++ DBG_Trace(DBG_LEVEL7, "WriteExtDspData: failed " ++ "to Map the program memory\n"); ++ } ++ } ++ } ++ if (!dwBaseAddr || !ulExtBase || !ulExtEnd) { ++ DBG_Trace(DBG_LEVEL7, "Symbols missing for Ext Prog loading\n"); ++ retVal = DSP_EFAIL; ++ } ++ if (DSP_SUCCEEDED(retVal)) { ++ for (i = 0; i < 4; i++) ++ remainByte[i] = 0x0; ++ ++ dwOffset = dwDSPAddr - ulExtBase; ++ /* Also make sure the dwDSPAddr is < ulExtEnd */ ++ if (dwDSPAddr > ulExtEnd || dwOffset > dwDSPAddr) { ++ DBG_Trace(DBG_LEVEL7, "We can not load at this address " ++ "dwDSPAddr=0x%x, ulExt/DynBase=0x%x, " ++ "ulExtEnd=0x%x\n", dwDSPAddr, ulExtBase, ++ ulExtEnd); ++ retVal = DSP_EFAIL; ++ } ++ } ++ if (DSP_SUCCEEDED(retVal)) { ++ if (ulNumBytes) ++ memcpy((u8 *) dwBaseAddr + dwOffset, pbHostBuf, ++ ulNumBytes); ++ else ++ *((u32 *) pbHostBuf) = dwBaseAddr+dwOffset; ++ } ++ /* Unmap here to force remap for other Ext loads */ ++ if ((bDynamicLoad || bTraceLoad) && pDevContext->dwDspExtBaseAddr) { ++ MEM_UnmapLinearAddress((void *) pDevContext->dwDspExtBaseAddr); ++ pDevContext->dwDspExtBaseAddr = 0x0; ++ } ++ bSymbolsReloaded = false; ++ return retVal; ++} ++ +diff --git a/drivers/dsp/bridge/wmd/tiomap_io.h b/drivers/dsp/bridge/wmd/tiomap_io.h +new file mode 100644 +index 0000000..84a7553 +--- /dev/null ++++ b/drivers/dsp/bridge/wmd/tiomap_io.h +@@ -0,0 +1,112 @@ ++/* ++ * tiomap_io.h ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== _tiomap_io.h ======== ++ * Description: ++ * Definitions, types and function prototypes for the io ++ * (r/w external mem). ++ * ++ *! Revision History ++ *! ================ ++ *! 08-Oct-2002 rr: Created. ++ */ ++ ++#ifndef _TIOMAP_IO_ ++#define _TIOMAP_IO_ ++ ++/* ++ * Symbol that defines beginning of shared memory. ++ * For OMAP (Helen) this is the DSP Virtual base address of SDRAM. ++ * This will be used to program DSP MMU to map DSP Virt to GPP phys. ++ * (see dspMmuTlbEntry()). ++ */ ++#define SHMBASENAME "SHM_BEG" ++#define EXTBASE "EXT_BEG" ++#define EXTEND "_EXT_END" ++#define DYNEXTBASE "_DYNEXT_BEG" ++#define DYNEXTEND "_DYNEXT_END" ++#define IVAEXTMEMBASE "_IVAEXTMEM_BEG" ++#define IVAEXTMEMEND "_IVAEXTMEM_END" ++ ++ ++#define DSP_TRACESEC_BEG "_BRIDGE_TRACE_BEG" ++#define DSP_TRACESEC_END "_BRIDGE_TRACE_END" ++ ++#define SYS_PUTCBEG "_SYS_PUTCBEG" ++#define SYS_PUTCEND "_SYS_PUTCEND" ++#define BRIDGE_SYS_PUTC_current "_BRIDGE_SYS_PUTC_current" ++ ++ ++#define WORDSWAP_ENABLE 0x3 /* Enable word swap */ ++ ++/* ++ * ======== ReadExtDspData ======== ++ * Reads it from DSP External memory. The external memory for the DSP ++ * is configured by the combination of DSP MMU and SHM Memory manager in the CDB ++ */ ++extern DSP_STATUS ReadExtDspData(struct WMD_DEV_CONTEXT *pDevContext, ++ OUT u8 *pbHostBuf, u32 dwDSPAddr, ++ u32 ulNumBytes, u32 ulMemType); ++ ++/* ++ * ======== WriteDspData ======== ++ */ ++extern DSP_STATUS WriteDspData(struct WMD_DEV_CONTEXT *pDevContext, ++ OUT u8 *pbHostBuf, u32 dwDSPAddr, ++ u32 ulNumBytes, u32 ulMemType); ++ ++/* ++ * ======== WriteExtDspData ======== ++ * Writes to the DSP External memory for external program. ++ * The ext mem for progra is configured by the combination of DSP MMU and ++ * SHM Memory manager in the CDB ++ */ ++extern DSP_STATUS WriteExtDspData(struct WMD_DEV_CONTEXT *pDevContext, ++ IN u8 *pbHostBuf, u32 dwDSPAddr, ++ u32 ulNumBytes, u32 ulMemType, ++ bool bDynamicLoad); ++ ++/* ++ * ======== WriteExt32BitDspData ======== ++ * Writes 32 bit data to the external memory ++ */ ++extern inline void WriteExt32BitDspData(IN const ++ struct WMD_DEV_CONTEXT *pDevContext, IN u32 dwDSPAddr, ++ IN u32 val) ++{ ++ *(u32 *)dwDSPAddr = ((pDevContext->tcWordSwapOn) ? (((val << 16) & ++ 0xFFFF0000) | ((val >> 16) & 0x0000FFFF)) : val); ++} ++ ++/* ++ * ======== ReadExt32BitDspData ======== ++ * Reads 32 bit data from the external memory ++ */ ++extern inline u32 ReadExt32BitDspData(IN const struct WMD_DEV_CONTEXT ++ *pDevContext, IN u32 dwDSPAddr) ++{ ++ u32 retVal; ++ retVal = *(u32 *)dwDSPAddr; ++ ++ retVal = ((pDevContext->tcWordSwapOn) ? (((retVal << 16) ++ & 0xFFFF0000) | ((retVal >> 16) & 0x0000FFFF)) : retVal); ++ return retVal; ++} ++ ++#endif /* _TIOMAP_IO_ */ ++ +diff --git a/drivers/dsp/bridge/wmd/tiomap_sm.c b/drivers/dsp/bridge/wmd/tiomap_sm.c +new file mode 100644 +index 0000000..a6d5d62 +--- /dev/null ++++ b/drivers/dsp/bridge/wmd/tiomap_sm.c +@@ -0,0 +1,195 @@ ++/* ++ * tiomap_sm.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++#include "_tiomap.h" ++#include "_tiomap_pwr.h" ++ ++#define MAILBOX_FIFOSTATUS(m) (0x80 + 4 * (m)) ++ ++static inline unsigned int fifo_full(void __iomem *mbox_base, int mbox_id) ++{ ++ return __raw_readl(mbox_base + MAILBOX_FIFOSTATUS(mbox_id)) & 0x1; ++} ++ ++DSP_STATUS CHNLSM_EnableInterrupt(struct WMD_DEV_CONTEXT *pDevContext) ++{ ++ DSP_STATUS status = DSP_SOK; ++ u32 numMbxMsg; ++ u32 mbxValue; ++ struct CFG_HOSTRES resources; ++ u32 devType; ++ struct IO_MGR *hIOMgr; ++ ++ DBG_Trace(DBG_ENTER, "CHNLSM_EnableInterrupt(0x%x)\n", pDevContext); ++ ++ /* Read the messages in the mailbox until the message queue is empty */ ++ ++ CFG_GetHostResources((struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), ++ &resources); ++ DEV_GetDevType(pDevContext->hDevObject, &devType); ++ status = DEV_GetIOMgr(pDevContext->hDevObject, &hIOMgr); ++ if (devType == DSP_UNIT) { ++ HW_MBOX_NumMsgGet(resources.dwMboxBase, ++ MBOX_DSP2ARM, &numMbxMsg); ++ while (numMbxMsg != 0) { ++ HW_MBOX_MsgRead(resources.dwMboxBase, ++ MBOX_DSP2ARM, ++ &mbxValue); ++ numMbxMsg--; ++ } ++ /* clear the DSP mailbox as well...*/ ++ HW_MBOX_NumMsgGet(resources.dwMboxBase, ++ MBOX_ARM2DSP, &numMbxMsg); ++ while (numMbxMsg != 0) { ++ HW_MBOX_MsgRead(resources.dwMboxBase, ++ MBOX_ARM2DSP, &mbxValue); ++ numMbxMsg--; ++ udelay(10); ++ ++ HW_MBOX_EventAck(resources.dwMboxBase, MBOX_ARM2DSP, ++ HW_MBOX_U1_DSP1, ++ HW_MBOX_INT_NEW_MSG); ++ } ++ /* Enable the new message events on this IRQ line */ ++ HW_MBOX_EventEnable(resources.dwMboxBase, ++ MBOX_DSP2ARM, ++ MBOX_ARM, ++ HW_MBOX_INT_NEW_MSG); ++ } ++ ++ return status; ++} ++ ++DSP_STATUS CHNLSM_DisableInterrupt(struct WMD_DEV_CONTEXT *pDevContext) ++{ ++ struct CFG_HOSTRES resources; ++ ++ DBG_Trace(DBG_ENTER, "CHNLSM_DisableInterrupt(0x%x)\n", pDevContext); ++ ++ CFG_GetHostResources((struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), ++ &resources); ++ HW_MBOX_EventDisable(resources.dwMboxBase, MBOX_DSP2ARM, ++ MBOX_ARM, HW_MBOX_INT_NEW_MSG); ++ return DSP_SOK; ++} ++ ++DSP_STATUS CHNLSM_InterruptDSP2(struct WMD_DEV_CONTEXT *pDevContext, ++ u16 wMbVal) ++{ ++#ifdef CONFIG_BRIDGE_DVFS ++ struct dspbridge_platform_data *pdata = ++ omap_dspbridge_dev->dev.platform_data; ++ u32 opplevel = 0; ++#endif ++ struct CFG_HOSTRES resources; ++ DSP_STATUS status = DSP_SOK; ++ unsigned long timeout; ++ u32 temp; ++ ++ status = CFG_GetHostResources((struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), ++ &resources); ++ if (DSP_FAILED(status)) ++ return DSP_EFAIL; ++#ifdef CONFIG_BRIDGE_DVFS ++ if (pDevContext->dwBrdState == BRD_DSP_HIBERNATION || ++ pDevContext->dwBrdState == BRD_HIBERNATION) { ++ if (pdata->dsp_get_opp) ++ opplevel = (*pdata->dsp_get_opp)(); ++ if (opplevel == 1) { ++ if (pdata->dsp_set_min_opp) ++ (*pdata->dsp_set_min_opp)(opplevel+1); ++ } ++ } ++#endif ++ ++ if (pDevContext->dwBrdState == BRD_DSP_HIBERNATION || ++ pDevContext->dwBrdState == BRD_HIBERNATION) { ++ /* Restore mailbox settings */ ++ /* Restart the peripheral clocks that were disabled only ++ * in DSP initiated Hibernation case.*/ ++ if (pDevContext->dwBrdState == BRD_DSP_HIBERNATION) { ++ DSP_PeripheralClocks_Enable(pDevContext, NULL); ++ /* Enabling Dpll in lock mode*/ ++ temp = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwCmBase) + 0x34)); ++ temp = (temp & 0xFFFFFFFE) | 0x1; ++ *((REG_UWORD32 *) ((u32) (resources.dwCmBase) + 0x34)) = ++ (u32) temp; ++ temp = (u32) *((REG_UWORD32 *) ++ ((u32) (resources.dwCmBase) + 0x4)); ++ temp = (temp & 0xFFFFFC8) | 0x37; ++ ++ *((REG_UWORD32 *) ((u32) (resources.dwCmBase) + 0x4)) = ++ (u32) temp; ++ } ++ HW_MBOX_restoreSettings(resources.dwMboxBase); ++ ++ /* Access MMU SYS CONFIG register to generate a short wakeup */ ++ temp = (u32) *((REG_UWORD32 *) ((u32) ++ (resources.dwDmmuBase) + 0x10)); ++ ++ pDevContext->dwBrdState = BRD_RUNNING; ++ } ++ timeout = jiffies + msecs_to_jiffies(1); ++ while (fifo_full((void __iomem *) resources.dwMboxBase, 0)) { ++ if (time_after(jiffies, timeout)) { ++ printk(KERN_ERR "dspbridge: timed out waiting for mailbox\n"); ++ return WMD_E_TIMEOUT; ++ } ++ } ++ DBG_Trace(DBG_LEVEL3, "writing %x to Mailbox\n", ++ wMbVal); ++ ++ HW_MBOX_MsgWrite(resources.dwMboxBase, MBOX_ARM2DSP, ++ wMbVal); ++ return DSP_SOK; ++} ++ ++bool CHNLSM_ISR(struct WMD_DEV_CONTEXT *pDevContext, bool *pfSchedDPC, ++ u16 *pwIntrVal) ++{ ++ struct CFG_HOSTRES resources; ++ u32 numMbxMsg; ++ u32 mbxValue; ++ ++ DBG_Trace(DBG_ENTER, "CHNLSM_ISR(0x%x)\n", pDevContext); ++ ++ CFG_GetHostResources((struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), &resources); ++ ++ HW_MBOX_NumMsgGet(resources.dwMboxBase, MBOX_DSP2ARM, &numMbxMsg); ++ ++ if (numMbxMsg > 0) { ++ HW_MBOX_MsgRead(resources.dwMboxBase, MBOX_DSP2ARM, &mbxValue); ++ ++ HW_MBOX_EventAck(resources.dwMboxBase, MBOX_DSP2ARM, ++ HW_MBOX_U0_ARM, HW_MBOX_INT_NEW_MSG); ++ ++ DBG_Trace(DBG_LEVEL3, "Read %x from Mailbox\n", mbxValue); ++ *pwIntrVal = (u16) mbxValue; ++ } ++ /* Set *pfSchedDPC to true; */ ++ *pfSchedDPC = true; ++ return true; ++} +diff --git a/drivers/dsp/bridge/wmd/ue_deh.c b/drivers/dsp/bridge/wmd/ue_deh.c +new file mode 100644 +index 0000000..d5551cb +--- /dev/null ++++ b/drivers/dsp/bridge/wmd/ue_deh.c +@@ -0,0 +1,329 @@ ++/* ++ * ue_deh.c ++ * ++ * DSP-BIOS Bridge driver support functions for TI OMAP processors. ++ * ++ * Copyright (C) 2005-2006 Texas Instruments, Inc. ++ * ++ * This package 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. ++ * ++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++ */ ++ ++ ++/* ++ * ======== ue_deh.c ======== ++ * Description: ++ * Implements upper edge DSP exception handling (DEH) functions. ++ * ++ *! Revision History: ++ *! ================ ++ *! 03-Jan-2005 hn: Support for IVA DEH. ++ *! 05-Jan-2004 vp: Updated for the 24xx HW library. ++ *! 19-Feb-2003 vp: Code review updates. ++ *! - Cosmetic changes. ++ *! 18-Oct-2002 sb: Ported to Linux platform. ++ *! 10-Dec-2001 kc: Updated DSP error reporting in DEBUG mode. ++ *! 10-Sep-2001 kc: created. ++ */ ++ ++/* ----------------------------------- Host OS */ ++#include ++ ++/* ----------------------------------- DSP/BIOS Bridge */ ++#include ++#include ++#include ++ ++/* ----------------------------------- Trace & Debug */ ++#include ++#include ++ ++/* ----------------------------------- OS Adaptation Layer */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ----------------------------------- Link Driver */ ++#include ++ ++/* ----------------------------------- Platform Manager */ ++#include ++#include ++ ++/* ------------------------------------ Hardware Abstraction Layer */ ++#include ++#include ++ ++/* ----------------------------------- This */ ++#include "mmu_fault.h" ++#include "_tiomap.h" ++#include "_deh.h" ++#include "_tiomap_mmu.h" ++#include "_tiomap_pwr.h" ++#include ++ ++static struct HW_MMUMapAttrs_t mapAttrs = { HW_LITTLE_ENDIAN, ++ HW_ELEM_SIZE_16BIT, ++ HW_MMU_CPUES} ; ++#define VirtToPhys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET) ++/* ++ * ======== WMD_DEH_Create ======== ++ * Creates DEH manager object. ++ */ ++DSP_STATUS WMD_DEH_Create(OUT struct DEH_MGR **phDehMgr, ++ struct DEV_OBJECT *hDevObject) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEH_MGR *pDehMgr = NULL; ++ struct CFG_HOSTRES cfgHostRes; ++ struct CFG_DEVNODE *hDevNode; ++ struct WMD_DEV_CONTEXT *hWmdContext = NULL; ++ ++ DBG_Trace(DBG_LEVEL1, "Entering DEH_Create: 0x%x\n", phDehMgr); ++ /* Message manager will be created when a file is loaded, since ++ * size of message buffer in shared memory is configurable in ++ * the base image. */ ++ /* Get WMD context info. */ ++ DEV_GetWMDContext(hDevObject, &hWmdContext); ++ DBC_Assert(hWmdContext); ++ /* Allocate IO manager object: */ ++ MEM_AllocObject(pDehMgr, struct DEH_MGR, SIGNATURE); ++ if (pDehMgr == NULL) { ++ status = DSP_EMEMORY; ++ } else { ++ /* Create an NTFY object to manage notifications */ ++ if (DSP_SUCCEEDED(status)) ++ status = NTFY_Create(&pDehMgr->hNtfy); ++ ++ /* Create a DPC object. */ ++ status = DPC_Create(&pDehMgr->hMmuFaultDpc, MMU_FaultDpc, ++ (void *)pDehMgr); ++ if (DSP_SUCCEEDED(status)) ++ status = DEV_GetDevNode(hDevObject, &hDevNode); ++ ++ if (DSP_SUCCEEDED(status)) ++ status = CFG_GetHostResources(hDevNode, &cfgHostRes); ++ ++ if (DSP_SUCCEEDED(status)) { ++ /* Fill in context structure */ ++ pDehMgr->hWmdContext = hWmdContext; ++ pDehMgr->errInfo.dwErrMask = 0L; ++ pDehMgr->errInfo.dwVal1 = 0L; ++ pDehMgr->errInfo.dwVal2 = 0L; ++ pDehMgr->errInfo.dwVal3 = 0L; ++ /* Install ISR function for DSP MMU fault */ ++ if ((request_irq(INT_DSP_MMU_IRQ, MMU_FaultIsr, 0, ++ "DspBridge\tiommu fault", (void *)pDehMgr)) == 0) ++ status = DSP_SOK; ++ else ++ status = DSP_EFAIL; ++ } ++ } ++ if (DSP_FAILED(status)) { ++ /* If create failed, cleanup */ ++ WMD_DEH_Destroy((struct DEH_MGR *)pDehMgr); ++ *phDehMgr = NULL; ++ } else { ++ *phDehMgr = (struct DEH_MGR *)pDehMgr; ++ DBG_Trace(DBG_LEVEL1, "ISR_IRQ Object 0x%x \n", ++ pDehMgr); ++ } ++ DBG_Trace(DBG_LEVEL1, "Exiting DEH_Create.\n"); ++ return status; ++} ++ ++/* ++ * ======== WMD_DEH_Destroy ======== ++ * Destroys DEH manager object. ++ */ ++DSP_STATUS WMD_DEH_Destroy(struct DEH_MGR *hDehMgr) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEH_MGR *pDehMgr = (struct DEH_MGR *)hDehMgr; ++ ++ DBG_Trace(DBG_LEVEL1, "Entering DEH_Destroy: 0x%x\n", pDehMgr); ++ if (MEM_IsValidHandle(pDehMgr, SIGNATURE)) { ++ /* If notification object exists, delete it */ ++ if (pDehMgr->hNtfy) ++ (void)NTFY_Delete(pDehMgr->hNtfy); ++ /* Disable DSP MMU fault */ ++ free_irq(INT_DSP_MMU_IRQ, pDehMgr); ++ (void)DPC_Destroy(pDehMgr->hMmuFaultDpc); ++ /* Deallocate the DEH manager object */ ++ MEM_FreeObject(pDehMgr); ++ } ++ DBG_Trace(DBG_LEVEL1, "Exiting DEH_Destroy.\n"); ++ return status; ++} ++ ++/* ++ * ======== WMD_DEH_RegisterNotify ======== ++ * Registers for DEH notifications. ++ */ ++DSP_STATUS WMD_DEH_RegisterNotify(struct DEH_MGR *hDehMgr, u32 uEventMask, ++ u32 uNotifyType, ++ struct DSP_NOTIFICATION *hNotification) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEH_MGR *pDehMgr = (struct DEH_MGR *)hDehMgr; ++ ++ DBG_Trace(DBG_LEVEL1, "Entering WMD_DEH_RegisterNotify: 0x%x\n", ++ pDehMgr); ++ ++ if (MEM_IsValidHandle(pDehMgr, SIGNATURE)) { ++ status = NTFY_Register(pDehMgr->hNtfy, hNotification, ++ uEventMask, uNotifyType); ++ } ++ DBG_Trace(DBG_LEVEL1, "Exiting WMD_DEH_RegisterNotify.\n"); ++ return status; ++} ++ ++ ++/* ++ * ======== WMD_DEH_Notify ======== ++ * DEH error notification function. Informs user about the error. ++ */ ++void WMD_DEH_Notify(struct DEH_MGR *hDehMgr, u32 ulEventMask, ++ u32 dwErrInfo) ++{ ++ struct DEH_MGR *pDehMgr = (struct DEH_MGR *)hDehMgr; ++ struct WMD_DEV_CONTEXT *pDevContext; ++ DSP_STATUS status = DSP_SOK; ++ u32 memPhysical = 0; ++ u32 HW_MMU_MAX_TLB_COUNT = 31; ++ u32 extern faultAddr; ++ struct CFG_HOSTRES resources; ++ u32 dummyVaAddr; ++ HW_STATUS hwStatus; ++ ++ status = CFG_GetHostResources( ++ (struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), ++ &resources); ++ if (DSP_FAILED(status)) ++ DBG_Trace(DBG_LEVEL7, ++ "**Failed to get Host Resources in MMU ISR **\n"); ++ ++ DBG_Trace(DBG_LEVEL1, "Entering WMD_DEH_Notify: 0x%x, 0x%x\n", pDehMgr, ++ ulEventMask); ++ if (MEM_IsValidHandle(pDehMgr, SIGNATURE)) { ++ printk(KERN_INFO "WMD_DEH_Notify: ********** DEVICE EXCEPTION " ++ "**********\n"); ++ pDevContext = (struct WMD_DEV_CONTEXT *)pDehMgr->hWmdContext; ++ ++ switch (ulEventMask) { ++ case DSP_SYSERROR: ++ /* reset errInfo structure before use */ ++ pDehMgr->errInfo.dwErrMask = DSP_SYSERROR; ++ pDehMgr->errInfo.dwVal1 = 0L; ++ pDehMgr->errInfo.dwVal2 = 0L; ++ pDehMgr->errInfo.dwVal3 = 0L; ++ pDehMgr->errInfo.dwVal1 = dwErrInfo; ++ printk(KERN_ERR "WMD_DEH_Notify: DSP_SYSERROR, errInfo " ++ "= 0x%x\n", dwErrInfo); ++ break; ++ case DSP_MMUFAULT: ++ /* MMU fault routine should have set err info ++ * structure */ ++ pDehMgr->errInfo.dwErrMask = DSP_MMUFAULT; ++ printk(KERN_INFO "WMD_DEH_Notify: DSP_MMUFAULT," ++ "errInfo = 0x%x\n", dwErrInfo); ++ printk(KERN_INFO "WMD_DEH_Notify: DSP_MMUFAULT, High " ++ "Address = 0x%x\n", ++ (unsigned int)pDehMgr->errInfo.dwVal1); ++ printk(KERN_INFO "WMD_DEH_Notify: DSP_MMUFAULT, Low " ++ "Address = 0x%x\n", ++ (unsigned int)pDehMgr->errInfo.dwVal2); ++ printk(KERN_INFO "WMD_DEH_Notify: DSP_MMUFAULT, fault " ++ "address = 0x%x\n", (unsigned int)faultAddr); ++ dummyVaAddr = (u32)MEM_Calloc(sizeof(char) * 0x1000, ++ MEM_PAGED); ++ memPhysical = (u32)MEM_Calloc(sizeof(char) * 0x1000, ++ MEM_PAGED); ++ dummyVaAddr = PG_ALIGN_LOW((u32)dummyVaAddr, ++ PG_SIZE_4K); ++ memPhysical = VirtToPhys(dummyVaAddr); ++ DBG_Trace(DBG_LEVEL6, "WMD_DEH_Notify: DSP_MMUFAULT, " ++ "mem Physical= 0x%x\n", memPhysical); ++ pDevContext = (struct WMD_DEV_CONTEXT *) ++ pDehMgr->hWmdContext; ++ /* Reset the dynamic mmu index to fixed count if it ++ * exceeds 31. So that the dynmmuindex is always ++ * between the range of standard/fixed entries ++ * and 31. */ ++ if (pDevContext->numTLBEntries > ++ HW_MMU_MAX_TLB_COUNT) { ++ pDevContext->numTLBEntries = pDevContext-> ++ fixedTLBEntries; ++ } ++ DBG_Trace(DBG_LEVEL6, "Adding TLB Entry %d: VA: 0x%x, " ++ "PA: 0x%x\n", pDevContext-> ++ numTLBEntries, faultAddr, memPhysical); ++ if (DSP_SUCCEEDED(status)) { ++ hwStatus = HW_MMU_TLBAdd(resources.dwDmmuBase, ++ memPhysical, faultAddr, ++ HW_PAGE_SIZE_4KB, 1, &mapAttrs, ++ HW_SET, HW_SET); ++ } ++ /* send an interrupt to DSP */ ++ HW_MBOX_MsgWrite(resources.dwMboxBase, MBOX_ARM2DSP, ++ MBX_DEH_CLASS | MBX_DEH_EMMU); ++ /* Clear MMU interrupt */ ++ HW_MMU_EventAck(resources.dwDmmuBase, ++ HW_MMU_TRANSLATION_FAULT); ++ break; ++ default: ++ DBG_Trace(DBG_LEVEL6, ++ "WMD_DEH_Notify: Unknown Error, errInfo = " ++ "0x%x\n", dwErrInfo); ++ break; ++ } ++ /* Set the Board state as ERROR */ ++ pDevContext->dwBrdState = BRD_ERROR; ++ /* Disable all the clocks that were enabled by DSP */ ++ (void)DSP_PeripheralClocks_Disable(pDevContext, NULL); ++ /* Call DSP Trace Buffer */ ++ PrintDspTraceBuffer(hDehMgr->hWmdContext); ++ ++ /* Signal DSP error/exception event. */ ++ NTFY_Notify(pDehMgr->hNtfy, ulEventMask); ++ } ++ DBG_Trace(DBG_LEVEL1, "Exiting WMD_DEH_Notify\n"); ++ ++} ++ ++/* ++ * ======== WMD_DEH_GetInfo ======== ++ * Retrieves error information. ++ */ ++DSP_STATUS WMD_DEH_GetInfo(struct DEH_MGR *hDehMgr, ++ struct DSP_ERRORINFO *pErrInfo) ++{ ++ DSP_STATUS status = DSP_SOK; ++ struct DEH_MGR *pDehMgr = (struct DEH_MGR *)hDehMgr; ++ ++ DBC_Require(pDehMgr); ++ DBC_Require(pErrInfo); ++ ++ DBG_Trace(DBG_LEVEL1, "Entering WMD_DEH_GetInfo: 0x%x\n", hDehMgr); ++ ++ if (MEM_IsValidHandle(pDehMgr, SIGNATURE)) { ++ /* Copy DEH error info structure to PROC error info ++ * structure. */ ++ pErrInfo->dwErrMask = pDehMgr->errInfo.dwErrMask; ++ pErrInfo->dwVal1 = pDehMgr->errInfo.dwVal1; ++ pErrInfo->dwVal2 = pDehMgr->errInfo.dwVal2; ++ pErrInfo->dwVal3 = pDehMgr->errInfo.dwVal3; ++ } ++ ++ DBG_Trace(DBG_LEVEL1, "Exiting WMD_DEH_GetInfo\n"); ++ ++ return status; ++} +-- +1.5.6.3 + diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/dss2-blank-rotate-accessible-by-user.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/dss2-blank-rotate-accessible-by-user.patch new file mode 100644 index 0000000000..d75f15d00a --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/dss2-blank-rotate-accessible-by-user.patch @@ -0,0 +1,20 @@ +--- a/drivers/video/fbsysfs.c 2009-07-17 12:23:16.000000000 -0700 ++++ b/drivers/video/fbsysfs.c 2009-07-17 12:24:32.000000000 -0700 +@@ -489,7 +489,7 @@ + * fbdev to use configfs instead of sysfs */ + static struct device_attribute device_attrs[] = { + __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp), +- __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank), ++ __ATTR(blank, S_IRUGO|S_IWUGO, show_blank, store_blank), + __ATTR(console, S_IRUGO|S_IWUSR, show_console, store_console), + __ATTR(cursor, S_IRUGO|S_IWUSR, show_cursor, store_cursor), + __ATTR(mode, S_IRUGO|S_IWUSR, show_mode, store_mode), +@@ -498,7 +498,7 @@ + __ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual), + __ATTR(name, S_IRUGO, show_name, NULL), + __ATTR(stride, S_IRUGO, show_stride, NULL), +- __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate), ++ __ATTR(rotate, S_IRUGO|S_IWUGO, show_rotate, store_rotate), + __ATTR(state, S_IRUGO|S_IWUSR, show_fbstate, store_fbstate), + #ifdef CONFIG_FB_BACKLIGHT + __ATTR(bl_curve, S_IRUGO|S_IWUSR, show_bl_curve, store_bl_curve), diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/dss2-export-status.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/dss2-export-status.patch new file mode 100644 index 0000000000..eaa78e28c7 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/dss2-export-status.patch @@ -0,0 +1,44 @@ +From c78da49092fd206943f77aa9ebc3fa2c1301ac5a Mon Sep 17 00:00:00 2001 +From: Tim Yamin +Date: Thu, 23 Apr 2009 18:19:32 -0700 +Subject: [PATCH] DSS2: Export display status to sysfs + +It is useful to know from userspace if the display has been turned off, +e.g. to toggle display power from userspace. + +Signed-off-by: Tim Yamin +--- + drivers/video/omap2/omapfb/omapfb-sysfs.c | 10 ++++++++++ + 1 files changed, 10 insertions(+), 0 deletions(-) + +diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c +index 2c88718..28438fb 100644 +--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c ++++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c +@@ -326,6 +326,15 @@ static ssize_t show_virt(struct device *dev, + return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region.vaddr); + } + ++static ssize_t show_display_state(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct fb_info *fbi = dev_get_drvdata(dev); ++ struct omap_display *display = fb2display(fbi); ++ ++ return snprintf(buf, PAGE_SIZE, "%d\n", display->state); ++} ++ + static struct device_attribute omapfb_attrs[] = { + __ATTR(rotate_type, S_IRUGO, show_rotate_type, NULL), + __ATTR(mirror, S_IRUGO | S_IWUSR, show_mirror, store_mirror), +@@ -333,6 +342,7 @@ static struct device_attribute omapfb_attrs[] = { + __ATTR(overlays, S_IRUGO | S_IWUSR, show_overlays, store_overlays), + __ATTR(phys_addr, S_IRUGO, show_phys, NULL), + __ATTR(virt_addr, S_IRUGO, show_virt, NULL), ++ __ATTR(display_state, S_IRUGO, show_display_state, NULL), + }; + + int omapfb_create_sysfs(struct omapfb2_device *fbdev) +-- +1.5.6.3 + diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/dss2-fix-XY-coordinates-when-rotating.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/dss2-fix-XY-coordinates-when-rotating.patch new file mode 100644 index 0000000000..98a82c8a35 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/dss2-fix-XY-coordinates-when-rotating.patch @@ -0,0 +1,177 @@ +From a9cc890ffea21fa492678b1755a263120cbddf0e Mon Sep 17 00:00:00 2001 +From: Tim Yamin +Date: Mon, 20 Apr 2009 20:29:11 -0700 +Subject: [PATCH] DSS2: OMAPFB: Translate X/Y coordinates for the video planes when rotating. + +When rotating the video planes, translate the X/Y coordinates such that +a [0,0] from userspace always maps to the correct upper left corner of +the display. This patch assumes that you rotate plane 0 before rotating +plane 1. Patch also corrects the scaling parameters so that the video is +displayed in the correct orientation (vertically, instead of horizontally) +when rotating by 90 / 270 degrees. + +Signed-off-by: Tim Yamin +--- + drivers/video/omap2/dss/dispc.c | 16 ++++++++++++---- + drivers/video/omap2/dss/overlay.c | 6 ++++++ + drivers/video/omap2/omapfb/omapfb-ioctl.c | 28 ++++++++++++++++++++++++++++ + 3 files changed, 46 insertions(+), 4 deletions(-) + +diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c +index 7e551c2..bece91d 100644 +--- a/drivers/video/omap2/dss/dispc.c ++++ b/drivers/video/omap2/dss/dispc.c +@@ -1580,10 +1580,18 @@ static int _dispc_setup_plane(enum omap_plane plane, + _dispc_set_pic_size(plane, width, height); + + if (plane != OMAP_DSS_GFX) { +- _dispc_set_scaling(plane, width, height, +- out_width, out_height, +- ilace, five_taps, fieldmode); +- _dispc_set_vid_size(plane, out_width, out_height); ++ if (rotation == 1 || rotation == 3) { ++ _dispc_set_scaling(plane, width, height, ++ out_height, out_width, ++ ilace, five_taps, fieldmode); ++ _dispc_set_vid_size(plane, out_height, out_width); ++ } else { ++ _dispc_set_scaling(plane, width, height, ++ out_width, out_height, ++ ilace, five_taps, fieldmode); ++ _dispc_set_vid_size(plane, out_width, out_height); ++ } ++ + _dispc_set_vid_color_conv(plane, cconv); + } + +diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c +index c047206..a1a02b5 100644 +--- a/drivers/video/omap2/dss/overlay.c ++++ b/drivers/video/omap2/dss/overlay.c +@@ -344,6 +344,20 @@ + outh = info->out_height; + } + ++ if ((ovl->supported_modes & info->color_mode) == 0) { ++ DSSERR("overlay doesn't support mode %d\n", info->color_mode); ++ return -EINVAL; ++ } ++ ++ if (ovl->id != OMAP_DSS_GFX && (info->rotation == 1 || ++ info->rotation == 3)) { ++ if(outw > dh || outh > dw) ++ return -EINVAL; ++ ++ /* If coordinates are invalid, they will be clipped later... */ ++ return 0; ++ } ++ + if (dw < info->pos_x + outw) { + DSSDBG("check_overlay failed 1: %d < %d + %d\n", + dw, info->pos_x, outw); +@@ -356,11 +370,6 @@ + return -EINVAL; + } + +- if ((ovl->supported_modes & info->color_mode) == 0) { +- DSSERR("overlay doesn't support mode %d\n", info->color_mode); +- return -EINVAL; +- } +- + return 0; + } + +diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c +index 79d8916..b548f62 100644 +--- a/drivers/video/omap2/dss/manager.c ++++ b/drivers/video/omap2/dss/manager.c +@@ -400,7 +400,7 @@ + struct omap_overlay *ovl; + bool ilace = 0; + int outw, outh; +- int r; ++ int r, pos_x = 0, pos_y = 0; + int num_planes_enabled = 0; + + DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name); +@@ -451,11 +451,51 @@ + else + outh = ovl->info.out_height; + ++ if (ovl->id != OMAP_DSS_GFX && ovl->info.rotation != 0) { ++ /* We need to rotate pos_x and pos_y with respect ++ to OMAP_DSS_GFX */ ++ ++ u16 dw, dh; ++ display->get_resolution(display, &dw, &dh); ++ ++ DSSDBG("plane pos was: (%d, %d), %dx%d, scr: %dx%d \n", ovl->info.pos_x, ++ ovl->info.pos_y, outw, outh, dw, dh); ++ ++ switch (ovl->info.rotation) { ++ case 1: ++ pos_y = ovl->info.pos_x; ++ pos_x = dw - ovl->info.pos_y - outh; ++ break; ++ case 2: ++ pos_x = dw - ovl->info.pos_x - outw; ++ pos_y = dh - ovl->info.pos_y - outh; ++ break; ++ case 3: ++ pos_x = ovl->info.pos_y; ++ pos_y = dh - ovl->info.pos_x - outw; ++ break; ++ } ++ ++ /* Check sanity */ ++ if (ovl->info.rotation != 2) { ++ if (dw < pos_x + outh) ++ pos_x = pos_y = 0; ++ else if (dh < pos_y + outw) ++ pos_x = pos_y = 0; ++ } else if ( (dw < ovl->info.pos_x + outw) || (dh < ovl->info.pos_y + outh) ) ++ pos_x = pos_y = 0; ++ ++ DSSDBG("pos_x is %d, pos_y is %d\n", pos_x, pos_y); ++ } else { ++ pos_x = ovl->info.pos_x; ++ pos_y = ovl->info.pos_y; ++ } ++ + r = dispc_setup_plane(ovl->id, ovl->manager->id, + ovl->info.paddr, + ovl->info.screen_width, +- ovl->info.pos_x, +- ovl->info.pos_y, ++ pos_x, ++ pos_y, + ovl->info.width, + ovl->info.height, + outw, +diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c +index 79d8916..b548f62 100644 +--- a/drivers/video/omap2/omapfb/omapfb-main.c ++++ b/drivers/video/omap2/omapfb/omapfb-main.c +@@ -484,22 +484,7 @@ + + if (var->rotate != fbi->var.rotate) { + DBG("rotation changing\n"); +- + ofbi->rotation = var->rotate; +- +- if (abs(var->rotate - fbi->var.rotate) != 2) { +- int tmp; +- DBG("rotate changing 90/270 degrees. " +- "swapping x/y res\n"); +- +- tmp = var->yres; +- var->yres = var->xres; +- var->xres = tmp; +- +- tmp = var->yres_virtual; +- var->yres_virtual = var->xres_virtual; +- var->xres_virtual = tmp; +- } + } + + xres_min = OMAPFB_PLANE_XRES_MIN; diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/dss2-fix-scaling-when-rotating.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/dss2-fix-scaling-when-rotating.patch new file mode 100644 index 0000000000..7cb8a7d9bf --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/dss2-fix-scaling-when-rotating.patch @@ -0,0 +1,52 @@ +From 19a31ba4e8408ce80a4dbb96af489304c5e8128f Mon Sep 17 00:00:00 2001 +From: Tim Yamin +Date: Fri, 22 May 2009 18:58:33 -0700 +Subject: [PATCH] Fix scaling checks when rotation is 90 or 270 degrees. + +--- + drivers/video/omap2/dss/dispc.c | 25 +++++++++++++++++++------ + 1 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c +index 088d353..77ca81b 100644 +--- a/drivers/video/omap2/dss/dispc.c ++++ b/drivers/video/omap2/dss/dispc.c +@@ -1508,16 +1508,29 @@ static int _dispc_setup_plane(enum omap_plane plane, + } + } else { + /* video plane */ +- ++ u8 error = 0; + unsigned long fclk = 0; + +- if (out_width < width / maxdownscale || +- out_width > width * 8) +- return -EINVAL; ++ if(rotation == 1 || rotation == 3) ++ { ++ if (out_width < height / maxdownscale || out_width > height * 8) ++ error = 1; ++ ++ if (out_height < width / maxdownscale || out_height > width * 8) ++ error = 1; ++ } else { ++ if (out_width < width / maxdownscale || out_width > width * 8) ++ error = 1; + +- if (out_height < height / maxdownscale || +- out_height > height * 8) ++ if (out_height < height / maxdownscale || out_height > height * 8) ++ error = 1; ++ } ++ ++ if(error != 0) ++ { ++ printk("DSS: Unable to down/up scale video plane\n"); + return -EINVAL; ++ } + + switch (color_mode) { + case OMAP_DSS_COLOR_RGB16: +-- +1.5.6.3 + diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/ehci.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/ehci.patch new file mode 100644 index 0000000000..5a8c84471b --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/ehci.patch @@ -0,0 +1,131 @@ +Index: git/arch/arm/mach-omap2/board-omap3beagle.c +=================================================================== +--- git.orig/arch/arm/mach-omap2/board-omap3beagle.c ++++ git/arch/arm/mach-omap2/board-omap3beagle.c +@@ -154,6 +154,7 @@ static int beagle_twl_gpio_setup(struct + * power switch and overcurrent detect + */ + ++#if 0 /* TODO: This needs to be modified to not rely on u-boot */ + gpio_request(gpio + 1, "EHCI_nOC"); + gpio_direction_input(gpio + 1); + +@@ -163,7 +164,7 @@ static int beagle_twl_gpio_setup(struct + + /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ + gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; +- ++#endif + return 0; + } + +Index: git/arch/arm/mach-omap2/usb-ehci.c +=================================================================== +--- git.orig/arch/arm/mach-omap2/usb-ehci.c ++++ git/arch/arm/mach-omap2/usb-ehci.c +@@ -147,9 +147,11 @@ static void setup_ehci_io_mux(void) + + void __init usb_ehci_init(void) + { ++#if 0 /* TODO: Setup Pin IO MUX for EHCI - moved this temporarily to U-boot */ + /* Setup Pin IO MUX for EHCI */ + if (cpu_is_omap34xx()) + setup_ehci_io_mux(); ++#endif + + if (platform_device_register(&ehci_device) < 0) { + printk(KERN_ERR "Unable to register HS-USB (EHCI) device\n"); +Index: git/drivers/usb/host/ehci-omap.c +=================================================================== +--- git.orig/drivers/usb/host/ehci-omap.c ++++ git/drivers/usb/host/ehci-omap.c +@@ -48,16 +48,25 @@ + * to get the PHY state machine in working state + */ + #define EXTERNAL_PHY_RESET ++#ifdef CONFIG_MACH_OMAP3_BEAGLE ++#define EXT_PHY_RESET_GPIO_PORT2 (147) ++#else + #define EXT_PHY_RESET_GPIO_PORT1 (57) + #define EXT_PHY_RESET_GPIO_PORT2 (61) ++#endif + #define EXT_PHY_RESET_DELAY (10) + ++#define PHY_STP_PULLUP_ENABLE (0x10) ++#define PHY_STP_PULLUP_DISABLE (0x90) ++ + /* ISSUE2: + * USBHOST supports External charge pump PHYs only + * Use the VBUS from Port1 to power VBUS of Port2 externally + * So use Port2 as the working ULPI port + */ ++#ifndef CONFIG_MACH_OMAP3_BEAGLE + #define VBUS_INTERNAL_CHARGEPUMP_HACK ++#endif + + #endif /* CONFIG_OMAP_EHCI_PHY_MODE */ + +@@ -225,14 +234,43 @@ static int omap_start_ehc(struct platfor + + #ifdef EXTERNAL_PHY_RESET + /* Refer: ISSUE1 */ ++#ifndef CONFIG_MACH_OMAP3_BEAGLE + gpio_request(EXT_PHY_RESET_GPIO_PORT1, "USB1 PHY reset"); + gpio_direction_output(EXT_PHY_RESET_GPIO_PORT1, 0); ++#endif + gpio_request(EXT_PHY_RESET_GPIO_PORT2, "USB2 PHY reset"); + gpio_direction_output(EXT_PHY_RESET_GPIO_PORT2, 0); ++ gpio_set_value(EXT_PHY_RESET_GPIO_PORT2, 0); + /* Hold the PHY in RESET for enough time till DIR is high */ + udelay(EXT_PHY_RESET_DELAY); + #endif + ++ /* ++ * The PHY register 0x7 - Interface Control register is ++ * configured to disable the integrated STP pull-up resistor ++ * used for interface protection. ++ * ++ * May not need to be here. ++ */ ++ omap_writel((0x7 << EHCI_INSNREG05_ULPI_REGADD_SHIFT) |/* interface reg */ ++ (2 << EHCI_INSNREG05_ULPI_OPSEL_SHIFT) |/* Write */ ++ (1 << EHCI_INSNREG05_ULPI_PORTSEL_SHIFT) |/* Port1 */ ++ (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT) |/* Start */ ++ (PHY_STP_PULLUP_DISABLE), ++ EHCI_INSNREG05_ULPI); ++ ++ while (!(omap_readl(EHCI_INSNREG05_ULPI) & (1<usbtll_fck_clk = clk_get(&dev->dev, USBHOST_TLL_FCLK); + if (IS_ERR(ehci_clocks->usbtll_fck_clk)) +@@ -307,7 +345,9 @@ static int omap_start_ehc(struct platfor + * Hold the PHY in RESET for enough time till PHY is settled and ready + */ + udelay(EXT_PHY_RESET_DELAY); ++#ifndef CONFIG_MACH_OMAP3_BEAGLE + gpio_set_value(EXT_PHY_RESET_GPIO_PORT1, 1); ++#endif + gpio_set_value(EXT_PHY_RESET_GPIO_PORT2, 1); + #endif + +@@ -393,7 +433,9 @@ static void omap_stop_ehc(struct platfor + + + #ifdef EXTERNAL_PHY_RESET ++#ifndef CONFIG_MACH_OMAP3_BEAGLE + gpio_free(EXT_PHY_RESET_GPIO_PORT1); ++#endif + gpio_free(EXT_PHY_RESET_GPIO_PORT2); + #endif + diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/logo_linux_clut224.ppm b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/logo_linux_clut224.ppm new file mode 100644 index 0000000000..76b746bf91 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/logo_linux_clut224.ppm @@ -0,0 +1,773 @@ +P3 +171 35 +255 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 204 204 204 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 136 136 136 0 0 0 0 0 0 0 0 0 +85 85 85 255 255 255 255 255 255 255 255 255 255 255 255 17 17 17 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 204 204 204 255 255 255 119 119 119 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 170 170 170 204 204 204 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 204 204 204 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 187 187 187 0 0 0 0 0 0 +85 85 85 255 255 255 255 255 255 255 255 255 255 255 255 17 17 17 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 204 204 204 255 255 255 119 119 119 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 238 238 238 255 255 255 17 17 17 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 119 119 119 255 255 255 +119 119 119 0 0 0 0 0 0 34 34 34 221 221 221 255 255 255 68 68 68 0 0 0 +0 0 0 0 0 0 0 0 0 204 204 204 255 255 255 17 17 17 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 238 238 238 255 255 255 17 17 17 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 119 119 119 255 255 255 +119 119 119 0 0 0 0 0 0 0 0 0 136 136 136 255 255 255 119 119 119 0 0 0 +0 0 0 0 0 0 0 0 0 204 204 204 255 255 255 17 17 17 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 136 136 136 238 238 238 255 255 255 255 255 255 +187 187 187 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 119 119 119 187 187 187 +255 255 255 255 255 255 255 255 255 187 187 187 85 85 85 0 0 0 0 0 0 0 0 0 +0 0 0 17 17 17 153 153 153 255 255 255 255 255 255 255 255 255 238 238 238 255 255 255 +85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 187 187 187 255 255 255 255 255 255 +238 238 238 136 136 136 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 102 102 102 +255 255 255 255 255 255 255 255 255 119 119 119 0 0 0 0 0 0 187 187 187 255 255 255 +255 255 255 255 255 255 68 68 68 0 0 0 119 119 119 187 187 187 255 255 255 255 255 255 +255 255 255 187 187 187 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 204 204 204 +255 255 255 255 255 255 255 255 255 136 136 136 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 153 153 153 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 102 102 102 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 119 119 119 255 255 255 +119 119 119 0 0 0 0 0 0 85 85 85 238 238 238 255 255 255 51 51 51 0 0 0 +0 0 0 0 0 0 0 0 0 204 204 204 255 255 255 17 17 17 0 0 0 0 0 0 +0 0 0 0 0 0 17 17 17 204 204 204 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 102 102 102 0 0 0 0 0 0 0 0 0 204 204 204 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 51 51 51 0 0 0 0 0 0 +0 0 0 221 221 221 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +119 119 119 0 0 0 0 0 0 119 119 119 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 204 204 204 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 102 102 102 +255 255 255 255 255 255 255 255 255 119 119 119 0 0 0 0 0 0 187 187 187 255 255 255 +255 255 255 255 255 255 68 68 68 0 0 0 204 204 204 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 51 51 51 0 0 0 0 0 0 0 0 0 204 204 204 +255 255 255 255 255 255 255 255 255 136 136 136 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 153 153 153 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 102 102 102 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 119 119 119 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 153 153 153 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 204 204 204 255 255 255 17 17 17 0 0 0 0 0 0 +0 0 0 0 0 0 153 153 153 255 255 255 170 170 170 17 17 17 0 0 0 0 0 0 +102 102 102 221 221 221 238 238 238 17 17 17 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 204 204 204 255 255 255 102 102 102 0 0 0 0 0 0 +34 34 34 255 255 255 238 238 238 17 17 17 0 0 0 0 0 0 136 136 136 255 255 255 +85 85 85 0 0 0 34 34 34 255 255 255 221 221 221 102 102 102 0 0 0 0 0 0 +17 17 17 170 170 170 255 255 255 136 136 136 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +119 119 119 255 255 255 119 119 119 68 68 68 255 255 255 221 221 221 0 0 0 187 187 187 +255 255 255 102 102 102 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 204 204 204 255 255 255 102 102 102 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 255 255 255 136 136 136 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 238 238 238 255 255 255 17 17 17 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 119 119 119 255 255 255 +255 255 255 255 255 255 255 255 255 221 221 221 119 119 119 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 204 204 204 255 255 255 17 17 17 0 0 0 0 0 0 +0 0 0 0 0 0 238 238 238 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 102 102 102 0 0 0 0 0 0 51 51 51 170 170 170 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 119 119 119 0 0 0 0 0 0 +0 0 0 170 170 170 255 255 255 255 255 255 255 255 255 187 187 187 136 136 136 51 51 51 +0 0 0 0 0 0 119 119 119 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 221 221 221 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +68 68 68 255 255 255 187 187 187 153 153 153 255 255 255 255 255 255 85 85 85 238 238 238 +255 255 255 34 34 34 0 0 0 0 0 0 51 51 51 170 170 170 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 119 119 119 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 255 255 255 136 136 136 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 238 238 238 255 255 255 17 17 17 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 119 119 119 255 255 255 +119 119 119 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 204 204 204 255 255 255 17 17 17 0 0 0 0 0 0 +0 0 0 0 0 0 238 238 238 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 119 119 119 0 0 0 68 68 68 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 119 119 119 0 0 0 0 0 0 +0 0 0 0 0 0 51 51 51 136 136 136 136 136 136 136 136 136 255 255 255 255 255 255 +102 102 102 0 0 0 119 119 119 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 238 238 238 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 238 238 238 221 221 221 238 238 238 255 255 255 255 255 255 204 204 204 255 255 255 +221 221 221 0 0 0 0 0 0 68 68 68 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 119 119 119 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 255 255 255 136 136 136 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 238 238 238 255 255 255 17 17 17 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 119 119 119 255 255 255 +119 119 119 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 204 204 204 255 255 255 17 17 17 0 0 0 0 0 0 +0 0 0 0 0 0 170 170 170 255 255 255 153 153 153 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 255 255 255 136 136 136 +0 0 0 0 0 0 51 51 51 204 204 204 255 255 255 119 119 119 0 0 0 0 0 0 +102 102 102 255 255 255 153 153 153 0 0 0 0 0 0 0 0 0 102 102 102 255 255 255 +204 204 204 0 0 0 51 51 51 255 255 255 204 204 204 85 85 85 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 204 204 204 255 255 255 255 255 255 170 170 170 221 221 221 255 255 255 255 255 255 +153 153 153 0 0 0 0 0 0 170 170 170 255 255 255 136 136 136 0 0 0 0 0 0 +51 51 51 204 204 204 255 255 255 119 119 119 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 85 85 85 255 255 255 136 136 136 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 238 238 238 255 255 255 51 51 51 0 0 0 0 0 0 +119 119 119 238 238 238 119 119 119 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 204 204 204 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 102 102 102 0 0 0 0 0 0 0 0 0 17 17 17 +238 238 238 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +85 85 85 0 0 0 17 17 17 221 221 221 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 102 102 102 0 0 0 136 136 136 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 204 204 204 0 0 0 +136 136 136 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +136 136 136 0 0 0 0 0 0 119 119 119 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 221 221 221 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 153 153 153 255 255 255 255 255 255 85 85 85 119 119 119 255 255 255 255 255 255 +102 102 102 0 0 0 0 0 0 136 136 136 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 204 204 204 0 0 0 136 136 136 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 204 204 204 0 0 0 +0 0 0 0 0 0 0 0 0 170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 +255 255 255 255 255 255 136 136 136 0 0 0 0 0 0 0 0 0 17 17 17 221 221 221 +255 255 255 102 102 102 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 68 68 68 255 255 255 238 238 238 34 34 34 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 68 68 68 255 255 255 238 238 238 34 34 34 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 204 204 204 255 255 255 255 255 255 +255 255 255 255 255 255 255 255 255 102 102 102 0 0 0 0 0 0 0 0 0 17 17 17 +238 238 238 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +85 85 85 0 0 0 0 0 0 17 17 17 136 136 136 255 255 255 255 255 255 255 255 255 +255 255 255 187 187 187 136 136 136 17 17 17 0 0 0 0 0 0 119 119 119 255 255 255 +255 255 255 255 255 255 136 136 136 187 187 187 255 255 255 255 255 255 204 204 204 0 0 0 +102 102 102 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 204 204 204 119 119 119 +0 0 0 0 0 0 0 0 0 0 0 0 102 102 102 187 187 187 255 255 255 255 255 255 +255 255 255 255 255 255 136 136 136 102 102 102 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 102 102 102 255 255 255 221 221 221 0 0 0 17 17 17 238 238 238 255 255 255 +34 34 34 0 0 0 0 0 0 0 0 0 119 119 119 255 255 255 255 255 255 255 255 255 +136 136 136 187 187 187 255 255 255 255 255 255 204 204 204 0 0 0 136 136 136 255 255 255 +255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 204 204 204 0 0 0 +0 0 0 0 0 0 0 0 0 17 17 17 170 170 170 255 255 255 255 255 255 255 255 255 +153 153 153 102 102 102 0 0 0 0 0 0 0 0 0 0 0 0 17 17 17 221 221 221 +255 255 255 102 102 102 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 68 68 68 255 255 255 238 238 238 34 34 34 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 68 68 68 255 255 255 238 238 238 34 34 34 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/memory-move-malloc-end.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/memory-move-malloc-end.patch new file mode 100644 index 0000000000..9000642104 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/memory-move-malloc-end.patch @@ -0,0 +1,9 @@ +--- git/arch/arm/plat-omap/include/mach/vmalloc.h 2009-06-09 15:14:54.000000000 -0700 ++++ git/arch/arm/plat-omap/include/mach/vmalloc.h 2009-06-09 15:06:35.000000000 -0700 +@@ -17,5 +17,5 @@ + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +-#define VMALLOC_END (PAGE_OFFSET + 0x18000000) ++#define VMALLOC_END (PAGE_OFFSET + 0x28000000) + diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/screen-backlight-accessible-by-user.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/screen-backlight-accessible-by-user.patch new file mode 100644 index 0000000000..14e0934468 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/screen-backlight-accessible-by-user.patch @@ -0,0 +1,11 @@ +--- a/drivers/video/backlight/backlight.c 2009-07-17 12:20:05.000000000 -0700 ++++ b/drivers/video/backlight/backlight.c 2009-07-17 12:20:46.000000000 -0700 +@@ -205,7 +205,7 @@ + + static struct device_attribute bl_device_attributes[] = { + __ATTR(bl_power, 0644, backlight_show_power, backlight_store_power), +- __ATTR(brightness, 0644, backlight_show_brightness, ++ __ATTR(brightness, 0666, backlight_show_brightness, + backlight_store_brightness), + __ATTR(actual_brightness, 0444, backlight_show_actual_brightness, + NULL), diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/screen-backlight.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/screen-backlight.patch new file mode 100644 index 0000000000..65b551f1de --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/screen-backlight.patch @@ -0,0 +1,10 @@ +--- a/arch/arm/mach-omap2/Kconfig ++++ b/arch/arm/mach-omap2/Kconfig +@@ -128,6 +128,7 @@ config MACH_OMAP3EVM + config MACH_OMAP3_BEAGLE + bool "OMAP3 BEAGLE board" + depends on ARCH_OMAP3 && ARCH_OMAP34XX ++ select BACKLIGHT_CLASS_DEVICE + + config MACH_OVERO + bool "Gumstix Overo board" diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/sound-headphone-detection.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/sound-headphone-detection.patch new file mode 100644 index 0000000000..ef8b3626bc --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/sound-headphone-detection.patch @@ -0,0 +1,93 @@ +From db8f1eba9154789c45c6a92413bbbd94f5d9c7f5 Mon Sep 17 00:00:00 2001 +From: Tim Yamin +Date: Wed, 29 Apr 2009 17:30:25 -0700 +Subject: [PATCH] Touch Book: turn on/off the class D amplifier depending on whether the + headphones are plugged into the jack or not. + +Signed-off-by: Tim Yamin +--- + sound/soc/omap/omap3beagle.c | 33 +++++++++++++++++++++++++++++++++ + 1 files changed, 33 insertions(+), 0 deletions(-) + +diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c +index fd24a4a..1236638 100644 +--- a/sound/soc/omap/omap3beagle.c ++++ b/sound/soc/omap/omap3beagle.c +@@ -20,7 +20,10 @@ + */ + + #include ++#include ++#include + #include ++ + #include + #include + #include +@@ -35,6 +38,9 @@ + #include "omap-pcm.h" + #include "../codecs/twl4030.h" + ++#define TB_HEADPHONE_GPIO 56 ++#define TB_HEADPHONE_IRQ OMAP_GPIO_IRQ(TB_HEADPHONE_GPIO) ++ + static int omap3beagle_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) + { +@@ -103,6 +109,33 @@ static struct snd_soc_device omap3beagle_snd_devdata = { + + static struct platform_device *omap3beagle_snd_device; + ++static void jack_work_func(struct work_struct *wq) ++{ ++ struct snd_soc_device *socdev = platform_get_drvdata(omap3beagle_snd_device); ++ struct snd_soc_codec *codec = socdev->codec; ++ ++ snd_soc_dapm_sync(codec); ++} ++DECLARE_WORK(jack_work, jack_work_func); ++ ++static irqreturn_t touchbook_headphone_event(int irq, void *snd) ++{ ++ int status = gpio_get_value(TB_HEADPHONE_GPIO); ++ struct snd_soc_device *socdev = platform_get_drvdata(omap3beagle_snd_device); ++ struct snd_soc_codec *codec = socdev->codec; ++ ++ if(status) { ++ snd_soc_dapm_disable_pin(codec, "HFL"); ++ snd_soc_dapm_disable_pin(codec, "HFR"); ++ } else { ++ snd_soc_dapm_enable_pin(codec, "HFL"); ++ snd_soc_dapm_enable_pin(codec, "HFR"); ++ } ++ ++ schedule_work(&jack_work); ++ return IRQ_HANDLED; ++} ++ + static int __init omap3beagle_soc_init(void) + { + int ret; +@@ -123,10 +156,22 @@ static int __init omap3beagle_soc_init(void) + omap3beagle_snd_devdata.dev = &omap3beagle_snd_device->dev; + *(unsigned int *)omap3beagle_dai.cpu_dai->private_data = 1; /* McBSP2 */ + ++ /* Touch Book -- headphone jack sensor */ ++ omap_set_gpio_debounce(TB_HEADPHONE_GPIO, 1); ++ omap_set_gpio_debounce_time(TB_HEADPHONE_GPIO, 0xff); ++ ++ ret = request_irq(TB_HEADPHONE_IRQ, touchbook_headphone_event, IRQF_TRIGGER_RISING | ++ IRQF_TRIGGER_FALLING, "touchbook_headphone", omap3beagle_snd_device); ++ if (ret < 0) ++ goto err1; ++ + ret = platform_device_add(omap3beagle_snd_device); + if (ret) + goto err1; + ++ /* Detect headphone status */ ++ touchbook_headphone_event(0, omap3beagle_snd_device); ++ + return 0; + + err1: diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/tincantools-puppy.diff b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/tincantools-puppy.diff new file mode 100644 index 0000000000..c7856731e5 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/tincantools-puppy.diff @@ -0,0 +1,66 @@ +--- /tmp/board-omap3beagle.c 2009-07-01 01:06:44.000000000 +0200 ++++ git/arch/arm/mach-omap2/board-omap3beagle.c 2009-07-01 01:06:50.000000000 +0200 +@@ -125,6 +125,13 @@ + .wires = 8, + .gpio_wp = 29, + }, ++ { ++ .mmc = 2, ++ .wires = 4, ++ .gpio_wp = 141, ++ .gpio_cd = 162, ++ .transceiver = true, ++ }, + {} /* Terminator */ + }; + +@@ -132,6 +139,11 @@ + .supply = "vmmc", + }; + ++static struct regulator_consumer_supply beagle_vmmc2_supply = { ++ .supply = "vmmc", ++}; ++ ++ + static struct regulator_consumer_supply beagle_vsim_supply = { + .supply = "vmmc_aux", + }; +@@ -148,6 +160,7 @@ + + /* link regulators to MMC adapters */ + beagle_vmmc1_supply.dev = mmc[0].dev; ++ beagle_vmmc2_supply.dev = mmc[1].dev; + beagle_vsim_supply.dev = mmc[0].dev; + + /* REVISIT: need ehci-omap hooks for external VBUS +@@ -209,6 +222,21 @@ + .consumer_supplies = &beagle_vmmc1_supply, + }; + ++/* VMMC2 for MMC2 pins CMD, CLK, DAT0..DAT3 (max 100 mA) */ ++static struct regulator_init_data beagle_vmmc2 = { ++ .constraints = { ++ .min_uV = 2700000, ++ .max_uV = 3150000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL ++ | REGULATOR_MODE_STANDBY, ++ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE ++ | REGULATOR_CHANGE_MODE ++ | REGULATOR_CHANGE_STATUS, ++ }, ++ .num_consumer_supplies = 1, ++ .consumer_supplies = &beagle_vmmc2_supply, ++}; ++ + /* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */ + static struct regulator_init_data beagle_vsim = { + .constraints = { +@@ -284,6 +312,7 @@ + .gpio = &beagle_gpio_data, + .power = &beagle_power_data, + .vmmc1 = &beagle_vmmc1, ++ .vmmc2 = &beagle_vmmc2, + .vsim = &beagle_vsim, + .vdac = &beagle_vdac, + .vpll2 = &beagle_vpll2, diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/touchscreen-ads7846-export-settings.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/touchscreen-ads7846-export-settings.patch new file mode 100644 index 0000000000..f8353afee5 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/touchscreen-ads7846-export-settings.patch @@ -0,0 +1,87 @@ +diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c +index 7c3897f..0c62ace 100644 +--- a/drivers/input/touchscreen/ads7846.c ++++ b/drivers/input/touchscreen/ads7846.c +@@ -491,9 +491,82 @@ static ssize_t ads7846_disable_store(struct device *dev, + + static DEVICE_ATTR(disable, 0664, ads7846_disable_show, ads7846_disable_store); + ++static ssize_t show_debounce_max(struct device *dev, struct device_attribute *attr, char *buf) { ++ struct ads7846 *ts = dev_get_drvdata(dev); ++ return sprintf(buf, "%u\n", ts->debounce_max); ++} ++ ++static ssize_t show_debounce_tol(struct device *dev, struct device_attribute *attr, char *buf) { ++ struct ads7846 *ts = dev_get_drvdata(dev); ++ return sprintf(buf, "%u\n", ts->debounce_tol); ++} ++ ++static ssize_t show_debounce_rep(struct device *dev, struct device_attribute *attr, char *buf) { ++ struct ads7846 *ts = dev_get_drvdata(dev); ++ return sprintf(buf, "%u\n", ts->debounce_rep); ++} ++ ++static ssize_t show_x_plate_ohms(struct device *dev, struct device_attribute *attr, char *buf) { ++ struct ads7846 *ts = dev_get_drvdata(dev); ++ return sprintf(buf, "%u\n", ts->x_plate_ohms); ++} ++ ++static ssize_t write_debounce_max(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { ++ struct ads7846 *ts = dev_get_drvdata(dev); ++ unsigned long i; ++ ++ if (strict_strtoul(buf, 10, &i)) ++ return -EINVAL; ++ ++ ts->debounce_max = i; ++ return count; ++} ++ ++static ssize_t write_debounce_tol(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { ++ struct ads7846 *ts = dev_get_drvdata(dev); ++ unsigned long i; ++ ++ if (strict_strtoul(buf, 10, &i)) ++ return -EINVAL; ++ ++ ts->debounce_tol = i; ++ return count; ++} ++ ++static ssize_t write_debounce_rep(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { ++ struct ads7846 *ts = dev_get_drvdata(dev); ++ unsigned long i; ++ ++ if (strict_strtoul(buf, 10, &i)) ++ return -EINVAL; ++ ++ ts->debounce_rep = i; ++ return count; ++} ++ ++static ssize_t write_x_plate_ohms(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { ++ struct ads7846 *ts = dev_get_drvdata(dev); ++ unsigned long i; ++ ++ if (strict_strtoul(buf, 10, &i)) ++ return -EINVAL; ++ ++ ts->x_plate_ohms = i; ++ return count; ++} ++ ++static DEVICE_ATTR(debounce_max, S_IRUGO | S_IWUGO, show_debounce_max, write_debounce_max); ++static DEVICE_ATTR(debounce_tol, S_IRUGO | S_IWUGO, show_debounce_tol, write_debounce_tol); ++static DEVICE_ATTR(debounce_rep, S_IRUGO | S_IWUGO, show_debounce_rep, write_debounce_rep); ++static DEVICE_ATTR(x_plate_ohms, S_IRUGO | S_IWUGO, show_x_plate_ohms, write_x_plate_ohms); ++ + static struct attribute *ads784x_attributes[] = { + &dev_attr_pen_down.attr, + &dev_attr_disable.attr, ++ &dev_attr_debounce_max.attr, ++ &dev_attr_debounce_tol.attr, ++ &dev_attr_debounce_rep.attr, ++ &dev_attr_x_plate_ohms.attr, + NULL, + }; + diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/touchscreen-ads7846-rotation-support.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/touchscreen-ads7846-rotation-support.patch new file mode 100644 index 0000000000..6196716f23 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/touchscreen-ads7846-rotation-support.patch @@ -0,0 +1,108 @@ +diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c +index 0c62ace..8f6e83c 100644 +--- a/drivers/input/touchscreen/ads7846.c ++++ b/drivers/input/touchscreen/ads7846.c +@@ -127,6 +127,7 @@ struct ads7846 { + void (*filter_cleanup)(void *data); + int (*get_pendown_state)(void); + int gpio_pendown; ++ int rotate; + }; + + /* leave chip selected when we're done, for quicker re-select? */ +@@ -511,6 +512,11 @@ static ssize_t show_x_plate_ohms(struct device *dev, struct device_attribute *at + return sprintf(buf, "%u\n", ts->x_plate_ohms); + } + ++static ssize_t show_rotate(struct device *dev, struct device_attribute *attr, char *buf) { ++ struct ads7846 *ts = dev_get_drvdata(dev); ++ return sprintf(buf, "%u\n", ts->rotate); ++} ++ + static ssize_t write_debounce_max(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { + struct ads7846 *ts = dev_get_drvdata(dev); + unsigned long i; +@@ -555,10 +561,22 @@ static ssize_t write_x_plate_ohms(struct device *dev, struct device_attribute *a + return count; + } + ++static ssize_t write_rotate(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { ++ struct ads7846 *ts = dev_get_drvdata(dev); ++ unsigned long i = 0; ++ ++ if (strict_strtoul(buf, 10, &i) || i > 3) ++ return -EINVAL; ++ ++ ts->rotate = i; ++ return count; ++} ++ + static DEVICE_ATTR(debounce_max, S_IRUGO | S_IWUGO, show_debounce_max, write_debounce_max); + static DEVICE_ATTR(debounce_tol, S_IRUGO | S_IWUGO, show_debounce_tol, write_debounce_tol); + static DEVICE_ATTR(debounce_rep, S_IRUGO | S_IWUGO, show_debounce_rep, write_debounce_rep); + static DEVICE_ATTR(x_plate_ohms, S_IRUGO | S_IWUGO, show_x_plate_ohms, write_x_plate_ohms); ++static DEVICE_ATTR(rotate, S_IRUGO | S_IWUGO, show_rotate, write_rotate); + + static struct attribute *ads784x_attributes[] = { + &dev_attr_pen_down.attr, +@@ -567,6 +585,7 @@ static struct attribute *ads784x_attributes[] = { + &dev_attr_debounce_tol.attr, + &dev_attr_debounce_rep.attr, + &dev_attr_x_plate_ohms.attr, ++ &dev_attr_rotate.attr, + NULL, + }; + +@@ -596,6 +615,8 @@ static void ads7846_rx(void *ads) + { + struct ads7846 *ts = ads; + struct ads7846_packet *packet = ts->packet; ++ struct ads7846_platform_data *pdata = ts->spi->dev.platform_data; ++ + unsigned Rt; + u16 x, y, z1, z2; + +@@ -657,6 +678,7 @@ static void ads7846_rx(void *ads) + * timer by reading the pen signal state (it's a GPIO _and_ IRQ). + */ + if (Rt) { ++ int t; + struct input_dev *input = ts->input; + + if (!ts->pendown) { +@@ -666,6 +688,27 @@ static void ads7846_rx(void *ads) + dev_dbg(&ts->spi->dev, "DOWN\n"); + #endif + } ++ ++ switch(ts->rotate) ++ { ++ case 0: ++ x = pdata->x_max - x + pdata->x_min; ++ y = pdata->y_max - y + pdata->y_min; ++ break; ++ case 1: ++ t = x; ++ x = pdata->x_max - (((y - pdata->y_min) * (pdata->x_max - pdata->x_min)) / (pdata->y_max - pdata->y_min)); ++ y = pdata->y_min + (((t - pdata->x_min) * (pdata->y_max - pdata->y_min)) / (pdata->x_max - pdata->x_min)); ++ break; ++ case 2: ++ break; ++ case 3: ++ t = x; ++ x = pdata->x_min + (((y - pdata->y_min) * (pdata->x_max - pdata->x_min)) / (pdata->y_max - pdata->y_min)); ++ y = pdata->y_max - (((t - pdata->x_min) * (pdata->y_max - pdata->y_min)) / (pdata->x_max - pdata->x_min)); ++ break; ++ } ++ + input_report_abs(input, ABS_X, x); + input_report_abs(input, ABS_Y, y); + input_report_abs(input, ABS_PRESSURE, Rt); +@@ -980,6 +1023,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) + + dev_set_drvdata(&spi->dev, ts); + ++ ts->rotate = 0; + ts->packet = packet; + ts->spi = spi; + ts->input = input_dev; diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/usb-lower-current-consumption-upon-insertion.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/usb-lower-current-consumption-upon-insertion.patch new file mode 100644 index 0000000000..e2df6cf83d --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/usb-lower-current-consumption-upon-insertion.patch @@ -0,0 +1,30 @@ +--- a/drivers/usb/core/hub.c 2009-07-28 08:47:00.000000000 -0700 ++++ b/drivers/usb/core/hub.c 2009-07-28 08:32:20.000000000 -0700 +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -3129,9 +3130,18 @@ + USB_PORT_FEAT_C_RESET); + } + +- if (connect_change) ++ if (connect_change) { ++ if(portstatus & USB_PORT_STAT_CONNECTION) { ++ gpio_set_value(176,0); ++ mdelay(25); ++ } + hub_port_connect_change(hub, i, + portstatus, portchange); ++ if(portstatus & USB_PORT_STAT_CONNECTION) { ++ mdelay(75); ++ gpio_set_value(176,1); ++ } ++ } + } /* end for i */ + + /* deal with hub status changes */ diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/usb-otg-pc-connection.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/usb-otg-pc-connection.patch new file mode 100644 index 0000000000..2bcfbdcc2f --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/usb-otg-pc-connection.patch @@ -0,0 +1,36 @@ +--- git/drivers/usb/gadget/file_storage.c 2009-06-07 12:18:05.000000000 -0700 ++++ git/drivers/usb/gadget/file_storage.c 2009-06-07 12:08:36.000000000 -0700 +@@ -283,8 +283,8 @@ + * + * DO NOT REUSE THESE IDs with any other driver!! Ever!! + * Instead: allocate your own, using normal USB-IF procedures. */ +-#define DRIVER_VENDOR_ID 0x0525 // NetChip +-#define DRIVER_PRODUCT_ID 0xa4a5 // Linux-USB File-backed Storage Gadget ++#define DRIVER_VENDOR_ID 0xa110 // Always Innovating, Inc. ++#define DRIVER_PRODUCT_ID 0x0001 // Tablet product + + + /* +@@ -2025,9 +2025,9 @@ + { + u8 *buf = (u8 *) bh->buf; + +- static char vendor_id[] = "Linux "; ++ static char vendor_id[] = "AI, Inc."; + static char product_disk_id[] = "File-Stor Gadget"; +- static char product_cdrom_id[] = "File-CD Gadget "; ++ static char product_cdrom_id[] = "Touch Book "; + + if (!fsg->curlun) { // Unsupported LUNs are okay + fsg->bad_lun_okay = 1; +@@ -3671,8 +3671,8 @@ + } + if (num_sectors < min_sectors) { + LINFO(curlun, "file too small: %s\n", filename); +- rc = -ETOOSMALL; +- goto out; ++// rc = -ETOOSMALL; ++// goto out; + } + + get_file(filp); diff --git a/recipes/linux/linux-omap_2.6.29.bb b/recipes/linux/linux-omap_2.6.29.bb index 56e6107a4c..7c16354b2d 100644 --- a/recipes/linux/linux-omap_2.6.29.bb +++ b/recipes/linux/linux-omap_2.6.29.bb @@ -3,7 +3,7 @@ require linux.inc DESCRIPTION = "Linux kernel for OMAP processors" KERNEL_IMAGETYPE = "uImage" -COMPATIBLE_MACHINE = "omap5912osk|omap1710h3|omap2430sdp|omap2420h4|beagleboard|omap3evm|omap3-pandora|overo|omapzoom" +COMPATIBLE_MACHINE = "omap5912osk|omap1710h3|omap2430sdp|omap2420h4|beagleboard|omap3evm|omap3-pandora|overo|omapzoom|omap3-touchbook" DEFAULT_PREFERENCE = "-1" DEFAULT_PREFERENCE_overo = "1" @@ -175,6 +175,35 @@ SRC_URI_append_beagleboard = " file://logo_linux_clut224.ppm \ file://beaglebug/beaglebug-full.patch;patch=1 \ " +SRC_URI_append_omap3-touchbook = " \ + file://beagle-asoc.patch;patch=1 \ + file://accelerometer-mma7455l.patch;patch=1 \ + file://accelerometer-touchscreen-mux-spi.patch;patch=1 \ + file://touchscreen-ads7846-export-settings.patch;patch=1 \ + file://touchscreen-ads7846-rotation-support.patch;patch=1 \ + file://dspbridge.patch;patch=1 \ + file://battery2-bq27200-no-error-message.patch;patch=1 \ + file://sound-headphone-detection.patch;patch=1 \ + file://dss2-fix-XY-coordinates-when-rotating.patch;patch=1 \ + file://screen-backlight.patch;patch=1 \ + file://battery1-tps65950-charging-management-1.patch;patch=1 \ + file://dss2-fix-scaling-when-rotating.patch;patch=1 \ + file://dss2-export-status.patch;patch=1 \ + file://usb-otg-pc-connection.patch;patch=1 \ + file://battery1-tps65950-charging-management-2.patch;patch=1 \ + file://memory-move-malloc-end.patch;patch=1 \ + file://aufs-1.patch;patch=1 \ + file://aufs-2.patch;patch=1 \ + file://aufs-3.patch;patch=1 \ + file://aufs-squashfs-mount-to-avoid-initramfs.patch;patch=1 \ + file://screen-backlight-accessible-by-user.patch;patch=1 \ + file://dss2-blank-rotate-accessible-by-user.patch;patch=1 \ + file://boot-no-power-message.patch;patch=1 \ + file://usb-lower-current-consumption-upon-insertion.patch;patch=1 \ + file://battery2-bq27200-gpio-charged.patch;patch=1 \ + file://board-omap3beagle.c \ +" + SRC_URI_append_omap3evm = " \ file://evm-mcspi-ts.diff;patch=1 \ " -- cgit v1.2.3 From a6d3ba856df758ae4db30c02121d95fb3d4829f3 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 15 Sep 2009 19:27:45 +0200 Subject: x-load: add omap3-touchbook support --- recipes/x-load/x-load_git.bb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/recipes/x-load/x-load_git.bb b/recipes/x-load/x-load_git.bb index 0fa8cdfc62..35090e621a 100644 --- a/recipes/x-load/x-load_git.bb +++ b/recipes/x-load/x-load_git.bb @@ -16,6 +16,11 @@ SRC_URI_append_beagleboard = " \ file://name.patch;patch=1 \ " +SRC_URI_append_omap3-touchbook = " \ + file://name.patch;patch=1 \ + " + + SRC_URI_append_omap3517-evm = " \ file://xload-shiva.diff;patch=1 \ " -- cgit v1.2.3 From 66c257096a310e48d0d3e4aab25f95016d9d797a Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sun, 13 Sep 2009 16:28:46 +0200 Subject: omap3-touchbook: add machine config based on the beagleboard one --- conf/machine/omap3-touchbook.conf | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 conf/machine/omap3-touchbook.conf diff --git a/conf/machine/omap3-touchbook.conf b/conf/machine/omap3-touchbook.conf new file mode 100644 index 0000000000..8e18e4d7cf --- /dev/null +++ b/conf/machine/omap3-touchbook.conf @@ -0,0 +1,47 @@ +#@TYPE: Machine +#@NAME: Always Innovating touchbook +#@DESCRIPTION: Machine configuration for the http://www.alwaysinnovating.com/touchbook/ +TARGET_ARCH = "arm" + +PREFERRED_PROVIDER_virtual/xserver = "xserver-xorg" +XSERVER = "xserver-xorg \ + xf86-input-evdev \ + xf86-input-mouse \ + xf86-video-omapfb \ + xf86-input-keyboard" + +# Only has DVI connector for external screen +GUI_MACHINE_CLASS = "bigscreen" + +require conf/machine/include/omap3.inc + +IMAGE_FSTYPES += "tar.bz2 ubi" +EXTRA_IMAGECMD_jffs2 = "-lnp " + +# Guesswork +SERIAL_CONSOLE = "115200 ttyS2" + +UBOOT_MACHINE = "omap3_beagle_config" +XLOAD_MACHINE = "beagleboard_config" + +# do ubiattach /dev/ubi_ctrl -m 4 +# From dmesg: +# UBI: smallest flash I/O unit: 2048 +# UBI: logical eraseblock size: 129024 bytes +# from ubiattach stdout: +# UBI device number 0, total 1996 LEBs +MKUBIFS_ARGS = "-m 2048 -e 129024 -c 1996" + +# do ubiattach /dev/ubi_ctrl -m 4 +# from dmesg: +# UBI: smallest flash I/O unit: 2048 +# UBI: physical eraseblock size: 131072 bytes (128 KiB) +# UBI: sub-page size: 512 +UBINIZE_ARGS = "-m 2048 -p 128KiB -s 512" + + +PREFERRED_VERSION_u-boot = "git" + +MACHINE_EXTRA_RRECOMMENDS = " omap3-sgx-modules " +# and sdio +MACHINE_FEATURES = "kernel26 screen apm usbgadget usbhost vfat alsa touchscreen" -- cgit v1.2.3 From 14a286d359b63e7267463f72abcb951919146634 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Wed, 16 Sep 2009 13:50:29 +0200 Subject: linux-omap 2.6.29: only use touchbook aufs stuff when passsing "special" as root device name --- .../omap3-touchbook/aufs-squashfs-mount-to-avoid-initramfs.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-squashfs-mount-to-avoid-initramfs.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-squashfs-mount-to-avoid-initramfs.patch index 1d409e2532..9a9b982fef 100644 --- a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-squashfs-mount-to-avoid-initramfs.patch +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/aufs-squashfs-mount-to-avoid-initramfs.patch @@ -7,7 +7,7 @@ + int do_special = 0; + if (strcmp(root_device_name, "special") == 0) + do_special = 1; -+ do_special = 1; ++ //do_special = 1; + + if (do_special) { + dev_t ROOT_DEV_RO; -- cgit v1.2.3 From a7144f8e73c4058e7f94769681b20508006fce53 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Wed, 16 Sep 2009 14:28:37 +0200 Subject: xserver-xorg-conf: add omap3-touchbook support --- .../xserver-xorg-conf/omap3-touchbook/xorg.conf | 29 ++++++++++++++++++++++ recipes/xorg-xserver/xserver-xorg-conf_0.1.bb | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 recipes/xorg-xserver/xserver-xorg-conf/omap3-touchbook/xorg.conf diff --git a/recipes/xorg-xserver/xserver-xorg-conf/omap3-touchbook/xorg.conf b/recipes/xorg-xserver/xserver-xorg-conf/omap3-touchbook/xorg.conf new file mode 100644 index 0000000000..983bb0823a --- /dev/null +++ b/recipes/xorg-xserver/xserver-xorg-conf/omap3-touchbook/xorg.conf @@ -0,0 +1,29 @@ +Section "Module" + Load "extmod" + Load "dbe" + Load "glx" + Load "freetype" + Load "type1" + Load "record" + Load "dri" +EndSection + +Section "Monitor" + Identifier "Builtin Default Monitor" +EndSection + +Section "Device" + Identifier "Builtin Default fbdev Device 0" + Driver "omapfb" +EndSection + +Section "Screen" + Identifier "Builtin Default fbdev Screen 0" + Device "Builtin Default fbdev Device 0" + Monitor "Builtin Default Monitor" +EndSection + +Section "ServerLayout" + Identifier "Builtin Default Layout" + Screen "Builtin Default fbdev Screen 0" +EndSection diff --git a/recipes/xorg-xserver/xserver-xorg-conf_0.1.bb b/recipes/xorg-xserver/xserver-xorg-conf_0.1.bb index 783d1b09cc..b572eab734 100644 --- a/recipes/xorg-xserver/xserver-xorg-conf_0.1.bb +++ b/recipes/xorg-xserver/xserver-xorg-conf_0.1.bb @@ -1,5 +1,5 @@ DESCRIPTION = "Machine specific xorg.conf files" -PR = "r8" +PR = "r9" SRC_URI = "file://xorg.conf" -- cgit v1.2.3 From 2a3d5c21971587a47b203359ed37a125b37aac39 Mon Sep 17 00:00:00 2001 From: Michael 'Mickey' Lauer Date: Mon, 14 Sep 2009 21:45:36 +0200 Subject: python-dbus: add some more dependencies --- recipes/python/python-dbus_0.83.0.bb | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/recipes/python/python-dbus_0.83.0.bb b/recipes/python/python-dbus_0.83.0.bb index 7bc81f0396..02b73e64bf 100644 --- a/recipes/python/python-dbus_0.83.0.bb +++ b/recipes/python/python-dbus_0.83.0.bb @@ -3,20 +3,24 @@ SECTION = "devel/python" HOMEPAGE = "http://www.freedesktop.org/Software/dbus" LICENSE = "MIT" DEPENDS = "expat dbus dbus-glib virtual/libintl python-pyrex-native" -PR = "ml1" +PR = "ml2" SRC_URI = "http://dbus.freedesktop.org/releases/dbus-python/dbus-python-${PV}.tar.gz" S = "${WORKDIR}/dbus-python-${PV}" -inherit distutils-base autotools pkgconfig +inherit distutils-base autotools_stage pkgconfig export BUILD_SYS export HOST_SYS -do_stage() { - autotools_stage_all -} +RDEPENDS_${PN} = "\ + python-io \ + python-lang \ + python-logging \ + python-threading \ + python-xml \ +" -RDEPENDS = "python-io python-logging python-stringold python-threading python-xml" - -FILES_${PN}-dev += "${libdir}/pkgconfig +FILES_${PN}-dev += "\ + ${libdir}/pkgconfig \ +" -- cgit v1.2.3 From 306ae77b3bd17c9a7e04227fc6b7b2d66c264476 Mon Sep 17 00:00:00 2001 From: Michael 'Mickey' Lauer Date: Wed, 16 Sep 2009 17:38:38 +0200 Subject: sane-toolchain.inc: bump default binutils to a version that works with the default gcc --- conf/distro/include/sane-toolchain.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/distro/include/sane-toolchain.inc b/conf/distro/include/sane-toolchain.inc index e2c6740e52..36ec5e572f 100644 --- a/conf/distro/include/sane-toolchain.inc +++ b/conf/distro/include/sane-toolchain.inc @@ -6,7 +6,7 @@ # Base line versions, good for most things PREFERRED_GCC_VERSION ?= "4.4.1" -PREFERRED_BINUTILS ?= "2.18" +PREFERRED_BINUTILS ?= "2.19.51" # Prefer glibc 2.6 and uclibc 0.9.30, these have had the most testing. PREFERRED_VERSION_glibc ?= "2.6.1" -- cgit v1.2.3 From 4c4c18764b51b6fcad9f232453ccb7b844cafa52 Mon Sep 17 00:00:00 2001 From: Aleksandr Koltsoff Date: Wed, 16 Sep 2009 00:19:14 +0000 Subject: sane-toolchain.inc: armv5te mentioned twice on eabi-capable list * armv5te is mentioned twice in the arm_eabi_supporting_arches list of sane-toolchain.inc. Remove the latter occurance. Signed-off-by: Khem Raj Acked-by: Cliff Brake --- conf/distro/include/sane-toolchain.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/distro/include/sane-toolchain.inc b/conf/distro/include/sane-toolchain.inc index 36ec5e572f..9351187fe1 100644 --- a/conf/distro/include/sane-toolchain.inc +++ b/conf/distro/include/sane-toolchain.inc @@ -157,7 +157,7 @@ def detect_arm_abi (d): def compute_os_portion_of_target_triplet (d): import bb arm_eabi_supporting_arches = "armv6 armv6-novfp \ - armv5te iwmmxt armv7a armv7 armv6 armv5teb armv5te armv4t" + armv5te iwmmxt armv7a armv7 armv6 armv5teb armv4t" ppc_spe_supporting_arches = "ppce500v2 ppce500" if bb.data.getVar("LIBC", d, 1) == "uclibc": -- cgit v1.2.3 From 1cf1e7ed145620df86e6a61ce3b3c2f576a3db03 Mon Sep 17 00:00:00 2001 From: Stanislav Brabec Date: Wed, 16 Sep 2009 19:31:14 +0000 Subject: libxcalibrate, calibrateproto: Increment PE to upgrade packages in feeds. --- recipes/xorg-lib/libxcalibrate_git.bb | 2 +- recipes/xorg-proto/calibrateproto_git.bb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/recipes/xorg-lib/libxcalibrate_git.bb b/recipes/xorg-lib/libxcalibrate_git.bb index 1092990184..fadaf933ec 100644 --- a/recipes/xorg-lib/libxcalibrate_git.bb +++ b/recipes/xorg-lib/libxcalibrate_git.bb @@ -6,7 +6,7 @@ DEPENDS = "virtual/libx11 calibrateproto libxext" PR = "r0" PV = "0.0+${PR}+gitr${SRCREV}" -PE = "1" +PE = "2" SRC_URI = "git://anongit.freedesktop.org/git/xorg/lib/libXCalibrate;protocol=git" diff --git a/recipes/xorg-proto/calibrateproto_git.bb b/recipes/xorg-proto/calibrateproto_git.bb index c3b334c4f3..6f5414fb1a 100644 --- a/recipes/xorg-proto/calibrateproto_git.bb +++ b/recipes/xorg-proto/calibrateproto_git.bb @@ -4,7 +4,7 @@ DESCRIPTION = "Touchscreen calibration protocol" PR = "r0" PV = "0.0+${PR}+gitr${SRCREV}" -PE = "1" +PE = "2" SRC_URI = "git://anongit.freedesktop.org/git/xorg/proto/calibrateproto;protocol=git" S = "${WORKDIR}/git" -- cgit v1.2.3 From 7081e345e4ff3ba1bfdca2484d6dae04a48af1a8 Mon Sep 17 00:00:00 2001 From: Stanislav Brabec Date: Wed, 16 Sep 2009 19:35:31 +0000 Subject: intltool: Increase INC_PR to replace pre-INC_PR packages in feeds. --- recipes/intltool/intltool.inc | 2 +- recipes/intltool/intltool_0.30.bb | 3 +-- recipes/intltool/intltool_0.31.bb | 3 +-- recipes/intltool/intltool_0.34.bb | 3 +-- recipes/intltool/intltool_0.35.0.bb | 2 +- recipes/intltool/intltool_0.35.2.bb | 3 +-- recipes/intltool/intltool_0.35.5.bb | 2 +- recipes/intltool/intltool_0.37.1.bb | 3 +-- recipes/intltool/intltool_0.40.3.bb | 8 ++++---- 9 files changed, 12 insertions(+), 17 deletions(-) diff --git a/recipes/intltool/intltool.inc b/recipes/intltool/intltool.inc index 1938407fd0..1de2ae0323 100644 --- a/recipes/intltool/intltool.inc +++ b/recipes/intltool/intltool.inc @@ -3,7 +3,7 @@ PRIORITY = "optional" SECTION = "devel" LICENSE = "GPL" DEPENDS += "libxml-parser-perl-native" -INC_PR = "r2" +INC_PR = "r3" URLV="${@'.'.join(bb.data.getVar('PV',d,1).split('.')[0:2])}" SRC_URI = "${GNOME_MIRROR}/intltool/${URLV}/intltool-${PV}.tar.bz2" diff --git a/recipes/intltool/intltool_0.30.bb b/recipes/intltool/intltool_0.30.bb index 04bd71fd71..ca4f86eb6f 100644 --- a/recipes/intltool/intltool_0.30.bb +++ b/recipes/intltool/intltool_0.30.bb @@ -1,4 +1,3 @@ require intltool.inc -PR = "${INC_PR}.1" - +PR = "${INC_PR}.0" diff --git a/recipes/intltool/intltool_0.31.bb b/recipes/intltool/intltool_0.31.bb index 04bd71fd71..ca4f86eb6f 100644 --- a/recipes/intltool/intltool_0.31.bb +++ b/recipes/intltool/intltool_0.31.bb @@ -1,4 +1,3 @@ require intltool.inc -PR = "${INC_PR}.1" - +PR = "${INC_PR}.0" diff --git a/recipes/intltool/intltool_0.34.bb b/recipes/intltool/intltool_0.34.bb index 04bd71fd71..ca4f86eb6f 100644 --- a/recipes/intltool/intltool_0.34.bb +++ b/recipes/intltool/intltool_0.34.bb @@ -1,4 +1,3 @@ require intltool.inc -PR = "${INC_PR}.1" - +PR = "${INC_PR}.0" diff --git a/recipes/intltool/intltool_0.35.0.bb b/recipes/intltool/intltool_0.35.0.bb index 6da883212a..efe780c6d9 100644 --- a/recipes/intltool/intltool_0.35.0.bb +++ b/recipes/intltool/intltool_0.35.0.bb @@ -3,4 +3,4 @@ require intltool.inc #RDEPENDS = "libxml-parser-perl" RRECOMMENDS = "perl-modules" -PR = "${INC_PR}.1" +PR = "${INC_PR}.0" diff --git a/recipes/intltool/intltool_0.35.2.bb b/recipes/intltool/intltool_0.35.2.bb index a8e2cf8905..de3c6084d5 100644 --- a/recipes/intltool/intltool_0.35.2.bb +++ b/recipes/intltool/intltool_0.35.2.bb @@ -3,5 +3,4 @@ require intltool.inc RDEPENDS = "perl-module-text-wrap perl-module-re" RRECOMMENDS = "perl-modules" -PR = "${INC_PR}.1" - +PR = "${INC_PR}.0" diff --git a/recipes/intltool/intltool_0.35.5.bb b/recipes/intltool/intltool_0.35.5.bb index 4cb7a794ef..6d3f5270d2 100644 --- a/recipes/intltool/intltool_0.35.5.bb +++ b/recipes/intltool/intltool_0.35.5.bb @@ -3,7 +3,7 @@ require intltool.inc RDEPENDS = "perl-module-text-wrap perl-module-re" RRECOMMENDS = "perl-modules" -PR = "${INC_PR}.1" +PR = "${INC_PR}.0" DEFAULT_PREFERENCE = "-1" diff --git a/recipes/intltool/intltool_0.37.1.bb b/recipes/intltool/intltool_0.37.1.bb index 04bd71fd71..ca4f86eb6f 100644 --- a/recipes/intltool/intltool_0.37.1.bb +++ b/recipes/intltool/intltool_0.37.1.bb @@ -1,4 +1,3 @@ require intltool.inc -PR = "${INC_PR}.1" - +PR = "${INC_PR}.0" diff --git a/recipes/intltool/intltool_0.40.3.bb b/recipes/intltool/intltool_0.40.3.bb index ddd6f8956d..d906cb787c 100644 --- a/recipes/intltool/intltool_0.40.3.bb +++ b/recipes/intltool/intltool_0.40.3.bb @@ -1,13 +1,13 @@ require intltool.inc -PR = "${INC_PR}.1" +PR = "${INC_PR}.0" EXTRA_OEMAKE = "'PERL_TARGET=/usr/bin/perl'" do_configure_prepend() { sed -i -e s:\\\$\(PERL\):\$\(PERL_TARGET\):g Makefile.am -} +} do_configure_append() { - sed -i -e s:head\ -1:head\ -n1:g intltool.m4 -} + sed -i -e s:head\ -1:head\ -n1:g intltool.m4 +} -- cgit v1.2.3 From 70bd2a139ac0d278ed71a390c59e6e25d4848214 Mon Sep 17 00:00:00 2001 From: Stanislav Brabec Date: Wed, 16 Sep 2009 19:38:00 +0000 Subject: wget: Increase INC_PR to replace pre-INC_PR packages in feeds. --- recipes/wget/wget.inc | 2 +- recipes/wget/wget_1.11.4.bb | 2 +- recipes/wget/wget_1.9.1.bb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/recipes/wget/wget.inc b/recipes/wget/wget.inc index 21814c8d66..21aa9369b8 100644 --- a/recipes/wget/wget.inc +++ b/recipes/wget/wget.inc @@ -1,7 +1,7 @@ DESCRIPTION = "A console URL download utility featuring HTTP, FTP, and more." SECTION = "console/network" DEPENDS = "" -INC_PR = "r7" +INC_PR = "r8" LICENSE = "GPL" S = "${WORKDIR}/wget-${PV}" diff --git a/recipes/wget/wget_1.11.4.bb b/recipes/wget/wget_1.11.4.bb index 4a20bab4e8..870e2a424a 100644 --- a/recipes/wget/wget_1.11.4.bb +++ b/recipes/wget/wget_1.11.4.bb @@ -1,4 +1,4 @@ -PR="${INC_PR}.1" +PR="${INC_PR}.0" DEFAULT_PREFERENCE="-1" SRC_URI = " \ diff --git a/recipes/wget/wget_1.9.1.bb b/recipes/wget/wget_1.9.1.bb index 50974ed87b..516cbef160 100644 --- a/recipes/wget/wget_1.9.1.bb +++ b/recipes/wget/wget_1.9.1.bb @@ -1,4 +1,4 @@ -PR = "${INC_PR}.1" +PR = "${INC_PR}.0" SRC_URI = " \ ${GNU_MIRROR}/wget/wget-${PV}.tar.gz \ -- cgit v1.2.3 From 9298697cbf536b2d1db9b6c720dfab34758adbf6 Mon Sep 17 00:00:00 2001 From: Stanislav Brabec Date: Wed, 16 Sep 2009 19:40:17 +0000 Subject: bluez-gnome: Fix crash on pairing configured rfcomm device. Typo fix. --- .../add-device-from-rfcomm-crash.patch | 15 ++++++++++++++ recipes/bluez/bluez-gnome-1.8/cs-typo.patch | 23 ++++++++++++++++++++++ recipes/bluez/bluez-gnome_1.8.bb | 5 ++++- 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 recipes/bluez/bluez-gnome-1.8/add-device-from-rfcomm-crash.patch create mode 100644 recipes/bluez/bluez-gnome-1.8/cs-typo.patch diff --git a/recipes/bluez/bluez-gnome-1.8/add-device-from-rfcomm-crash.patch b/recipes/bluez/bluez-gnome-1.8/add-device-from-rfcomm-crash.patch new file mode 100644 index 0000000000..825b84f0dc --- /dev/null +++ b/recipes/bluez/bluez-gnome-1.8/add-device-from-rfcomm-crash.patch @@ -0,0 +1,15 @@ +Fix for crash after access to the configured, but not yet paired RFCOMM device. +http://www.spinics.net/lists/linux-bluetooth/msg03299.html +Index: bluez-gnome-1.8/common/bluetooth-client.c +=================================================================== +--- bluez-gnome-1.8.orig/common/bluetooth-client.c ++++ bluez-gnome-1.8/common/bluetooth-client.c +@@ -330,7 +330,7 @@ static void add_device(DBusGProxy *adapt + name = value ? g_value_get_string(value) : NULL; + + value = g_hash_table_lookup(hash, "Class"); +- type = class_to_type(g_value_get_uint(value)); ++ type = value ? class_to_type(g_value_get_uint(value)) : BLUETOOTH_TYPE_ANY; + + value = g_hash_table_lookup(hash, "Icon"); + icon = value ? g_value_get_string(value) : "bluetooth"; diff --git a/recipes/bluez/bluez-gnome-1.8/cs-typo.patch b/recipes/bluez/bluez-gnome-1.8/cs-typo.patch new file mode 100644 index 0000000000..0bb28ea7b4 --- /dev/null +++ b/recipes/bluez/bluez-gnome-1.8/cs-typo.patch @@ -0,0 +1,23 @@ +https://bugs.launchpad.net/bugs/427412 +Index: bluez-gnome-1.8/po/cs.po +=================================================================== +--- bluez-gnome-1.8.orig/po/cs.po ++++ bluez-gnome-1.8/po/cs.po +@@ -262,7 +262,7 @@ + #: ../applet/main.c:110 ../applet/main.c:141 ../applet/main.c:204 + #: ../applet/agent.c:685 ../applet/agent.c:726 ../applet/agent.c:871 + msgid "Bluetooth device" +-msgstr "Bluetooth zářízení" ++msgstr "Bluetooth zařízení" + + #: ../applet/main.c:137 + #, c-format +@@ -295,7 +295,7 @@ + + #: ../applet/main.c:529 + msgid "A Bluetooth manager for the GNOME desktop" +-msgstr "Správce bluetooth pro GNOME" ++msgstr "Správce Bluetooth pro GNOME" + + #: ../applet/main.c:532 ../analyzer/dialog.c:128 + msgid "translator-credits" diff --git a/recipes/bluez/bluez-gnome_1.8.bb b/recipes/bluez/bluez-gnome_1.8.bb index 4756cf199f..43568e4939 100644 --- a/recipes/bluez/bluez-gnome_1.8.bb +++ b/recipes/bluez/bluez-gnome_1.8.bb @@ -1,10 +1,13 @@ DESCRIPTION = "Bluetooth configuration applet" LICENSE = "GPL+LGPL" +PR = "r1" DEPENDS = "dbus-glib gconf libnotify gtk+" RRECOMMENDS = "gnome-icon-theme" -SRC_URI = "http://www.kernel.org/pub/linux/bluetooth/${P}.tar.gz" +SRC_URI = "http://www.kernel.org/pub/linux/bluetooth/${P}.tar.gz \ + file://add-device-from-rfcomm-crash.patch;patch=1 \ + file://cs-typo.patch;patch=1" inherit autotools pkgconfig gconf mime -- cgit v1.2.3 From 952eef23ccbc52076a3e0b4f45fb0c58d5354ce7 Mon Sep 17 00:00:00 2001 From: Stanislav Brabec Date: Wed, 16 Sep 2009 19:50:10 +0000 Subject: gtk+: Implemented INC_PR, require hicolor-icon-theme. --- recipes/gtk+/gtk+.inc | 3 +++ recipes/gtk+/gtk+_2.12.0.bb | 2 +- recipes/gtk+/gtk+_2.12.11.bb | 2 +- recipes/gtk+/gtk+_2.12.3.bb | 2 +- recipes/gtk+/gtk+_2.14.1.bb | 2 +- recipes/gtk+/gtk+_2.14.2.bb | 2 +- recipes/gtk+/gtk+_2.16.4.bb | 2 +- recipes/gtk+/gtk+_2.16.6.bb | 1 + 8 files changed, 10 insertions(+), 6 deletions(-) diff --git a/recipes/gtk+/gtk+.inc b/recipes/gtk+/gtk+.inc index 9322d709e4..d47ace0c06 100644 --- a/recipes/gtk+/gtk+.inc +++ b/recipes/gtk+/gtk+.inc @@ -8,6 +8,8 @@ DEPENDS = "glib-2.0 tiff pango atk jpeg libpng libxext libxcursor gtk-doc libgcr libxrandr libxdamage libxrender libxcomposite" PROVIDES = "gdk-pixbuf" +INC_PR = "r6" + inherit autotools pkgconfig LEAD_SONAME = "libgtk-x11-2.0.so" @@ -18,6 +20,7 @@ FILES_${PN} = "${bindir}/gdk-pixbuf-query-loaders \ ${libdir}/lib*.so.* \ ${datadir}/themes ${sysconfdir} \ ${libdir}/gtk-2.0/${LIBV}/engines/libpixmap.so" +RDEPENDS_${PN} = "hicolor-icon-theme" FILES_${PN}-dev += " \ ${datadir}/gtk-2.0/include \ diff --git a/recipes/gtk+/gtk+_2.12.0.bb b/recipes/gtk+/gtk+_2.12.0.bb index 3d4dcde40f..f5741b65c3 100644 --- a/recipes/gtk+/gtk+_2.12.0.bb +++ b/recipes/gtk+/gtk+_2.12.0.bb @@ -1,6 +1,6 @@ require gtk+.inc -PR = "r3" +PR = "${INC_PR}.0" DEPENDS += "cairo" diff --git a/recipes/gtk+/gtk+_2.12.11.bb b/recipes/gtk+/gtk+_2.12.11.bb index d246eb8de9..8a0db74ac5 100644 --- a/recipes/gtk+/gtk+_2.12.11.bb +++ b/recipes/gtk+/gtk+_2.12.11.bb @@ -1,6 +1,6 @@ require gtk+.inc -PR = "r4" +PR = "${INC_PR}.0" DEPENDS += "cairo" diff --git a/recipes/gtk+/gtk+_2.12.3.bb b/recipes/gtk+/gtk+_2.12.3.bb index 642154b207..8a0db74ac5 100644 --- a/recipes/gtk+/gtk+_2.12.3.bb +++ b/recipes/gtk+/gtk+_2.12.3.bb @@ -1,6 +1,6 @@ require gtk+.inc -PR = "r3" +PR = "${INC_PR}.0" DEPENDS += "cairo" diff --git a/recipes/gtk+/gtk+_2.14.1.bb b/recipes/gtk+/gtk+_2.14.1.bb index 627a1750c0..dc4f2f254a 100644 --- a/recipes/gtk+/gtk+_2.14.1.bb +++ b/recipes/gtk+/gtk+_2.14.1.bb @@ -1,6 +1,6 @@ require gtk+.inc -PR = "r1" +PR = "${INC_PR}.0" DEPENDS += "cairo jasper" diff --git a/recipes/gtk+/gtk+_2.14.2.bb b/recipes/gtk+/gtk+_2.14.2.bb index 0289e2ed22..bc4a5869ac 100644 --- a/recipes/gtk+/gtk+_2.14.2.bb +++ b/recipes/gtk+/gtk+_2.14.2.bb @@ -1,6 +1,6 @@ require gtk+.inc -PR = "r5" +PR = "${INC_PR}.0" DEPENDS += "cairo jasper" diff --git a/recipes/gtk+/gtk+_2.16.4.bb b/recipes/gtk+/gtk+_2.16.4.bb index 4fde9b6825..890a27f724 100644 --- a/recipes/gtk+/gtk+_2.16.4.bb +++ b/recipes/gtk+/gtk+_2.16.4.bb @@ -1,7 +1,7 @@ require gtk+.inc DEPENDS += "cairo jasper" -PR = "r0" +PR = "${INC_PR}.0" # disabled per default - this uses as little patches as possible DEFAULT_PREFERENCE = "-1" diff --git a/recipes/gtk+/gtk+_2.16.6.bb b/recipes/gtk+/gtk+_2.16.6.bb index 43df738c30..890a27f724 100644 --- a/recipes/gtk+/gtk+_2.16.6.bb +++ b/recipes/gtk+/gtk+_2.16.6.bb @@ -1,6 +1,7 @@ require gtk+.inc DEPENDS += "cairo jasper" +PR = "${INC_PR}.0" # disabled per default - this uses as little patches as possible DEFAULT_PREFERENCE = "-1" -- cgit v1.2.3 From e6b1829aea56351d31ad4091a59bb334426dd5c4 Mon Sep 17 00:00:00 2001 From: Stanislav Brabec Date: Wed, 16 Sep 2009 20:25:59 +0000 Subject: prismstumbler: Don't apply wireless.patch for linux-libc-headers >= 2.6.30. --- recipes/prismstumbler/prismstumbler_0.7.3+0.7.4pre1.bb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/recipes/prismstumbler/prismstumbler_0.7.3+0.7.4pre1.bb b/recipes/prismstumbler/prismstumbler_0.7.3+0.7.4pre1.bb index b7c71002af..bc23824e42 100644 --- a/recipes/prismstumbler/prismstumbler_0.7.3+0.7.4pre1.bb +++ b/recipes/prismstumbler/prismstumbler_0.7.3+0.7.4pre1.bb @@ -9,9 +9,11 @@ DEPENDS = "libpcap gtk+ wireless-tools sqlite zlib dbus-glib gpsd" RDEPENDS = "wireless-tools" RRECOMMENDS = "gpsd" +# wireless.patch is required for linux-libc-headers == 2.6.23 +# but breaks build with linux-libc-headers >= 2.6.30. SRC_URI = "http://projects.linuxtogo.org/frs/download.php/14/${PN}-0.7.4pre1.tar.gz \ file://gpsapi.patch;patch=1 \ - file://wireless.patch;patch=1 \ + ${@['', 'file://wireless.patch;patch=1'][bb.data.getVar('PREFERRED_VERSION_linux-libc-headers', d, 1) and bb.data.getVar('PREFERRED_VERSION_linux-libc-headers', d, 1).split('.')[2] < '30']} \ file://fix-includes.patch;patch=1;pnum=0" S = "${WORKDIR}/${PN}-0.7.4pre1" -- cgit v1.2.3 From 43690fb819de85796ae5c0dd7d7156949c74ee9e Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Mon, 14 Sep 2009 20:13:41 -0700 Subject: preferred-xorg-versions-X11R7.4.inc: Lock PREFERRED_VERSION_dri2proto ?= "1.1" * With dri2proto 2.0 recipe being added now it gets picked up this recipes needs newer version of xorg-utils so we tie down the version of dri2proto to 1.1 Signed-off-by: Khem Raj --- conf/distro/include/preferred-xorg-versions-X11R7.4.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/conf/distro/include/preferred-xorg-versions-X11R7.4.inc b/conf/distro/include/preferred-xorg-versions-X11R7.4.inc index 21f9758f0e..156653f18c 100644 --- a/conf/distro/include/preferred-xorg-versions-X11R7.4.inc +++ b/conf/distro/include/preferred-xorg-versions-X11R7.4.inc @@ -203,6 +203,7 @@ PREFERRED_VERSION_bigreqsproto ?= "1.0.2" PREFERRED_VERSION_compositeproto ?= "0.4" PREFERRED_VERSION_damageproto ?= "1.1.0" PREFERRED_VERSION_dmxproto ?= "2.2.2" +PREFERRED_VERSION_dri2proto ?= "1.1" PREFERRED_VERSION_fixesproto ?= "4.0" PREFERRED_VERSION_fontcacheproto ?= "0.1.2" PREFERRED_VERSION_fontsproto ?= "2.0.2" -- cgit v1.2.3 From 249fc51167e2ef15cc3a517c34e9e432b54f6cb1 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Tue, 15 Sep 2009 20:37:50 -0700 Subject: clutter.inc: Add omap5912osk to COMPATIBLE_MACHINE Signed-off-by: Khem Raj --- recipes/clutter/clutter.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/clutter/clutter.inc b/recipes/clutter/clutter.inc index 4e36669d48..705cece91e 100644 --- a/recipes/clutter/clutter.inc +++ b/recipes/clutter/clutter.inc @@ -2,7 +2,7 @@ DESCRIPTION = "Clutter graphics library" HOMEPAGE = "http://www.clutter-project.org/" LICENSE = "LGPL" -COMPATIBLE_MACHINE = "(zylonite|mx31litekit|omap-3430ldp|omap-3430sdp|mx31ads|qemuarm|qemux86|ipodtouch|omap3517-evm|beagleboard|overo|omap3evm)" +COMPATIBLE_MACHINE = "(zylonite|mx31litekit|omap-3430ldp|omap-3430sdp|mx31ads|qemuarm|qemux86|ipodtouch|omap3517-evm|beagleboard|overo|omap3evm|omap5912osk)" STDDEPENDS = "virtual/libx11 gtk-doc-native pango glib-2.0 libxfixes gtk+" BASE_CONF = "--disable-gtk-doc ${@get_clutter_fpu_setting(bb, d)}" -- cgit v1.2.3 From f43c3adb4bfefbc663f89737927a79f79738f66f Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Tue, 15 Sep 2009 20:40:03 -0700 Subject: glib-2.0-native_2.21.4.bb: New recipe for native glib 2.21.4 * Build shared library instead of static. * with libint.a the link order matters and generally for uclibc targets we append -lintl to LDFLAGS and sometime it gets specified before the objects and symbols do not get pulled in. Better we generate shared object so the linking order does not matter Signed-off-by: Khem Raj glib-2.0_2.21.4.bb: Make default prefrence. * Move to INC_PR Signed-off-by: Khem Raj --- recipes/glib-2.0/glib-2.0-native_2.21.4.bb | 40 +++++++++++++++++++++++++ recipes/glib-2.0/glib-2.0_2.12.10.bb | 2 +- recipes/glib-2.0/glib-2.0_2.12.11.bb | 1 + recipes/glib-2.0/glib-2.0_2.12.12.bb | 3 +- recipes/glib-2.0/glib-2.0_2.12.13.bb | 2 +- recipes/glib-2.0/glib-2.0_2.12.6.bb | 1 + recipes/glib-2.0/glib-2.0_2.12.9.bb | 1 + recipes/glib-2.0/glib-2.0_2.14.0.bb | 1 + recipes/glib-2.0/glib-2.0_2.14.1.bb | 1 + recipes/glib-2.0/glib-2.0_2.14.4.bb | 1 + recipes/glib-2.0/glib-2.0_2.15.6.bb | 1 + recipes/glib-2.0/glib-2.0_2.16.1.bb | 3 +- recipes/glib-2.0/glib-2.0_2.16.3.bb | 3 +- recipes/glib-2.0/glib-2.0_2.16.4.bb | 3 +- recipes/glib-2.0/glib-2.0_2.16.5.bb | 3 +- recipes/glib-2.0/glib-2.0_2.18.0.bb | 2 +- recipes/glib-2.0/glib-2.0_2.18.1.bb | 2 +- recipes/glib-2.0/glib-2.0_2.18.3.bb | 2 +- recipes/glib-2.0/glib-2.0_2.20.4.bb | 3 +- recipes/glib-2.0/glib-2.0_2.21.4.bb | 4 +-- recipes/glib-2.0/glib.inc | 2 +- recipes/proxy-libintl/proxy-libintl_20080418.bb | 12 ++++---- 22 files changed, 66 insertions(+), 27 deletions(-) create mode 100644 recipes/glib-2.0/glib-2.0-native_2.21.4.bb diff --git a/recipes/glib-2.0/glib-2.0-native_2.21.4.bb b/recipes/glib-2.0/glib-2.0-native_2.21.4.bb new file mode 100644 index 0000000000..b5ce9da849 --- /dev/null +++ b/recipes/glib-2.0/glib-2.0-native_2.21.4.bb @@ -0,0 +1,40 @@ +require glib-2.0_${PV}.bb + +FILESPATH = "${FILE_DIRNAME}/glib-2.0-${PV}:${FILE_DIRNAME}/files" +DEPENDS = "gettext-native gtk-doc-native" +EXTRA_OECONF = "" + +inherit native + +do_configure_prepend() { + if [ -e ${S}/${TARGET_SYS}-libtool ] ; then + echo "${TARGET_SYS}-libtool already present" + else + cp ${STAGING_BINDIR}/${TARGET_SYS}-libtool ${S} + fi + +} + +do_stage () { + install -m 0755 gobject/glib-mkenums ${STAGING_BINDIR}/ + install -m 0755 gobject/.libs/glib-genmarshal ${STAGING_BINDIR}/ + install -m 0755 glib-gettextize ${STAGING_BINDIR}/ + oe_libinstall -so -C glib libglib-2.0 ${STAGING_LIBDIR} + oe_libinstall -so -C gmodule libgmodule-2.0 ${STAGING_LIBDIR} + oe_libinstall -so -C gthread libgthread-2.0 ${STAGING_LIBDIR} + oe_libinstall -so -C gobject libgobject-2.0 ${STAGING_LIBDIR} + oe_libinstall -so -C gio libgio-2.0 ${STAGING_LIBDIR} + autotools_stage_includes + install -d ${STAGING_INCDIR}/glib-2.0/glib + install -m 0755 ${S}/glibconfig.h ${STAGING_INCDIR}/glib-2.0/glibconfig.h + install -d ${STAGING_DATADIR}/aclocal + install -m 0644 ${S}/m4macros/glib-2.0.m4 ${STAGING_DATADIR}/aclocal/glib-2.0.m4 + install -m 0644 ${S}/m4macros/glib-gettext.m4 ${STAGING_DATADIR}/aclocal/glib-gettext.m4 + install -d ${STAGING_DATADIR}/glib-2.0/gettext/po + install -m 0755 mkinstalldirs ${STAGING_DATADIR}/glib-2.0/gettext/ + install -m 0644 po/Makefile.in.in ${STAGING_DATADIR}/glib-2.0/gettext/po/ +} + +do_install () { + : +} diff --git a/recipes/glib-2.0/glib-2.0_2.12.10.bb b/recipes/glib-2.0/glib-2.0_2.12.10.bb index 4d8e59b355..acd1927647 100644 --- a/recipes/glib-2.0/glib-2.0_2.12.10.bb +++ b/recipes/glib-2.0/glib-2.0_2.12.10.bb @@ -1,5 +1,5 @@ require glib.inc - +PR = "${INC_PR}.0" SRC_URI = "http://ftp.gnome.org/pub/GNOME/sources/glib/2.12/glib-${PV}.tar.bz2 \ file://glibconfig-sysdefs.h \ file://configure-libtool.patch;patch=1" diff --git a/recipes/glib-2.0/glib-2.0_2.12.11.bb b/recipes/glib-2.0/glib-2.0_2.12.11.bb index 4d8e59b355..31a1d53a63 100644 --- a/recipes/glib-2.0/glib-2.0_2.12.11.bb +++ b/recipes/glib-2.0/glib-2.0_2.12.11.bb @@ -1,4 +1,5 @@ require glib.inc +PR = "${INC_PR}.0" SRC_URI = "http://ftp.gnome.org/pub/GNOME/sources/glib/2.12/glib-${PV}.tar.bz2 \ file://glibconfig-sysdefs.h \ diff --git a/recipes/glib-2.0/glib-2.0_2.12.12.bb b/recipes/glib-2.0/glib-2.0_2.12.12.bb index 2e5259073a..31a1d53a63 100644 --- a/recipes/glib-2.0/glib-2.0_2.12.12.bb +++ b/recipes/glib-2.0/glib-2.0_2.12.12.bb @@ -1,6 +1,5 @@ require glib.inc - -PR = "r2" +PR = "${INC_PR}.0" SRC_URI = "http://ftp.gnome.org/pub/GNOME/sources/glib/2.12/glib-${PV}.tar.bz2 \ file://glibconfig-sysdefs.h \ diff --git a/recipes/glib-2.0/glib-2.0_2.12.13.bb b/recipes/glib-2.0/glib-2.0_2.12.13.bb index 2e5259073a..e543b83679 100644 --- a/recipes/glib-2.0/glib-2.0_2.12.13.bb +++ b/recipes/glib-2.0/glib-2.0_2.12.13.bb @@ -1,6 +1,6 @@ require glib.inc -PR = "r2" +PR = "${INC_PR}.0" SRC_URI = "http://ftp.gnome.org/pub/GNOME/sources/glib/2.12/glib-${PV}.tar.bz2 \ file://glibconfig-sysdefs.h \ diff --git a/recipes/glib-2.0/glib-2.0_2.12.6.bb b/recipes/glib-2.0/glib-2.0_2.12.6.bb index 4d8e59b355..31a1d53a63 100644 --- a/recipes/glib-2.0/glib-2.0_2.12.6.bb +++ b/recipes/glib-2.0/glib-2.0_2.12.6.bb @@ -1,4 +1,5 @@ require glib.inc +PR = "${INC_PR}.0" SRC_URI = "http://ftp.gnome.org/pub/GNOME/sources/glib/2.12/glib-${PV}.tar.bz2 \ file://glibconfig-sysdefs.h \ diff --git a/recipes/glib-2.0/glib-2.0_2.12.9.bb b/recipes/glib-2.0/glib-2.0_2.12.9.bb index 4d8e59b355..31a1d53a63 100644 --- a/recipes/glib-2.0/glib-2.0_2.12.9.bb +++ b/recipes/glib-2.0/glib-2.0_2.12.9.bb @@ -1,4 +1,5 @@ require glib.inc +PR = "${INC_PR}.0" SRC_URI = "http://ftp.gnome.org/pub/GNOME/sources/glib/2.12/glib-${PV}.tar.bz2 \ file://glibconfig-sysdefs.h \ diff --git a/recipes/glib-2.0/glib-2.0_2.14.0.bb b/recipes/glib-2.0/glib-2.0_2.14.0.bb index e4318cd1f0..37117b2577 100644 --- a/recipes/glib-2.0/glib-2.0_2.14.0.bb +++ b/recipes/glib-2.0/glib-2.0_2.14.0.bb @@ -1,4 +1,5 @@ require glib.inc +PR = "${INC_PR}.0" SRC_URI = "http://ftp.gnome.org/pub/GNOME/sources/glib/2.14/glib-${PV}.tar.bz2 \ file://glibconfig-sysdefs.h \ diff --git a/recipes/glib-2.0/glib-2.0_2.14.1.bb b/recipes/glib-2.0/glib-2.0_2.14.1.bb index e4318cd1f0..37117b2577 100644 --- a/recipes/glib-2.0/glib-2.0_2.14.1.bb +++ b/recipes/glib-2.0/glib-2.0_2.14.1.bb @@ -1,4 +1,5 @@ require glib.inc +PR = "${INC_PR}.0" SRC_URI = "http://ftp.gnome.org/pub/GNOME/sources/glib/2.14/glib-${PV}.tar.bz2 \ file://glibconfig-sysdefs.h \ diff --git a/recipes/glib-2.0/glib-2.0_2.14.4.bb b/recipes/glib-2.0/glib-2.0_2.14.4.bb index e4318cd1f0..37117b2577 100644 --- a/recipes/glib-2.0/glib-2.0_2.14.4.bb +++ b/recipes/glib-2.0/glib-2.0_2.14.4.bb @@ -1,4 +1,5 @@ require glib.inc +PR = "${INC_PR}.0" SRC_URI = "http://ftp.gnome.org/pub/GNOME/sources/glib/2.14/glib-${PV}.tar.bz2 \ file://glibconfig-sysdefs.h \ diff --git a/recipes/glib-2.0/glib-2.0_2.15.6.bb b/recipes/glib-2.0/glib-2.0_2.15.6.bb index 525a9d23de..4fcbf67e70 100644 --- a/recipes/glib-2.0/glib-2.0_2.15.6.bb +++ b/recipes/glib-2.0/glib-2.0_2.15.6.bb @@ -1,4 +1,5 @@ require glib.inc +PR = "${INC_PR}.0" SRC_URI = "http://ftp.gnome.org/pub/GNOME/sources/glib/2.15/glib-${PV}.tar.bz2 \ file://glibconfig-sysdefs.h \ diff --git a/recipes/glib-2.0/glib-2.0_2.16.1.bb b/recipes/glib-2.0/glib-2.0_2.16.1.bb index db388d7277..7e2ddd31ce 100644 --- a/recipes/glib-2.0/glib-2.0_2.16.1.bb +++ b/recipes/glib-2.0/glib-2.0_2.16.1.bb @@ -1,6 +1,5 @@ require glib.inc - -PR = "r5" +PR = "${INC_PR}.0" SRC_URI = "http://ftp.gnome.org/pub/GNOME/sources/glib/2.16/glib-${PV}.tar.bz2 \ file://glibconfig-sysdefs.h \ diff --git a/recipes/glib-2.0/glib-2.0_2.16.3.bb b/recipes/glib-2.0/glib-2.0_2.16.3.bb index f70539f18e..36fdc878aa 100644 --- a/recipes/glib-2.0/glib-2.0_2.16.3.bb +++ b/recipes/glib-2.0/glib-2.0_2.16.3.bb @@ -1,10 +1,9 @@ require glib.inc +PR = "${INC_PR}.0" # This version requires a newer libtool that isn't default yet DEFAULT_PREFERENCE = "-1" -PR = "r0" - SRC_URI = "http://ftp.gnome.org/pub/GNOME/sources/glib/2.16/glib-${PV}.tar.bz2 \ file://glibconfig-sysdefs.h \ file://configure-libtool.patch;patch=1 \ diff --git a/recipes/glib-2.0/glib-2.0_2.16.4.bb b/recipes/glib-2.0/glib-2.0_2.16.4.bb index a1ce510c51..0e4ba2d16b 100644 --- a/recipes/glib-2.0/glib-2.0_2.16.4.bb +++ b/recipes/glib-2.0/glib-2.0_2.16.4.bb @@ -1,10 +1,9 @@ require glib.inc +PR = "${INC_PR}.0" # This version requires a newer libtool that isn't default yet DEFAULT_PREFERENCE = "-1" -PR = "r1" - SRC_URI = "http://ftp.gnome.org/pub/GNOME/sources/glib/2.16/glib-${PV}.tar.bz2 \ file://glibconfig-sysdefs.h \ file://configure-libtool.patch;patch=1 \ diff --git a/recipes/glib-2.0/glib-2.0_2.16.5.bb b/recipes/glib-2.0/glib-2.0_2.16.5.bb index f70539f18e..36fdc878aa 100644 --- a/recipes/glib-2.0/glib-2.0_2.16.5.bb +++ b/recipes/glib-2.0/glib-2.0_2.16.5.bb @@ -1,10 +1,9 @@ require glib.inc +PR = "${INC_PR}.0" # This version requires a newer libtool that isn't default yet DEFAULT_PREFERENCE = "-1" -PR = "r0" - SRC_URI = "http://ftp.gnome.org/pub/GNOME/sources/glib/2.16/glib-${PV}.tar.bz2 \ file://glibconfig-sysdefs.h \ file://configure-libtool.patch;patch=1 \ diff --git a/recipes/glib-2.0/glib-2.0_2.18.0.bb b/recipes/glib-2.0/glib-2.0_2.18.0.bb index 8fead80143..ce8bcb3aa8 100644 --- a/recipes/glib-2.0/glib-2.0_2.18.0.bb +++ b/recipes/glib-2.0/glib-2.0_2.18.0.bb @@ -1,5 +1,5 @@ require glib.inc -PR = "r0" +PR = "${INC_PR}.0" SRC_URI = "\ http://ftp.gnome.org/pub/GNOME/sources/glib/2.18/glib-${PV}.tar.bz2 \ diff --git a/recipes/glib-2.0/glib-2.0_2.18.1.bb b/recipes/glib-2.0/glib-2.0_2.18.1.bb index 449fcd3769..6243c0d326 100644 --- a/recipes/glib-2.0/glib-2.0_2.18.1.bb +++ b/recipes/glib-2.0/glib-2.0_2.18.1.bb @@ -1,5 +1,5 @@ require glib.inc -PR = "r0" +PR = "${INC_PR}.0" SRC_URI = "\ http://ftp.gnome.org/pub/GNOME/sources/glib/2.18/glib-${PV}.tar.bz2 \ diff --git a/recipes/glib-2.0/glib-2.0_2.18.3.bb b/recipes/glib-2.0/glib-2.0_2.18.3.bb index c8789e75d9..6243c0d326 100644 --- a/recipes/glib-2.0/glib-2.0_2.18.3.bb +++ b/recipes/glib-2.0/glib-2.0_2.18.3.bb @@ -1,5 +1,5 @@ require glib.inc -PR = "r1" +PR = "${INC_PR}.0" SRC_URI = "\ http://ftp.gnome.org/pub/GNOME/sources/glib/2.18/glib-${PV}.tar.bz2 \ diff --git a/recipes/glib-2.0/glib-2.0_2.20.4.bb b/recipes/glib-2.0/glib-2.0_2.20.4.bb index e0afd218f7..f0cb5cd08b 100644 --- a/recipes/glib-2.0/glib-2.0_2.20.4.bb +++ b/recipes/glib-2.0/glib-2.0_2.20.4.bb @@ -1,6 +1,5 @@ require glib.inc - -PR = "r0" +PR = "${INC_PR}.0" SRC_URI = "\ http://ftp.gnome.org/pub/GNOME/sources/glib/2.20/glib-${PV}.tar.bz2 \ diff --git a/recipes/glib-2.0/glib-2.0_2.21.4.bb b/recipes/glib-2.0/glib-2.0_2.21.4.bb index 5402a81535..4aac57f96d 100644 --- a/recipes/glib-2.0/glib-2.0_2.21.4.bb +++ b/recipes/glib-2.0/glib-2.0_2.21.4.bb @@ -1,7 +1,5 @@ require glib.inc - -DEFAULT_PREFERENCE = "-1" -DEFAULT_PREFERENCE_angstrom = "1" +PR = "${INC_PR}.0" SRC_URI = "\ http://ftp.gnome.org/pub/GNOME/sources/glib/2.21/glib-${PV}.tar.bz2 \ diff --git a/recipes/glib-2.0/glib.inc b/recipes/glib-2.0/glib.inc index df2bf0c869..53d8d99199 100644 --- a/recipes/glib-2.0/glib.inc +++ b/recipes/glib-2.0/glib.inc @@ -10,7 +10,7 @@ DEPENDS += "glib-2.0-native gtk-doc" DEPENDS += "virtual/libiconv virtual/libintl" PACKAGES =+ "gobject-2.0 gmodule-2.0 gthread-2.0 gio-2.0 glib-2.0-utils " -PR = "r5" +INC_PR = "r5" LEAD_SONAME = "libglib-2.0.*" FILES_glib-2.0-utils = "${bindir}/*" diff --git a/recipes/proxy-libintl/proxy-libintl_20080418.bb b/recipes/proxy-libintl/proxy-libintl_20080418.bb index dbe7b92c7e..6c625d6ba0 100644 --- a/recipes/proxy-libintl/proxy-libintl_20080418.bb +++ b/recipes/proxy-libintl/proxy-libintl_20080418.bb @@ -5,16 +5,18 @@ LICENSE = "LGPL" PR = "r1" PROVIDES = "virtual/libintl" - +LEAD_SONAME = "libintl.so" SRC_URI = " \ http://ftp.gnome.org/pub/GNOME/binaries/win32/dependencies/${PN}-${PV}.zip \ file://stub-only.patch;patch=1 \ + file://create-as-shared-lib.patch;patch=1 \ " S = "${WORKDIR}" -FILES_${PN}-dev = "${includedir} ${libdir}" +FILES_${PN}-dev = "${includedir}" +FILES_${PN} = "${libdir}/libintl.so" CFLAGS_append = " -Wall -I ../../include ${@['-DSTUB_ONLY', ''][bb.data.getVar('USE_NLS', d, 1) != 'no']}" @@ -32,15 +34,13 @@ do_install() { install -d ${D}/usr/lib install -m 0644 ${WORKDIR}/include/libintl.h ${D}/${includedir} - install -m 0644 ${WORKDIR}/lib/libintl.a ${D}/${libdir} + install -m 0644 ${WORKDIR}/lib/libintl.so ${D}/${libdir} } do_stage() { install -m 0644 ${WORKDIR}/include/libintl.h ${STAGING_INCDIR}/ - oe_libinstall -a -C lib libintl ${STAGING_LIBDIR}/ + oe_libinstall -a -so -C lib libintl ${STAGING_LIBDIR}/ } - - -- cgit v1.2.3 From cb86af0943cf0c38f8fd8fba32ed129574e11a97 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Tue, 15 Sep 2009 20:41:52 -0700 Subject: proxy-libintl-20080418: Add the patch to compile as shared library * Keep generating .a file. Signed-off-by: Khem Raj --- .../create-as-shared-lib.patch | 31 ++++++++++++++++++++++ recipes/proxy-libintl/proxy-libintl_20080418.bb | 4 +-- 2 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 recipes/proxy-libintl/proxy-libintl-20080418/create-as-shared-lib.patch diff --git a/recipes/proxy-libintl/proxy-libintl-20080418/create-as-shared-lib.patch b/recipes/proxy-libintl/proxy-libintl-20080418/create-as-shared-lib.patch new file mode 100644 index 0000000000..306e3b8212 --- /dev/null +++ b/recipes/proxy-libintl/proxy-libintl-20080418/create-as-shared-lib.patch @@ -0,0 +1,31 @@ +--- a/src/proxy-libintl/Makefile.org 2009-09-12 23:19:04.989421607 -0700 ++++ a/src/proxy-libintl/Makefile 2009-09-12 23:21:14.100640001 -0700 +@@ -4,20 +4,20 @@ ZIPFILE = proxy-libintl-$(TIMESTAMP).zip + CC = gcc + CFLAGS = -Wall -I ../../include + +-all : ../../lib/libintl.a ../../lib/intl.lib ++all : ../../lib/libintl.so ../../lib/intl.lib + +-../../lib/libintl.a : libintl.o +- ar rc $@ libintl.o ++../../lib/libintl.so : libintl.o ++ $(CC) -shared -o $@ libintl.o + +-../../lib/intl.lib : ../../lib/libintl.a +- cp ../../lib/libintl.a $@ +- strip --strip-unneeded $@ ++../../lib/intl.lib : ../../lib/libintl.so ++ cp ../../lib/libintl.so $@ ++ $(STRIP) --strip-unneeded $@ + + libintl.o : libintl.c + $(CC) $(CFLAGS) -c libintl.c + + clean : +- rm -f *.o ../../lib/libintl.a ../../$(ZIPFILE) ++ rm -f *.o ../../lib/libintl.so ../../$(ZIPFILE) + + dist : clean all +- cd ../..; zip $(ZIPFILE) include/libintl.h lib/{libintl.a,intl.lib} src/proxy-libintl/{README.txt,COPYING.LIB.txt,Makefile,libintl.[ch]}; manifestify $(ZIPFILE) ++ cd ../..; zip $(ZIPFILE) include/libintl.h lib/{libintl.so,intl.lib} src/proxy-libintl/{README.txt,COPYING.LIB.txt,Makefile,libintl.[ch]}; manifestify $(ZIPFILE) diff --git a/recipes/proxy-libintl/proxy-libintl_20080418.bb b/recipes/proxy-libintl/proxy-libintl_20080418.bb index 6c625d6ba0..36a0e5d0aa 100644 --- a/recipes/proxy-libintl/proxy-libintl_20080418.bb +++ b/recipes/proxy-libintl/proxy-libintl_20080418.bb @@ -5,7 +5,6 @@ LICENSE = "LGPL" PR = "r1" PROVIDES = "virtual/libintl" -LEAD_SONAME = "libintl.so" SRC_URI = " \ http://ftp.gnome.org/pub/GNOME/binaries/win32/dependencies/${PN}-${PV}.zip \ @@ -15,7 +14,7 @@ SRC_URI = " \ S = "${WORKDIR}" -FILES_${PN}-dev = "${includedir}" +FILES_${PN}-dev = "${includedir} ${libdir}/libintl.a" FILES_${PN} = "${libdir}/libintl.so" @@ -35,6 +34,7 @@ do_install() { install -m 0644 ${WORKDIR}/include/libintl.h ${D}/${includedir} install -m 0644 ${WORKDIR}/lib/libintl.so ${D}/${libdir} + install -m 0644 ${WORKDIR}/lib/libintl.a ${D}/${libdir} } -- cgit v1.2.3 From 0624cfcd88665ee317e39d53be9febdba013a244 Mon Sep 17 00:00:00 2001 From: Brijesh Singh Date: Tue, 15 Sep 2009 14:03:54 -0500 Subject: ti-cs1-omap35330: update SR_URI --- conf/checksums.ini | 5 +++++ recipes/ti/ti-cs1-omap3530_1.0.1.bb | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/conf/checksums.ini b/conf/checksums.ini index 30fcf01067..bf17d0ce55 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -29026,3 +29026,8 @@ sha256=f57c4e33eb2cdd87a6c2f01bfa4794340fbe61ea1a1cfc7dac3b6671e1dd22af md5=5f7b88ebb2bcd7e8044328482d079661 sha256=f57c4e33eb2cdd87a6c2f01bfa4794340fbe61ea1a1cfc7dac3b6671e1dd22af +[http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/dvsdk/DVSDK_3_00/latest//exports/cs1omap3530_setuplinux_1_00_01-42.bin] +md5=a1e19ef37638e977d059fd22af666301 +sha256=fc7ac2829df8d394635aa1cc704b78e93ca287111df1001e5738ae2282691219 + + diff --git a/recipes/ti/ti-cs1-omap3530_1.0.1.bb b/recipes/ti/ti-cs1-omap3530_1.0.1.bb index 61d5406305..9779c33b71 100644 --- a/recipes/ti/ti-cs1-omap3530_1.0.1.bb +++ b/recipes/ti/ti-cs1-omap3530_1.0.1.bb @@ -1,12 +1,12 @@ require ti-codec.inc require ti-cs1-omap3530.inc -SRC_URI = "http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/dvsdk/DVSDK_3_00/latest//exports/cs1omap3530_setuplinux_1_00_01.bin" +SRC_URI = "http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/dvsdk/DVSDK_3_00/latest//exports/cs1omap3530_setuplinux_1_00_01-42.bin" # Specify names of the InstallJammer binary file and the tarball it extracts -BINFILE = "cs1omap3530_setuplinux_1_00_01.bin" +BINFILE = "cs1omap3530_setuplinux_1_00_01-42.bin" -S = "${WORKDIR}/dvsdk_3_00_00_40/cs1omap3530_1_00_01" +S = "${WORKDIR}/dvsdk_3_00_01_42/cs1omap3530_1_00_01" DEPENDS="ti-codec-engine ti-dsplink-module" @@ -14,7 +14,7 @@ export CODEGEN_INSTALL_DIR # Yes, the xdc stuff still breaks with a '.' in PWD PV = "101" -PR = "r4" +PR = "r5" do_compile() { -- cgit v1.2.3 From cac885572c1429e0522935ffa0854bdf1ed15bcc Mon Sep 17 00:00:00 2001 From: Brijesh Singh Date: Tue, 15 Sep 2009 14:17:02 -0500 Subject: gstreamer-ti: import omapfbsink in gst_ti and add support for hw accelerated framecopy based on dmai transport buffers. The new element is registered as "omapdmaifbsink" --- .../ti/gstreamer-ti/gstreamer-ti-add-omapfb.patch | 1336 ++++++++++++++++++++ recipes/ti/gstreamer-ti_svn.bb | 11 +- 2 files changed, 1345 insertions(+), 2 deletions(-) create mode 100644 recipes/ti/gstreamer-ti/gstreamer-ti-add-omapfb.patch diff --git a/recipes/ti/gstreamer-ti/gstreamer-ti-add-omapfb.patch b/recipes/ti/gstreamer-ti/gstreamer-ti-add-omapfb.patch new file mode 100644 index 0000000000..e7b1dab300 --- /dev/null +++ b/recipes/ti/gstreamer-ti/gstreamer-ti-add-omapfb.patch @@ -0,0 +1,1336 @@ +diff -uNr ticodecplugin/configure.ac ticodecplugin.new/configure.ac +--- ticodecplugin/configure.ac 2009-09-05 00:04:51.000000000 -0500 ++++ ticodecplugin.new/configure.ac 2009-09-15 13:14:44.000000000 -0500 +@@ -25,6 +25,7 @@ + AC_SUBST(ACLOCAL_AMFLAGS, "-I m4") + + AM_CONFIG_HEADER(config.h) ++AM_PROG_AS + + dnl check for tools + AC_PROG_CC +diff -uNr ticodecplugin/src/Makefile.am ticodecplugin.new/src/Makefile.am +--- ticodecplugin/src/Makefile.am 2009-09-05 00:04:51.000000000 -0500 ++++ ticodecplugin.new/src/Makefile.am 2009-09-15 13:14:44.000000000 -0500 +@@ -4,16 +4,16 @@ + plugin_LTLIBRARIES = libgstticodecplugin.la + + # sources used to compile this plug-in +-libgstticodecplugin_la_SOURCES = gstticodecplugin.c gsttiauddec.c gsttiauddec1.c gsttividdec.c gsttividdec2.c gsttiimgenc1.c gsttiimgenc.c gsttiimgdec1.c gsttiimgdec.c gsttidmaibuffertransport.c gstticircbuffer.c gsttidmaivideosink.c gstticodecs.c gstticodecs_platform.c gsttiquicktime_aac.c gsttiquicktime_h264.c gsttividenc.c gsttividenc1.c gstticommonutils.c ++libgstticodecplugin_la_SOURCES = gstticodecplugin.c gsttiauddec.c gsttiauddec1.c gsttividdec.c gsttividdec2.c gsttiimgenc1.c gsttiimgenc.c gsttiimgdec1.c gsttiimgdec.c gsttidmaibuffertransport.c gstticircbuffer.c gsttidmaivideosink.c gstticodecs.c gstticodecs_platform.c gsttiquicktime_aac.c gsttiquicktime_h264.c gsttividenc.c gsttividenc1.c gstticommonutils.c omapfb.c yuv.S + + # flags used to compile this plugin + # add other _CFLAGS and _LIBS as needed +-libgstticodecplugin_la_CFLAGS = $(GST_CFLAGS) $(shell cat $(XDC_CONFIG_BASENAME)/compiler.opt) +-libgstticodecplugin_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) -lgstvideo-0.10 -lgstaudio-0.10 -lm ++libgstticodecplugin_la_CFLAGS = $(GST_CFLAGS) $(shell cat $(XDC_CONFIG_BASENAME)/compiler.opt) -I$(LINUXKERNEL_INSTALL_DIR)/include ++libgstticodecplugin_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) -lgstvideo-0.10 -lgstaudio-0.10 -lm -lX11 + libgstticodecplugin_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -Wl,$(XDC_CONFIG_BASENAME)/linker.cmd + + # headers we need but don't want installed +-noinst_HEADERS = gsttiauddec.h gsttiauddec1.h gsttividdec.h gsttividdec2.h gsttiimgenc1.h gsttiimgenc.h gsttiimgdec1.h gsttiimgdec.h gsttidmaibuffertransport.h gstticircbuffer.h gsttidmaivideosink.h gsttithreadprops.h gstticodecs.h gsttiquicktime_aac.h gsttiquicktime_h264.h gsttividenc.h gsttividenc1.h gstticommonutils.h ++noinst_HEADERS = gsttiauddec.h gsttiauddec1.h gsttividdec.h gsttividdec2.h gsttiimgenc1.h gsttiimgenc.h gsttiimgdec1.h gsttiimgdec.h gsttidmaibuffertransport.h gstticircbuffer.h gsttidmaivideosink.h gsttithreadprops.h gstticodecs.h gsttiquicktime_aac.h gsttiquicktime_h264.h gsttividenc.h gsttividenc1.h gstticommonutils.h omapfb.h + + # XDC Configuration + CONFIGURO = $(XDC_INSTALL_DIR)/xs xdc.tools.configuro +diff -uNr ticodecplugin/src/gstticodecplugin.c ticodecplugin.new/src/gstticodecplugin.c +--- ticodecplugin/src/gstticodecplugin.c 2009-09-05 00:04:51.000000000 -0500 ++++ ticodecplugin.new/src/gstticodecplugin.c 2009-09-15 13:14:44.000000000 -0500 +@@ -44,6 +44,7 @@ + #include "gsttidmaivideosink.h" + #include "gsttividenc.h" + #include "gsttividenc1.h" ++#include "omapfb.h" + + /* entry point to initialize the plug-in + * initialize the plug-in itself +@@ -137,6 +138,13 @@ + GST_TYPE_TIDMAIVIDEOSINK)) + return FALSE; + ++ env_value = getenv("GST_Omapfbdmaisink_DISABLE"); ++ ++ if ((!env_value || strcmp(env_value,"1")) && !gst_element_register( ++ TICodecPlugin, "omapdmaifbsink", GST_RANK_PRIMARY, ++ GST_OMAPFB_SINK_TYPE)) ++ return FALSE; ++ + return TRUE; + } + +diff -uNr ticodecplugin/src/omapfb.c ticodecplugin.new/src/omapfb.c +--- ticodecplugin/src/omapfb.c 1969-12-31 18:00:00.000000000 -0600 ++++ ticodecplugin.new/src/omapfb.c 2009-09-15 13:16:03.000000000 -0500 +@@ -0,0 +1,1005 @@ ++/* ++ * Copyright (C) 2008 Felipe Contreras ++ * Copyright (C) 2009 Tim Yamin ++ * Copyright (C) 2009 Brijesh Singh ++ * ++ * X code largely copied from ximagesink by Julien Moutte and ++ * vo_omapfb.c by Gregoire Gentil. ++ * ++ * Use DMAI hw framecopy module to copy the dmai transport buffers. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation ++ * version 2.1 of the License. ++ * ++ * This library 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 ++ * Lesser 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 Street, Fifth Floor, Boston, MA 02111-1301 USA ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "omapfb.h" ++#include ++ ++static GstVideoSinkClass *parent_class = NULL; ++ ++extern void yuv420_to_yuv422(__uint8_t *yuv, __uint8_t *y, __uint8_t *u, __uint8_t *v, ++ int w, int h, int yw, int cw, int dw); ++ ++static void x11_get_window_abs_position(Display *display, Window window, ++ int *wx, int *wy, int *ww, int *wh) ++{ ++ Window root, parent; ++ Window *child; ++ unsigned int n_children; ++ XWindowAttributes attribs; ++ ++ /* Get window attributes */ ++ XGetWindowAttributes(display, window, &attribs); ++ ++ /* Get relative position of given window */ ++ *wx = attribs.x; ++ *wy = attribs.y; ++ if (ww) ++ *ww = attribs.width; ++ if (wh) ++ *wh = attribs.height; ++ ++ /* Query window tree information */ ++ XQueryTree(display, window, &root, &parent, &child, &n_children); ++ if (parent) ++ { ++ int x, y; ++ ++ /* If we have a parent we must go there and discover his position */ ++ x11_get_window_abs_position(display, parent, &x, &y, NULL, NULL); ++ *wx += x; ++ *wy += y; ++ } ++ ++ /* If we had children, free them */ ++ if(n_children) ++ XFree(child); ++} ++ ++static GstXWindow * ++gst_omapfbsink_xwindow_new (GstOmapFbSink * omapfbsink, gint width, gint height) ++{ ++ GstXWindow *xwindow = NULL; ++ XGCValues values; ++ ++ if(!omapfbsink->xcontext) ++ return NULL; ++ ++ xwindow = g_new0 (GstXWindow, 1); ++ xwindow->width = width; ++ xwindow->height = height; ++ xwindow->internal = TRUE; ++ ++ g_mutex_lock (omapfbsink->x_lock); ++ xwindow->win = XCreateSimpleWindow (omapfbsink->xcontext->disp, ++ omapfbsink->xcontext->root, ++ 0, 0, xwindow->width, xwindow->height, ++ 0, 0, omapfbsink->colorKey); ++ ++ /* We have to do that to prevent X from redrawing the background on ++ ConfigureNotify. This takes away flickering of video when resizing. */ ++ XSetWindowBackgroundPixmap (omapfbsink->xcontext->disp, xwindow->win, None); ++ ++ if (omapfbsink->handle_events) { ++ Atom wm_delete; ++ ++ XSelectInput (omapfbsink->xcontext->disp, xwindow->win, ExposureMask | ++ StructureNotifyMask | PointerMotionMask | KeyPressMask | ++ KeyReleaseMask | ButtonPressMask | ButtonReleaseMask); ++ ++ /* Tell the window manager we'd like delete client messages instead of ++ * being killed */ ++ wm_delete = XInternAtom (omapfbsink->xcontext->disp, ++ "WM_DELETE_WINDOW", False); ++ (void) XSetWMProtocols (omapfbsink->xcontext->disp, xwindow->win, ++ &wm_delete, 1); ++ } ++ ++ xwindow->gc = XCreateGC (omapfbsink->xcontext->disp, xwindow->win, ++ 0, &values); ++ ++ XMapRaised (omapfbsink->xcontext->disp, xwindow->win); ++ XSync (omapfbsink->xcontext->disp, FALSE); ++ ++ g_mutex_unlock (omapfbsink->x_lock); ++ gst_x_overlay_got_xwindow_id (GST_X_OVERLAY (omapfbsink), xwindow->win); ++ ++ return xwindow; ++} ++ ++static gboolean gst_omapfbsink_update_plane (GstOmapFbSink *omapfbsink) ++{ ++ int wx, wy, ww, wh; ++ if (!omapfbsink->xcontext) ++ { ++ if (ioctl (omapfbsink->overlay_fd, OMAPFB_SETUP_PLANE, &omapfbsink->plane_info)) ++ return FALSE; ++ return TRUE; ++ } ++ ++ if (omapfbsink->plane_info.enabled != 1) ++ return FALSE; ++ ++ x11_get_window_abs_position(omapfbsink->xcontext->disp, ++ omapfbsink->xwindow->win, &wx, &wy, &ww, &wh); ++ ++ if (wx != omapfbsink->xwindow->wx || wy != omapfbsink->xwindow->wy || ++ wh != omapfbsink->xwindow->height || ww != omapfbsink->xwindow->width) { ++ omapfbsink->plane_info.out_width = omapfbsink->xwindow->width = ww; ++ omapfbsink->plane_info.out_height = omapfbsink->xwindow->height = wh; ++ omapfbsink->plane_info.pos_x = omapfbsink->xwindow->wx = wx; ++ omapfbsink->plane_info.pos_y = omapfbsink->xwindow->wy = wy; ++ ++ GST_DEBUG_OBJECT(omapfbsink, "updating geometry to: (%d,%d) %dx%d", wx, wy, ww, wh); ++ ++ XSetForeground (omapfbsink->xcontext->disp, omapfbsink->xwindow->gc, omapfbsink->colorKey); ++ XFillRectangle (omapfbsink->xcontext->disp, omapfbsink->xwindow->win, omapfbsink->xwindow->gc, 0, 0, ww, wh); ++ ++ if (ioctl (omapfbsink->overlay_fd, OMAPFB_SETUP_PLANE, &omapfbsink->plane_info)) ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++static void ++gst_omapfbsink_expose (GstXOverlay * overlay) ++{ ++ gst_omapfbsink_update_plane(GST_OMAPFB_SINK (overlay)); ++} ++ ++static void ++gst_omapfbsink_xwindow_destroy (GstOmapFbSink * omapfbsink, ++ GstXWindow * xwindow) ++{ ++ g_return_if_fail (xwindow != NULL); ++ g_mutex_lock (omapfbsink->x_lock); ++ ++ /* If we did not create that window we just free the GC and let it live */ ++ if (xwindow->internal) ++ XDestroyWindow (omapfbsink->xcontext->disp, xwindow->win); ++ else ++ XSelectInput (omapfbsink->xcontext->disp, xwindow->win, 0); ++ ++ XFreeGC (omapfbsink->xcontext->disp, xwindow->gc); ++ XSync (omapfbsink->xcontext->disp, FALSE); ++ g_mutex_unlock (omapfbsink->x_lock); ++ g_free (xwindow); ++} ++ ++/* This function handles XEvents that might be in the queue. It generates ++ GstEvent that will be sent upstream in the pipeline to handle interactivity ++ and navigation.*/ ++static void ++gst_omapfbsink_handle_xevents (GstOmapFbSink * omapfbsink) ++{ ++ XEvent e; ++ g_mutex_lock (omapfbsink->flow_lock); ++ g_mutex_lock (omapfbsink->x_lock); ++ ++ while (XCheckWindowEvent (omapfbsink->xcontext->disp, ++ omapfbsink->xwindow->win, ExposureMask | StructureNotifyMask, &e)) { ++ switch (e.type) { ++ case Expose: ++ case ConfigureNotify: ++ gst_omapfbsink_update_plane (omapfbsink); ++ break; ++ default: ++ break; ++ } ++ } ++ ++ /* Handle Display events */ ++ while (XPending (omapfbsink->xcontext->disp)) { ++ XNextEvent (omapfbsink->xcontext->disp, &e); ++ ++ switch (e.type) { ++ case ClientMessage:{ ++ Atom wm_delete; ++ ++ wm_delete = XInternAtom (omapfbsink->xcontext->disp, ++ "WM_DELETE_WINDOW", False); ++ if (wm_delete == (Atom) e.xclient.data.l[0]) { ++ /* Handle window deletion by posting an error on the bus */ ++ GST_ELEMENT_ERROR (omapfbsink, RESOURCE, NOT_FOUND, ++ ("Output window was closed"), (NULL)); ++ ++ g_mutex_unlock (omapfbsink->x_lock); ++ gst_omapfbsink_xwindow_destroy (omapfbsink, omapfbsink->xwindow); ++ omapfbsink->xwindow = NULL; ++ g_mutex_lock (omapfbsink->x_lock); ++ } ++ break; ++ } ++ default: ++ break; ++ } ++ } ++ ++ g_mutex_unlock (omapfbsink->x_lock); ++ g_mutex_unlock (omapfbsink->flow_lock); ++} ++ ++static gpointer ++gst_omapfbsink_event_thread (GstOmapFbSink * omapfbsink) ++{ ++ GST_OBJECT_LOCK (omapfbsink); ++ while (omapfbsink->running) { ++ GST_OBJECT_UNLOCK (omapfbsink); ++ ++ if (omapfbsink->xwindow) ++ gst_omapfbsink_handle_xevents (omapfbsink); ++ g_usleep (100000); ++ ++ GST_OBJECT_LOCK (omapfbsink); ++ } ++ GST_OBJECT_UNLOCK (omapfbsink); ++ ++ return NULL; ++} ++ ++/* This function gets the X Display and global info about it. Everything is ++ stored in our object and will be cleaned when the object is disposed. */ ++static GstXContext * ++gst_omapfbsink_xcontext_get (GstOmapFbSink * omapfbsink) ++{ ++ GstXContext *xcontext = g_new0 (GstXContext, 1); ++ g_mutex_lock (omapfbsink->x_lock); ++ ++ xcontext->disp = XOpenDisplay (omapfbsink->display_name); ++ ++ if (!xcontext->disp) { ++ g_mutex_unlock (omapfbsink->x_lock); ++ g_free (xcontext); ++ GST_ELEMENT_WARNING (omapfbsink, RESOURCE, WRITE, ++ ("Could not initialise X output"), ++ ("Could not open display")); ++ return NULL; ++ } ++ ++ xcontext->screen = DefaultScreenOfDisplay (xcontext->disp); ++ xcontext->screen_num = DefaultScreen (xcontext->disp); ++ xcontext->visual = DefaultVisual (xcontext->disp, xcontext->screen_num); ++ xcontext->root = DefaultRootWindow (xcontext->disp); ++ ++ xcontext->width = DisplayWidth (xcontext->disp, xcontext->screen_num); ++ xcontext->height = DisplayHeight (xcontext->disp, xcontext->screen_num); ++ ++ g_mutex_unlock (omapfbsink->x_lock); ++ ++ /* Setup our event listening thread */ ++ GST_OBJECT_LOCK (omapfbsink); ++ omapfbsink->running = TRUE; ++ omapfbsink->event_thread = g_thread_create ( ++ (GThreadFunc) gst_omapfbsink_event_thread, omapfbsink, TRUE, NULL); ++ GST_OBJECT_UNLOCK (omapfbsink); ++ ++ return xcontext; ++} ++ ++static void ++gst_omapfbsink_set_xwindow_id (GstXOverlay * overlay, XID xwindow_id) ++{ ++ GstOmapFbSink *omapfbsink = GST_OMAPFB_SINK (overlay); ++ GstXWindow *xwindow = NULL; ++ XWindowAttributes attr; ++ ++ /* If we already use that window, return */ ++ if (omapfbsink->xwindow && (xwindow_id == omapfbsink->xwindow->win)) ++ return; ++ ++ /* If the element has not initialized the X11 context try to do so */ ++ if (!omapfbsink->xcontext && ++ !(omapfbsink->xcontext = gst_omapfbsink_xcontext_get (omapfbsink))) { ++ g_mutex_unlock (omapfbsink->flow_lock); ++ return; ++ } ++ ++ /* If a window is there already we destroy it */ ++ if (omapfbsink->xwindow) { ++ gst_omapfbsink_xwindow_destroy (omapfbsink, omapfbsink->xwindow); ++ omapfbsink->xwindow = NULL; ++ } ++ ++ /* If the xid is 0 we go back to an internal window */ ++ if (xwindow_id == 0) { ++ /* If no width/height caps nego did not happen window will be created ++ during caps nego then */ ++ if (GST_VIDEO_SINK_WIDTH (omapfbsink) && GST_VIDEO_SINK_HEIGHT (omapfbsink)) { ++ xwindow = gst_omapfbsink_xwindow_new (omapfbsink, ++ GST_VIDEO_SINK_WIDTH (omapfbsink), ++ GST_VIDEO_SINK_HEIGHT (omapfbsink)); ++ } ++ } else { ++ xwindow = g_new0 (GstXWindow, 1); ++ xwindow->wx = xwindow->wy = -1; ++ xwindow->win = xwindow_id; ++ ++ /* We get window geometry, set the event we want to receive, ++ and create a GC */ ++ g_mutex_lock (omapfbsink->x_lock); ++ XGetWindowAttributes (omapfbsink->xcontext->disp, xwindow->win, &attr); ++ xwindow->width = attr.width; ++ xwindow->height = attr.height; ++ xwindow->internal = FALSE; ++ if (omapfbsink->handle_events) { ++ XSelectInput (omapfbsink->xcontext->disp, xwindow->win, ExposureMask | ++ StructureNotifyMask | PointerMotionMask | KeyPressMask | ++ KeyReleaseMask); ++ } ++ ++ xwindow->gc = XCreateGC (omapfbsink->xcontext->disp, xwindow->win, 0, NULL); ++ g_mutex_unlock (omapfbsink->x_lock); ++ } ++ ++ if (xwindow) { ++ omapfbsink->xwindow = xwindow; ++ ++ g_mutex_lock (omapfbsink->x_lock); ++ gst_omapfbsink_update_plane(omapfbsink); ++ g_mutex_unlock (omapfbsink->x_lock); ++ } ++} ++ ++static void ++gst_omapfbsink_xwindow_clear (GstOmapFbSink * omapfbsink, ++ GstXWindow * xwindow) ++{ ++ g_return_if_fail (xwindow != NULL); ++ g_mutex_lock (omapfbsink->x_lock); ++ ++ XSetForeground (omapfbsink->xcontext->disp, xwindow->gc, ++ XBlackPixel (omapfbsink->xcontext->disp, ++ omapfbsink->xcontext->screen_num)); ++ ++ XFillRectangle (omapfbsink->xcontext->disp, xwindow->win, xwindow->gc, ++ 0, 0, xwindow->width, xwindow->height); ++ ++ XSync (omapfbsink->xcontext->disp, FALSE); ++ g_mutex_unlock (omapfbsink->x_lock); ++} ++ ++static void ++gst_omapfbsink_set_event_handling (GstXOverlay * overlay, ++ gboolean handle_events) ++{ ++ GstOmapFbSink *omapfbsink = GST_OMAPFB_SINK (overlay); ++ omapfbsink->handle_events = handle_events; ++ ++ g_mutex_lock (omapfbsink->flow_lock); ++ ++ if (G_UNLIKELY (!omapfbsink->xwindow)) { ++ g_mutex_unlock (omapfbsink->flow_lock); ++ return; ++ } ++ ++ g_mutex_lock (omapfbsink->x_lock); ++ ++ if (handle_events) { ++ if (omapfbsink->xwindow->internal) { ++ XSelectInput (omapfbsink->xcontext->disp, omapfbsink->xwindow->win, ++ ExposureMask | StructureNotifyMask | PointerMotionMask | ++ KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask); ++ } else { ++ XSelectInput (omapfbsink->xcontext->disp, omapfbsink->xwindow->win, ++ ExposureMask | StructureNotifyMask | PointerMotionMask | ++ KeyPressMask | KeyReleaseMask); ++ } ++ } else { ++ XSelectInput (omapfbsink->xcontext->disp, omapfbsink->xwindow->win, 0); ++ } ++ ++ g_mutex_unlock (omapfbsink->x_lock); ++ g_mutex_unlock (omapfbsink->flow_lock); ++} ++ ++static void ++gst_omapfbsink_xoverlay_init (GstXOverlayClass * iface) ++{ ++ iface->set_xwindow_id = gst_omapfbsink_set_xwindow_id; ++ iface->expose = gst_omapfbsink_expose; ++ iface->handle_events = gst_omapfbsink_set_event_handling; ++} ++ ++static GstCaps * ++generate_sink_template (void) ++{ ++ GstCaps *caps; ++ GstStructure *struc; ++ ++ caps = gst_caps_new_empty (); ++ ++ struc = gst_structure_new ("video/x-raw-yuv", ++ "width", GST_TYPE_INT_RANGE, 16, 4096, ++ "height", GST_TYPE_INT_RANGE, 16, 4096, ++ "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 30, 1, ++ NULL); ++ ++ { ++ GValue list; ++ GValue val; ++ ++ list.g_type = val.g_type = 0; ++ ++ g_value_init (&list, GST_TYPE_LIST); ++ g_value_init (&val, GST_TYPE_FOURCC); ++ ++#if 0 ++ gst_value_set_fourcc (&val, GST_MAKE_FOURCC ('Y', 'U', 'Y', '2')); ++ gst_value_list_append_value (&list, &val); ++#else ++ gst_value_set_fourcc (&val, GST_MAKE_FOURCC ('I', '4', '2', '0')); ++ gst_value_list_append_value (&list, &val); ++ ++ gst_value_set_fourcc (&val, GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y')); ++ gst_value_list_append_value (&list, &val); ++#endif ++ ++ gst_structure_set_value (struc, "format", &list); ++ ++ g_value_unset (&val); ++ g_value_unset (&list); ++ } ++ ++ gst_caps_append_structure (caps, struc); ++ ++ return caps; ++} ++ ++static GstFlowReturn ++buffer_alloc (GstBaseSink *bsink, ++ guint64 offset, ++ guint size, ++ GstCaps *caps, ++ GstBuffer **buf) ++{ ++ GstOmapFbSink *self; ++ GstBuffer *buffer = NULL; ++ GstFlowReturn ret = GST_FLOW_OK; ++ self = GST_OMAPFB_SINK (bsink); ++ ++ if(self->row_skip) { ++ buffer = gst_buffer_new (); ++ GST_BUFFER_DATA (buffer) = self->buffer = self->framebuffer; ++ GST_BUFFER_SIZE (buffer) = self->buffer_size = size; ++ gst_buffer_set_caps (buffer, caps); ++ } else { ++ if(self->buffer && size == self->buffer_size) { ++ buffer = gst_buffer_new (); ++ GST_BUFFER_DATA (buffer) = self->buffer; ++ GST_BUFFER_SIZE (buffer) = size; ++ gst_buffer_set_caps (buffer, caps); ++ } else { ++ if(self->buffer) ++ free(self->buffer); ++ if(posix_memalign(&self->buffer, 16, (size_t) size) == 0) { ++ buffer = gst_buffer_new (); ++ GST_BUFFER_DATA (buffer) = self->buffer; ++ GST_BUFFER_SIZE (buffer) = self->buffer_size = size; ++ gst_buffer_set_caps (buffer, caps); ++ } else { ++ GST_ELEMENT_ERROR (self, RESOURCE, WRITE, ("Could not allocate aligned buf!"), ++ ("Could not alloc aligned buf!")); ++ } ++ } ++ } ++ ++ *buf = buffer; ++ return ret; ++} ++ ++static void ++x_memcpy (GstOmapFbSink *omapfbsink, __uint8_t *outBuf, __uint8_t *inBuf) ++{ ++ BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; ++ Buffer_Handle hInBuf = NULL, hOutBuf = NULL; ++ Framecopy_Attrs fcAttrs = Framecopy_Attrs_DEFAULT; ++ int size; ++ ++ if (omapfbsink->hFc == NULL) { ++ fcAttrs.accel = TRUE; ++ omapfbsink->hFc = Framecopy_create(&fcAttrs); ++ if (omapfbsink->hFc == NULL) { ++ GST_ELEMENT_ERROR(omapfbsink, RESOURCE, WRITE, ("failed to create dmai framecopy handle"), ("failed to create dmai framecopy handle")); ++ goto cleanup; ++ } ++ } ++ ++ gfxAttrs.bAttrs.reference = TRUE; ++ gfxAttrs.dim.width = GST_VIDEO_SINK_WIDTH (omapfbsink); ++ gfxAttrs.dim.height = GST_VIDEO_SINK_HEIGHT (omapfbsink); ++ gfxAttrs.colorSpace = ColorSpace_UYVY; ++ gfxAttrs.dim.lineLength = omapfbsink->fixinfo.line_length; ++ size = gfxAttrs.dim.height * gfxAttrs.dim.width * 2; ++ ++ hInBuf = Buffer_create(size, BufferGfx_getBufferAttrs(&gfxAttrs)); ++ if (hInBuf == NULL) { ++ GST_ELEMENT_ERROR(omapfbsink, RESOURCE, WRITE, ("Could not allocate refer dmai buffer"), ("Could not allocate refer dmai buffer")); ++ goto cleanup; ++ } ++ Buffer_setUserPtr(hInBuf, (Int8*) inBuf); ++ Buffer_setNumBytesUsed(hInBuf,Buffer_getSize(hInBuf)); ++ ++ hOutBuf = Buffer_create(size, BufferGfx_getBufferAttrs(&gfxAttrs)); ++ if (hOutBuf == NULL) { ++ GST_ELEMENT_ERROR(omapfbsink, RESOURCE, WRITE, ("Could not allocate refer dmai buffer"), ("Could not allocate refer dmai buffer")); ++ goto cleanup; ++ } ++ Buffer_setUserPtr(hOutBuf, (Int8*) outBuf); ++ Buffer_setNumBytesUsed(hOutBuf,Buffer_getSize(hOutBuf)); ++ ++ ++ if (Framecopy_config(omapfbsink->hFc, hInBuf, hOutBuf) < 0) { ++ GST_ELEMENT_ERROR(omapfbsink, RESOURCE, WRITE, ("failed to configure dmai framecopy handle"), ("failed to configure dmai framecopy handle")); ++ goto cleanup; ++ } ++ ++ if (Framecopy_execute(omapfbsink->hFc, hInBuf, hOutBuf) < 0) { ++ GST_ELEMENT_ERROR(omapfbsink, RESOURCE, WRITE, ("failed to execute dmai framecopy handle"), ("failed to configure dmai framecopy handle")); ++ goto cleanup; ++ } ++ cleanup: ++ ++ if (hInBuf) ++ Buffer_delete(hInBuf); ++ if (hOutBuf) ++ Buffer_delete(hOutBuf); ++} ++ ++static GstFlowReturn ++render (GstBaseSink * bsink, GstBuffer * buf) ++{ ++ int i, w, h; ++ GstOmapFbSink *omapfbsink = GST_OMAPFB_SINK(bsink); ++ __uint8_t *fb = omapfbsink->framebuffer, *data = GST_BUFFER_DATA(buf); ++ gboolean useXcopy = FALSE; ++ ++ if (GST_IS_TIDMAIBUFFERTRANSPORT(buf)) { ++ GST_LOG("found dmai transport buffer, enabling hw framecopy.\n"); ++ useXcopy = TRUE; ++ } ++ ++ if(omapfbsink->plane_info.enabled == 2) ++ { ++ omapfbsink->plane_info.enabled = 1; ++ ++ g_mutex_lock (omapfbsink->x_lock); ++ gst_omapfbsink_update_plane(omapfbsink); ++ g_mutex_unlock (omapfbsink->x_lock); ++ } ++ ++ /* If a buffer which wasn't supplied by us is given to us to render with, ++ we need to copy to our buffer first so that memory alignment constraints ++ are met. */ ++ if((data != omapfbsink->buffer && GST_BUFFER_SIZE(buf) <= omapfbsink->buffer_size) && !useXcopy) ++ { ++ memcpy(omapfbsink->buffer, data, GST_BUFFER_SIZE(buf)); ++ data = omapfbsink->buffer; ++ } ++ ++ /* buffer_alloc gave a direct buffer, so we have nothing to ++ do here... */ ++ if(omapfbsink->row_skip) ++ return GST_FLOW_OK; ++ ++ switch(omapfbsink->image_format) { ++ case GST_MAKE_FOURCC('I', '4', '2', '0'): ++ /* Convert to YUV422 and send to FB */ ++ ++ h = GST_VIDEO_SINK_HEIGHT (omapfbsink); ++ w = GST_VIDEO_SINK_WIDTH (omapfbsink); ++ ++ __uint8_t *y, *u, *v; ++ y = data; ++ u = y + w * h; ++ v = u + w / 2 * h / 2; ++ yuv420_to_yuv422(fb, y, u, v, w & ~15, h, w, w / 2, omapfbsink->fixinfo.line_length); ++ break; ++ ++ case GST_MAKE_FOURCC('U', 'Y', 'V', 'Y'): ++ /* Send to FB, taking into account line_length */ ++ if (useXcopy) { ++ x_memcpy(omapfbsink, fb, data); ++ } ++ else { ++ ++ w = 2 * GST_VIDEO_SINK_WIDTH (omapfbsink); ++ for(i = 0; i < GST_VIDEO_SINK_HEIGHT (omapfbsink); i++) ++ { ++ memcpy(fb, data, w); ++ ++ fb += omapfbsink->fixinfo.line_length; ++ data += w; ++ } ++ } ++ break; ++ } ++ ++ return GST_FLOW_OK; ++} ++ ++static gboolean ++setcaps (GstBaseSink *bsink, ++ GstCaps *vscapslist) ++{ ++ GstOmapFbSink *self; ++ GstStructure *structure; ++ ++ gint width, height; ++ struct omapfb_color_key color_key; ++ ++ self = GST_OMAPFB_SINK (bsink); ++ ++ structure = gst_caps_get_structure (vscapslist, 0); ++ ++ gst_structure_get_int (structure, "width", &width); ++ gst_structure_get_int (structure, "height", &height); ++ ++ self->overlay_info.xres = MIN (self->varinfo.xres, width) & ~15; ++ self->overlay_info.yres = MIN (self->varinfo.yres, height) & ~15; ++ self->overlay_info.xres_virtual = self->overlay_info.xres; ++ self->overlay_info.yres_virtual = self->overlay_info.yres; ++ ++ self->overlay_info.xoffset = 0; ++ self->overlay_info.yoffset = 0; ++ ++ gst_structure_get_fourcc (structure, "format", &self->image_format); ++ switch(self->image_format) { ++ case GST_MAKE_FOURCC('I', '4', '2', '0'): ++ self->row_skip = FALSE; /* Colorspace conversion required */ ++ self->overlay_info.nonstd = OMAPFB_COLOR_YUY422; ++ break; ++ case GST_MAKE_FOURCC('U', 'Y', 'V', 'Y'): ++ /* Can data be pushed straight to the FB or do we need to interleave? */ ++ if (self->fixinfo.line_length != 2 * width) ++ self->row_skip = FALSE; ++ else ++ self->row_skip = TRUE; ++ self->overlay_info.nonstd = OMAPFB_COLOR_YUV422; ++ break; ++ } ++ ++ if (ioctl (self->overlay_fd, FBIOPUT_VSCREENINFO, &self->overlay_info)) ++ return FALSE; ++ ++ GST_VIDEO_SINK_WIDTH (self) = width; ++ GST_VIDEO_SINK_HEIGHT (self) = height; ++ if (!self->xwindow) { ++ self->xwindow = gst_omapfbsink_xwindow_new (self, ++ GST_VIDEO_SINK_WIDTH (self), GST_VIDEO_SINK_HEIGHT (self)); ++ } ++ ++ color_key.channel_out = OMAPFB_CHANNEL_OUT_LCD; ++ color_key.background = 0x0; ++ color_key.trans_key = self->colorKey; ++ if (self->xwindow) ++ color_key.key_type = OMAPFB_COLOR_KEY_GFX_DST; ++ else ++ color_key.key_type = OMAPFB_COLOR_KEY_DISABLED; ++ ++ if (ioctl (self->overlay_fd, OMAPFB_SET_COLOR_KEY, &color_key)) ++ return FALSE; ++ ++ self->plane_info.pos_x = 0; ++ self->plane_info.pos_y = 0; ++ self->plane_info.out_width = self->overlay_info.xres; ++ self->plane_info.out_height = self->overlay_info.yres; ++ self->plane_info.enabled = 2; ++ ++ if (ioctl (self->overlay_fd, FBIOGET_FSCREENINFO, &self->fixinfo)) ++ return FALSE; ++ ++ self->enabled = TRUE; ++ return TRUE; ++} ++ ++static gboolean ++start (GstBaseSink *bsink) ++{ ++ GstOmapFbSink *self; ++ int fd; ++ ++ self = GST_OMAPFB_SINK (bsink); ++ ++ fd = open ("/dev/fb0", O_RDWR); ++ ++ if (fd == -1) ++ return FALSE; ++ ++ if (ioctl (fd, FBIOGET_VSCREENINFO, &self->varinfo)) ++ { ++ close (fd); ++ return FALSE; ++ } ++ ++ if (close (fd)) ++ return FALSE; ++ ++ self->overlay_fd = open ("/dev/fb1", O_RDWR); ++ ++ if (self->overlay_fd == -1) ++ return FALSE; ++ ++ if (ioctl (self->overlay_fd, FBIOGET_VSCREENINFO, &self->overlay_info)) ++ return FALSE; ++ ++ if (ioctl (self->overlay_fd, OMAPFB_QUERY_PLANE, &self->plane_info)) ++ return FALSE; ++ ++ if (ioctl (self->overlay_fd, OMAPFB_QUERY_MEM, &self->mem_info)) ++ return FALSE; ++ ++ self->framebuffer = mmap (NULL, self->mem_info.size, PROT_WRITE, MAP_SHARED, self->overlay_fd, 0); ++ if (self->framebuffer == MAP_FAILED) ++ return FALSE; ++ ++ return TRUE; ++} ++ ++static gboolean ++stop (GstBaseSink *bsink) ++{ ++ GstOmapFbSink *self; ++ ++ self = GST_OMAPFB_SINK (bsink); ++ ++ if (self->enabled) ++ { ++ self->plane_info.enabled = 0; ++ ++ if (ioctl (self->overlay_fd, OMAPFB_SETUP_PLANE, &self->plane_info)) ++ return FALSE; ++ } ++ ++ if (munmap (self->framebuffer, self->mem_info.size)) ++ return FALSE; ++ ++ if (close (self->overlay_fd)) ++ return FALSE; ++ ++ if (self->hFc) ++ Framecopy_delete(self->hFc); ++ ++ return TRUE; ++} ++ ++/* This function cleans the X context. Closing the Display and unrefing the ++ caps for supported formats. */ ++static void ++gst_omapfbsink_xcontext_clear (GstOmapFbSink * omapfbsink) ++{ ++ GstXContext *xcontext; ++ GST_OBJECT_LOCK (omapfbsink); ++ if (omapfbsink->xcontext == NULL) { ++ GST_OBJECT_UNLOCK (omapfbsink); ++ return; ++ } ++ ++ xcontext = omapfbsink->xcontext; ++ omapfbsink->xcontext = NULL; ++ ++ GST_OBJECT_UNLOCK (omapfbsink); ++ g_mutex_lock (omapfbsink->x_lock); ++ ++ XCloseDisplay (xcontext->disp); ++ g_mutex_unlock (omapfbsink->x_lock); ++ g_free (xcontext); ++} ++ ++static void ++gst_omapfbsink_reset (GstOmapFbSink *omapfbsink) ++{ ++ GThread *thread; ++ ++ GST_OBJECT_LOCK (omapfbsink); ++ omapfbsink->running = FALSE; ++ /* grab thread and mark it as NULL */ ++ thread = omapfbsink->event_thread; ++ omapfbsink->event_thread = NULL; ++ GST_OBJECT_UNLOCK (omapfbsink); ++ ++ /* Wait for our event thread to finish before we clean up our stuff. */ ++ if (thread) ++ g_thread_join (thread); ++ ++ g_mutex_lock (omapfbsink->flow_lock); ++ if (omapfbsink->xwindow) { ++ gst_omapfbsink_xwindow_clear (omapfbsink, omapfbsink->xwindow); ++ gst_omapfbsink_xwindow_destroy (omapfbsink, omapfbsink->xwindow); ++ omapfbsink->xwindow = NULL; ++ } ++ g_mutex_unlock (omapfbsink->flow_lock); ++ gst_omapfbsink_xcontext_clear (omapfbsink); ++} ++ ++static GstStateChangeReturn ++gst_omapfbsink_change_state (GstElement * element, GstStateChange transition) ++{ ++ GstOmapFbSink *omapfbsink; ++ GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; ++ GstXContext *xcontext = NULL; ++ ++ omapfbsink = GST_OMAPFB_SINK (element); ++ ++ switch (transition) { ++ case GST_STATE_CHANGE_NULL_TO_READY: ++ ++ /* Initializing the XContext */ ++ if (omapfbsink->xcontext == NULL) { ++ xcontext = gst_omapfbsink_xcontext_get (omapfbsink); ++ ++ GST_OBJECT_LOCK (omapfbsink); ++ omapfbsink->xcontext = xcontext; ++ GST_OBJECT_UNLOCK (omapfbsink); ++ } ++ break; ++ case GST_STATE_CHANGE_READY_TO_PAUSED: ++ g_mutex_lock (omapfbsink->flow_lock); ++ if (omapfbsink->xwindow) ++ gst_omapfbsink_xwindow_clear (omapfbsink, omapfbsink->xwindow); ++ g_mutex_unlock (omapfbsink->flow_lock); ++ break; ++ case GST_STATE_CHANGE_PAUSED_TO_PLAYING: ++ break; ++ default: ++ break; ++ } ++ ++ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); ++ ++ switch (transition) { ++ case GST_STATE_CHANGE_PLAYING_TO_PAUSED: ++ break; ++ case GST_STATE_CHANGE_PAUSED_TO_READY: ++ GST_VIDEO_SINK_WIDTH (omapfbsink) = 0; ++ GST_VIDEO_SINK_HEIGHT (omapfbsink) = 0; ++ break; ++ case GST_STATE_CHANGE_READY_TO_NULL: ++ gst_omapfbsink_reset (omapfbsink); ++ break; ++ default: ++ break; ++ } ++ ++ return ret; ++} ++ ++static void ++type_class_init (gpointer g_class, ++ gpointer class_data) ++{ ++ GstElementClass *element_class; ++ GstBaseSinkClass *base_sink_class; ++ ++ element_class = (GstElementClass *) g_class; ++ base_sink_class = (GstBaseSinkClass *) g_class; ++ ++ parent_class = g_type_class_peek_parent (g_class); ++ ++ base_sink_class->set_caps = GST_DEBUG_FUNCPTR (setcaps); ++ base_sink_class->buffer_alloc = GST_DEBUG_FUNCPTR (buffer_alloc); ++ base_sink_class->render = GST_DEBUG_FUNCPTR (render); ++ base_sink_class->start = GST_DEBUG_FUNCPTR (start); ++ base_sink_class->stop = GST_DEBUG_FUNCPTR (stop); ++ ++ element_class->change_state = gst_omapfbsink_change_state; ++} ++ ++static void ++type_base_init (gpointer g_class) ++{ ++ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); ++ ++ { ++ GstElementDetails details; ++ ++ details.longname = "Linux OMAP framebuffer sink"; ++ details.klass = "Sink/Video"; ++ details.description = "Renders video with omapfb"; ++ details.author = "Felipe Contreras"; ++ ++ gst_element_class_set_details (element_class, &details); ++ } ++ ++ { ++ GstPadTemplate *template; ++ ++ template = gst_pad_template_new ("sink", GST_PAD_SINK, ++ GST_PAD_ALWAYS, ++ generate_sink_template ()); ++ ++ gst_element_class_add_pad_template (element_class, template); ++ } ++} ++ ++static gboolean ++gst_omapfbsink_interface_supported (GstImplementsInterface * iface, GType type) ++{ ++ g_assert (type == GST_TYPE_X_OVERLAY); ++ return TRUE; ++} ++ ++static void ++gst_omapfbsink_interface_init (GstImplementsInterfaceClass * klass) ++{ ++ klass->supported = gst_omapfbsink_interface_supported; ++} ++ ++static void ++gst_omapfbsink_init (GstOmapFbSink * omapfbsink) ++{ ++ omapfbsink->display_name = NULL; ++ omapfbsink->xcontext = NULL; ++ omapfbsink->xwindow = NULL; ++ ++ omapfbsink->event_thread = NULL; ++ omapfbsink->running = FALSE; ++ ++ omapfbsink->x_lock = g_mutex_new (); ++ omapfbsink->flow_lock = g_mutex_new (); ++ ++ omapfbsink->handle_events = TRUE; ++ omapfbsink->colorKey = 0xff0; ++ ++ omapfbsink->plane_info.enabled = 0; ++ omapfbsink->row_skip = FALSE; ++ ++ omapfbsink->buffer = NULL; ++ omapfbsink->buffer_size = 0; ++ omapfbsink->hFc = NULL; ++} ++ ++GType ++gst_omapfbsink_get_type (void) ++{ ++ static GType type = 0; ++ ++ if (G_UNLIKELY (type == 0)) ++ { ++ GTypeInfo *type_info; ++ static const GInterfaceInfo iface_info = { ++ (GInterfaceInitFunc) gst_omapfbsink_interface_init, ++ NULL, ++ NULL, ++ }; ++ static const GInterfaceInfo overlay_info = { ++ (GInterfaceInitFunc) gst_omapfbsink_xoverlay_init, ++ NULL, ++ NULL, ++ }; ++ type_info = g_new0 (GTypeInfo, 1); ++ type_info->class_size = sizeof (GstOmapFbSinkClass); ++ type_info->base_init = type_base_init; ++ type_info->class_init = type_class_init; ++ type_info->instance_size = sizeof (GstOmapFbSink); ++ type_info->instance_init = (GInstanceInitFunc) gst_omapfbsink_init; ++ ++ type = g_type_register_static (GST_TYPE_BASE_SINK, "GstOmapFbSink", type_info, 0); ++ g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE, &iface_info); ++ g_type_add_interface_static (type, GST_TYPE_X_OVERLAY, &overlay_info); ++ ++ g_free (type_info); ++ } ++ ++ return type; ++} +diff -uNr ticodecplugin/src/omapfb.h ticodecplugin.new/src/omapfb.h +--- ticodecplugin/src/omapfb.h 1969-12-31 18:00:00.000000000 -0600 ++++ ticodecplugin.new/src/omapfb.h 2009-09-15 13:14:44.000000000 -0500 +@@ -0,0 +1,142 @@ ++/* ++ * Copyright (C) 2008 Felipe Contreras ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation ++ * version 2.1 of the License. ++ * ++ * This library 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 ++ * Lesser 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 Street, Fifth Floor, Boston, MA 02111-1301 USA ++ */ ++ ++#ifndef GST_OMAPFB_H ++#define GST_OMAPFB_H ++ ++#include ++#include ++ ++#include "gsttidmaibuffertransport.h" ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++ ++ ++G_BEGIN_DECLS ++ ++#define GST_OMAPFB_SINK_TYPE (gst_omapfbsink_get_type ()) ++#define GST_OMAPFB_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_OMAPFB_SINK_TYPE, GstOmapFbSink)) ++ ++typedef struct GstXContext GstXContext; ++typedef struct GstXWindow GstXWindow; ++typedef struct GstOmapFbSink GstOmapFbSink; ++typedef struct GstOmapFbSinkClass GstOmapFbSinkClass; ++ ++/** ++ * GstXWindow: ++ * @win: the Window ID of this X11 window ++ * @width: the width in pixels of Window @win ++ * @height: the height in pixels of Window @win ++ * @internal: used to remember if Window @win was created internally or passed ++ * through the #GstXOverlay interface ++ * @gc: the Graphical Context of Window @win ++ * ++ * Structure used to store informations about a Window. ++ */ ++struct GstXWindow { ++ Window win; ++ gint width, height; ++ gboolean internal; ++ GC gc; ++ ++ gint wx, wy; ++}; ++ ++/** ++ * GstXContext: ++ * @disp: the X11 Display of this context ++ * @screen: the default Screen of Display @disp ++ * @screen_num: the Screen number of @screen ++ * @visual: the default Visual of Screen @screen ++ * @root: the root Window of Display @disp ++ * @white: the value of a white pixel on Screen @screen ++ * @black: the value of a black pixel on Screen @screen ++ * @depth: the color depth of Display @disp ++ * @bpp: the number of bits per pixel on Display @disp ++ * @endianness: the endianness of image bytes on Display @disp ++ * @width: the width in pixels of Display @disp ++ * @height: the height in pixels of Display @disp ++ * ++ * Structure used to store various informations collected/calculated for a ++ * Display. ++ */ ++struct GstXContext { ++ Display *disp; ++ Screen *screen; ++ gint screen_num; ++ ++ Visual *visual; ++ Window root; ++ ++ gint depth; ++ gint bpp; ++ ++ gint width, height; ++}; ++ ++struct GstOmapFbSink ++{ ++ GstVideoSink videosink; ++ ++ struct fb_fix_screeninfo fixinfo; ++ struct fb_var_screeninfo varinfo; ++ struct fb_var_screeninfo overlay_info; ++ struct omapfb_mem_info mem_info; ++ struct omapfb_plane_info plane_info; ++ ++ int overlay_fd; ++ unsigned char *framebuffer; ++ gboolean enabled; ++ ++ GMutex *x_lock; ++ GMutex *flow_lock; ++ ++ GstXContext *xcontext; ++ GstXWindow *xwindow; ++ ++ gulong colorKey; ++ char *display_name; ++ GThread *event_thread; ++ ++ void *buffer; ++ guint buffer_size; ++ guint image_format; ++ ++ gboolean row_skip; ++ gboolean handle_events; ++ gboolean running; ++ Framecopy_Handle hFc; ++}; ++ ++struct GstOmapFbSinkClass ++{ ++ GstBaseSinkClass parent_class; ++}; ++ ++GType gst_omapfbsink_get_type (void); ++ ++G_END_DECLS ++ ++#endif /* GST_OMAPFB_H */ +diff -uNr ticodecplugin/src/yuv.S ticodecplugin.new/src/yuv.S +--- ticodecplugin/src/yuv.S 1969-12-31 18:00:00.000000000 -0600 ++++ ticodecplugin.new/src/yuv.S 2009-09-15 13:14:44.000000000 -0500 +@@ -0,0 +1,117 @@ ++/* ++ Copyright (C) 2008 Mans Rullgard ++ ++ Permission is hereby granted, free of charge, to any person ++ obtaining a copy of this software and associated documentation ++ files (the "Software"), to deal in the Software without ++ restriction, including without limitation the rights to use, copy, ++ modify, merge, publish, distribute, sublicense, and/or sell copies ++ of the Software, and to permit persons to whom the Software is ++ furnished to do so, subject to the following conditions: ++ ++ The above copyright notice and this permission notice shall be ++ included in all copies or substantial portions of the Software. ++ ++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ DEALINGS IN THE SOFTWARE. ++*/ ++ ++ .fpu neon ++ .text ++ ++@ yuv420_to_yuv422(uint8_t *yuv, uint8_t *y, uint8_t *u, uint8_t *v, ++@ int w, int h, int yw, int cw, int dw) ++ ++#define yuv r0 ++#define y r1 ++#define u r2 ++#define v r3 ++#define w r4 ++#define h r5 ++#define yw r6 ++#define cw r7 ++#define dw r8 ++ ++#define tyuv r9 ++#define ty r10 ++#define tu r11 ++#define tv r12 ++#define i lr ++ ++ .global yuv420_to_yuv422 ++ .func yuv420_to_yuv422 ++yuv420_to_yuv422: ++ push {r4-r11,lr} ++ add r4, sp, #36 ++ ldm r4, {r4-r8} ++1: ++ mov tu, u ++ mov tv, v ++ vld1.64 {d2}, [u,:64], cw @ u0 ++ vld1.64 {d3}, [v,:64], cw @ v0 ++ mov tyuv, yuv ++ mov ty, y ++ vzip.8 d2, d3 @ u0v0 ++ mov i, #16 ++2: ++ pld [y, #64] ++ vld1.64 {d0, d1}, [y,:128], yw @ y0 ++ pld [u, #64] ++ subs i, i, #4 ++ vld1.64 {d6}, [u,:64], cw @ u2 ++ pld [y, #64] ++ vld1.64 {d4, d5}, [y,:128], yw @ y1 ++ pld [v, #64] ++ vld1.64 {d7}, [v,:64], cw @ v2 ++ pld [y, #64] ++ vld1.64 {d16,d17}, [y,:128], yw @ y2 ++ vzip.8 d6, d7 @ u2v2 ++ pld [u, #64] ++ vld1.64 {d22}, [u,:64], cw @ u4 ++ pld [v, #64] ++ vld1.64 {d23}, [v,:64], cw @ v4 ++ pld [y, #64] ++ vld1.64 {d20,d21}, [y,:128], yw @ y3 ++ vmov q9, q3 @ u2v2 ++ vzip.8 d22, d23 @ u4v4 ++ vrhadd.u8 q3, q1, q3 @ u1v1 ++ vzip.8 q0, q1 @ y0u0y0v0 ++ vmov q12, q11 @ u4v4 ++ vzip.8 q2, q3 @ y1u1y1v1 ++ vrhadd.u8 q11, q9, q11 @ u3v3 ++ vst1.64 {d0-d3}, [yuv,:128], dw @ y0u0y0v0 ++ vzip.8 q8, q9 @ y2u2y2v2 ++ vst1.64 {d4-d7}, [yuv,:128], dw @ y1u1y1v1 ++ vzip.8 q10, q11 @ y3u3y3v3 ++ vst1.64 {d16-d19}, [yuv,:128], dw @ y2u2y2v2 ++ vmov q1, q12 ++ vst1.64 {d20-d23}, [yuv,:128], dw @ y3u3y3v3 ++ bgt 2b ++ subs w, w, #16 ++ add yuv, tyuv, #32 ++ add y, ty, #16 ++ add u, tu, #8 ++ add v, tv, #8 ++ bgt 1b ++ ++ ldr w, [sp, #36] ++ subs h, h, #16 ++ add yuv, yuv, dw, lsl #4 ++ sub yuv, yuv, w, lsl #1 ++ add y, y, yw, lsl #4 ++ sub y, y, w ++ add u, u, cw, lsl #3 ++ sub u, u, w, asr #1 ++ add v, v, cw, lsl #3 ++ sub v, v, w, asr #1 ++ bgt 1b ++ ++ pop {r4-r11,pc} ++ .endfunc ++ diff --git a/recipes/ti/gstreamer-ti_svn.bb b/recipes/ti/gstreamer-ti_svn.bb index 8fcc528019..e1782ba477 100644 --- a/recipes/ti/gstreamer-ti_svn.bb +++ b/recipes/ti/gstreamer-ti_svn.bb @@ -11,10 +11,11 @@ SRCREV = "335" SRC_URI = "svn://gforge.ti.com/svn/gstreamer_ti/trunk;module=gstreamer_ti;proto=https;user=anonymous;pswd='' \ file://gstreamer-ti-tracker-824.patch;patch=1 \ file://gstreamer-ti-tracker-462.patch;patch=1 \ + file://gstreamer-ti-add-omapfb.patch;patch=1 \ " # Again, no '.' in PWD allowed :( -PR = "r33" +PR = "r35" PV = "svnr${SRCREV}" S = "${WORKDIR}/gstreamer_ti/ti_build/ticodecplugin" @@ -66,7 +67,13 @@ PACKAGES += "gstreamer-ti-demo-script" FILES_gstreamer-ti-demo-script = "${installdir}/gst/*" RDEPENDS_gstreamer-ti-demo-script = "gstreamer-ti" -RDEPENDS_${PN} = "ti-dmai-apps" +RDEPENDS_${PN} = " \ +gst-plugins-base-meta \ +gst-plugins-good-meta \ +gst-plugins-bad-meta \ +gst-plugins-ugly-meta \ +ti-dmai-apps" + FILES_${PN} += "${libdir}/gstreamer-0.10/*.so" FILES_${PN}-dev += "${libdir}/gstreamer-0.10/*.a ${libdir}/gstreamer-0.10/*.la" FILES_${PN}-dbg += "${libdir}/gstreamer-0.10/.debug" -- cgit v1.2.3 From 33e67dff775d3edcc3a4521106351792c1519093 Mon Sep 17 00:00:00 2001 From: Brijesh Singh Date: Wed, 16 Sep 2009 08:29:03 -0500 Subject: gstreamer-ti: remove mp3 cap from gst_ti auddec1 element. * Default TSPA codec does not have mp3 decoder and this patch removes the mp3 decoder caps from auddec1 element. This will help playbin on auto-detecting mp3 decoder when dsp decoder is not available. --- ...ti-remove-mp3-decode-support-from-auddec1.patch | 26 ++++++++++++++++++++++ recipes/ti/gstreamer-ti_svn.bb | 3 ++- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 recipes/ti/gstreamer-ti/gstreamer-ti-remove-mp3-decode-support-from-auddec1.patch diff --git a/recipes/ti/gstreamer-ti/gstreamer-ti-remove-mp3-decode-support-from-auddec1.patch b/recipes/ti/gstreamer-ti/gstreamer-ti-remove-mp3-decode-support-from-auddec1.patch new file mode 100644 index 0000000000..0fb7861a1c --- /dev/null +++ b/recipes/ti/gstreamer-ti/gstreamer-ti-remove-mp3-decode-support-from-auddec1.patch @@ -0,0 +1,26 @@ +This patch removes mp3 decoder cap from auddec elements. mp3 decoder is not part of tspa combo. If you are adding mp3 decoder support in your combo then do not apply this patch. + +diff -uNr ticodecplugin/src/gsttiauddec1.c ticodecplugin.new/src/gsttiauddec1.c +--- ticodecplugin/src/gsttiauddec1.c 2009-09-05 00:04:51.000000000 -0500 ++++ ticodecplugin.new/src/gsttiauddec1.c 2009-09-15 03:28:28.000000000 -0500 +@@ -85,7 +85,7 @@ + GST_PAD_ALWAYS, + GST_STATIC_CAPS + ("audio/mpeg, " +- "mpegversion = (int) { 1, 4 }") ++ "mpegversion = (int) { 4 }") + ); + + /* Define source (output) pad capabilities. Currently, RAW is supported. */ +diff -uNr ticodecplugin/src/gsttiauddec.c ticodecplugin.new/src/gsttiauddec.c +--- ticodecplugin/src/gsttiauddec.c 2009-09-05 00:04:51.000000000 -0500 ++++ ticodecplugin.new/src/gsttiauddec.c 2009-09-16 07:51:24.000000000 -0500 +@@ -85,7 +85,7 @@ + GST_PAD_ALWAYS, + GST_STATIC_CAPS + ("audio/mpeg, " +- "mpegversion = (int) { 1, 4 }") ++ "mpegversion = (int) { 4 }") + ); + + /* Constants */ diff --git a/recipes/ti/gstreamer-ti_svn.bb b/recipes/ti/gstreamer-ti_svn.bb index e1782ba477..537a2f9cd4 100644 --- a/recipes/ti/gstreamer-ti_svn.bb +++ b/recipes/ti/gstreamer-ti_svn.bb @@ -12,10 +12,11 @@ SRC_URI = "svn://gforge.ti.com/svn/gstreamer_ti/trunk;module=gstreamer_ti;proto= file://gstreamer-ti-tracker-824.patch;patch=1 \ file://gstreamer-ti-tracker-462.patch;patch=1 \ file://gstreamer-ti-add-omapfb.patch;patch=1 \ + file://gstreamer-ti-remove-mp3-decode-support-from-auddec1.patch;patch=1 \ " # Again, no '.' in PWD allowed :( -PR = "r35" +PR = "r36" PV = "svnr${SRCREV}" S = "${WORKDIR}/gstreamer_ti/ti_build/ticodecplugin" -- cgit v1.2.3 From 05a753b24b94d4b1db756356820e3913a2e702bb Mon Sep 17 00:00:00 2001 From: Brijesh Singh Date: Wed, 16 Sep 2009 08:29:38 -0500 Subject: gst-player: add recipe for a simple gstreamer player --- recipes/gstreamer/gst-player_svn.bb | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 recipes/gstreamer/gst-player_svn.bb diff --git a/recipes/gstreamer/gst-player_svn.bb b/recipes/gstreamer/gst-player_svn.bb new file mode 100644 index 0000000000..c44213bfa8 --- /dev/null +++ b/recipes/gstreamer/gst-player_svn.bb @@ -0,0 +1,20 @@ +DESCRIPTION="A simple gstreamer based player" + +DEPENDS = "gstreamer" +RDEPENDS = "gstreamer-ti" + +SRCREV = "6" +SRC_URI = "svn://gstplayer.googlecode.com/svn;module=trunk;proto=http" + +S = "${WORKDIR}/trunk/gstplayer" + +PV = "svnr${SRCREV}" +PR = "r2" + +TARGET_CC_ARCH += "${LDFLAGS}" + +do_install() { + install -d ${D}/usr/bin + install -m 0755 gstplayer ${D}/usr/bin +} + -- cgit v1.2.3 From 718a561ceb1e9668678faaa863b65f670bf7015e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xerxes=20R=C3=A5nby?= Date: Thu, 17 Sep 2009 11:27:17 +0200 Subject: llvm 2.7: New recipe. llvm-native 2.7: Likewise. --- recipes/llvm/llvm2.7-native_2.6+svnr20090916.bb | 16 +++++++++++++++ .../llvm/llvm2.7/llvm-debugonly-zeroormore.patch | 13 ++++++++++++ recipes/llvm/llvm2.7_2.6+svnr20090916.bb | 24 ++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 recipes/llvm/llvm2.7-native_2.6+svnr20090916.bb create mode 100644 recipes/llvm/llvm2.7/llvm-debugonly-zeroormore.patch create mode 100644 recipes/llvm/llvm2.7_2.6+svnr20090916.bb diff --git a/recipes/llvm/llvm2.7-native_2.6+svnr20090916.bb b/recipes/llvm/llvm2.7-native_2.6+svnr20090916.bb new file mode 100644 index 0000000000..ab0bbc5aa8 --- /dev/null +++ b/recipes/llvm/llvm2.7-native_2.6+svnr20090916.bb @@ -0,0 +1,16 @@ +require llvm-native.inc + +SRCREV = "82130" + +PV = "2.6+svnr${SRCREV}" + +PR = "r0" + +SRC_URI = "\ + svn://llvm.org/svn/llvm-project/llvm/;proto=http;module=trunk \ + file://llvm-debugonly-zeroormore.patch;patch=1 \ +" + +S = "${WORKDIR}/trunk" + +LLVM_RELEASE = "2.7" diff --git a/recipes/llvm/llvm2.7/llvm-debugonly-zeroormore.patch b/recipes/llvm/llvm2.7/llvm-debugonly-zeroormore.patch new file mode 100644 index 0000000000..ee32a7966c --- /dev/null +++ b/recipes/llvm/llvm2.7/llvm-debugonly-zeroormore.patch @@ -0,0 +1,13 @@ +Index: trunk/lib/Support/Debug.cpp +=================================================================== +--- trunk.orig/lib/Support/Debug.cpp 2009-09-17 10:41:42.000000000 +0200 ++++ trunk/lib/Support/Debug.cpp 2009-09-17 10:42:55.000000000 +0200 +@@ -48,7 +48,7 @@ + static cl::opt > + DebugOnly("debug-only", cl::desc("Enable a specific type of debug output"), + cl::Hidden, cl::value_desc("debug string"), +- cl::location(DebugOnlyOptLoc), cl::ValueRequired); ++ cl::location(DebugOnlyOptLoc), cl::ValueRequired, cl::ZeroOrMore); + + // isCurrentDebugType - Return true if the specified string is the debug type + // specified on the command line, or if none was specified on the command line diff --git a/recipes/llvm/llvm2.7_2.6+svnr20090916.bb b/recipes/llvm/llvm2.7_2.6+svnr20090916.bb new file mode 100644 index 0000000000..022657c5ff --- /dev/null +++ b/recipes/llvm/llvm2.7_2.6+svnr20090916.bb @@ -0,0 +1,24 @@ +require llvm.inc + +SRCREV = "82130" + +PV = "2.6+svnr${SRCREV}" + +PR = "r0" + +DEPENDS = "llvm-common llvm2.7-native" + +SRC_URI = "\ + svn://llvm.org/svn/llvm-project/llvm/;proto=http;module=trunk \ + file://llvm-debugonly-zeroormore.patch;patch=1 \ +" + +EXTRA_OECMAKE += "\ + -DLLVM_TARGET_ARCH:STRING=${LLVM_ARCH} \ + -DLLVM_ENABLE_ASSERTIONS:BOOL=ON \ + -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo \ + " + +S = "${WORKDIR}/trunk" + +LLVM_RELEASE = "2.7" -- cgit v1.2.3 From 2f514aa042fe5b24fa866d34e56461c03d490e43 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 17 Sep 2009 15:21:46 +0200 Subject: ffmpeg svn: sync with git version to fix versioning --- recipes/ffmpeg/ffmpeg_svn.bb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/recipes/ffmpeg/ffmpeg_svn.bb b/recipes/ffmpeg/ffmpeg_svn.bb index c7aaa7127c..8e1f5e4161 100644 --- a/recipes/ffmpeg/ffmpeg_svn.bb +++ b/recipes/ffmpeg/ffmpeg_svn.bb @@ -2,11 +2,11 @@ require ffmpeg.inc DEPENDS += "schroedinger libgsm" -SRCREV = "16396" +SRCREV = "19894" PE = "1" -PV = "0.4.9+svnr${SRCREV}" -PR = "r2" +PV = "0.5.0+${PR}+svnr${SRCREV}" +PR = "r0" DEFAULT_PREFERENCE = "-1" @@ -42,7 +42,8 @@ EXTRA_OECONF = " \ --enable-libgsm \ --enable-libmp3lame \ --enable-libschroedinger \ - --enable-swscale \ + --enable-libtheora \ + --enable-libvorbis \ --arch=${TARGET_ARCH} \ --enable-cross-compile \ --extra-cflags="${TARGET_CFLAGS} ${HOST_CC_ARCH}${TOOLCHAIN_OPTIONS}" \ -- cgit v1.2.3 From a0818d6ec740a5a38b4cb46a947844e37e4439cf Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 17 Sep 2009 15:22:58 +0200 Subject: omap3-touchbook: also generate squashfs files --- conf/machine/omap3-touchbook.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/machine/omap3-touchbook.conf b/conf/machine/omap3-touchbook.conf index 8e18e4d7cf..37e39dce3f 100644 --- a/conf/machine/omap3-touchbook.conf +++ b/conf/machine/omap3-touchbook.conf @@ -15,7 +15,7 @@ GUI_MACHINE_CLASS = "bigscreen" require conf/machine/include/omap3.inc -IMAGE_FSTYPES += "tar.bz2 ubi" +IMAGE_FSTYPES += "squashfs tar.bz2 ubi" EXTRA_IMAGECMD_jffs2 = "-lnp " # Guesswork -- cgit v1.2.3 From 6d3ad5fb212eba132f0af77629babb58eedd1c52 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 17 Sep 2009 15:23:31 +0200 Subject: linux-omap 2.6.31: add extra EHCI and USB patches from http://arago-project.org/git/people/?p=ajay/omap-usb-driver.git;a=summary --- .../linux/linux-omap-2.6.31/beagleboard/defconfig | 2 +- .../linux/linux-omap-2.6.31/beagleboard/ehci.patch | 13 - .../linux/linux-omap-2.6.31/ehci-phy-reset.patch | 34 - .../0001-musb-fix-put_device-call-sequence.patch | 45 + .../usb/0002-ehci-fix-ehci-pin-mux-init.patch | 206 +++++ ...ci-adding-mux-pin-for-EHCI-phy-reset-line.patch | 42 + ...-correct-EHCI-init-parameters-on-OMAP3EVM.patch | 34 + ...005-ehci-fix-phy_reset-init-in-ehci-probe.patch | 35 + ...ehci-increase-timeout-to-fix-ehci-failure.patch | 30 + .../usb/0007-ehci-portwise-configurations.patch | 498 +++++++++++ ...8-omap3-Add-CHIP_GE_OMAP3430ES3-for-HSUSB.patch | 41 + .../usb/0009-ehci-Support-for-ES3.x.patch | 170 ++++ ...10-ehci-update-driver-with-generic-change.patch | 31 + ...0011-musb-fix-musb-gadget_driver-NULL-bug.patch | 31 + .../0012-musb-Add-back-old-musb-procfs-file.patch | 947 +++++++++++++++++++++ ...b-Remove-USB_SUSPEND-auto-select-with-OTG.patch | 29 + ...le-PING-on-status-phase-of-control-transf.patch | 34 + ...musb-Add-context-save-and-restore-support.patch | 422 +++++++++ .../usb/0016-usb-update-defconfig.patch | 618 ++++++++++++++ recipes/linux/linux-omap_2.6.31.bb | 17 +- 20 files changed, 3230 insertions(+), 49 deletions(-) delete mode 100644 recipes/linux/linux-omap-2.6.31/ehci-phy-reset.patch create mode 100644 recipes/linux/linux-omap-2.6.31/usb/0001-musb-fix-put_device-call-sequence.patch create mode 100644 recipes/linux/linux-omap-2.6.31/usb/0002-ehci-fix-ehci-pin-mux-init.patch create mode 100644 recipes/linux/linux-omap-2.6.31/usb/0003-ehci-adding-mux-pin-for-EHCI-phy-reset-line.patch create mode 100644 recipes/linux/linux-omap-2.6.31/usb/0004-ehci-correct-EHCI-init-parameters-on-OMAP3EVM.patch create mode 100644 recipes/linux/linux-omap-2.6.31/usb/0005-ehci-fix-phy_reset-init-in-ehci-probe.patch create mode 100644 recipes/linux/linux-omap-2.6.31/usb/0006-ehci-increase-timeout-to-fix-ehci-failure.patch create mode 100644 recipes/linux/linux-omap-2.6.31/usb/0007-ehci-portwise-configurations.patch create mode 100644 recipes/linux/linux-omap-2.6.31/usb/0008-omap3-Add-CHIP_GE_OMAP3430ES3-for-HSUSB.patch create mode 100644 recipes/linux/linux-omap-2.6.31/usb/0009-ehci-Support-for-ES3.x.patch create mode 100644 recipes/linux/linux-omap-2.6.31/usb/0010-ehci-update-driver-with-generic-change.patch create mode 100644 recipes/linux/linux-omap-2.6.31/usb/0011-musb-fix-musb-gadget_driver-NULL-bug.patch create mode 100644 recipes/linux/linux-omap-2.6.31/usb/0012-musb-Add-back-old-musb-procfs-file.patch create mode 100644 recipes/linux/linux-omap-2.6.31/usb/0013-musb-Remove-USB_SUSPEND-auto-select-with-OTG.patch create mode 100644 recipes/linux/linux-omap-2.6.31/usb/0014-musb-disable-PING-on-status-phase-of-control-transf.patch create mode 100644 recipes/linux/linux-omap-2.6.31/usb/0015-musb-Add-context-save-and-restore-support.patch create mode 100644 recipes/linux/linux-omap-2.6.31/usb/0016-usb-update-defconfig.patch diff --git a/recipes/linux/linux-omap-2.6.31/beagleboard/defconfig b/recipes/linux/linux-omap-2.6.31/beagleboard/defconfig index 81f3cadce4..629148b783 100644 --- a/recipes/linux/linux-omap-2.6.31/beagleboard/defconfig +++ b/recipes/linux/linux-omap-2.6.31/beagleboard/defconfig @@ -224,7 +224,7 @@ CONFIG_ARCH_OMAP3430=y # CONFIG_MACH_OMAP3_BEAGLE=y # CONFIG_MACH_OMAP_LDP is not set -CONFIG_MACH_OVERO=y +CONFIG_MACH_OVERO=n CONFIG_MACH_OMAP3EVM=y # CONFIG_MACH_OMAP3_PANDORA is not set # CONFIG_MACH_OMAP_3430SDP is not set diff --git a/recipes/linux/linux-omap-2.6.31/beagleboard/ehci.patch b/recipes/linux/linux-omap-2.6.31/beagleboard/ehci.patch index 633b1b2269..d8dcd522dc 100644 --- a/recipes/linux/linux-omap-2.6.31/beagleboard/ehci.patch +++ b/recipes/linux/linux-omap-2.6.31/beagleboard/ehci.patch @@ -20,16 +20,3 @@ index 07aee90..65934ea 100644 /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; -@@ -412,7 +412,8 @@ static void __init omap3_beagle_init(void) - gpio_direction_output(170, true); - - usb_musb_init(); -- usb_ehci_init(EHCI_HCD_OMAP_MODE_PHY, true, true, 57, 61); -+ usb_ehci_init(EHCI_HCD_OMAP_MODE_PHY, false, true, -+ -EINVAL, 147); - omap3beagle_flash_init(); - - /* Ensure SDRC pins are mux'd for self-refresh */ --- -1.6.0.4 - diff --git a/recipes/linux/linux-omap-2.6.31/ehci-phy-reset.patch b/recipes/linux/linux-omap-2.6.31/ehci-phy-reset.patch deleted file mode 100644 index 4041c21306..0000000000 --- a/recipes/linux/linux-omap-2.6.31/ehci-phy-reset.patch +++ /dev/null @@ -1,34 +0,0 @@ -phy_reset is not getting updated from platform_data. - -Signed-off-by: Ajay Kumar Gupta ---- - drivers/usb/host/ehci-omap.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c -index 0058f03..55e5259 100644 ---- a/drivers/usb/host/ehci-omap.c -+++ b/drivers/usb/host/ehci-omap.c -@@ -33,7 +33,6 @@ - * - add suspend/resume - * - move workarounds to board-files - * - differentiate between ES2.x and ES3.x -- * - make it enumerate devices - */ - - #include -@@ -590,6 +589,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) - - platform_set_drvdata(pdev, omap); - omap->dev = &pdev->dev; -+ omap->phy_reset = pdata->phy_reset; - omap->reset_gpio_port1 = pdata->reset_gpio_port1; - omap->reset_gpio_port2 = pdata->reset_gpio_port2; - omap->phy_mode = pdata->phy_mode; --- -1.6.2.4 - --- -To unsubscribe from this list: send the line "unsubscribe linux-omap" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/recipes/linux/linux-omap-2.6.31/usb/0001-musb-fix-put_device-call-sequence.patch b/recipes/linux/linux-omap-2.6.31/usb/0001-musb-fix-put_device-call-sequence.patch new file mode 100644 index 0000000000..1164fcb417 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/usb/0001-musb-fix-put_device-call-sequence.patch @@ -0,0 +1,45 @@ +From f5d23fe1ff54df953c7b65699d6065b4a6336932 Mon Sep 17 00:00:00 2001 +From: Ajay Kumar Gupta +Date: Mon, 3 Aug 2009 11:16:18 +0530 +Subject: [PATCH 01/16] musb: fix put_device() call sequence + +Invoke put_device(musb->xceiv->dev) before musb_platform_exit()as +xceiv is getting unregistered in musb_platform_exit(). + +Fixes put_device() panic when module insert/removal is performed +multiple times. + +Signed-off-by: Ajay Kumar Gupta +--- + drivers/usb/musb/musb_core.c | 8 ++++---- + 1 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c +index c7c1ca0..129f9dc 100644 +--- a/drivers/usb/musb/musb_core.c ++++ b/drivers/usb/musb/musb_core.c +@@ -1850,6 +1850,10 @@ static void musb_free(struct musb *musb) + dma_controller_destroy(c); + } + ++#ifdef CONFIG_USB_MUSB_OTG ++ put_device(musb->xceiv->dev); ++#endif ++ + musb_writeb(musb->mregs, MUSB_DEVCTL, 0); + musb_platform_exit(musb); + musb_writeb(musb->mregs, MUSB_DEVCTL, 0); +@@ -1859,10 +1863,6 @@ static void musb_free(struct musb *musb) + clk_put(musb->clock); + } + +-#ifdef CONFIG_USB_MUSB_OTG +- put_device(musb->xceiv->dev); +-#endif +- + #ifdef CONFIG_USB_MUSB_HDRC_HCD + usb_put_hcd(musb_to_hcd(musb)); + #else +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.31/usb/0002-ehci-fix-ehci-pin-mux-init.patch b/recipes/linux/linux-omap-2.6.31/usb/0002-ehci-fix-ehci-pin-mux-init.patch new file mode 100644 index 0000000000..82e4c1edb0 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/usb/0002-ehci-fix-ehci-pin-mux-init.patch @@ -0,0 +1,206 @@ +From 9c6a05af8f862025f5187a2f37be87db39ae709f Mon Sep 17 00:00:00 2001 +From: Ajay Kumar Gupta +Date: Fri, 3 Jul 2009 15:55:24 +0530 +Subject: [PATCH 02/16] ehci: fix ehci pin mux init + +EHCI pin mux init fucntion is still using old #ifdef which are not defined +anymore.This causes pin mux init to always set TLL settings and thus EHCI +PHY mode doesn't work. + +Fixing this issue by using phy_mode parameter to initialize mux settings. + +Signed-off-by: Ajay Kumar Gupta +Signed-off-by: Felipe Balbi +--- + arch/arm/mach-omap2/usb-ehci.c | 167 ++++++++++++++++++++-------------------- + 1 files changed, 83 insertions(+), 84 deletions(-) + +diff --git a/arch/arm/mach-omap2/usb-ehci.c b/arch/arm/mach-omap2/usb-ehci.c +index 56fc7f4..6a96569 100644 +--- a/arch/arm/mach-omap2/usb-ehci.c ++++ b/arch/arm/mach-omap2/usb-ehci.c +@@ -68,90 +68,89 @@ static struct platform_device ehci_device = { + /* + * setup_ehci_io_mux - initialize IO pad mux for USBHOST + */ +-static void setup_ehci_io_mux(void) ++static void setup_ehci_io_mux(enum ehci_hcd_omap_mode phy_mode) + { +-#ifdef CONFIG_OMAP_EHCI_PHY_MODE +- /* PHY mode of operation for board: 750-2083-001 +- * ISP1504 connected to Port1 and Port2 +- * Do Func Mux setting for 12-pin ULPI PHY mode +- */ +- +- /* Port1 */ +- omap_cfg_reg(Y9_3430_USB1HS_PHY_STP); +- omap_cfg_reg(Y8_3430_USB1HS_PHY_CLK); +- omap_cfg_reg(AA14_3430_USB1HS_PHY_DIR); +- omap_cfg_reg(AA11_3430_USB1HS_PHY_NXT); +- omap_cfg_reg(W13_3430_USB1HS_PHY_DATA0); +- omap_cfg_reg(W12_3430_USB1HS_PHY_DATA1); +- omap_cfg_reg(W11_3430_USB1HS_PHY_DATA2); +- omap_cfg_reg(Y11_3430_USB1HS_PHY_DATA3); +- omap_cfg_reg(W9_3430_USB1HS_PHY_DATA4); +- omap_cfg_reg(Y12_3430_USB1HS_PHY_DATA5); +- omap_cfg_reg(W8_3430_USB1HS_PHY_DATA6); +- omap_cfg_reg(Y13_3430_USB1HS_PHY_DATA7); +- +- /* Port2 */ +- omap_cfg_reg(AA10_3430_USB2HS_PHY_STP); +- omap_cfg_reg(AA8_3430_USB2HS_PHY_CLK); +- omap_cfg_reg(AA9_3430_USB2HS_PHY_DIR); +- omap_cfg_reg(AB11_3430_USB2HS_PHY_NXT); +- omap_cfg_reg(AB10_3430_USB2HS_PHY_DATA0); +- omap_cfg_reg(AB9_3430_USB2HS_PHY_DATA1); +- omap_cfg_reg(W3_3430_USB2HS_PHY_DATA2); +- omap_cfg_reg(T4_3430_USB2HS_PHY_DATA3); +- omap_cfg_reg(T3_3430_USB2HS_PHY_DATA4); +- omap_cfg_reg(R3_3430_USB2HS_PHY_DATA5); +- omap_cfg_reg(R4_3430_USB2HS_PHY_DATA6); +- omap_cfg_reg(T2_3430_USB2HS_PHY_DATA7); +- +-#else +- /* Set Func mux for : +- * TLL mode of operation +- * 12-pin ULPI SDR TLL mode for Port1/2/3 +- */ +- +- /* Port1 */ +- omap_cfg_reg(Y9_3430_USB1HS_TLL_STP); +- omap_cfg_reg(Y8_3430_USB1HS_TLL_CLK); +- omap_cfg_reg(AA14_3430_USB1HS_TLL_DIR); +- omap_cfg_reg(AA11_3430_USB1HS_TLL_NXT); +- omap_cfg_reg(W13_3430_USB1HS_TLL_DATA0); +- omap_cfg_reg(W12_3430_USB1HS_TLL_DATA1); +- omap_cfg_reg(W11_3430_USB1HS_TLL_DATA2); +- omap_cfg_reg(Y11_3430_USB1HS_TLL_DATA3); +- omap_cfg_reg(W9_3430_USB1HS_TLL_DATA4); +- omap_cfg_reg(Y12_3430_USB1HS_TLL_DATA5); +- omap_cfg_reg(W8_3430_USB1HS_TLL_DATA6); +- omap_cfg_reg(Y13_3430_USB1HS_TLL_DATA7); +- +- /* Port2 */ +- omap_cfg_reg(AA10_3430_USB2HS_TLL_STP); +- omap_cfg_reg(AA8_3430_USB2HS_TLL_CLK); +- omap_cfg_reg(AA9_3430_USB2HS_TLL_DIR); +- omap_cfg_reg(AB11_3430_USB2HS_TLL_NXT); +- omap_cfg_reg(AB10_3430_USB2HS_TLL_DATA0); +- omap_cfg_reg(AB9_3430_USB2HS_TLL_DATA1); +- omap_cfg_reg(W3_3430_USB2HS_TLL_DATA2); +- omap_cfg_reg(T4_3430_USB2HS_TLL_DATA3); +- omap_cfg_reg(T3_3430_USB2HS_TLL_DATA4); +- omap_cfg_reg(R3_3430_USB2HS_TLL_DATA5); +- omap_cfg_reg(R4_3430_USB2HS_TLL_DATA6); +- omap_cfg_reg(T2_3430_USB2HS_TLL_DATA7); +- +- /* Port3 */ +- omap_cfg_reg(AB3_3430_USB3HS_TLL_STP); +- omap_cfg_reg(AA6_3430_USB3HS_TLL_CLK); +- omap_cfg_reg(AA3_3430_USB3HS_TLL_DIR); +- omap_cfg_reg(Y3_3430_USB3HS_TLL_NXT); +- omap_cfg_reg(AA5_3430_USB3HS_TLL_DATA0); +- omap_cfg_reg(Y4_3430_USB3HS_TLL_DATA1); +- omap_cfg_reg(Y5_3430_USB3HS_TLL_DATA2); +- omap_cfg_reg(W5_3430_USB3HS_TLL_DATA3); +- omap_cfg_reg(AB12_3430_USB3HS_TLL_DATA4); +- omap_cfg_reg(AB13_3430_USB3HS_TLL_DATA5); +- omap_cfg_reg(AA13_3430_USB3HS_TLL_DATA6); +- omap_cfg_reg(AA12_3430_USB3HS_TLL_DATA7); +-#endif /* CONFIG_OMAP_EHCI_PHY_MODE */ ++ if (phy_mode == EHCI_HCD_OMAP_MODE_PHY) { ++ /* PHY mode of operation for board: 750-2083-001 ++ * ISP1504 connected to Port1 and Port2 ++ * Do Func Mux setting for 12-pin ULPI PHY mode ++ */ ++ /* Port1 */ ++ omap_cfg_reg(Y9_3430_USB1HS_PHY_STP); ++ omap_cfg_reg(Y8_3430_USB1HS_PHY_CLK); ++ omap_cfg_reg(AA14_3430_USB1HS_PHY_DIR); ++ omap_cfg_reg(AA11_3430_USB1HS_PHY_NXT); ++ omap_cfg_reg(W13_3430_USB1HS_PHY_DATA0); ++ omap_cfg_reg(W12_3430_USB1HS_PHY_DATA1); ++ omap_cfg_reg(W11_3430_USB1HS_PHY_DATA2); ++ omap_cfg_reg(Y11_3430_USB1HS_PHY_DATA3); ++ omap_cfg_reg(W9_3430_USB1HS_PHY_DATA4); ++ omap_cfg_reg(Y12_3430_USB1HS_PHY_DATA5); ++ omap_cfg_reg(W8_3430_USB1HS_PHY_DATA6); ++ omap_cfg_reg(Y13_3430_USB1HS_PHY_DATA7); ++ ++ /* Port2 */ ++ omap_cfg_reg(AA10_3430_USB2HS_PHY_STP); ++ omap_cfg_reg(AA8_3430_USB2HS_PHY_CLK); ++ omap_cfg_reg(AA9_3430_USB2HS_PHY_DIR); ++ omap_cfg_reg(AB11_3430_USB2HS_PHY_NXT); ++ omap_cfg_reg(AB10_3430_USB2HS_PHY_DATA0); ++ omap_cfg_reg(AB9_3430_USB2HS_PHY_DATA1); ++ omap_cfg_reg(W3_3430_USB2HS_PHY_DATA2); ++ omap_cfg_reg(T4_3430_USB2HS_PHY_DATA3); ++ omap_cfg_reg(T3_3430_USB2HS_PHY_DATA4); ++ omap_cfg_reg(R3_3430_USB2HS_PHY_DATA5); ++ omap_cfg_reg(R4_3430_USB2HS_PHY_DATA6); ++ omap_cfg_reg(T2_3430_USB2HS_PHY_DATA7); ++ ++ } else { ++ /* Set Func mux for : ++ * TLL mode of operation ++ * 12-pin ULPI SDR TLL mode for Port1/2/3 ++ */ ++ ++ /* Port1 */ ++ omap_cfg_reg(Y9_3430_USB1HS_TLL_STP); ++ omap_cfg_reg(Y8_3430_USB1HS_TLL_CLK); ++ omap_cfg_reg(AA14_3430_USB1HS_TLL_DIR); ++ omap_cfg_reg(AA11_3430_USB1HS_TLL_NXT); ++ omap_cfg_reg(W13_3430_USB1HS_TLL_DATA0); ++ omap_cfg_reg(W12_3430_USB1HS_TLL_DATA1); ++ omap_cfg_reg(W11_3430_USB1HS_TLL_DATA2); ++ omap_cfg_reg(Y11_3430_USB1HS_TLL_DATA3); ++ omap_cfg_reg(W9_3430_USB1HS_TLL_DATA4); ++ omap_cfg_reg(Y12_3430_USB1HS_TLL_DATA5); ++ omap_cfg_reg(W8_3430_USB1HS_TLL_DATA6); ++ omap_cfg_reg(Y13_3430_USB1HS_TLL_DATA7); ++ ++ /* Port2 */ ++ omap_cfg_reg(AA10_3430_USB2HS_TLL_STP); ++ omap_cfg_reg(AA8_3430_USB2HS_TLL_CLK); ++ omap_cfg_reg(AA9_3430_USB2HS_TLL_DIR); ++ omap_cfg_reg(AB11_3430_USB2HS_TLL_NXT); ++ omap_cfg_reg(AB10_3430_USB2HS_TLL_DATA0); ++ omap_cfg_reg(AB9_3430_USB2HS_TLL_DATA1); ++ omap_cfg_reg(W3_3430_USB2HS_TLL_DATA2); ++ omap_cfg_reg(T4_3430_USB2HS_TLL_DATA3); ++ omap_cfg_reg(T3_3430_USB2HS_TLL_DATA4); ++ omap_cfg_reg(R3_3430_USB2HS_TLL_DATA5); ++ omap_cfg_reg(R4_3430_USB2HS_TLL_DATA6); ++ omap_cfg_reg(T2_3430_USB2HS_TLL_DATA7); ++ ++ /* Port3 */ ++ omap_cfg_reg(AB3_3430_USB3HS_TLL_STP); ++ omap_cfg_reg(AA6_3430_USB3HS_TLL_CLK); ++ omap_cfg_reg(AA3_3430_USB3HS_TLL_DIR); ++ omap_cfg_reg(Y3_3430_USB3HS_TLL_NXT); ++ omap_cfg_reg(AA5_3430_USB3HS_TLL_DATA0); ++ omap_cfg_reg(Y4_3430_USB3HS_TLL_DATA1); ++ omap_cfg_reg(Y5_3430_USB3HS_TLL_DATA2); ++ omap_cfg_reg(W5_3430_USB3HS_TLL_DATA3); ++ omap_cfg_reg(AB12_3430_USB3HS_TLL_DATA4); ++ omap_cfg_reg(AB13_3430_USB3HS_TLL_DATA5); ++ omap_cfg_reg(AA13_3430_USB3HS_TLL_DATA6); ++ omap_cfg_reg(AA12_3430_USB3HS_TLL_DATA7); ++ } + + return; + } +@@ -172,7 +171,7 @@ void __init usb_ehci_init(enum ehci_hcd_omap_mode phy_mode, + + /* Setup Pin IO MUX for EHCI */ + if (cpu_is_omap34xx()) +- setup_ehci_io_mux(); ++ setup_ehci_io_mux(phy_mode); + + if (platform_device_register(&ehci_device) < 0) { + printk(KERN_ERR "Unable to register HS-USB (EHCI) device\n"); +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.31/usb/0003-ehci-adding-mux-pin-for-EHCI-phy-reset-line.patch b/recipes/linux/linux-omap-2.6.31/usb/0003-ehci-adding-mux-pin-for-EHCI-phy-reset-line.patch new file mode 100644 index 0000000000..e740614864 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/usb/0003-ehci-adding-mux-pin-for-EHCI-phy-reset-line.patch @@ -0,0 +1,42 @@ +From 2f0fe550c81056cb22c0cb8bf54c464e313e1047 Mon Sep 17 00:00:00 2001 +From: Ajay Kumar Gupta +Date: Mon, 6 Jul 2009 12:46:08 +0530 +Subject: [PATCH 03/16] ehci: adding mux pin for EHCI phy reset line + +GPIO135 is used as EHCI (port2) phy reset pin on Multi Media Daughter card +connected to OMAP3EVM. + +Signed-off-by: Ajay Kumar Gupta +--- + arch/arm/mach-omap2/mux.c | 2 ++ + arch/arm/plat-omap/include/mach/mux.h | 1 + + 2 files changed, 3 insertions(+), 0 deletions(-) + +diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c +index 2daa595..339ba80 100644 +--- a/arch/arm/mach-omap2/mux.c ++++ b/arch/arm/mach-omap2/mux.c +@@ -472,6 +472,8 @@ MUX_CFG_34XX("G25_34XX_GPIO86_OUT", 0x0fc, + OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) + MUX_CFG_34XX("AG4_34XX_GPIO134_OUT", 0x160, + OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) ++MUX_CFG_34XX("AF4_34XX_GPIO135_OUT", 0x162, ++ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) + MUX_CFG_34XX("AE4_34XX_GPIO136_OUT", 0x164, + OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) + MUX_CFG_34XX("AF6_34XX_GPIO140_UP", 0x16c, +diff --git a/arch/arm/plat-omap/include/mach/mux.h b/arch/arm/plat-omap/include/mach/mux.h +index 98dfab6..4bcf8a5 100644 +--- a/arch/arm/plat-omap/include/mach/mux.h ++++ b/arch/arm/plat-omap/include/mach/mux.h +@@ -846,6 +846,7 @@ enum omap34xx_index { + L8_34XX_GPIO63, + G25_34XX_GPIO86_OUT, + AG4_34XX_GPIO134_OUT, ++ AF4_34XX_GPIO135_OUT, + AE4_34XX_GPIO136_OUT, + AF6_34XX_GPIO140_UP, + AE6_34XX_GPIO141, +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.31/usb/0004-ehci-correct-EHCI-init-parameters-on-OMAP3EVM.patch b/recipes/linux/linux-omap-2.6.31/usb/0004-ehci-correct-EHCI-init-parameters-on-OMAP3EVM.patch new file mode 100644 index 0000000000..65bb871682 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/usb/0004-ehci-correct-EHCI-init-parameters-on-OMAP3EVM.patch @@ -0,0 +1,34 @@ +From 4cc29612d5a706049b14e67bcc3b22490bdddcf7 Mon Sep 17 00:00:00 2001 +From: Ajay Kumar Gupta +Date: Fri, 10 Jul 2009 10:01:39 +0530 +Subject: [PATCH 04/16] ehci: correct EHCI init parameters on OMAP3EVM + +Multimedia Daughter card on OMAP3EVM uses port2 as EHCI port. +Other ports (port1 and port3)are not used. + +GPIO135 has been used as EHCI phy reset pin so the mux config +is also setup. + +Signed-off-by: Ajay Kumar Gupta +--- + arch/arm/mach-omap2/board-omap3evm.c | 4 +++- + 1 files changed, 3 insertions(+), 1 deletions(-) + +diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c +index 35f6075..18b747b 100644 +--- a/arch/arm/mach-omap2/board-omap3evm.c ++++ b/arch/arm/mach-omap2/board-omap3evm.c +@@ -308,7 +308,9 @@ static void __init omap3_evm_init(void) + usb_nop_xceiv_register(); + #endif + usb_musb_init(); +- usb_ehci_init(EHCI_HCD_OMAP_MODE_PHY, true, true, 57, 61); ++ /* Setup EHCI phy reset padconfig */ ++ omap_cfg_reg(AF4_34XX_GPIO135_OUT); ++ usb_ehci_init(EHCI_HCD_OMAP_MODE_PHY, false, true, -EINVAL, 135); + ads7846_dev_init(); + } + +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.31/usb/0005-ehci-fix-phy_reset-init-in-ehci-probe.patch b/recipes/linux/linux-omap-2.6.31/usb/0005-ehci-fix-phy_reset-init-in-ehci-probe.patch new file mode 100644 index 0000000000..07f9386170 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/usb/0005-ehci-fix-phy_reset-init-in-ehci-probe.patch @@ -0,0 +1,35 @@ +From 42c413f8f9005a5ca109f82baff81f8e400b8854 Mon Sep 17 00:00:00 2001 +From: Ajay Kumar Gupta +Date: Mon, 13 Jul 2009 14:10:46 +0530 +Subject: [PATCH 05/16] ehci: fix phy_reset init in ehci probe + +phy_reset is not getting updated from platform_data. + +Signed-off-by: Ajay Kumar Gupta +--- + drivers/usb/host/ehci-omap.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c +index 0058f03..55e5259 100644 +--- a/drivers/usb/host/ehci-omap.c ++++ b/drivers/usb/host/ehci-omap.c +@@ -33,7 +33,6 @@ + * - add suspend/resume + * - move workarounds to board-files + * - differentiate between ES2.x and ES3.x +- * - make it enumerate devices + */ + + #include +@@ -590,6 +589,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) + + platform_set_drvdata(pdev, omap); + omap->dev = &pdev->dev; ++ omap->phy_reset = pdata->phy_reset; + omap->reset_gpio_port1 = pdata->reset_gpio_port1; + omap->reset_gpio_port2 = pdata->reset_gpio_port2; + omap->phy_mode = pdata->phy_mode; +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.31/usb/0006-ehci-increase-timeout-to-fix-ehci-failure.patch b/recipes/linux/linux-omap-2.6.31/usb/0006-ehci-increase-timeout-to-fix-ehci-failure.patch new file mode 100644 index 0000000000..1190aada1f --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/usb/0006-ehci-increase-timeout-to-fix-ehci-failure.patch @@ -0,0 +1,30 @@ +From 4e499dd02940a567ca805010e9c3f78d8ab7bc79 Mon Sep 17 00:00:00 2001 +From: Ajay Kumar Gupta +Date: Mon, 6 Jul 2009 17:59:02 +0530 +Subject: [PATCH 06/16] ehci: increase timeout to fix ehci failure + +Sometime during TLL reset and waiting loop for TLL reset timeouts and thus +ehci init fails. Fixing this by increasing timeout value. + +Signed-off-by: Ajay Kumar Gupta +Signed-off-by: Felipe Balbi +--- + drivers/usb/host/ehci-omap.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c +index 55e5259..c7631f5 100644 +--- a/drivers/usb/host/ehci-omap.c ++++ b/drivers/usb/host/ehci-omap.c +@@ -244,7 +244,7 @@ static void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask) + */ + static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) + { +- unsigned long timeout = jiffies + msecs_to_jiffies(100); ++ unsigned long timeout = jiffies + msecs_to_jiffies(1000); + unsigned reg = 0; + int ret = 0; + +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.31/usb/0007-ehci-portwise-configurations.patch b/recipes/linux/linux-omap-2.6.31/usb/0007-ehci-portwise-configurations.patch new file mode 100644 index 0000000000..46258dac9b --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/usb/0007-ehci-portwise-configurations.patch @@ -0,0 +1,498 @@ +From 4d0b781b146ee79cee1208589498e8ac959d5796 Mon Sep 17 00:00:00 2001 +From: Ajay Kumar Gupta +Date: Thu, 13 Aug 2009 09:10:44 +0530 +Subject: [PATCH 07/16] ehci: portwise configurations + +OMAP3 EHCI has three ports and we can configure port modes +(PHY/TLL) on per port basis in silicon version ES3.0 onwards. + +This patch modifies the existing EHCI driver to accomodate +portwise mode configuration. + +Changes being done: + + - Pass platform_data pointer as parameter to usb_ehci_init() + to avoid multiple parameters. + - Use platform_data pointer in usb-ehci.c as platform_data + directly without copying it to another *pdata*. + - Initializing platform_data in all platform files with + platform specific ehci parameters. + - Added port_mode[OMAP_HS_USB_PORTS]in platform_data + structures.This allows to setup mux pins on per port basis. + - Added phy_reset_gpio[OMAP_HS_USB_PORTS]. + +Signed-off-by: Ajay Kumar Gupta +--- + arch/arm/mach-omap2/board-3430sdp.c | 15 +++++- + arch/arm/mach-omap2/board-omap3beagle.c | 15 +++++- + arch/arm/mach-omap2/board-omap3evm.c | 15 +++++- + arch/arm/mach-omap2/board-omap3pandora.c | 15 +++++- + arch/arm/mach-omap2/usb-ehci.c | 95 +++++++++++++++--------------- + arch/arm/plat-omap/include/mach/usb.h | 12 ++-- + drivers/usb/host/ehci-omap.c | 63 +++++++++++--------- + 7 files changed, 145 insertions(+), 85 deletions(-) + +diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c +index 439ebcc..f9fabb0 100644 +--- a/arch/arm/mach-omap2/board-3430sdp.c ++++ b/arch/arm/mach-omap2/board-3430sdp.c +@@ -480,6 +480,19 @@ static void enable_board_wakeup_source(void) + omap_cfg_reg(AF26_34XX_SYS_NIRQ); /* T2 interrupt line (keypad) */ + } + ++static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { ++ ++ .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, ++ .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, ++ .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, ++ ++ .chargepump = true, ++ .phy_reset = true, ++ .reset_gpio_port[0] = 57, ++ .reset_gpio_port[1] = 61, ++ .reset_gpio_port[2] = -EINVAL ++}; ++ + static void __init omap_3430sdp_init(void) + { + omap3430_i2c_init(); +@@ -495,8 +508,8 @@ static void __init omap_3430sdp_init(void) + omap_serial_init(); + usb_musb_init(); + board_smc91x_init(); +- usb_ehci_init(EHCI_HCD_OMAP_MODE_PHY, true, true, 57, 61); + enable_board_wakeup_source(); ++ usb_ehci_init(&ehci_pdata); + } + + static void __init omap_3430sdp_map_io(void) +diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c +index a661fe3..4109969 100644 +--- a/arch/arm/mach-omap2/board-omap3beagle.c ++++ b/arch/arm/mach-omap2/board-omap3beagle.c +@@ -395,6 +395,19 @@ static void __init omap3beagle_flash_init(void) + } + } + ++static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { ++ ++ .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, ++ .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, ++ .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, ++ ++ .chargepump = false, ++ .phy_reset = true, ++ .reset_gpio_port[0] = -EINVAL, ++ .reset_gpio_port[1] = 147, ++ .reset_gpio_port[2] = -EINVAL ++}; ++ + static void __init omap3_beagle_init(void) + { + omap3_beagle_i2c_init(); +@@ -408,7 +421,7 @@ static void __init omap3_beagle_init(void) + gpio_direction_output(170, true); + + usb_musb_init(); +- usb_ehci_init(EHCI_HCD_OMAP_MODE_PHY, true, true, 57, 61); ++ usb_ehci_init(&ehci_pdata); + omap3beagle_flash_init(); + + /* Ensure SDRC pins are mux'd for self-refresh */ +diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c +index 18b747b..62a6f32 100644 +--- a/arch/arm/mach-omap2/board-omap3evm.c ++++ b/arch/arm/mach-omap2/board-omap3evm.c +@@ -293,6 +293,19 @@ static struct platform_device *omap3_evm_devices[] __initdata = { + &omap3evm_smc911x_device, + }; + ++static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { ++ ++ .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN, ++ .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, ++ .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, ++ ++ .chargepump = false, ++ .phy_reset = true, ++ .reset_gpio_port[0] = -EINVAL, ++ .reset_gpio_port[1] = 135, ++ .reset_gpio_port[2] = -EINVAL ++}; ++ + static void __init omap3_evm_init(void) + { + omap3_evm_i2c_init(); +@@ -310,7 +323,7 @@ static void __init omap3_evm_init(void) + usb_musb_init(); + /* Setup EHCI phy reset padconfig */ + omap_cfg_reg(AF4_34XX_GPIO135_OUT); +- usb_ehci_init(EHCI_HCD_OMAP_MODE_PHY, false, true, -EINVAL, 135); ++ usb_ehci_init(&ehci_pdata); + ads7846_dev_init(); + } + +diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c +index c9d6488..9f115dc 100644 +--- a/arch/arm/mach-omap2/board-omap3pandora.c ++++ b/arch/arm/mach-omap2/board-omap3pandora.c +@@ -383,6 +383,19 @@ static struct platform_device *omap3pandora_devices[] __initdata = { + &pandora_keys_gpio, + }; + ++static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { ++ ++ .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, ++ .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN, ++ .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, ++ ++ .chargepump = false, ++ .phy_reset = true, ++ .reset_gpio_port[0] = 16, ++ .reset_gpio_port[1] = -EINVAL, ++ .reset_gpio_port[2] = -EINVAL ++}; ++ + static void __init omap3pandora_init(void) + { + omap3pandora_i2c_init(); +@@ -392,7 +405,7 @@ static void __init omap3pandora_init(void) + spi_register_board_info(omap3pandora_spi_board_info, + ARRAY_SIZE(omap3pandora_spi_board_info)); + omap3pandora_ads7846_init(); +- usb_ehci_init(EHCI_HCD_OMAP_MODE_PHY, false, true, 16, -EINVAL); ++ usb_ehci_init(&ehci_pdata); + pandora_keys_gpio_init(); + usb_musb_init(); + +diff --git a/arch/arm/mach-omap2/usb-ehci.c b/arch/arm/mach-omap2/usb-ehci.c +index 6a96569..a29c8ca 100644 +--- a/arch/arm/mach-omap2/usb-ehci.c ++++ b/arch/arm/mach-omap2/usb-ehci.c +@@ -68,14 +68,10 @@ static struct platform_device ehci_device = { + /* + * setup_ehci_io_mux - initialize IO pad mux for USBHOST + */ +-static void setup_ehci_io_mux(enum ehci_hcd_omap_mode phy_mode) ++static void setup_ehci_io_mux(enum ehci_hcd_omap_mode *port_mode) + { +- if (phy_mode == EHCI_HCD_OMAP_MODE_PHY) { +- /* PHY mode of operation for board: 750-2083-001 +- * ISP1504 connected to Port1 and Port2 +- * Do Func Mux setting for 12-pin ULPI PHY mode +- */ +- /* Port1 */ ++ switch (port_mode[0]) { ++ case EHCI_HCD_OMAP_MODE_PHY: + omap_cfg_reg(Y9_3430_USB1HS_PHY_STP); + omap_cfg_reg(Y8_3430_USB1HS_PHY_CLK); + omap_cfg_reg(AA14_3430_USB1HS_PHY_DIR); +@@ -88,28 +84,8 @@ static void setup_ehci_io_mux(enum ehci_hcd_omap_mode phy_mode) + omap_cfg_reg(Y12_3430_USB1HS_PHY_DATA5); + omap_cfg_reg(W8_3430_USB1HS_PHY_DATA6); + omap_cfg_reg(Y13_3430_USB1HS_PHY_DATA7); +- +- /* Port2 */ +- omap_cfg_reg(AA10_3430_USB2HS_PHY_STP); +- omap_cfg_reg(AA8_3430_USB2HS_PHY_CLK); +- omap_cfg_reg(AA9_3430_USB2HS_PHY_DIR); +- omap_cfg_reg(AB11_3430_USB2HS_PHY_NXT); +- omap_cfg_reg(AB10_3430_USB2HS_PHY_DATA0); +- omap_cfg_reg(AB9_3430_USB2HS_PHY_DATA1); +- omap_cfg_reg(W3_3430_USB2HS_PHY_DATA2); +- omap_cfg_reg(T4_3430_USB2HS_PHY_DATA3); +- omap_cfg_reg(T3_3430_USB2HS_PHY_DATA4); +- omap_cfg_reg(R3_3430_USB2HS_PHY_DATA5); +- omap_cfg_reg(R4_3430_USB2HS_PHY_DATA6); +- omap_cfg_reg(T2_3430_USB2HS_PHY_DATA7); +- +- } else { +- /* Set Func mux for : +- * TLL mode of operation +- * 12-pin ULPI SDR TLL mode for Port1/2/3 +- */ +- +- /* Port1 */ ++ break; ++ case EHCI_HCD_OMAP_MODE_TLL: + omap_cfg_reg(Y9_3430_USB1HS_TLL_STP); + omap_cfg_reg(Y8_3430_USB1HS_TLL_CLK); + omap_cfg_reg(AA14_3430_USB1HS_TLL_DIR); +@@ -122,8 +98,29 @@ static void setup_ehci_io_mux(enum ehci_hcd_omap_mode phy_mode) + omap_cfg_reg(Y12_3430_USB1HS_TLL_DATA5); + omap_cfg_reg(W8_3430_USB1HS_TLL_DATA6); + omap_cfg_reg(Y13_3430_USB1HS_TLL_DATA7); ++ break; ++ case EHCI_HCD_OMAP_MODE_UNKNOWN: ++ /* FALLTHROUGH */ ++ default: ++ break; ++ } + +- /* Port2 */ ++ switch (port_mode[1]) { ++ case EHCI_HCD_OMAP_MODE_PHY: ++ omap_cfg_reg(AA10_3430_USB2HS_PHY_STP); ++ omap_cfg_reg(AA8_3430_USB2HS_PHY_CLK); ++ omap_cfg_reg(AA9_3430_USB2HS_PHY_DIR); ++ omap_cfg_reg(AB11_3430_USB2HS_PHY_NXT); ++ omap_cfg_reg(AB10_3430_USB2HS_PHY_DATA0); ++ omap_cfg_reg(AB9_3430_USB2HS_PHY_DATA1); ++ omap_cfg_reg(W3_3430_USB2HS_PHY_DATA2); ++ omap_cfg_reg(T4_3430_USB2HS_PHY_DATA3); ++ omap_cfg_reg(T3_3430_USB2HS_PHY_DATA4); ++ omap_cfg_reg(R3_3430_USB2HS_PHY_DATA5); ++ omap_cfg_reg(R4_3430_USB2HS_PHY_DATA6); ++ omap_cfg_reg(T2_3430_USB2HS_PHY_DATA7); ++ break; ++ case EHCI_HCD_OMAP_MODE_TLL: + omap_cfg_reg(AA10_3430_USB2HS_TLL_STP); + omap_cfg_reg(AA8_3430_USB2HS_TLL_CLK); + omap_cfg_reg(AA9_3430_USB2HS_TLL_DIR); +@@ -136,8 +133,18 @@ static void setup_ehci_io_mux(enum ehci_hcd_omap_mode phy_mode) + omap_cfg_reg(R3_3430_USB2HS_TLL_DATA5); + omap_cfg_reg(R4_3430_USB2HS_TLL_DATA6); + omap_cfg_reg(T2_3430_USB2HS_TLL_DATA7); ++ break; ++ case EHCI_HCD_OMAP_MODE_UNKNOWN: ++ /* FALLTHROUGH */ ++ default: ++ break; ++ } + +- /* Port3 */ ++ switch (port_mode[2]) { ++ case EHCI_HCD_OMAP_MODE_PHY: ++ printk(KERN_WARNING "Port3 can't be used in PHY mode\n"); ++ break; ++ case EHCI_HCD_OMAP_MODE_TLL: + omap_cfg_reg(AB3_3430_USB3HS_TLL_STP); + omap_cfg_reg(AA6_3430_USB3HS_TLL_CLK); + omap_cfg_reg(AA3_3430_USB3HS_TLL_DIR); +@@ -150,28 +157,23 @@ static void setup_ehci_io_mux(enum ehci_hcd_omap_mode phy_mode) + omap_cfg_reg(AB13_3430_USB3HS_TLL_DATA5); + omap_cfg_reg(AA13_3430_USB3HS_TLL_DATA6); + omap_cfg_reg(AA12_3430_USB3HS_TLL_DATA7); ++ break; ++ case EHCI_HCD_OMAP_MODE_UNKNOWN: ++ /* FALLTHROUGH */ ++ default: ++ break; + } + + return; + } + +-static struct ehci_hcd_omap_platform_data pdata __initconst; +- +-void __init usb_ehci_init(enum ehci_hcd_omap_mode phy_mode, +- int chargepump, int phy_reset, int reset_gpio_port1, +- int reset_gpio_port2) ++void __init usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata) + { +- pdata.phy_mode = phy_mode; +- pdata.chargepump = chargepump; +- pdata.phy_reset = phy_reset; +- pdata.reset_gpio_port1 = reset_gpio_port1; +- pdata.reset_gpio_port2 = reset_gpio_port2; +- +- platform_device_add_data(&ehci_device, &pdata, sizeof(pdata)); ++ platform_device_add_data(&ehci_device, pdata, sizeof(*pdata)); + + /* Setup Pin IO MUX for EHCI */ + if (cpu_is_omap34xx()) +- setup_ehci_io_mux(phy_mode); ++ setup_ehci_io_mux(pdata->port_mode); + + if (platform_device_register(&ehci_device) < 0) { + printk(KERN_ERR "Unable to register HS-USB (EHCI) device\n"); +@@ -181,9 +183,8 @@ void __init usb_ehci_init(enum ehci_hcd_omap_mode phy_mode, + + #else + +-void __init usb_ehci_init(enum ehci_hcd_omap_mode phy_mode, +- int chargepump, int phy_reset, int reset_gpio_port1, +- int reset_gpio_port2) ++void __init usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata) ++ + { + } + +diff --git a/arch/arm/plat-omap/include/mach/usb.h b/arch/arm/plat-omap/include/mach/usb.h +index 1b1366c..d1b14cc 100644 +--- a/arch/arm/plat-omap/include/mach/usb.h ++++ b/arch/arm/plat-omap/include/mach/usb.h +@@ -5,6 +5,7 @@ + + #include + ++#define OMAP3_HS_USB_PORTS 3 + enum ehci_hcd_omap_mode { + EHCI_HCD_OMAP_MODE_UNKNOWN, + EHCI_HCD_OMAP_MODE_PHY, +@@ -12,13 +13,12 @@ enum ehci_hcd_omap_mode { + }; + + struct ehci_hcd_omap_platform_data { +- enum ehci_hcd_omap_mode phy_mode; ++ enum ehci_hcd_omap_mode port_mode[OMAP3_HS_USB_PORTS]; + unsigned chargepump:1; + unsigned phy_reset:1; + +- /* have to be valid if phy_reset is true */ +- int reset_gpio_port1; +- int reset_gpio_port2; ++ /* have to be valid if phy_reset is true and portx is in phy mode */ ++ int reset_gpio_port[OMAP3_HS_USB_PORTS]; + }; + + /*-------------------------------------------------------------------------*/ +@@ -45,9 +45,7 @@ struct ehci_hcd_omap_platform_data { + + extern void usb_musb_init(void); + +-extern void usb_ehci_init(enum ehci_hcd_omap_mode phy_mode, +- int chargepump, int phy_reset, int reset_gpio_port1, +- int reset_gpio_port2); ++extern void usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata); + + #endif + +diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c +index c7631f5..3175122 100644 +--- a/drivers/usb/host/ehci-omap.c ++++ b/drivers/usb/host/ehci-omap.c +@@ -162,8 +162,7 @@ struct ehci_hcd_omap { + */ + + /* gpio for resetting phy */ +- int reset_gpio_port1; +- int reset_gpio_port2; ++ int reset_gpio_port[OMAP3_HS_USB_PORTS]; + + /* phy reset workaround */ + int phy_reset; +@@ -172,7 +171,7 @@ struct ehci_hcd_omap { + int chargepump; + + /* desired phy_mode: TLL, PHY */ +- enum ehci_hcd_omap_mode phy_mode; ++ enum ehci_hcd_omap_mode port_mode[OMAP3_HS_USB_PORTS]; + + void __iomem *uhh_base; + void __iomem *tll_base; +@@ -297,14 +296,16 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) + + if (omap->phy_reset) { + /* Refer: ISSUE1 */ +- if (gpio_is_valid(omap->reset_gpio_port1)) { +- gpio_request(omap->reset_gpio_port1, "USB1 PHY reset"); +- gpio_direction_output(omap->reset_gpio_port1, 0); ++ if (gpio_is_valid(omap->reset_gpio_port[0])) { ++ gpio_request(omap->reset_gpio_port[0], ++ "USB1 PHY reset"); ++ gpio_direction_output(omap->reset_gpio_port[0], 0); + } + +- if (gpio_is_valid(omap->reset_gpio_port2)) { +- gpio_request(omap->reset_gpio_port2, "USB2 PHY reset"); +- gpio_direction_output(omap->reset_gpio_port2, 0); ++ if (gpio_is_valid(omap->reset_gpio_port[1])) { ++ gpio_request(omap->reset_gpio_port[1], ++ "USB2 PHY reset"); ++ gpio_direction_output(omap->reset_gpio_port[1], 0); + } + + /* Hold the PHY in RESET for enough time till DIR is high */ +@@ -361,7 +362,10 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) + + ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); + +- if (omap->phy_mode == EHCI_HCD_OMAP_MODE_PHY) { ++ if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) || ++ (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) || ++ (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY)) { ++ + reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG); + + reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN +@@ -374,7 +378,9 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) + ehci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); + dev_dbg(omap->dev, "Entered ULPI PHY MODE: success\n"); + +- } else if (omap->phy_mode == EHCI_HCD_OMAP_MODE_TLL) { ++ } else if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) || ++ (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) || ++ (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL)) { + + /* Enable UTMI mode for all 3 TLL channels */ + omap_usb_utmi_init(omap, +@@ -396,11 +402,11 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) + */ + udelay(10); + +- if (gpio_is_valid(omap->reset_gpio_port1)) +- gpio_set_value(omap->reset_gpio_port1, 1); ++ if (gpio_is_valid(omap->reset_gpio_port[0])) ++ gpio_set_value(omap->reset_gpio_port[0], 1); + +- if (gpio_is_valid(omap->reset_gpio_port2)) +- gpio_set_value(omap->reset_gpio_port2, 1); ++ if (gpio_is_valid(omap->reset_gpio_port[1])) ++ gpio_set_value(omap->reset_gpio_port[1], 1); + } + + if (omap->chargepump) { +@@ -438,11 +444,11 @@ err_tll_fck: + clk_put(omap->usbhost1_48m_fck); + + if (omap->phy_reset) { +- if (gpio_is_valid(omap->reset_gpio_port1)) +- gpio_free(omap->reset_gpio_port1); ++ if (gpio_is_valid(omap->reset_gpio_port[0])) ++ gpio_free(omap->reset_gpio_port[0]); + +- if (gpio_is_valid(omap->reset_gpio_port2)) +- gpio_free(omap->reset_gpio_port2); ++ if (gpio_is_valid(omap->reset_gpio_port[1])) ++ gpio_free(omap->reset_gpio_port[1]); + } + + err_host_48m_fck: +@@ -531,11 +537,11 @@ static void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) + } + + if (omap->phy_reset) { +- if (gpio_is_valid(omap->reset_gpio_port1)) +- gpio_free(omap->reset_gpio_port1); ++ if (gpio_is_valid(omap->reset_gpio_port[0])) ++ gpio_free(omap->reset_gpio_port[0]); + +- if (gpio_is_valid(omap->reset_gpio_port2)) +- gpio_free(omap->reset_gpio_port2); ++ if (gpio_is_valid(omap->reset_gpio_port[1])) ++ gpio_free(omap->reset_gpio_port[1]); + } + + dev_dbg(omap->dev, "Clock to USB host has been disabled\n"); +@@ -590,10 +596,13 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) + platform_set_drvdata(pdev, omap); + omap->dev = &pdev->dev; + omap->phy_reset = pdata->phy_reset; +- omap->reset_gpio_port1 = pdata->reset_gpio_port1; +- omap->reset_gpio_port2 = pdata->reset_gpio_port2; +- omap->phy_mode = pdata->phy_mode; +- omap->chargepump = pdata->chargepump; ++ omap->reset_gpio_port[0] = pdata->reset_gpio_port[0]; ++ omap->reset_gpio_port[1] = pdata->reset_gpio_port[1]; ++ omap->reset_gpio_port[2] = pdata->reset_gpio_port[2]; ++ omap->port_mode[0] = pdata->port_mode[0]; ++ omap->port_mode[1] = pdata->port_mode[1]; ++ omap->port_mode[2] = pdata->port_mode[2]; ++ omap->chargepump = pdata->chargepump; + omap->ehci = hcd_to_ehci(hcd); + omap->ehci->sbrn = 0x20; + +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.31/usb/0008-omap3-Add-CHIP_GE_OMAP3430ES3-for-HSUSB.patch b/recipes/linux/linux-omap-2.6.31/usb/0008-omap3-Add-CHIP_GE_OMAP3430ES3-for-HSUSB.patch new file mode 100644 index 0000000000..25764aa52c --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/usb/0008-omap3-Add-CHIP_GE_OMAP3430ES3-for-HSUSB.patch @@ -0,0 +1,41 @@ +From 073182af5855d4114ab3d40db3fba1298573f0be Mon Sep 17 00:00:00 2001 +From: Ajay Kumar Gupta +Date: Fri, 10 Jul 2009 12:15:04 +0530 +Subject: [PATCH 08/16] omap3: Add CHIP_GE_OMAP3430ES3 for HSUSB + +OMAP3 HSUSB ports can be individually programmed in PHY or TLL +mode in ES3.0 onwards whereas this is not supported in ES2.1 +and earlier versions. + +CHIP_GE_OMAP3430ES3 is added to program this behavior at runtime. + +Also updated the existing macros to use the priviously defined +*_GE_* logic instead of repeating the same logic again. + +Signed-off-by: Ajay Kumar Gupta +--- + arch/arm/plat-omap/include/mach/cpu.h | 7 ++++--- + 1 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/plat-omap/include/mach/cpu.h b/arch/arm/plat-omap/include/mach/cpu.h +index 7a5f9e8..60d867c 100644 +--- a/arch/arm/plat-omap/include/mach/cpu.h ++++ b/arch/arm/plat-omap/include/mach/cpu.h +@@ -414,10 +414,11 @@ IS_OMAP_TYPE(3430, 0x3430) + * chips at ES2 and beyond, but not, for example, any OMAP lines after + * OMAP3. + */ +-#define CHIP_GE_OMAP3430ES2 (CHIP_IS_OMAP3430ES2 | \ +- CHIP_IS_OMAP3430ES3_0 | \ +- CHIP_IS_OMAP3430ES3_1) + #define CHIP_GE_OMAP3430ES3_1 (CHIP_IS_OMAP3430ES3_1) ++#define CHIP_GE_OMAP3430ES3 (CHIP_IS_OMAP3430ES3_0 | \ ++ CHIP_GE_OMAP3430ES3_1) ++#define CHIP_GE_OMAP3430ES2 (CHIP_IS_OMAP3430ES2 | \ ++ CHIP_GE_OMAP3430ES3) + + + int omap_chip_is(struct omap_chip_id oci); +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.31/usb/0009-ehci-Support-for-ES3.x.patch b/recipes/linux/linux-omap-2.6.31/usb/0009-ehci-Support-for-ES3.x.patch new file mode 100644 index 0000000000..bd29031f1c --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/usb/0009-ehci-Support-for-ES3.x.patch @@ -0,0 +1,170 @@ +From 2caa398b8d7d37ecbf062fd36c54ed6807e3ab5b Mon Sep 17 00:00:00 2001 +From: Ajay Kumar Gupta +Date: Mon, 13 Jul 2009 14:13:26 +0530 +Subject: [PATCH 09/16] ehci: Support for ES3.x + +OMAP ES3.x supports portwise PHY or TLL mode of operation whereas +in ES2.x all the three ports can either be in PHY mode or in TLL +mode.Port3 can not be configured in PHY mode. + +Port mode must be defined either PHY, TLL or UNKNOWN in platform +files.Be careful of the scenario where one port is set as PHY and +other in TLL but the OMAP silicon version is 2.x or earlier where +this scenario is *not* supported. + +Changes are : + - Setup all the bypass configuration in omap_start_ehc() + based on ES version. + - Remove UHH_HOSTCONFIG programming for bypass settings + in omap_usb_utmi_init() + +Signed-off-by: Ajay Kumar Gupta +--- + drivers/usb/host/ehci-omap.c | 90 ++++++++++++++++++++++++------------------ + 1 files changed, 52 insertions(+), 38 deletions(-) + +diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c +index 3175122..81a0b65 100644 +--- a/drivers/usb/host/ehci-omap.c ++++ b/drivers/usb/host/ehci-omap.c +@@ -32,7 +32,6 @@ + * - move DPLL5 programming to clock fw + * - add suspend/resume + * - move workarounds to board-files +- * - differentiate between ES2.x and ES3.x + */ + + #include +@@ -102,6 +101,9 @@ + #define OMAP_UHH_SYSSTATUS (0x14) + #define OMAP_UHH_HOSTCONFIG (0x40) + #define OMAP_UHH_HOSTCONFIG_ULPI_BYPASS (1 << 0) ++#define OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS (1 << 0) ++#define OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS (1 << 11) ++#define OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS (1 << 12) + #define OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN (1 << 2) + #define OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN (1 << 3) + #define OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN (1 << 4) +@@ -185,16 +187,6 @@ static void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask) + unsigned reg; + int i; + +- reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG); +- reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS +- | OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN +- | OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN +- | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN; +- reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; +- +- /* Use UTMI Ports of TLL */ +- ehci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); +- + /* Program the 3 TLL channels upfront */ + for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) { + reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); +@@ -243,7 +235,9 @@ static void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask) + */ + static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) + { ++ struct omap_chip_id oci = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES3); + unsigned long timeout = jiffies + msecs_to_jiffies(1000); ++ u8 tll_ch_mask = 0; + unsigned reg = 0; + int ret = 0; + +@@ -362,37 +356,58 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) + + ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); + +- if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) || +- (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) || +- (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY)) { ++ reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG); + +- reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG); ++ /* setup ULPI bypass and burst configurations */ ++ reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN ++ | OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN ++ | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN); ++ reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; + +- reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN +- | OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN +- | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN); +- reg &= ~(OMAP_UHH_HOSTCONFIG_ULPI_BYPASS +- | OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN); ++ /* Bypass the TLL module for PHY mode operation */ ++ if (omap_chip_is(oci)) { ++ dev_dbg(omap->dev, "OMAP3 ES version > ES3\n"); ++ if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) ++ reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; ++ else if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) ++ reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; + +- /* Bypass the TLL module for PHY mode operation */ +- ehci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); +- dev_dbg(omap->dev, "Entered ULPI PHY MODE: success\n"); ++ if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) ++ reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; ++ else if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) ++ reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; ++ ++ if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY) ++ reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; ++ else if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL) ++ reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; + +- } else if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) || +- (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) || +- (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL)) { +- +- /* Enable UTMI mode for all 3 TLL channels */ +- omap_usb_utmi_init(omap, +- OMAP_TLL_CHANNEL_1_EN_MASK | +- OMAP_TLL_CHANNEL_2_EN_MASK | +- OMAP_TLL_CHANNEL_3_EN_MASK +- ); + } else { +- dev_err(hcd->self.controller, +- "UNKOWN mode requested\n"); +- ret = -EINVAL; +- goto err_unknown_mode; ++ dev_dbg(omap->dev, "OMAP3 ES version < ES3\n"); ++ if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) || ++ (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) || ++ (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY)) ++ reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; ++ else ++ reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; ++ } ++ ehci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); ++ dev_dbg(omap->dev, "UHH setup done, uhh_base=%x\n", reg); ++ ++ ++ if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) || ++ (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) || ++ (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL)) { ++ ++ if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) ++ tll_ch_mask |= OMAP_TLL_CHANNEL_1_EN_MASK; ++ if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) ++ tll_ch_mask |= OMAP_TLL_CHANNEL_2_EN_MASK; ++ if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL) ++ tll_ch_mask |= OMAP_TLL_CHANNEL_3_EN_MASK; ++ ++ /* Enable UTMI mode for required TLL channels */ ++ omap_usb_utmi_init(omap, tll_ch_mask); + } + + if (omap->phy_reset) { +@@ -430,7 +445,6 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) + + return 0; + +-err_unknown_mode: + err_sys_status: + clk_disable(omap->usbtll_ick); + clk_put(omap->usbtll_ick); +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.31/usb/0010-ehci-update-driver-with-generic-change.patch b/recipes/linux/linux-omap-2.6.31/usb/0010-ehci-update-driver-with-generic-change.patch new file mode 100644 index 0000000000..c517931edd --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/usb/0010-ehci-update-driver-with-generic-change.patch @@ -0,0 +1,31 @@ +From 4ad1dd4ce8c9c04c2fbfad72a78247d848090329 Mon Sep 17 00:00:00 2001 +From: Ajay Kumar Gupta +Date: Fri, 10 Jul 2009 19:46:20 +0530 +Subject: [PATCH 10/16] ehci: update driver with generic change + +Update the OMAP EHCI driver in accordance with below patch +introduced in generic EHCI driver. + +commit: b18ffd49e86102a9ed0a1cc83fdafe3891e844e5 +USB: EHCI: update toggle state for linked QHs + +Signed-off-by: Ajay Kumar Gupta +--- + drivers/usb/host/ehci-omap.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c +index 81a0b65..8b944d7 100644 +--- a/drivers/usb/host/ehci-omap.c ++++ b/drivers/usb/host/ehci-omap.c +@@ -761,6 +761,7 @@ static const struct hc_driver ehci_omap_hc_driver = { + .urb_enqueue = ehci_urb_enqueue, + .urb_dequeue = ehci_urb_dequeue, + .endpoint_disable = ehci_endpoint_disable, ++ .endpoint_reset = ehci_endpoint_reset, + + /* + * scheduling support +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.31/usb/0011-musb-fix-musb-gadget_driver-NULL-bug.patch b/recipes/linux/linux-omap-2.6.31/usb/0011-musb-fix-musb-gadget_driver-NULL-bug.patch new file mode 100644 index 0000000000..0d74743ac0 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/usb/0011-musb-fix-musb-gadget_driver-NULL-bug.patch @@ -0,0 +1,31 @@ +From 1adaab4805926b3674fd083e7e0ac2b29a30a34a Mon Sep 17 00:00:00 2001 +From: Ajay Kumar Gupta +Date: Fri, 12 Jun 2009 19:01:42 +0530 +Subject: [PATCH 11/16] musb: fix musb->gadget_driver != NULL bug + +musb->gadget_driver != NULL is observed when CONFIG_SUSPEND is +enabled causing failure in gadget driver registration. + +Fixing this by making musb->gadget_driver = NULL during musb +initialization. + +Signed-off-by: Ajay Kumar Gupta +--- + drivers/usb/musb/musb_gadget.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c +index 8b3c4e2..d69d98e 100644 +--- a/drivers/usb/musb/musb_gadget.c ++++ b/drivers/usb/musb/musb_gadget.c +@@ -1650,6 +1650,7 @@ int __init musb_gadget_setup(struct musb *musb) + musb->g.dev.dma_mask = musb->controller->dma_mask; + musb->g.dev.release = musb_gadget_release; + musb->g.name = musb_driver_name; ++ musb->gadget_driver = NULL; + + if (is_otg_enabled(musb)) + musb->g.is_otg = 1; +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.31/usb/0012-musb-Add-back-old-musb-procfs-file.patch b/recipes/linux/linux-omap-2.6.31/usb/0012-musb-Add-back-old-musb-procfs-file.patch new file mode 100644 index 0000000000..bc1ad5a648 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/usb/0012-musb-Add-back-old-musb-procfs-file.patch @@ -0,0 +1,947 @@ +From 7f43c6297c781c2d403ee397fe2cfccaaf3eea42 Mon Sep 17 00:00:00 2001 +From: Ajay Kumar Gupta +Date: Sat, 20 Jun 2009 14:06:38 +0530 +Subject: [PATCH 12/16] musb: Add back old musb procfs file + +Procfs file is removed from musb and an equivalent debugfs is +expected to replace it. + +Adding the old file back to retain the debug functionalities untill +we get debugfs equivalent in mainline. + +Signed-off-by: Ajay Kumar Gupta +--- + drivers/usb/musb/Makefile | 3 + + drivers/usb/musb/musb_core.c | 8 +- + drivers/usb/musb/musb_core.h | 19 + + drivers/usb/musb/musb_procfs.c | 838 ++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 863 insertions(+), 5 deletions(-) + create mode 100644 drivers/usb/musb/musb_procfs.c + +diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile +index 85710cc..06969c5 100644 +--- a/drivers/usb/musb/Makefile ++++ b/drivers/usb/musb/Makefile +@@ -74,4 +74,7 @@ endif + + ifeq ($(CONFIG_USB_MUSB_DEBUG),y) + EXTRA_CFLAGS += -DDEBUG ++ ifeq ($(CONFIG_PROC_FS),y) ++ musb_hdrc-objs += musb_procfs.o ++ endif + endif +diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c +index 129f9dc..f5ca435 100644 +--- a/drivers/usb/musb/musb_core.c ++++ b/drivers/usb/musb/musb_core.c +@@ -2046,8 +2046,6 @@ bad_config: + musb->xceiv->state = OTG_STATE_A_IDLE; + + status = usb_add_hcd(musb_to_hcd(musb), -1, 0); +- if (status) +- goto fail; + + DBG(1, "%s mode, status %d, devctl %02x %c\n", + "HOST", status, +@@ -2062,8 +2060,6 @@ bad_config: + musb->xceiv->state = OTG_STATE_B_IDLE; + + status = musb_gadget_setup(musb); +- if (status) +- goto fail; + + DBG(1, "%s mode, status %d, dev%02x\n", + is_otg_enabled(musb) ? "OTG" : "PERIPHERAL", +@@ -2082,7 +2078,8 @@ bad_config: + #endif + if (status) + goto fail2; +- ++ if (status == 0) ++ musb_debug_create("driver/musb_hdrc", musb); + return 0; + + fail2: +@@ -2152,6 +2149,7 @@ static int __devexit musb_remove(struct platform_device *pdev) + * - OTG mode: both roles are deactivated (or never-activated) + */ + musb_shutdown(pdev); ++ musb_debug_delete("driver/musb_hdrc", musb); + #ifdef CONFIG_USB_MUSB_HDRC_HCD + if (musb->board_mode == MUSB_HOST) + usb_remove_hcd(musb_to_hcd(musb)); +diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h +index 381d648..b0b4fbd 100644 +--- a/drivers/usb/musb/musb_core.h ++++ b/drivers/usb/musb/musb_core.h +@@ -562,4 +562,23 @@ extern int musb_platform_get_vbus_status(struct musb *musb); + extern int __init musb_platform_init(struct musb *musb); + extern int musb_platform_exit(struct musb *musb); + ++/*-------------------------- ProcFS definitions ---------------------*/ ++ ++struct proc_dir_entry; ++ ++#if (CONFIG_USB_MUSB_DEBUG > 0) && defined(MUSB_CONFIG_PROC_FS) ++extern struct proc_dir_entry *musb_debug_create(char *name, struct musb *data); ++extern void musb_debug_delete(char *name, struct musb *data); ++ ++#else ++static inline struct proc_dir_entry * ++musb_debug_create(char *name, struct musb *data) ++{ ++ return NULL; ++} ++static inline void musb_debug_delete(char *name, struct musb *data) ++{ ++} ++#endif ++ + #endif /* __MUSB_CORE_H__ */ +diff --git a/drivers/usb/musb/musb_procfs.c b/drivers/usb/musb/musb_procfs.c +new file mode 100644 +index 0000000..d789d4d +--- /dev/null ++++ b/drivers/usb/musb/musb_procfs.c +@@ -0,0 +1,838 @@ ++/* ++ * MUSB OTG driver debug support ++ * ++ * Copyright 2005 Mentor Graphics Corporation ++ * Copyright (C) 2005-2006 by Texas Instruments ++ * Copyright (C) 2006-2007 Nokia Corporation ++ * ++ * 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. ++ * ++ * 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 ++ * ++ * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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 /* FIXME remove procfs writes */ ++#include ++ ++#include "musb_core.h" ++ ++#include "davinci.h" ++ ++#ifdef CONFIG_USB_MUSB_HDRC_HCD ++ ++static int dump_qh(struct musb_qh *qh, char *buf, unsigned max) ++{ ++ int count; ++ int tmp; ++ struct usb_host_endpoint *hep = qh->hep; ++ struct urb *urb; ++ ++ count = snprintf(buf, max, " qh %p dev%d ep%d%s max%d\n", ++ qh, qh->dev->devnum, qh->epnum, ++ ({ char *s; switch (qh->type) { ++ case USB_ENDPOINT_XFER_BULK: ++ s = "-bulk"; break; ++ case USB_ENDPOINT_XFER_INT: ++ s = "-int"; break; ++ case USB_ENDPOINT_XFER_CONTROL: ++ s = ""; break; ++ default: ++ s = "iso"; break; ++ }; s; }), ++ qh->maxpacket); ++ if (count <= 0) ++ return 0; ++ buf += count; ++ max -= count; ++ ++ list_for_each_entry(urb, &hep->urb_list, urb_list) { ++ tmp = snprintf(buf, max, "\t%s urb %p %d/%d\n", ++ usb_pipein(urb->pipe) ? "in" : "out", ++ urb, urb->actual_length, ++ urb->transfer_buffer_length); ++ if (tmp <= 0) ++ break; ++ tmp = min(tmp, (int)max); ++ count += tmp; ++ buf += tmp; ++ max -= tmp; ++ } ++ return count; ++} ++ ++static int ++dump_queue(struct list_head *q, char *buf, unsigned max) ++{ ++ int count = 0; ++ struct musb_qh *qh; ++ ++ list_for_each_entry(qh, q, ring) { ++ int tmp; ++ ++ tmp = dump_qh(qh, buf, max); ++ if (tmp <= 0) ++ break; ++ tmp = min(tmp, (int)max); ++ count += tmp; ++ buf += tmp; ++ max -= tmp; ++ } ++ return count; ++} ++ ++#endif /* HCD */ ++ ++#ifdef CONFIG_USB_GADGET_MUSB_HDRC ++static int dump_ep(struct musb_ep *ep, char *buffer, unsigned max) ++{ ++ char *buf = buffer; ++ int code = 0; ++ void __iomem *regs = ep->hw_ep->regs; ++ char *mode = "1buf"; ++ ++ if (ep->is_in) { ++ if (ep->hw_ep->tx_double_buffered) ++ mode = "2buf"; ++ } else { ++ if (ep->hw_ep->rx_double_buffered) ++ mode = "2buf"; ++ } ++ ++ do { ++ struct usb_request *req; ++ ++ code = snprintf(buf, max, ++ "\n%s (hw%d): %s%s, csr %04x maxp %04x\n", ++ ep->name, ep->current_epnum, ++ mode, ep->dma ? " dma" : "", ++ musb_readw(regs, ++ (ep->is_in || !ep->current_epnum) ++ ? MUSB_TXCSR ++ : MUSB_RXCSR), ++ musb_readw(regs, ep->is_in ++ ? MUSB_TXMAXP ++ : MUSB_RXMAXP) ++ ); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ ++ if (is_cppi_enabled() && ep->current_epnum) { ++ unsigned cppi = ep->current_epnum - 1; ++ void __iomem *base = ep->musb->ctrl_base; ++ unsigned off1 = cppi << 2; ++ void __iomem *ram = base; ++ char tmp[16]; ++ ++ if (ep->is_in) { ++ ram += DAVINCI_TXCPPI_STATERAM_OFFSET(cppi); ++ tmp[0] = 0; ++ } else { ++ ram += DAVINCI_RXCPPI_STATERAM_OFFSET(cppi); ++ snprintf(tmp, sizeof tmp, "%d left, ", ++ musb_readl(base, ++ DAVINCI_RXCPPI_BUFCNT0_REG + off1)); ++ } ++ ++ code = snprintf(buf, max, "%cX DMA%d: %s" ++ "%08x %08x, %08x %08x; " ++ "%08x %08x %08x .. %08x\n", ++ ep->is_in ? 'T' : 'R', ++ ep->current_epnum - 1, tmp, ++ musb_readl(ram, 0 * 4), ++ musb_readl(ram, 1 * 4), ++ musb_readl(ram, 2 * 4), ++ musb_readl(ram, 3 * 4), ++ musb_readl(ram, 4 * 4), ++ musb_readl(ram, 5 * 4), ++ musb_readl(ram, 6 * 4), ++ musb_readl(ram, 7 * 4)); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } ++ ++ if (list_empty(&ep->req_list)) { ++ code = snprintf(buf, max, "\t(queue empty)\n"); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ break; ++ } ++ list_for_each_entry(req, &ep->req_list, list) { ++ code = snprintf(buf, max, "\treq %p, %s%s%d/%d\n", ++ req, ++ req->zero ? "zero, " : "", ++ req->short_not_ok ? "!short, " : "", ++ req->actual, req->length); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } ++ } while (0); ++ return buf - buffer; ++} ++#endif ++ ++static int ++dump_end_info(struct musb *musb, u8 epnum, char *aBuffer, unsigned max) ++{ ++ int code = 0; ++ char *buf = aBuffer; ++ struct musb_hw_ep *hw_ep = &musb->endpoints[epnum]; ++ ++ do { ++ musb_ep_select(musb->mregs, epnum); ++#ifdef CONFIG_USB_MUSB_HDRC_HCD ++ if (is_host_active(musb)) { ++ int dump_rx, dump_tx; ++ void __iomem *regs = hw_ep->regs; ++ ++ /* TEMPORARY (!) until we have a real periodic ++ * schedule tree ... ++ */ ++ if (!epnum) { ++ /* control is shared, uses RX queue ++ * but (mostly) shadowed tx registers ++ */ ++ dump_tx = !list_empty(&musb->control); ++ dump_rx = 0; ++ } else if (hw_ep == musb->bulk_ep) { ++ dump_tx = !list_empty(&musb->out_bulk); ++ dump_rx = !list_empty(&musb->in_bulk); ++ } else if (hw_ep->in_qh || hw_ep->out_qh) { ++ if (hw_ep->in_qh) ++ dump_rx = 1; ++ else ++ dump_rx = 0; ++ dump_tx = !dump_rx; ++ } else ++ break; ++ /* END TEMPORARY */ ++ ++ ++ if (dump_rx) { ++ code = snprintf(buf, max, ++ "\nRX%d: %s rxcsr %04x interval %02x " ++ "max %04x type %02x; " ++ "dev %d hub %d port %d" ++ "\n", ++ epnum, ++ hw_ep->rx_double_buffered ++ ? "2buf" : "1buf", ++ musb_readw(regs, MUSB_RXCSR), ++ musb_readb(regs, MUSB_RXINTERVAL), ++ musb_readw(regs, MUSB_RXMAXP), ++ musb_readb(regs, MUSB_RXTYPE), ++ /* FIXME: assumes multipoint */ ++ musb_readb(musb->mregs, ++ MUSB_BUSCTL_OFFSET(epnum, ++ MUSB_RXFUNCADDR)), ++ musb_readb(musb->mregs, ++ MUSB_BUSCTL_OFFSET(epnum, ++ MUSB_RXHUBADDR)), ++ musb_readb(musb->mregs, ++ MUSB_BUSCTL_OFFSET(epnum, ++ MUSB_RXHUBPORT)) ++ ); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ ++ if (is_cppi_enabled() ++ && epnum ++ && hw_ep->rx_channel) { ++ unsigned cppi = epnum - 1; ++ unsigned off1 = cppi << 2; ++ void __iomem *base; ++ void __iomem *ram; ++ char tmp[16]; ++ ++ base = musb->ctrl_base; ++ ram = DAVINCI_RXCPPI_STATERAM_OFFSET( ++ cppi) + base; ++ snprintf(tmp, sizeof tmp, "%d left, ", ++ musb_readl(base, ++ DAVINCI_RXCPPI_BUFCNT0_REG ++ + off1)); ++ ++ code = snprintf(buf, max, ++ " rx dma%d: %s" ++ "%08x %08x, %08x %08x; " ++ "%08x %08x %08x .. %08x\n", ++ cppi, tmp, ++ musb_readl(ram, 0 * 4), ++ musb_readl(ram, 1 * 4), ++ musb_readl(ram, 2 * 4), ++ musb_readl(ram, 3 * 4), ++ musb_readl(ram, 4 * 4), ++ musb_readl(ram, 5 * 4), ++ musb_readl(ram, 6 * 4), ++ musb_readl(ram, 7 * 4)); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } ++ ++ if (hw_ep == musb->bulk_ep ++ && !list_empty( ++ &musb->in_bulk)) { ++ code = dump_queue(&musb->in_bulk, ++ buf, max); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } else if (hw_ep->in_qh) { ++ code = dump_qh(hw_ep->in_qh, ++ buf, max); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } ++ } ++ ++ if (dump_tx) { ++ code = snprintf(buf, max, ++ "\nTX%d: %s txcsr %04x interval %02x " ++ "max %04x type %02x; " ++ "dev %d hub %d port %d" ++ "\n", ++ epnum, ++ hw_ep->tx_double_buffered ++ ? "2buf" : "1buf", ++ musb_readw(regs, MUSB_TXCSR), ++ musb_readb(regs, MUSB_TXINTERVAL), ++ musb_readw(regs, MUSB_TXMAXP), ++ musb_readb(regs, MUSB_TXTYPE), ++ /* FIXME: assumes multipoint */ ++ musb_readb(musb->mregs, ++ MUSB_BUSCTL_OFFSET(epnum, ++ MUSB_TXFUNCADDR)), ++ musb_readb(musb->mregs, ++ MUSB_BUSCTL_OFFSET(epnum, ++ MUSB_TXHUBADDR)), ++ musb_readb(musb->mregs, ++ MUSB_BUSCTL_OFFSET(epnum, ++ MUSB_TXHUBPORT)) ++ ); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ ++ if (is_cppi_enabled() ++ && epnum ++ && hw_ep->tx_channel) { ++ unsigned cppi = epnum - 1; ++ void __iomem *base; ++ void __iomem *ram; ++ ++ base = musb->ctrl_base; ++ ram = DAVINCI_RXCPPI_STATERAM_OFFSET( ++ cppi) + base; ++ code = snprintf(buf, max, ++ " tx dma%d: " ++ "%08x %08x, %08x %08x; " ++ "%08x %08x %08x .. %08x\n", ++ cppi, ++ musb_readl(ram, 0 * 4), ++ musb_readl(ram, 1 * 4), ++ musb_readl(ram, 2 * 4), ++ musb_readl(ram, 3 * 4), ++ musb_readl(ram, 4 * 4), ++ musb_readl(ram, 5 * 4), ++ musb_readl(ram, 6 * 4), ++ musb_readl(ram, 7 * 4)); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } ++ ++ if (hw_ep == musb->control_ep ++ && !list_empty( ++ &musb->control)) { ++ code = dump_queue(&musb->control, ++ buf, max); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } else if (hw_ep == musb->bulk_ep ++ && !list_empty( ++ &musb->out_bulk)) { ++ code = dump_queue(&musb->out_bulk, ++ buf, max); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } else if (hw_ep->out_qh) { ++ code = dump_qh(hw_ep->out_qh, ++ buf, max); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } ++ } ++ } ++#endif ++#ifdef CONFIG_USB_GADGET_MUSB_HDRC ++ if (is_peripheral_active(musb)) { ++ code = 0; ++ ++ if (hw_ep->ep_in.desc || !epnum) { ++ code = dump_ep(&hw_ep->ep_in, buf, max); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } ++ if (hw_ep->ep_out.desc) { ++ code = dump_ep(&hw_ep->ep_out, buf, max); ++ if (code <= 0) ++ break; ++ code = min(code, (int) max); ++ buf += code; ++ max -= code; ++ } ++ } ++#endif ++ } while (0); ++ ++ return buf - aBuffer; ++} ++ ++/* Dump the current status and compile options. ++ * @param musb the device driver instance ++ * @param buffer where to dump the status; it must be big enough to hold the ++ * result otherwise "BAD THINGS HAPPENS(TM)". ++ */ ++static int dump_header_stats(struct musb *musb, char *buffer) ++{ ++ int code, count = 0; ++ const void __iomem *mbase = musb->mregs; ++ ++ *buffer = 0; ++ count = sprintf(buffer, "Status: %sHDRC, Mode=%s " ++ "(Power=%02x, DevCtl=%02x)\n", ++ (musb->is_multipoint ? "M" : ""), MUSB_MODE(musb), ++ musb_readb(mbase, MUSB_POWER), ++ musb_readb(mbase, MUSB_DEVCTL)); ++ if (count <= 0) ++ return 0; ++ buffer += count; ++ ++ code = sprintf(buffer, "OTG state: %s; %sactive\n", ++ otg_state_string(musb), ++ musb->is_active ? "" : "in"); ++ if (code <= 0) ++ goto done; ++ buffer += code; ++ count += code; ++ ++ code = sprintf(buffer, ++ "Options: " ++#ifdef CONFIG_MUSB_PIO_ONLY ++ "pio" ++#elif defined(CONFIG_USB_TI_CPPI_DMA) ++ "cppi-dma" ++#elif defined(CONFIG_USB_INVENTRA_DMA) ++ "musb-dma" ++#elif defined(CONFIG_USB_TUSB_OMAP_DMA) ++ "tusb-omap-dma" ++#else ++ "?dma?" ++#endif ++ ", " ++#ifdef CONFIG_USB_MUSB_OTG ++ "otg (peripheral+host)" ++#elif defined(CONFIG_USB_GADGET_MUSB_HDRC) ++ "peripheral" ++#elif defined(CONFIG_USB_MUSB_HDRC_HCD) ++ "host" ++#endif ++ ", debug=%d [eps=%d]\n", ++ musb_debug, ++ musb->nr_endpoints); ++ if (code <= 0) ++ goto done; ++ count += code; ++ buffer += code; ++ ++#ifdef CONFIG_USB_GADGET_MUSB_HDRC ++ code = sprintf(buffer, "Peripheral address: %02x\n", ++ musb_readb(musb->ctrl_base, MUSB_FADDR)); ++ if (code <= 0) ++ goto done; ++ buffer += code; ++ count += code; ++#endif ++ ++#ifdef CONFIG_USB_MUSB_HDRC_HCD ++ code = sprintf(buffer, "Root port status: %08x\n", ++ musb->port1_status); ++ if (code <= 0) ++ goto done; ++ buffer += code; ++ count += code; ++#endif ++ ++#ifdef CONFIG_ARCH_DAVINCI ++ code = sprintf(buffer, ++ "DaVinci: ctrl=%02x stat=%1x phy=%03x\n" ++ "\trndis=%05x auto=%04x intsrc=%08x intmsk=%08x" ++ "\n", ++ musb_readl(musb->ctrl_base, DAVINCI_USB_CTRL_REG), ++ musb_readl(musb->ctrl_base, DAVINCI_USB_STAT_REG), ++ __raw_readl((void __force __iomem *) ++ IO_ADDRESS(USBPHY_CTL_PADDR)), ++ musb_readl(musb->ctrl_base, DAVINCI_RNDIS_REG), ++ musb_readl(musb->ctrl_base, DAVINCI_AUTOREQ_REG), ++ musb_readl(musb->ctrl_base, ++ DAVINCI_USB_INT_SOURCE_REG), ++ musb_readl(musb->ctrl_base, ++ DAVINCI_USB_INT_MASK_REG)); ++ if (code <= 0) ++ goto done; ++ count += code; ++ buffer += code; ++#endif /* DAVINCI */ ++ ++#ifdef CONFIG_USB_TUSB6010 ++ code = sprintf(buffer, ++ "TUSB6010: devconf %08x, phy enable %08x drive %08x" ++ "\n\totg %03x timer %08x" ++ "\n\tprcm conf %08x mgmt %08x; int src %08x mask %08x" ++ "\n", ++ musb_readl(musb->ctrl_base, TUSB_DEV_CONF), ++ musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL_ENABLE), ++ musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL), ++ musb_readl(musb->ctrl_base, TUSB_DEV_OTG_STAT), ++ musb_readl(musb->ctrl_base, TUSB_DEV_OTG_TIMER), ++ musb_readl(musb->ctrl_base, TUSB_PRCM_CONF), ++ musb_readl(musb->ctrl_base, TUSB_PRCM_MNGMT), ++ musb_readl(musb->ctrl_base, TUSB_INT_SRC), ++ musb_readl(musb->ctrl_base, TUSB_INT_MASK)); ++ if (code <= 0) ++ goto done; ++ count += code; ++ buffer += code; ++#endif /* DAVINCI */ ++ ++ if (is_cppi_enabled() && musb->dma_controller) { ++ code = sprintf(buffer, ++ "CPPI: txcr=%d txsrc=%01x txena=%01x; " ++ "rxcr=%d rxsrc=%01x rxena=%01x " ++ "\n", ++ musb_readl(musb->ctrl_base, ++ DAVINCI_TXCPPI_CTRL_REG), ++ musb_readl(musb->ctrl_base, ++ DAVINCI_TXCPPI_RAW_REG), ++ musb_readl(musb->ctrl_base, ++ DAVINCI_TXCPPI_INTENAB_REG), ++ musb_readl(musb->ctrl_base, ++ DAVINCI_RXCPPI_CTRL_REG), ++ musb_readl(musb->ctrl_base, ++ DAVINCI_RXCPPI_RAW_REG), ++ musb_readl(musb->ctrl_base, ++ DAVINCI_RXCPPI_INTENAB_REG)); ++ if (code <= 0) ++ goto done; ++ count += code; ++ buffer += code; ++ } ++ ++#ifdef CONFIG_USB_GADGET_MUSB_HDRC ++ if (is_peripheral_enabled(musb)) { ++ code = sprintf(buffer, "Gadget driver: %s\n", ++ musb->gadget_driver ++ ? musb->gadget_driver->driver.name ++ : "(none)"); ++ if (code <= 0) ++ goto done; ++ count += code; ++ buffer += code; ++ } ++#endif ++ ++done: ++ return count; ++} ++ ++/* Write to ProcFS ++ * ++ * C soft-connect ++ * c soft-disconnect ++ * I enable HS ++ * i disable HS ++ * s stop session ++ * F force session (OTG-unfriendly) ++ * E rElinquish bus (OTG) ++ * H request host mode ++ * h cancel host request ++ * T start sending TEST_PACKET ++ * D set/query the debug level ++ */ ++static int musb_proc_write(struct file *file, const char __user *buffer, ++ unsigned long count, void *data) ++{ ++ char cmd; ++ u8 reg; ++ struct musb *musb = (struct musb *)data; ++ void __iomem *mbase = musb->mregs; ++ ++ /* MOD_INC_USE_COUNT; */ ++ ++ if (unlikely(copy_from_user(&cmd, buffer, 1))) ++ return -EFAULT; ++ ++ switch (cmd) { ++ case 'S': ++ if (mbase) { ++ reg = musb_readb(mbase, MUSB_POWER) ++ | MUSB_POWER_SUSPENDM; ++ musb_writeb(mbase, MUSB_POWER, reg); ++ } ++ break; ++ ++ case 'C': ++ if (mbase) { ++ reg = musb_readb(mbase, MUSB_POWER) ++ | MUSB_POWER_SOFTCONN; ++ musb_writeb(mbase, MUSB_POWER, reg); ++ } ++ break; ++ ++ case 'c': ++ if (mbase) { ++ reg = musb_readb(mbase, MUSB_POWER) ++ & ~MUSB_POWER_SOFTCONN; ++ musb_writeb(mbase, MUSB_POWER, reg); ++ } ++ break; ++ ++ case 'I': ++ if (mbase) { ++ reg = musb_readb(mbase, MUSB_POWER) ++ | MUSB_POWER_HSENAB; ++ musb_writeb(mbase, MUSB_POWER, reg); ++ } ++ break; ++ ++ case 'i': ++ if (mbase) { ++ reg = musb_readb(mbase, MUSB_POWER) ++ & ~MUSB_POWER_HSENAB; ++ musb_writeb(mbase, MUSB_POWER, reg); ++ } ++ break; ++ ++ case 'F': ++ reg = musb_readb(mbase, MUSB_DEVCTL); ++ reg |= MUSB_DEVCTL_SESSION; ++ musb_writeb(mbase, MUSB_DEVCTL, reg); ++ break; ++ ++ case 'H': ++ if (mbase) { ++ reg = musb_readb(mbase, MUSB_DEVCTL); ++ reg |= MUSB_DEVCTL_HR; ++ musb_writeb(mbase, MUSB_DEVCTL, reg); ++ /* MUSB_HST_MODE( ((struct musb*)data) ); */ ++ /* WARNING("Host Mode\n"); */ ++ } ++ break; ++ ++ case 'h': ++ if (mbase) { ++ reg = musb_readb(mbase, MUSB_DEVCTL); ++ reg &= ~MUSB_DEVCTL_HR; ++ musb_writeb(mbase, MUSB_DEVCTL, reg); ++ } ++ break; ++ ++ case 'T': ++ if (mbase) { ++ musb_load_testpacket(musb); ++ musb_writeb(mbase, MUSB_TESTMODE, ++ MUSB_TEST_PACKET); ++ } ++ break; ++ ++#if (CONFIG_USB_MUSB_DEBUG > 0) ++ /* set/read debug level */ ++ case 'D':{ ++ if (count > 1) { ++ char digits[8], *p = digits; ++ int i = 0, level = 0, sign = 1; ++ int len = min(count - 1, (unsigned long)8); ++ ++ if (copy_from_user(&digits, &buffer[1], len)) ++ return -EFAULT; ++ ++ /* optional sign */ ++ if (*p == '-') { ++ len -= 1; ++ sign = -sign; ++ p++; ++ } ++ ++ /* read it */ ++ while (i++ < len && *p > '0' && *p < '9') { ++ level = level * 10 + (*p - '0'); ++ p++; ++ } ++ ++ level *= sign; ++ DBG(1, "debug level %d\n", level); ++ musb_debug = level; ++ } ++ } ++ break; ++ ++ ++ case '?': ++ INFO("?: you are seeing it\n"); ++ INFO("S: suspend the usb bus\n"); ++ INFO("C/c: soft connect enable/disable\n"); ++ INFO("I/i: hispeed enable/disable\n"); ++ INFO("F: force session start\n"); ++ INFO("H: host mode\n"); ++ INFO("T: start sending TEST_PACKET\n"); ++ INFO("D: set/read dbug level\n"); ++ break; ++#endif ++ ++ default: ++ ERR("Command %c not implemented\n", cmd); ++ break; ++ } ++ ++ musb_platform_try_idle(musb, 0); ++ ++ return count; ++} ++ ++static int musb_proc_read(char *page, char **start, ++ off_t off, int count, int *eof, void *data) ++{ ++ char *buffer = page; ++ int code = 0; ++ unsigned long flags; ++ struct musb *musb = data; ++ unsigned epnum; ++ ++ count -= off; ++ count -= 1; /* for NUL at end */ ++ if (count <= 0) ++ return -EINVAL; ++ ++ spin_lock_irqsave(&musb->lock, flags); ++ ++ code = dump_header_stats(musb, buffer); ++ if (code > 0) { ++ buffer += code; ++ count -= code; ++ } ++ ++ /* generate the report for the end points */ ++ /* REVISIT ... not unless something's connected! */ ++ for (epnum = 0; count >= 0 && epnum < musb->nr_endpoints; ++ epnum++) { ++ code = dump_end_info(musb, epnum, buffer, count); ++ if (code > 0) { ++ buffer += code; ++ count -= code; ++ } ++ } ++ ++ musb_platform_try_idle(musb, 0); ++ ++ spin_unlock_irqrestore(&musb->lock, flags); ++ *eof = 1; ++ ++ return buffer - page; ++} ++ ++void __devexit musb_debug_delete(char *name, struct musb *musb) ++{ ++ if (musb->proc_entry) ++ remove_proc_entry(name, NULL); ++} ++ ++struct proc_dir_entry *__init ++musb_debug_create(char *name, struct musb *data) ++{ ++ struct proc_dir_entry *pde; ++ ++ /* FIXME convert everything to seq_file; then later, debugfs */ ++ ++ if (!name) ++ return NULL; ++ ++ pde = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR, NULL); ++ data->proc_entry = pde; ++ if (pde) { ++ pde->data = data; ++ /* pde->owner = THIS_MODULE; */ ++ ++ pde->read_proc = musb_proc_read; ++ pde->write_proc = musb_proc_write; ++ ++ pde->size = 0; ++ ++ pr_debug("Registered /proc/%s\n", name); ++ } else { ++ pr_debug("Cannot create a valid proc file entry"); ++ } ++ ++ return pde; ++} +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.31/usb/0013-musb-Remove-USB_SUSPEND-auto-select-with-OTG.patch b/recipes/linux/linux-omap-2.6.31/usb/0013-musb-Remove-USB_SUSPEND-auto-select-with-OTG.patch new file mode 100644 index 0000000000..4d18b3e49c --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/usb/0013-musb-Remove-USB_SUSPEND-auto-select-with-OTG.patch @@ -0,0 +1,29 @@ +From 2fa09793f0da931d7b893291d684162d03eccef2 Mon Sep 17 00:00:00 2001 +From: Ajay Kumar Gupta +Date: Sat, 20 Jun 2009 14:09:15 +0530 +Subject: [PATCH 13/16] musb: Remove USB_SUSPEND auto select with OTG + +As USB power management is not yet supported in MUSB but we want to +use OTG build image so disable auto selection of USB_SUSPEND with +OTG till power management is supported. + +Signed-off-by: Ajay Kumar Gupta +--- + drivers/usb/core/Kconfig | 1 - + 1 files changed, 0 insertions(+), 1 deletions(-) + +diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig +index ad92594..4c7d6e8 100644 +--- a/drivers/usb/core/Kconfig ++++ b/drivers/usb/core/Kconfig +@@ -109,7 +109,6 @@ config USB_SUSPEND + config USB_OTG + bool + depends on USB && EXPERIMENTAL +- select USB_SUSPEND + default n + + +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.31/usb/0014-musb-disable-PING-on-status-phase-of-control-transf.patch b/recipes/linux/linux-omap-2.6.31/usb/0014-musb-disable-PING-on-status-phase-of-control-transf.patch new file mode 100644 index 0000000000..f93c2a2ed6 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/usb/0014-musb-disable-PING-on-status-phase-of-control-transf.patch @@ -0,0 +1,34 @@ +From 9d49c81b7ebf7942efc14bc9533a14cb64cd68e6 Mon Sep 17 00:00:00 2001 +From: Ajay Kumar Gupta +Date: Fri, 12 Jun 2009 19:07:13 +0530 +Subject: [PATCH 14/16] musb: disable PING on status phase of control transfer + +PING token is not mandatory in status phase of control transfer +so some high speed USB sticks doesn't support this.If such devices +are connected to MUSB then they would not respond to PING token +causing delayed or failed enumeration. + +Fixing this issue by disabling PING token in status phase of control +transfers. + +Signed-off-by: Ajay Kumar Gupta +--- + drivers/usb/musb/musb_host.c | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c +index cf94511..4d301d2 100644 +--- a/drivers/usb/musb/musb_host.c ++++ b/drivers/usb/musb/musb_host.c +@@ -1056,6 +1056,8 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb) + else + csr = MUSB_CSR0_H_STATUSPKT + | MUSB_CSR0_TXPKTRDY; ++ /* disable ping token in status phase */ ++ csr |= MUSB_CSR0_H_DIS_PING; + + /* flag status stage */ + musb->ep0_stage = MUSB_EP0_STATUS; +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.31/usb/0015-musb-Add-context-save-and-restore-support.patch b/recipes/linux/linux-omap-2.6.31/usb/0015-musb-Add-context-save-and-restore-support.patch new file mode 100644 index 0000000000..3bf368c79f --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/usb/0015-musb-Add-context-save-and-restore-support.patch @@ -0,0 +1,422 @@ +From 2b65475db2df6c0b7ebb8960e77e3aaf27147bda Mon Sep 17 00:00:00 2001 +From: Ajay Kumar Gupta +Date: Thu, 3 Sep 2009 17:07:40 +0530 +Subject: [PATCH 15/16] musb: Add context save and restore support + +Adding support for MUSB register save and restore during system +suspend and resume. + +Changes: + - Added musb_save/restore_context() functions + - Added platform specific musb_platform_save/restore_context() + to handle platform specific jobs. + - Maintaining BlackFin compatibility by adding read/write + functions for registers which are not available in BlackFin + +Tested system suspend and resume on OMAP3EVM board. + +Signed-off-by: Anand Gadiyar +Signed-off-by: Ajay Kumar Gupta +--- + drivers/usb/musb/musb_core.c | 157 +++++++++++++++++++++++++++++++++++++++++- + drivers/usb/musb/musb_core.h | 39 ++++++++++ + drivers/usb/musb/musb_regs.h | 90 ++++++++++++++++++++++++ + drivers/usb/musb/omap2430.c | 16 ++++ + 4 files changed, 300 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c +index f5ca435..0de19da 100644 +--- a/drivers/usb/musb/musb_core.c ++++ b/drivers/usb/musb/musb_core.c +@@ -2165,20 +2165,169 @@ static int __devexit musb_remove(struct platform_device *pdev) + + #ifdef CONFIG_PM + ++static struct musb_context_registers musb_context; ++ ++void musb_save_context(void __iomem *musb_base) ++{ ++ int i; ++ ++ musb_platform_save_context(&musb_context); ++ ++ musb_context.faddr = musb_readb(musb_base, MUSB_FADDR); ++ musb_context.power = musb_readb(musb_base, MUSB_POWER); ++ musb_context.intrtx = musb_readw(musb_base, MUSB_INTRTX); ++ musb_context.intrrx = musb_readw(musb_base, MUSB_INTRRX); ++ musb_context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE); ++ musb_context.intrrxe = musb_readw(musb_base, MUSB_INTRRXE); ++ musb_context.intrusb = musb_readb(musb_base, MUSB_INTRUSB); ++ musb_context.intrusbe = musb_readb(musb_base, MUSB_INTRUSBE); ++ musb_context.frame = musb_readw(musb_base, MUSB_FRAME); ++ musb_context.index = musb_readb(musb_base, MUSB_INDEX); ++ musb_context.testmode = musb_readb(musb_base, MUSB_TESTMODE); ++ musb_context.devctl = musb_readb(musb_base, MUSB_DEVCTL); ++ ++ for (i = 0; i < MUSB_C_NUM_EPS; ++i) { ++ musb_writeb(musb_base, MUSB_INDEX, i); ++ musb_context.index_regs[i].txmaxp = ++ musb_readw(musb_base, 0x10 + MUSB_TXMAXP); ++ musb_context.index_regs[i].txcsr = ++ musb_readw(musb_base, 0x10 + MUSB_TXCSR); ++ musb_context.index_regs[i].rxmaxp = ++ musb_readw(musb_base, 0x10 + MUSB_RXMAXP); ++ musb_context.index_regs[i].rxcsr = ++ musb_readw(musb_base, 0x10 + MUSB_RXCSR); ++ musb_context.index_regs[i].rxcount = ++ musb_readw(musb_base, 0x10 + MUSB_RXCOUNT); ++ musb_context.index_regs[i].txtype = ++ musb_readb(musb_base, 0x10 + MUSB_TXTYPE); ++ musb_context.index_regs[i].txinterval = ++ musb_readb(musb_base, 0x10 + MUSB_TXINTERVAL); ++ musb_context.index_regs[i].rxtype = ++ musb_readb(musb_base, 0x10 + MUSB_RXTYPE); ++ musb_context.index_regs[i].rxinterval = ++ musb_readb(musb_base, 0x10 + MUSB_RXINTERVAL); ++ ++ musb_context.index_regs[i].txfifoadd = ++ musb_read_txfifoadd(musb_base); ++ musb_context.index_regs[i].rxfifoadd = ++ musb_read_rxfifoadd(musb_base); ++ musb_context.index_regs[i].txfifosz = ++ musb_read_txfifosz(musb_base); ++ musb_context.index_regs[i].rxfifosz = ++ musb_read_rxfifosz(musb_base); ++ ++ musb_context.index_regs[i].txfunaddr = ++ musb_read_txfunaddr(musb_base, i); ++ musb_context.index_regs[i].txhubaddr = ++ musb_read_txhubaddr(musb_base, i); ++ musb_context.index_regs[i].txhubport = ++ musb_read_txhubport(musb_base, i); ++ ++ musb_context.index_regs[i].rxfunaddr = ++ musb_read_rxfunaddr(musb_base, i); ++ musb_context.index_regs[i].rxhubaddr = ++ musb_read_rxhubaddr(musb_base, i); ++ musb_context.index_regs[i].rxhubport = ++ musb_read_rxhubport(musb_base, i); ++ } ++ ++ musb_writeb(musb_base, MUSB_INDEX, musb_context.index); ++} ++ ++void musb_restore_context(void __iomem *musb_base) ++{ ++ int i; ++ void __iomem *ep_target_regs; ++ ++ musb_writeb(musb_base, MUSB_FADDR, musb_context.faddr); ++ musb_writeb(musb_base, MUSB_POWER, musb_context.power); ++ musb_writew(musb_base, MUSB_INTRTX, musb_context.intrtx); ++ musb_writew(musb_base, MUSB_INTRRX, musb_context.intrrx); ++ musb_writew(musb_base, MUSB_INTRTXE, musb_context.intrtxe); ++ musb_writew(musb_base, MUSB_INTRRXE, musb_context.intrrxe); ++ musb_writeb(musb_base, MUSB_INTRUSB, musb_context.intrusb); ++ musb_writeb(musb_base, MUSB_INTRUSBE, musb_context.intrusbe); ++ musb_writew(musb_base, MUSB_FRAME, musb_context.frame); ++ musb_writeb(musb_base, MUSB_TESTMODE, musb_context.testmode); ++ musb_writeb(musb_base, MUSB_DEVCTL, musb_context.devctl); ++ ++ ++ for (i = 0; i < MUSB_C_NUM_EPS; ++i) { ++ musb_writeb(musb_base, MUSB_INDEX, i); ++ musb_writew(musb_base, 0x10 + MUSB_TXMAXP, ++ musb_context.index_regs[i].txmaxp); ++ musb_writew(musb_base, 0x10 + MUSB_TXCSR, ++ musb_context.index_regs[i].txcsr); ++ musb_writew(musb_base, 0x10 + MUSB_RXMAXP, ++ musb_context.index_regs[i].rxmaxp); ++ musb_writew(musb_base, 0x10 + MUSB_RXCSR, ++ musb_context.index_regs[i].rxcsr); ++ musb_writew(musb_base, 0x10 + MUSB_RXCOUNT, ++ musb_context.index_regs[i].rxcount); ++ musb_writeb(musb_base, 0x10 + MUSB_TXTYPE, ++ musb_context.index_regs[i].txtype); ++ musb_writeb(musb_base, 0x10 + MUSB_TXINTERVAL, ++ musb_context.index_regs[i].txinterval); ++ musb_writeb(musb_base, 0x10 + MUSB_RXTYPE, ++ musb_context.index_regs[i].rxtype); ++ musb_writeb(musb_base, 0x10 + MUSB_RXINTERVAL, ++ musb_context.index_regs[i].rxinterval); ++ ++ musb_write_txfifosz(musb_base, ++ musb_context.index_regs[i].txfifosz); ++ musb_write_rxfifosz(musb_base, ++ musb_context.index_regs[i].rxfifosz); ++ musb_write_txfifoadd(musb_base, ++ musb_context.index_regs[i].txfifoadd); ++ musb_write_rxfifoadd(musb_base, ++ musb_context.index_regs[i].rxfifoadd); ++ ++ musb_write_txfunaddr(musb_base, i, ++ musb_context.index_regs[i].txfunaddr); ++ musb_write_txhubaddr(musb_base, i, ++ musb_context.index_regs[i].txhubaddr); ++ musb_write_txhubport(musb_base, i, ++ musb_context.index_regs[i].txhubport); ++ ++ ep_target_regs = musb_read_target_reg_base(i, musb_base); ++ ++ musb_write_rxfunaddr(ep_target_regs, ++ musb_context.index_regs[i].rxfunaddr); ++ musb_write_rxhubaddr(ep_target_regs, ++ musb_context.index_regs[i].rxhubaddr); ++ musb_write_rxhubport(ep_target_regs, ++ musb_context.index_regs[i].rxhubport); ++ } ++ ++ musb_writeb(musb_base, MUSB_INDEX, musb_context.index); ++ ++ musb_platform_restore_context(&musb_context); ++} ++ + static int musb_suspend(struct platform_device *pdev, pm_message_t message) + { + unsigned long flags; + struct musb *musb = dev_to_musb(&pdev->dev); ++ u8 reg; + + if (!musb->clock) + return 0; + + spin_lock_irqsave(&musb->lock, flags); + ++ musb_save_context(musb->mregs); ++ + if (is_peripheral_active(musb)) { +- /* FIXME force disconnect unless we know USB will wake +- * the system up quickly enough to respond ... ++ /* System is entering into suspend where gadget would not be ++ * able to respond to host and thus it will be in an unknown ++ * state for host.Re-enumemation of gadget is required after ++ * resume to make the gadget functional thus doing a force ++ * disconnect. + */ ++ reg = musb_readb(musb->mregs, MUSB_POWER); ++ reg &= ~MUSB_POWER_SOFTCONN; ++ musb_writeb(musb->mregs, MUSB_POWER, reg); ++ + } else if (is_host_active(musb)) { + /* we know all the children are suspended; sometimes + * they will even be wakeup-enabled. +@@ -2205,6 +2354,8 @@ static int musb_resume_early(struct platform_device *pdev) + else + clk_enable(musb->clock); + ++ musb_restore_context(musb->mregs); ++ + /* for static cmos like DaVinci, register values were preserved + * unless for some reason the whole soc powered down or the USB + * module got reset through the PSC (vs just being disabled). +@@ -2215,6 +2366,8 @@ static int musb_resume_early(struct platform_device *pdev) + #else + #define musb_suspend NULL + #define musb_resume_early NULL ++#define musb_save_context do {} while (0) ++#define musb_restore_context do {} while (0) + #endif + + static struct platform_driver musb_driver = { +diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h +index b0b4fbd..4568a8e 100644 +--- a/drivers/usb/musb/musb_core.h ++++ b/drivers/usb/musb/musb_core.h +@@ -446,6 +446,45 @@ struct musb { + #endif + }; + ++#ifdef CONFIG_PM ++struct musb_csr_regs { ++ /* FIFO registers */ ++ u16 txmaxp, txcsr, rxmaxp, rxcsr, rxcount; ++ u16 rxfifoadd, txfifoadd; ++ u8 txtype, txinterval, rxtype, rxinterval; ++ u8 rxfifosz, txfifosz; ++ u8 txfunaddr, txhubaddr, txhubport; ++ u8 rxfunaddr, rxhubaddr, rxhubport; ++}; ++ ++struct musb_context_registers { ++ ++#if defined(CONFIG_ARCH_OMAP34XX) ++ u32 otg_sysconfig, otg_forcestandby; ++#endif ++ u8 faddr, power; ++ u16 intrtx, intrrx, intrtxe, intrrxe; ++ u8 intrusb, intrusbe; ++ u16 frame; ++ u8 index, testmode; ++ ++ u8 devctl, misc; ++ ++ struct musb_csr_regs index_regs[MUSB_C_NUM_EPS]; ++}; ++ ++#if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430) ++extern void musb_platform_save_context(struct musb_context_registers ++ *musb_context); ++extern void musb_platform_restore_context(struct musb_context_registers ++ *musb_context); ++#else ++#define musb_platform_save_context(x) do {} while (0) ++#define musb_platform_restore_context(x) do {} while (0) ++#endif ++ ++#endif ++ + static inline void musb_set_vbus(struct musb *musb, int is_on) + { + musb->board_set_vbus(musb, is_on); +diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h +index fbfd3fd..a8e19da 100644 +--- a/drivers/usb/musb/musb_regs.h ++++ b/drivers/usb/musb/musb_regs.h +@@ -321,6 +321,26 @@ static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) + musb_writew(mbase, MUSB_RXFIFOADD, c_off); + } + ++static inline u8 musb_read_txfifosz(void __iomem *mbase) ++{ ++ return musb_readb(mbase, MUSB_TXFIFOSZ); ++} ++ ++static inline u16 musb_read_txfifoadd(void __iomem *mbase) ++{ ++ return musb_readw(mbase, MUSB_TXFIFOADD); ++} ++ ++static inline u8 musb_read_rxfifosz(void __iomem *mbase) ++{ ++ return musb_readb(mbase, MUSB_RXFIFOSZ); ++} ++ ++static inline u16 musb_read_rxfifoadd(void __iomem *mbase) ++{ ++ return musb_readw(mbase, MUSB_RXFIFOADD); ++} ++ + static inline u8 musb_read_configdata(void __iomem *mbase) + { + musb_writeb(mbase, MUSB_INDEX, 0); +@@ -376,6 +396,36 @@ static inline void musb_write_txhubport(void __iomem *mbase, u8 epnum, + qh_h_port_reg); + } + ++static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum) ++{ ++ return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXFUNCADDR)); ++} ++ ++static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum) ++{ ++ return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBADDR)); ++} ++ ++static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum) ++{ ++ return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBPORT)); ++} ++ ++static inline u8 musb_read_txfunaddr(void __iomem *mbase, u8 epnum) ++{ ++ return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR)); ++} ++ ++static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum) ++{ ++ return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR)); ++} ++ ++static inline u8 musb_read_txhubport(void __iomem *mbase, u8 epnum) ++{ ++ return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT)); ++} ++ + #else /* CONFIG_BLACKFIN */ + + #define USB_BASE USB_FADDR +@@ -464,6 +514,22 @@ static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) + { + } + ++static inline u8 musb_read_txfifosz(void __iomem *mbase) ++{ ++} ++ ++static inline u16 musb_read_txfifoadd(void __iomem *mbase) ++{ ++} ++ ++static inline u8 musb_read_rxfifosz(void __iomem *mbase) ++{ ++} ++ ++static inline u16 musb_read_rxfifoadd(void __iomem *mbase) ++{ ++} ++ + static inline u8 musb_read_configdata(void __iomem *mbase) + { + return 0; +@@ -509,6 +575,30 @@ static inline void musb_write_txhubport(void __iomem *mbase, u8 epnum, + { + } + ++static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum) ++{ ++} ++ ++static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum) ++{ ++} ++ ++static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum) ++{ ++} ++ ++static inline u8 musb_read_txfunaddr(void __iomem *mbase, u8 epnum) ++{ ++} ++ ++static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum) ++{ ++} ++ ++static inline void musb_read_txhubport(void __iomem *mbase, u8 epnum) ++{ ++} ++ + #endif /* CONFIG_BLACKFIN */ + + #endif /* __MUSB_REGS_H__ */ +diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c +index 3487520..84af3b3 100644 +--- a/drivers/usb/musb/omap2430.c ++++ b/drivers/usb/musb/omap2430.c +@@ -255,6 +255,22 @@ int __init musb_platform_init(struct musb *musb) + return 0; + } + ++#ifdef CONFIG_PM ++void musb_platform_save_context(struct musb_context_registers ++ *musb_context) ++{ ++ musb_context->otg_sysconfig = omap_readl(OTG_SYSCONFIG); ++ musb_context->otg_forcestandby = omap_readl(OTG_FORCESTDBY); ++} ++ ++void musb_platform_restore_context(struct musb_context_registers ++ *musb_context) ++{ ++ omap_writel(musb_context->otg_sysconfig, OTG_SYSCONFIG); ++ omap_writel(musb_context->otg_forcestandby, OTG_FORCESTDBY); ++} ++#endif ++ + int musb_platform_suspend(struct musb *musb) + { + u32 l; +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.31/usb/0016-usb-update-defconfig.patch b/recipes/linux/linux-omap-2.6.31/usb/0016-usb-update-defconfig.patch new file mode 100644 index 0000000000..865016aca7 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/usb/0016-usb-update-defconfig.patch @@ -0,0 +1,618 @@ +From cbcea73d911a840a420b9e0dbf5e0715d00533b0 Mon Sep 17 00:00:00 2001 +From: Ajay Kumar Gupta +Date: Fri, 11 Sep 2009 10:48:54 +0530 +Subject: [PATCH 16/16] usb: update defconfig + + - Enabled USB Audio/Video (UVC) + - Enabled RNDIS gadget builtin + - ENabled EHCI +--- + arch/arm/configs/omap3_evm_defconfig | 229 +++++++++++++++++++++++++--------- + 1 files changed, 171 insertions(+), 58 deletions(-) + +diff --git a/arch/arm/configs/omap3_evm_defconfig b/arch/arm/configs/omap3_evm_defconfig +index d5ff477..8a8b4b0 100644 +--- a/arch/arm/configs/omap3_evm_defconfig ++++ b/arch/arm/configs/omap3_evm_defconfig +@@ -9,7 +9,6 @@ CONFIG_GENERIC_GPIO=y + CONFIG_GENERIC_TIME=y + CONFIG_GENERIC_CLOCKEVENTS=y + CONFIG_MMU=y +-# CONFIG_NO_IOPORT is not set + CONFIG_GENERIC_HARDIRQS=y + CONFIG_STACKTRACE_SUPPORT=y + CONFIG_HAVE_LATENCYTOP_SUPPORT=y +@@ -18,13 +17,12 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y + CONFIG_HARDIRQS_SW_RESEND=y + CONFIG_GENERIC_IRQ_PROBE=y + CONFIG_RWSEM_GENERIC_SPINLOCK=y +-# CONFIG_ARCH_HAS_ILOG2_U32 is not set +-# CONFIG_ARCH_HAS_ILOG2_U64 is not set + CONFIG_GENERIC_HWEIGHT=y + CONFIG_GENERIC_CALIBRATE_DELAY=y + CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y + CONFIG_VECTORS_BASE=0xffff0000 + CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++CONFIG_CONSTRUCTORS=y + + # + # General setup +@@ -77,7 +75,6 @@ CONFIG_UID16=y + CONFIG_KALLSYMS=y + # CONFIG_KALLSYMS_ALL is not set + CONFIG_KALLSYMS_EXTRA_PASS=y +-# CONFIG_STRIP_ASM_SYMS is not set + CONFIG_HOTPLUG=y + CONFIG_PRINTK=y + CONFIG_BUG=y +@@ -90,7 +87,12 @@ CONFIG_TIMERFD=y + CONFIG_EVENTFD=y + CONFIG_SHMEM=y + CONFIG_AIO=y ++ ++# ++# Performance Counters ++# + CONFIG_VM_EVENT_COUNTERS=y ++# CONFIG_STRIP_ASM_SYMS is not set + CONFIG_COMPAT_BRK=y + CONFIG_SLAB=y + # CONFIG_SLUB is not set +@@ -102,6 +104,10 @@ CONFIG_HAVE_OPROFILE=y + CONFIG_HAVE_KPROBES=y + CONFIG_HAVE_KRETPROBES=y + CONFIG_HAVE_CLK=y ++ ++# ++# GCOV-based kernel profiling ++# + # CONFIG_SLOW_WORK is not set + CONFIG_HAVE_GENERIC_DMA_COHERENT=y + CONFIG_SLABINFO=y +@@ -114,7 +120,7 @@ CONFIG_MODULE_UNLOAD=y + CONFIG_MODVERSIONS=y + CONFIG_MODULE_SRCVERSION_ALL=y + CONFIG_BLOCK=y +-# CONFIG_LBD is not set ++CONFIG_LBDAF=y + # CONFIG_BLK_DEV_BSG is not set + # CONFIG_BLK_DEV_INTEGRITY is not set + +@@ -141,13 +147,14 @@ CONFIG_FREEZER=y + # CONFIG_ARCH_VERSATILE is not set + # CONFIG_ARCH_AT91 is not set + # CONFIG_ARCH_CLPS711X is not set ++# CONFIG_ARCH_GEMINI is not set + # CONFIG_ARCH_EBSA110 is not set + # CONFIG_ARCH_EP93XX is not set +-# CONFIG_ARCH_GEMINI is not set + # CONFIG_ARCH_FOOTBRIDGE is not set ++# CONFIG_ARCH_MXC is not set ++# CONFIG_ARCH_STMP3XXX is not set + # CONFIG_ARCH_NETX is not set + # CONFIG_ARCH_H720X is not set +-# CONFIG_ARCH_IMX is not set + # CONFIG_ARCH_IOP13XX is not set + # CONFIG_ARCH_IOP32X is not set + # CONFIG_ARCH_IOP33X is not set +@@ -156,25 +163,25 @@ CONFIG_FREEZER=y + # CONFIG_ARCH_IXP4XX is not set + # CONFIG_ARCH_L7200 is not set + # CONFIG_ARCH_KIRKWOOD is not set +-# CONFIG_ARCH_KS8695 is not set +-# CONFIG_ARCH_NS9XXX is not set + # CONFIG_ARCH_LOKI is not set + # CONFIG_ARCH_MV78XX0 is not set +-# CONFIG_ARCH_MXC is not set + # CONFIG_ARCH_ORION5X is not set ++# CONFIG_ARCH_MMP is not set ++# CONFIG_ARCH_KS8695 is not set ++# CONFIG_ARCH_NS9XXX is not set ++# CONFIG_ARCH_W90X900 is not set + # CONFIG_ARCH_PNX4008 is not set + # CONFIG_ARCH_PXA is not set +-# CONFIG_ARCH_MMP is not set ++# CONFIG_ARCH_MSM is not set + # CONFIG_ARCH_RPC is not set + # CONFIG_ARCH_SA1100 is not set + # CONFIG_ARCH_S3C2410 is not set + # CONFIG_ARCH_S3C64XX is not set + # CONFIG_ARCH_SHARK is not set + # CONFIG_ARCH_LH7A40X is not set ++# CONFIG_ARCH_U300 is not set + # CONFIG_ARCH_DAVINCI is not set + CONFIG_ARCH_OMAP=y +-# CONFIG_ARCH_MSM is not set +-# CONFIG_ARCH_W90X900 is not set + + # + # TI OMAP Implementations +@@ -183,6 +190,7 @@ CONFIG_ARCH_OMAP_OTG=y + # CONFIG_ARCH_OMAP1 is not set + # CONFIG_ARCH_OMAP2 is not set + CONFIG_ARCH_OMAP3=y ++# CONFIG_ARCH_OMAP4 is not set + + # + # OMAP Feature Selections +@@ -202,7 +210,8 @@ CONFIG_OMAP_DM_TIMER=y + CONFIG_OMAP_LL_DEBUG_UART1=y + # CONFIG_OMAP_LL_DEBUG_UART2 is not set + # CONFIG_OMAP_LL_DEBUG_UART3 is not set +-CONFIG_OMAP_SERIAL_WAKE=y ++# CONFIG_OMAP_PM_NONE is not set ++CONFIG_OMAP_PM_NOOP=y + CONFIG_ARCH_OMAP34XX=y + CONFIG_ARCH_OMAP3430=y + +@@ -216,6 +225,7 @@ CONFIG_MACH_OMAP3EVM=y + # CONFIG_MACH_OMAP3_PANDORA is not set + # CONFIG_MACH_OMAP_3430SDP is not set + # CONFIG_MACH_NOKIA_RX51 is not set ++# CONFIG_MACH_OMAP_ZOOM2 is not set + + # + # Processor Type +@@ -243,7 +253,6 @@ CONFIG_ARM_THUMB=y + # CONFIG_CPU_DCACHE_DISABLE is not set + # CONFIG_CPU_BPREDICT_DISABLE is not set + CONFIG_HAS_TLS_REG=y +-# CONFIG_OUTER_CACHE is not set + # CONFIG_ARM_ERRATA_430973 is not set + # CONFIG_ARM_ERRATA_458693 is not set + # CONFIG_ARM_ERRATA_460075 is not set +@@ -271,7 +280,6 @@ CONFIG_PAGE_OFFSET=0xC0000000 + CONFIG_HZ=128 + CONFIG_AEABI=y + CONFIG_OABI_COMPAT=y +-CONFIG_ARCH_FLATMEM_HAS_HOLES=y + # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set + # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set + # CONFIG_HIGHMEM is not set +@@ -286,11 +294,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 + # CONFIG_PHYS_ADDR_T_64BIT is not set + CONFIG_ZONE_DMA_FLAG=0 + CONFIG_VIRT_TO_BUS=y +-CONFIG_UNEVICTABLE_LRU=y + CONFIG_HAVE_MLOCK=y + CONFIG_HAVE_MLOCKED_PAGE_BIT=y ++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 + # CONFIG_LEDS is not set + CONFIG_ALIGNMENT_TRAP=y ++# CONFIG_UACCESS_WITH_MEMCPY is not set + + # + # Boot options +@@ -401,6 +410,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" + # CONFIG_ECONET is not set + # CONFIG_WAN_ROUTER is not set + # CONFIG_PHONET is not set ++# CONFIG_IEEE802154 is not set + # CONFIG_NET_SCHED is not set + # CONFIG_DCB is not set + +@@ -418,7 +428,11 @@ CONFIG_WIRELESS=y + # CONFIG_WIRELESS_OLD_REGULATORY is not set + # CONFIG_WIRELESS_EXT is not set + # CONFIG_LIB80211 is not set +-# CONFIG_MAC80211 is not set ++ ++# ++# CFG80211 needs to be enabled for MAC80211 ++# ++CONFIG_MAC80211_DEFAULT_PS_VALUE=0 + # CONFIG_WIMAX is not set + # CONFIG_RFKILL is not set + # CONFIG_NET_9P is not set +@@ -516,6 +530,7 @@ CONFIG_MTD_NAND=y + # CONFIG_MTD_NAND_ECC_SMC is not set + # CONFIG_MTD_NAND_MUSEUM_IDS is not set + # CONFIG_MTD_NAND_GPIO is not set ++# CONFIG_MTD_NAND_OMAP2 is not set + CONFIG_MTD_NAND_IDS=y + # CONFIG_MTD_NAND_DISKONCHIP is not set + # CONFIG_MTD_NAND_NANDSIM is not set +@@ -551,6 +566,7 @@ CONFIG_BLK_DEV_RAM_SIZE=16384 + # CONFIG_BLK_DEV_XIP is not set + # CONFIG_CDROM_PKTCDVD is not set + # CONFIG_ATA_OVER_ETH is not set ++# CONFIG_MG_DISK is not set + # CONFIG_MISC_DEVICES is not set + CONFIG_HAVE_IDE=y + # CONFIG_IDE is not set +@@ -574,10 +590,6 @@ CONFIG_BLK_DEV_SD=y + # CONFIG_BLK_DEV_SR is not set + # CONFIG_CHR_DEV_SG is not set + # CONFIG_CHR_DEV_SCH is not set +- +-# +-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +-# + # CONFIG_SCSI_MULTI_LUN is not set + # CONFIG_SCSI_CONSTANTS is not set + # CONFIG_SCSI_LOGGING is not set +@@ -602,7 +614,6 @@ CONFIG_SCSI_LOWLEVEL=y + # CONFIG_ATA is not set + # CONFIG_MD is not set + CONFIG_NETDEVICES=y +-CONFIG_COMPAT_NET_DEV_OPS=y + # CONFIG_DUMMY is not set + # CONFIG_BONDING is not set + # CONFIG_MACVLAN is not set +@@ -628,6 +639,8 @@ CONFIG_SMC911X=y + # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set + # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set + # CONFIG_B44 is not set ++# CONFIG_KS8842 is not set ++# CONFIG_KS8851 is not set + # CONFIG_NETDEV_1000 is not set + # CONFIG_NETDEV_10000 is not set + +@@ -677,12 +690,13 @@ CONFIG_INPUT_EVDEV=y + # + CONFIG_INPUT_KEYBOARD=y + # CONFIG_KEYBOARD_ATKBD is not set +-# CONFIG_KEYBOARD_SUNKBD is not set + # CONFIG_KEYBOARD_LKKBD is not set +-# CONFIG_KEYBOARD_XTKBD is not set ++# CONFIG_KEYBOARD_GPIO is not set ++# CONFIG_KEYBOARD_MATRIX is not set + # CONFIG_KEYBOARD_NEWTON is not set + # CONFIG_KEYBOARD_STOWAWAY is not set +-# CONFIG_KEYBOARD_GPIO is not set ++# CONFIG_KEYBOARD_SUNKBD is not set ++# CONFIG_KEYBOARD_XTKBD is not set + # CONFIG_INPUT_MOUSE is not set + # CONFIG_INPUT_JOYSTICK is not set + # CONFIG_INPUT_TABLET is not set +@@ -692,6 +706,7 @@ CONFIG_TOUCHSCREEN_ADS7846=y + # CONFIG_TOUCHSCREEN_AD7879_I2C is not set + # CONFIG_TOUCHSCREEN_AD7879_SPI is not set + # CONFIG_TOUCHSCREEN_AD7879 is not set ++# CONFIG_TOUCHSCREEN_EETI is not set + # CONFIG_TOUCHSCREEN_FUJITSU is not set + # CONFIG_TOUCHSCREEN_GUNZE is not set + # CONFIG_TOUCHSCREEN_ELO is not set +@@ -705,6 +720,7 @@ CONFIG_TOUCHSCREEN_ADS7846=y + # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set + # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set + # CONFIG_TOUCHSCREEN_TSC2007 is not set ++# CONFIG_TOUCHSCREEN_W90X900 is not set + # CONFIG_INPUT_MISC is not set + + # +@@ -764,6 +780,7 @@ CONFIG_I2C_HELPER_AUTO=y + # + # I2C system bus drivers (mostly embedded / system-on-chip) + # ++# CONFIG_I2C_DESIGNWARE is not set + # CONFIG_I2C_GPIO is not set + # CONFIG_I2C_OCORES is not set + CONFIG_I2C_OMAP=y +@@ -789,7 +806,6 @@ CONFIG_I2C_OMAP=y + # CONFIG_SENSORS_PCF8574 is not set + # CONFIG_PCF8575 is not set + # CONFIG_SENSORS_PCA9539 is not set +-# CONFIG_SENSORS_MAX6875 is not set + # CONFIG_SENSORS_TSL2550 is not set + # CONFIG_I2C_DEBUG_CORE is not set + # CONFIG_I2C_DEBUG_ALGO is not set +@@ -850,6 +866,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y + # + # CONFIG_SOFT_WATCHDOG is not set + CONFIG_OMAP_WATCHDOG=y ++# CONFIG_TWL4030_WATCHDOG is not set + + # + # USB-based Watchdog Cards +@@ -880,23 +897,74 @@ CONFIG_TWL4030_CORE=y + # CONFIG_MFD_WM8400 is not set + # CONFIG_MFD_WM8350_I2C is not set + # CONFIG_MFD_PCF50633 is not set +- +-# +-# Multimedia devices +-# ++# CONFIG_AB3100_CORE is not set ++# CONFIG_EZX_PCAP is not set ++CONFIG_MEDIA_SUPPORT=y + + # + # Multimedia core support + # +-# CONFIG_VIDEO_DEV is not set ++CONFIG_VIDEO_DEV=y ++CONFIG_VIDEO_V4L2_COMMON=y ++CONFIG_VIDEO_ALLOW_V4L1=y ++CONFIG_VIDEO_V4L1_COMPAT=y + # CONFIG_DVB_CORE is not set +-# CONFIG_VIDEO_MEDIA is not set ++CONFIG_VIDEO_MEDIA=y + + # + # Multimedia drivers + # +-CONFIG_DAB=y +-# CONFIG_USB_DABUSB is not set ++# CONFIG_MEDIA_ATTACH is not set ++CONFIG_MEDIA_TUNER=y ++# CONFIG_MEDIA_TUNER_CUSTOMISE is not set ++CONFIG_MEDIA_TUNER_SIMPLE=y ++CONFIG_MEDIA_TUNER_TDA8290=y ++CONFIG_MEDIA_TUNER_TDA9887=y ++CONFIG_MEDIA_TUNER_TEA5761=y ++CONFIG_MEDIA_TUNER_TEA5767=y ++CONFIG_MEDIA_TUNER_MT20XX=y ++CONFIG_MEDIA_TUNER_XC2028=y ++CONFIG_MEDIA_TUNER_XC5000=y ++CONFIG_MEDIA_TUNER_MC44S803=y ++CONFIG_VIDEO_V4L2=y ++CONFIG_VIDEO_V4L1=y ++CONFIG_VIDEO_CAPTURE_DRIVERS=y ++# CONFIG_VIDEO_ADV_DEBUG is not set ++# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set ++CONFIG_VIDEO_HELPER_CHIPS_AUTO=y ++# CONFIG_VIDEO_VIVI is not set ++# CONFIG_VIDEO_CPIA is not set ++# CONFIG_VIDEO_CPIA2 is not set ++# CONFIG_VIDEO_SAA5246A is not set ++# CONFIG_VIDEO_SAA5249 is not set ++# CONFIG_SOC_CAMERA is not set ++CONFIG_V4L_USB_DRIVERS=y ++CONFIG_USB_VIDEO_CLASS=y ++CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y ++# CONFIG_USB_GSPCA is not set ++# CONFIG_VIDEO_PVRUSB2 is not set ++# CONFIG_VIDEO_HDPVR is not set ++# CONFIG_VIDEO_EM28XX is not set ++# CONFIG_VIDEO_CX231XX is not set ++# CONFIG_VIDEO_USBVISION is not set ++# CONFIG_USB_VICAM is not set ++# CONFIG_USB_IBMCAM is not set ++# CONFIG_USB_KONICAWC is not set ++# CONFIG_USB_QUICKCAM_MESSENGER is not set ++# CONFIG_USB_ET61X251 is not set ++# CONFIG_VIDEO_OVCAMCHIP is not set ++# CONFIG_USB_OV511 is not set ++# CONFIG_USB_SE401 is not set ++# CONFIG_USB_SN9C102 is not set ++# CONFIG_USB_STV680 is not set ++# CONFIG_USB_ZC0301 is not set ++# CONFIG_USB_PWC is not set ++# CONFIG_USB_PWC_INPUT_EVDEV is not set ++# CONFIG_USB_ZR364XX is not set ++# CONFIG_USB_STKWEBCAM is not set ++# CONFIG_USB_S2255 is not set ++# CONFIG_RADIO_ADAPTERS is not set ++# CONFIG_DAB is not set + + # + # Graphics support +@@ -916,7 +984,35 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m + # + # CONFIG_VGA_CONSOLE is not set + CONFIG_DUMMY_CONSOLE=y +-# CONFIG_SOUND is not set ++CONFIG_SOUND=y ++# CONFIG_SOUND_OSS_CORE is not set ++CONFIG_SND=y ++CONFIG_SND_TIMER=y ++CONFIG_SND_PCM=y ++CONFIG_SND_HWDEP=y ++CONFIG_SND_RAWMIDI=y ++# CONFIG_SND_SEQUENCER is not set ++# CONFIG_SND_MIXER_OSS is not set ++# CONFIG_SND_PCM_OSS is not set ++# CONFIG_SND_HRTIMER is not set ++# CONFIG_SND_DYNAMIC_MINORS is not set ++# CONFIG_SND_SUPPORT_OLD_API is not set ++# CONFIG_SND_VERBOSE_PROCFS is not set ++# CONFIG_SND_VERBOSE_PRINTK is not set ++# CONFIG_SND_DEBUG is not set ++# CONFIG_SND_RAWMIDI_SEQ is not set ++# CONFIG_SND_OPL3_LIB_SEQ is not set ++# CONFIG_SND_OPL4_LIB_SEQ is not set ++# CONFIG_SND_SBAWE_SEQ is not set ++# CONFIG_SND_EMU10K1_SEQ is not set ++# CONFIG_SND_DRIVERS is not set ++# CONFIG_SND_ARM is not set ++# CONFIG_SND_SPI is not set ++CONFIG_SND_USB=y ++CONFIG_SND_USB_AUDIO=y ++# CONFIG_SND_USB_CAIAQ is not set ++# CONFIG_SND_SOC is not set ++# CONFIG_SOUND_PRIME is not set + CONFIG_HID_SUPPORT=y + CONFIG_HID=y + # CONFIG_HID_DEBUG is not set +@@ -938,7 +1034,7 @@ CONFIG_USB_HID=y + # CONFIG_HID_CHERRY is not set + # CONFIG_HID_CHICONY is not set + # CONFIG_HID_CYPRESS is not set +-# CONFIG_DRAGONRISE_FF is not set ++# CONFIG_HID_DRAGONRISE is not set + # CONFIG_HID_EZKEY is not set + # CONFIG_HID_KYE is not set + # CONFIG_HID_GYRATION is not set +@@ -952,14 +1048,15 @@ CONFIG_USB_HID=y + # CONFIG_HID_SAMSUNG is not set + # CONFIG_HID_SONY is not set + # CONFIG_HID_SUNPLUS is not set +-# CONFIG_GREENASIA_FF is not set ++# CONFIG_HID_GREENASIA is not set ++# CONFIG_HID_SMARTJOYPLUS is not set + # CONFIG_HID_TOPSEED is not set +-# CONFIG_THRUSTMASTER_FF is not set +-# CONFIG_ZEROPLUS_FF is not set ++# CONFIG_HID_THRUSTMASTER is not set ++# CONFIG_HID_ZEROPLUS is not set + CONFIG_USB_SUPPORT=y + CONFIG_USB_ARCH_HAS_HCD=y + CONFIG_USB_ARCH_HAS_OHCI=y +-# CONFIG_USB_ARCH_HAS_EHCI is not set ++CONFIG_USB_ARCH_HAS_EHCI=y + CONFIG_USB=y + # CONFIG_USB_DEBUG is not set + CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +@@ -974,7 +1071,7 @@ CONFIG_USB_SUSPEND=y + CONFIG_USB_OTG=y + # CONFIG_USB_OTG_WHITELIST is not set + # CONFIG_USB_OTG_BLACKLIST_HUB is not set +-CONFIG_USB_MON=y ++# CONFIG_USB_MON is not set + # CONFIG_USB_WUSB is not set + # CONFIG_USB_WUSB_CBAF is not set + +@@ -982,6 +1079,9 @@ CONFIG_USB_MON=y + # USB Host Controller Drivers + # + # CONFIG_USB_C67X00_HCD is not set ++CONFIG_USB_EHCI_HCD=y ++# CONFIG_USB_EHCI_ROOT_HUB_TT is not set ++# CONFIG_USB_EHCI_TT_NEWSCHED is not set + # CONFIG_USB_OXU210HP_HCD is not set + # CONFIG_USB_ISP116X_HCD is not set + # CONFIG_USB_ISP1760_HCD is not set +@@ -1003,7 +1103,7 @@ CONFIG_USB_MUSB_HDRC_HCD=y + # CONFIG_MUSB_PIO_ONLY is not set + CONFIG_USB_INVENTRA_DMA=y + # CONFIG_USB_TI_CPPI_DMA is not set +-# CONFIG_USB_MUSB_DEBUG is not set ++CONFIG_USB_MUSB_DEBUG=y + + # + # USB Device Class drivers +@@ -1063,10 +1163,11 @@ CONFIG_USB_STORAGE=y + # CONFIG_USB_IDMOUSE is not set + # CONFIG_USB_FTDI_ELAN is not set + # CONFIG_USB_APPLEDISPLAY is not set ++# CONFIG_USB_SISUSBVGA is not set + # CONFIG_USB_LD is not set + # CONFIG_USB_TRANCEVIBRATOR is not set + # CONFIG_USB_IOWARRIOR is not set +-CONFIG_USB_TEST=y ++# CONFIG_USB_TEST is not set + # CONFIG_USB_ISIGHTFW is not set + # CONFIG_USB_VST is not set + CONFIG_USB_GADGET=y +@@ -1081,19 +1182,22 @@ CONFIG_USB_GADGET_SELECTED=y + # CONFIG_USB_GADGET_OMAP is not set + # CONFIG_USB_GADGET_PXA25X is not set + # CONFIG_USB_GADGET_PXA27X is not set +-# CONFIG_USB_GADGET_S3C2410 is not set ++# CONFIG_USB_GADGET_S3C_HSOTG is not set + # CONFIG_USB_GADGET_IMX is not set ++# CONFIG_USB_GADGET_S3C2410 is not set + # CONFIG_USB_GADGET_M66592 is not set + # CONFIG_USB_GADGET_AMD5536UDC is not set + # CONFIG_USB_GADGET_FSL_QE is not set + # CONFIG_USB_GADGET_CI13XXX is not set + # CONFIG_USB_GADGET_NET2280 is not set + # CONFIG_USB_GADGET_GOKU is not set ++# CONFIG_USB_GADGET_LANGWELL is not set + # CONFIG_USB_GADGET_DUMMY_HCD is not set + CONFIG_USB_GADGET_DUALSPEED=y +-CONFIG_USB_ZERO=m +-# CONFIG_USB_ZERO_HNPTEST is not set +-# CONFIG_USB_ETH is not set ++# CONFIG_USB_ZERO is not set ++# CONFIG_USB_AUDIO is not set ++CONFIG_USB_ETH=y ++CONFIG_USB_ETH_RNDIS=y + # CONFIG_USB_GADGETFS is not set + # CONFIG_USB_FILE_STORAGE is not set + # CONFIG_USB_G_SERIAL is not set +@@ -1108,7 +1212,7 @@ CONFIG_USB_OTG_UTILS=y + # CONFIG_USB_GPIO_VBUS is not set + # CONFIG_ISP1301_OMAP is not set + # CONFIG_TWL4030_USB is not set +-# CONFIG_NOP_USB_XCEIV is not set ++CONFIG_NOP_USB_XCEIV=y + CONFIG_MMC=y + # CONFIG_MMC_DEBUG is not set + # CONFIG_MMC_UNSAFE_RESUME is not set +@@ -1125,7 +1229,6 @@ CONFIG_MMC_BLOCK_BOUNCE=y + # MMC/SD/SDIO Host Controller Drivers + # + # CONFIG_MMC_SDHCI is not set +-# CONFIG_MMC_OMAP is not set + CONFIG_MMC_OMAP_HS=m + # CONFIG_MMC_SPI is not set + # CONFIG_MEMSTICK is not set +@@ -1139,12 +1242,20 @@ CONFIG_REGULATOR=y + # CONFIG_REGULATOR_DEBUG is not set + # CONFIG_REGULATOR_FIXED_VOLTAGE is not set + # CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set ++# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set + # CONFIG_REGULATOR_BQ24022 is not set ++# CONFIG_REGULATOR_MAX1586 is not set + CONFIG_REGULATOR_TWL4030=y ++# CONFIG_REGULATOR_LP3971 is not set + # CONFIG_UIO is not set + # CONFIG_STAGING is not set + + # ++# CBUS support ++# ++# CONFIG_CBUS is not set ++ ++# + # File systems + # + CONFIG_EXT2_FS=y +@@ -1158,10 +1269,12 @@ CONFIG_JBD=y + # CONFIG_REISERFS_FS is not set + # CONFIG_JFS_FS is not set + # CONFIG_FS_POSIX_ACL is not set +-CONFIG_FILE_LOCKING=y + # CONFIG_XFS_FS is not set ++# CONFIG_GFS2_FS is not set + # CONFIG_OCFS2_FS is not set + # CONFIG_BTRFS_FS is not set ++CONFIG_FILE_LOCKING=y ++CONFIG_FSNOTIFY=y + CONFIG_DNOTIFY=y + CONFIG_INOTIFY=y + CONFIG_INOTIFY_USER=y +@@ -1247,6 +1360,7 @@ CONFIG_NFS_FS=y + CONFIG_NFS_V3=y + # CONFIG_NFS_V3_ACL is not set + CONFIG_NFS_V4=y ++# CONFIG_NFS_V4_1 is not set + CONFIG_ROOT_NFS=y + # CONFIG_NFSD is not set + CONFIG_LOCKD=y +@@ -1349,6 +1463,7 @@ CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 + # CONFIG_TIMER_STATS is not set + # CONFIG_DEBUG_OBJECTS is not set + # CONFIG_DEBUG_SLAB is not set ++# CONFIG_DEBUG_KMEMLEAK is not set + # CONFIG_DEBUG_RT_MUTEXES is not set + # CONFIG_RT_MUTEX_TESTER is not set + # CONFIG_DEBUG_SPINLOCK is not set +@@ -1377,17 +1492,15 @@ CONFIG_DEBUG_INFO=y + # CONFIG_PAGE_POISONING is not set + CONFIG_HAVE_FUNCTION_TRACER=y + CONFIG_TRACING_SUPPORT=y +- +-# +-# Tracers +-# ++CONFIG_FTRACE=y + # CONFIG_FUNCTION_TRACER is not set + # CONFIG_IRQSOFF_TRACER is not set + # CONFIG_SCHED_TRACER is not set +-# CONFIG_CONTEXT_SWITCH_TRACER is not set +-# CONFIG_EVENT_TRACER is not set ++# CONFIG_ENABLE_DEFAULT_TRACERS is not set + # CONFIG_BOOT_TRACER is not set +-# CONFIG_TRACE_BRANCH_PROFILING is not set ++CONFIG_BRANCH_PROFILE_NONE=y ++# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set ++# CONFIG_PROFILE_ALL_BRANCHES is not set + # CONFIG_STACK_TRACER is not set + # CONFIG_KMEMTRACE is not set + # CONFIG_WORKQUEUE_TRACER is not set +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap_2.6.31.bb b/recipes/linux/linux-omap_2.6.31.bb index b2387fc6e7..70bd906f55 100644 --- a/recipes/linux/linux-omap_2.6.31.bb +++ b/recipes/linux/linux-omap_2.6.31.bb @@ -18,7 +18,6 @@ SRC_URI = "git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.g file://defconfig" SRC_URI_append = " \ - file://ehci-phy-reset.patch;patch=1 \ file://ehci.patch;patch=1 \ file://0001-implement-TIF_RESTORE_SIGMASK-support-and-enable-the.patch;patch=1 \ file://cache/l1cache-shift.patch;patch=1 \ @@ -48,6 +47,22 @@ SRC_URI_append = " \ file://madc/madc-driver.patch;patch=1 \ file://madc/madc.patch;patch=1 \ file://arch-has-holes.diff;patch=1 \ + file://usb/0001-musb-fix-put_device-call-sequence.patch;patch=1 \ + file://usb/0002-ehci-fix-ehci-pin-mux-init.patch;patch=1 \ + file://usb/0003-ehci-adding-mux-pin-for-EHCI-phy-reset-line.patch;patch=1 \ + file://usb/0004-ehci-correct-EHCI-init-parameters-on-OMAP3EVM.patch;patch=1 \ + file://usb/0005-ehci-fix-phy_reset-init-in-ehci-probe.patch;patch=1 \ + file://usb/0006-ehci-increase-timeout-to-fix-ehci-failure.patch;patch=1 \ + file://usb/0007-ehci-portwise-configurations.patch;patch=1 \ + file://usb/0008-omap3-Add-CHIP_GE_OMAP3430ES3-for-HSUSB.patch;patch=1 \ + file://usb/0009-ehci-Support-for-ES3.x.patch;patch=1 \ + file://usb/0010-ehci-update-driver-with-generic-change.patch;patch=1 \ + file://usb/0011-musb-fix-musb-gadget_driver-NULL-bug.patch;patch=1 \ + file://usb/0012-musb-Add-back-old-musb-procfs-file.patch;patch=1 \ + file://usb/0013-musb-Remove-USB_SUSPEND-auto-select-with-OTG.patch;patch=1 \ + file://usb/0014-musb-disable-PING-on-status-phase-of-control-transf.patch;patch=1 \ + file://usb/0015-musb-Add-context-save-and-restore-support.patch;patch=1 \ + file://usb/0016-usb-update-defconfig.patch;patch=1 \ " SRC_URI_append_beagleboard = " file://logo_linux_clut224.ppm \ -- cgit v1.2.3 From fd8af199bbe9c164e5f5a462636d973efeb2e80e Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 17 Sep 2009 19:01:41 +0200 Subject: linux-omap 2.6.31: add some more display fixes --- .../linux/linux-omap-2.6.31/beagleboard/defconfig | 21 +- .../dss2/beagle-dss2-support.patch | 326 +++++++++++++++++++++ recipes/linux/linux-omap-2.6.31/fix-omapfb.patch | 137 +++++++++ recipes/linux/linux-omap-2.6.31/modedb-hd720.patch | 13 + recipes/linux/linux-omap_2.6.31.bb | 3 + 5 files changed, 490 insertions(+), 10 deletions(-) create mode 100644 recipes/linux/linux-omap-2.6.31/dss2/beagle-dss2-support.patch create mode 100644 recipes/linux/linux-omap-2.6.31/fix-omapfb.patch create mode 100644 recipes/linux/linux-omap-2.6.31/modedb-hd720.patch diff --git a/recipes/linux/linux-omap-2.6.31/beagleboard/defconfig b/recipes/linux/linux-omap-2.6.31/beagleboard/defconfig index 629148b783..efe8e6d8dd 100644 --- a/recipes/linux/linux-omap-2.6.31/beagleboard/defconfig +++ b/recipes/linux/linux-omap-2.6.31/beagleboard/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31-rc8-omap1 -# Fri Sep 4 15:16:17 2009 +# Linux kernel version: 2.6.31-omap1 +# Thu Sep 17 17:27:43 2009 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -216,6 +216,8 @@ CONFIG_OMAP_DM_TIMER=y # CONFIG_OMAP_LL_DEBUG_UART1 is not set # CONFIG_OMAP_LL_DEBUG_UART2 is not set CONFIG_OMAP_LL_DEBUG_UART3=y +# CONFIG_OMAP_PM_NONE is not set +CONFIG_OMAP_PM_NOOP=y CONFIG_ARCH_OMAP34XX=y CONFIG_ARCH_OMAP3430=y @@ -224,7 +226,7 @@ CONFIG_ARCH_OMAP3430=y # CONFIG_MACH_OMAP3_BEAGLE=y # CONFIG_MACH_OMAP_LDP is not set -CONFIG_MACH_OVERO=n +# CONFIG_MACH_OVERO is not set CONFIG_MACH_OMAP3EVM=y # CONFIG_MACH_OMAP3_PANDORA is not set # CONFIG_MACH_OMAP_3430SDP is not set @@ -285,6 +287,7 @@ CONFIG_PREEMPT=y CONFIG_HZ=128 CONFIG_AEABI=y # CONFIG_OABI_COMPAT is not set +CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set # CONFIG_HIGHMEM is not set @@ -1686,8 +1689,7 @@ CONFIG_DVB_USB_ANYSEE=m CONFIG_DVB_USB_DTV5100=m CONFIG_DVB_USB_AF9015=m # CONFIG_DVB_USB_CE6230 is not set -CONFIG_DVB_SIANO_SMS1XXX=m -CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS=y +# CONFIG_SMS_SIANO_MDTV is not set # # Supported FlexCopII (B2C2) Adapters @@ -1760,7 +1762,7 @@ CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set +CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_TILEBLITTING is not set # @@ -1793,8 +1795,8 @@ CONFIG_FB_OMAP2_NUM_FBS=3 # OMAP2/3 Display Device Drivers # CONFIG_PANEL_GENERIC=y -CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C=m -CONFIG_PANEL_SHARP_LS037V7DW01=m +CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C=y +CONFIG_PANEL_SHARP_LS037V7DW01=y # CONFIG_PANEL_TAAL is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set @@ -1864,7 +1866,6 @@ CONFIG_SND_USB_CAIAQ_INPUT=y CONFIG_SND_SOC=y CONFIG_SND_OMAP_SOC=y CONFIG_SND_OMAP_SOC_MCBSP=y -# CONFIG_SND_OMAP_SOC_OVERO is not set # CONFIG_SND_OMAP_SOC_OMAP3EVM is not set CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE=y CONFIG_SND_SOC_I2C_AND_SPI=y @@ -2563,7 +2564,7 @@ CONFIG_NLS_ISO8859_8=m CONFIG_NLS_CODEPAGE_1250=m CONFIG_NLS_CODEPAGE_1251=m CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_1=y CONFIG_NLS_ISO8859_2=m CONFIG_NLS_ISO8859_3=m CONFIG_NLS_ISO8859_4=m diff --git a/recipes/linux/linux-omap-2.6.31/dss2/beagle-dss2-support.patch b/recipes/linux/linux-omap-2.6.31/dss2/beagle-dss2-support.patch new file mode 100644 index 0000000000..53f921e087 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/dss2/beagle-dss2-support.patch @@ -0,0 +1,326 @@ +--- /tmp/board-omap3beagle.c 2009-09-17 17:44:58.000000000 +0200 ++++ git/arch/arm/mach-omap2/board-omap3beagle.c 2009-09-17 18:48:57.000000000 +0200 +@@ -31,6 +31,7 @@ + + #include + #include ++#include + + #include + #include +@@ -45,6 +46,7 @@ + #include + #include + #include ++#include + + #include "mmc-twl4030.h" + +@@ -169,15 +171,6 @@ + {} /* Terminator */ + }; + +-static struct platform_device omap3_beagle_lcd_device = { +- .name = "omap3beagle_lcd", +- .id = -1, +-}; +- +-static struct omap_lcd_config omap3_beagle_lcd_config __initdata = { +- .ctrl_name = "internal", +-}; +- + static struct regulator_consumer_supply beagle_vmmc1_supply = { + .supply = "vmmc", + }; +@@ -228,16 +221,6 @@ + .setup = beagle_twl_gpio_setup, + }; + +-static struct regulator_consumer_supply beagle_vdac_supply = { +- .supply = "vdac", +- .dev = &omap3_beagle_lcd_device.dev, +-}; +- +-static struct regulator_consumer_supply beagle_vdvi_supply = { +- .supply = "vdvi", +- .dev = &omap3_beagle_lcd_device.dev, +-}; +- + /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ + static struct regulator_init_data beagle_vmmc1 = { + .constraints = { +@@ -268,61 +251,10 @@ + .consumer_supplies = &beagle_vsim_supply, + }; + +-/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */ +-static struct regulator_init_data beagle_vdac = { +- .constraints = { +- .min_uV = 1800000, +- .max_uV = 1800000, +- .valid_modes_mask = REGULATOR_MODE_NORMAL +- | REGULATOR_MODE_STANDBY, +- .valid_ops_mask = REGULATOR_CHANGE_MODE +- | REGULATOR_CHANGE_STATUS, +- }, +- .num_consumer_supplies = 1, +- .consumer_supplies = &beagle_vdac_supply, +-}; +- +-/* VPLL2 for digital video outputs */ +-static struct regulator_init_data beagle_vpll2 = { +- .constraints = { +- .name = "VDVI", +- .min_uV = 1800000, +- .max_uV = 1800000, +- .valid_modes_mask = REGULATOR_MODE_NORMAL +- | REGULATOR_MODE_STANDBY, +- .valid_ops_mask = REGULATOR_CHANGE_MODE +- | REGULATOR_CHANGE_STATUS, +- }, +- .num_consumer_supplies = 1, +- .consumer_supplies = &beagle_vdvi_supply, +-}; +- + static struct twl4030_usb_data beagle_usb_data = { + .usb_mode = T2_USB_MODE_ULPI, + }; + +-static struct twl4030_platform_data beagle_twldata = { +- .irq_base = TWL4030_IRQ_BASE, +- .irq_end = TWL4030_IRQ_END, +- +- /* platform_data for children goes here */ +- .usb = &beagle_usb_data, +- .gpio = &beagle_gpio_data, +- .vmmc1 = &beagle_vmmc1, +- .vsim = &beagle_vsim, +- .vdac = &beagle_vdac, +- .vpll2 = &beagle_vpll2, +-}; +- +-static struct i2c_board_info __initdata beagle_i2c1_boardinfo[] = { +- { +- I2C_BOARD_INFO("twl4030", 0x48), +- .flags = I2C_CLIENT_WAKE, +- .irq = INT_34XX_SYS_NIRQ, +- .platform_data = &beagle_twldata, +- }, +-}; +- + #if defined(CONFIG_RTC_DRV_DS1307) || \ + defined(CONFIG_RTC_DRV_DS1307_MODULE) + +@@ -335,18 +267,6 @@ + static struct i2c_board_info __initdata beagle_i2c2_boardinfo[] = {}; + #endif + +-static int __init omap3_beagle_i2c_init(void) +-{ +- omap_register_i2c_bus(1, 2600, beagle_i2c1_boardinfo, +- ARRAY_SIZE(beagle_i2c1_boardinfo)); +- omap_register_i2c_bus(2, 400, beagle_i2c2_boardinfo, +- ARRAY_SIZE(beagle_i2c2_boardinfo)); +- /* Bus 3 is attached to the DVI port where devices like the pico DLP +- * projector don't work reliably with 400kHz */ +- omap_register_i2c_bus(3, 100, NULL, 0); +- return 0; +-} +- + static struct gpio_led gpio_leds[] = { + { + .name = "beagleboard::usr0", +@@ -400,14 +320,158 @@ + }, + }; + +-static struct omap_board_config_kernel omap3_beagle_config[] __initdata = { +- { OMAP_TAG_LCD, &omap3_beagle_lcd_config }, ++/* DSS */ ++ ++static int beagle_enable_dvi(struct omap_dss_device *dssdev) ++{ ++ if (dssdev->reset_gpio != -1) ++ gpio_set_value(dssdev->reset_gpio, 1); ++ ++ return 0; ++} ++ ++static void beagle_disable_dvi(struct omap_dss_device *dssdev) ++{ ++ if (dssdev->reset_gpio != -1) ++ gpio_set_value(dssdev->reset_gpio, 0); ++} ++ ++static struct omap_dss_device beagle_dvi_device = { ++ .type = OMAP_DISPLAY_TYPE_DPI, ++ .name = "dvi", ++ .driver_name = "generic_panel", ++ .phy.dpi.data_lines = 24, ++ .reset_gpio = 170, ++ .platform_enable = beagle_enable_dvi, ++ .platform_disable = beagle_disable_dvi, + }; + ++static int beagle_panel_enable_tv(struct omap_dss_device *dssdev) ++{ ++ return 0; ++} ++ ++static void beagle_panel_disable_tv(struct omap_dss_device *dssdev) ++{ ++} ++ ++static struct omap_dss_device beagle_tv_device = { ++ .name = "tv", ++ .driver_name = "venc", ++ .type = OMAP_DISPLAY_TYPE_VENC, ++ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO, ++ .platform_enable = beagle_panel_enable_tv, ++ .platform_disable = beagle_panel_disable_tv, ++}; ++ ++static struct omap_dss_device *beagle_dss_devices[] = { ++ &beagle_dvi_device, ++ &beagle_tv_device, ++}; ++ ++static struct omap_dss_board_info beagle_dss_data = { ++ .num_devices = ARRAY_SIZE(beagle_dss_devices), ++ .devices = beagle_dss_devices, ++ .default_device = &beagle_dvi_device, ++}; ++ ++static struct platform_device beagle_dss_device = { ++ .name = "omapdss", ++ .id = -1, ++ .dev = { ++ .platform_data = &beagle_dss_data, ++ }, ++}; ++ ++static struct regulator_consumer_supply beagle_vdda_dac_supply = { ++ .supply = "vdda_dac", ++ .dev = &beagle_dss_device.dev, ++}; ++ ++static struct regulator_consumer_supply beagle_vdds_dsi_supply = { ++ .supply = "vdds_dsi", ++ .dev = &beagle_dss_device.dev, ++}; ++ ++static void __init beagle_display_init(void) ++{ ++ int r; ++ ++ r = gpio_request(beagle_dvi_device.reset_gpio, "DVI reset"); ++ if (r < 0) { ++ printk(KERN_ERR "Unable to get DVI reset GPIO\n"); ++ return; ++ } ++ ++ gpio_direction_output(beagle_dvi_device.reset_gpio, 0); ++} ++ ++/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */ ++static struct regulator_init_data beagle_vdac = { ++ .constraints = { ++ .min_uV = 1800000, ++ .max_uV = 1800000, ++ .apply_uV = true, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL ++ | REGULATOR_MODE_STANDBY, ++ .valid_ops_mask = REGULATOR_CHANGE_MODE ++ | REGULATOR_CHANGE_STATUS, ++ }, ++ .num_consumer_supplies = 1, ++ .consumer_supplies = &beagle_vdda_dac_supply, ++}; ++ ++/* VPLL2 for digital video outputs */ ++static struct regulator_init_data beagle_vpll2 = { ++ .constraints = { ++ .name = "VDVI", ++ .min_uV = 1800000, ++ .max_uV = 1800000, .valid_modes_mask = REGULATOR_MODE_NORMAL ++ | REGULATOR_MODE_STANDBY, ++ .valid_ops_mask = REGULATOR_CHANGE_MODE ++ | REGULATOR_CHANGE_STATUS, ++ }, ++ .num_consumer_supplies = 1, ++ .consumer_supplies = &beagle_vdds_dsi_supply, ++}; ++ ++static struct twl4030_platform_data beagle_twldata = { ++ .irq_base = TWL4030_IRQ_BASE, ++ .irq_end = TWL4030_IRQ_END, ++ ++ /* platform_data for children goes here */ ++ .usb = &beagle_usb_data, ++ .gpio = &beagle_gpio_data, ++ .vmmc1 = &beagle_vmmc1, ++ .vsim = &beagle_vsim, ++ .vdac = &beagle_vdac, ++ .vpll2 = &beagle_vpll2, ++}; ++ ++static struct i2c_board_info __initdata beagle_i2c1_boardinfo[] = { ++ { ++ I2C_BOARD_INFO("twl4030", 0x48), ++ .flags = I2C_CLIENT_WAKE, ++ .irq = INT_34XX_SYS_NIRQ, ++ .platform_data = &beagle_twldata, ++ }, ++}; ++ ++static int __init omap3_beagle_i2c_init(void) ++{ ++ omap_register_i2c_bus(1, 2600, beagle_i2c1_boardinfo, ++ ARRAY_SIZE(beagle_i2c1_boardinfo)); ++ omap_register_i2c_bus(2, 400, beagle_i2c2_boardinfo, ++ ARRAY_SIZE(beagle_i2c2_boardinfo)); ++ /* Bus 3 is attached to the DVI port where devices like the pico DLP ++ * projector don't work reliably with 400kHz */ ++ omap_register_i2c_bus(3, 100, NULL, 0); ++ return 0; ++} ++ ++ + static void __init omap3_beagle_init_irq(void) + { +- omap_board_config = omap3_beagle_config; +- omap_board_config_size = ARRAY_SIZE(omap3_beagle_config); + omap2_init_common_hw(mt46h32m32lf6_sdrc_params, + mt46h32m32lf6_sdrc_params); + omap_init_irq(); +@@ -418,7 +482,7 @@ + } + + static struct platform_device *omap3_beagle_devices[] __initdata = { +- &omap3_beagle_lcd_device, ++ &beagle_dss_device, + &leds_gpio, + &keys_gpio, + }; +@@ -480,11 +544,8 @@ + platform_add_devices(omap3_beagle_devices, + ARRAY_SIZE(omap3_beagle_devices)); + omap_serial_init(); +- ++ + omap_cfg_reg(J25_34XX_GPIO170); +- gpio_request(170, "DVI_nPD"); +- /* REVISIT leave DVI powered down until it's needed ... */ +- gpio_direction_output(170, true); + + omap3beagle_enc28j60_init(); + +@@ -492,6 +553,8 @@ + usb_ehci_init(&ehci_pdata); + omap3beagle_flash_init(); + ++ beagle_display_init(); ++ + /* Ensure SDRC pins are mux'd for self-refresh */ + omap_cfg_reg(H16_34XX_SDRC_CKE0); + omap_cfg_reg(H17_34XX_SDRC_CKE1); diff --git a/recipes/linux/linux-omap-2.6.31/fix-omapfb.patch b/recipes/linux/linux-omap-2.6.31/fix-omapfb.patch new file mode 100644 index 0000000000..6658bceb12 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/fix-omapfb.patch @@ -0,0 +1,137 @@ +From linux-omap-owner@vger.kernel.org Sat Sep 12 18:36:17 2009 +Received: from localhost + ([127.0.0.1] helo=dominion ident=koen) + by dominion.dominion.void with esmtp (Exim 4.69) + (envelope-from ) + id 1MmVaD-0005nl-6f + for koen@localhost; Sat, 12 Sep 2009 18:36:17 +0200 +Received: from xs.service.utwente.nl [130.89.5.250] + by dominion with POP3 (fetchmail-6.3.9-rc2) + for (single-drop); Sat, 12 Sep 2009 18:36:17 +0200 (CEST) +Received: from mail.service.utwente.nl ([130.89.5.254]) by exchange.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959); + Sat, 12 Sep 2009 18:34:31 +0200 +Received: from mx.utwente.nl ([130.89.2.13]) by mail.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959); + Sat, 12 Sep 2009 18:34:31 +0200 +Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) + by mx.utwente.nl (8.12.10/SuSE Linux 0.7) with ESMTP id n8CGYLR7001279 + for ; Sat, 12 Sep 2009 18:34:22 +0200 +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S1754253AbZILQeP (ORCPT ); + Sat, 12 Sep 2009 12:34:15 -0400 +Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754362AbZILQeP + (ORCPT ); + Sat, 12 Sep 2009 12:34:15 -0400 +Received: from fg-out-1718.google.com ([72.14.220.157]:62107 "EHLO + fg-out-1718.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S1754253AbZILQeO (ORCPT + ); Sat, 12 Sep 2009 12:34:14 -0400 +Received: by fg-out-1718.google.com with SMTP id 22so194962fge.1 + for ; Sat, 12 Sep 2009 09:34:17 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=gamma; + h=domainkey-signature:received:received:sender:from:to:cc:subject + :date:message-id:x-mailer; + bh=AAXJA19IlSONsCjIPh2mme+ulWCBhEJbyCxyyJZk4jY=; + b=CENOacQ7/T2g5eQKy8wvo7vClGTIOU0xNgsYWpcBl2GAwrVooMvJRMWImFJYSEaU9r + wZTrSIouwCoeC5J2yZII6kezDggm44Nj1eA8S+c9Hj/SSt6oU1Jqc9Ttvn7jS2SxC47i + 0QMLWTjaRyCHVy8jfQtObilIeTnBjDMU70FkE= +DomainKey-Signature: a=rsa-sha1; c=nofws; + d=gmail.com; s=gamma; + h=sender:from:to:cc:subject:date:message-id:x-mailer; + b=TVKZoERoRk1PULFXvIXEWvDKkUb/E37Cni4zLjE4PU+5bT/zGL4a+NSkifrRx5w3ku + X7DR9Zc5c1NIJ0mhR5kCk6fZ6Yjp1vwo6tmzvZB9Dcy6AxWumrzjBte2EdW1Lw1l1URf + /QDALV74V+WT4Etn+yPAlt6Zd7WbgVcqCSEc4= +Received: by 10.87.42.14 with SMTP id u14mr3277117fgj.28.1252773257105; + Sat, 12 Sep 2009 09:34:17 -0700 (PDT) +Received: from localhost ([95.87.222.103]) + by mx.google.com with ESMTPS id 4sm1764938fge.4.2009.09.12.09.34.12 + (version=TLSv1/SSLv3 cipher=RC4-MD5); + Sat, 12 Sep 2009 09:34:13 -0700 (PDT) +From: Sergio Aguirre +To: Imre Deak +Cc: linux-fbdev-devel@lists.sourceforge.net, linux-omap@vger.kernel.org, + Sergio Aguirre +Subject: [PATCH] omapfb: Reorder Register_framebuffer call +Date: Sat, 12 Sep 2009 19:34:09 +0300 +Message-Id: <1252773249-24444-1-git-send-email-saaguirre@ti.com> +X-Mailer: git-send-email 1.6.4.2 +Sender: linux-omap-owner@vger.kernel.org +Precedence: bulk +List-ID: +X-Mailing-List: linux-omap@vger.kernel.org +X-UTwente-MailScanner-Information: Scanned by MailScanner. Contact icts.servicedesk@utwente.nl for more information. +X-UTwente-MailScanner: Found to be clean +X-UTwente-MailScanner-From: linux-omap-owner@vger.kernel.org +X-Spam-Status: No +X-OriginalArrivalTime: 12 Sep 2009 16:34:31.0630 (UTC) FILETIME=[E7A3E6E0:01CA33C6] + +This fixes the issue in which mm_lock mutex was attempted to be +used without initializing previously. + +Thanks to the testers! + - OMAP3430 SDP (Anand Gadiyar) + - OMAP3530 EVM (Vaibhav Hiremath) + - LogicPD's OMAP boards (Peter Brada) + - Beagleboard Rev. C2 (Eric Witcher) + +Signed-off-by: Sergio Aguirre +Tested-by: Vaibhav Hiremath +Tested-by: Anand Gadiyar +Tested-by: Peter Barada +Tested-by: Eric Witcher +--- + drivers/video/omap/omapfb_main.c | 20 +++++++++++--------- + 1 files changed, 11 insertions(+), 9 deletions(-) + +diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c +index 125e605..60f9482 100644 +--- a/drivers/video/omap/omapfb_main.c ++++ b/drivers/video/omap/omapfb_main.c +@@ -1503,12 +1503,21 @@ static int fbinfo_init(struct omapfb_device *fbdev, struct fb_info *info) + var->rotate = def_rotate; + var->bits_per_pixel = fbdev->panel->bpp; + ++ r = register_framebuffer(info); ++ if (r != 0) { ++ dev_err(fbdev->dev, ++ "registering framebuffer failed\n"); ++ return r; ++ } ++ + set_fb_var(info, var); + set_fb_fix(info); + + r = fb_alloc_cmap(&info->cmap, 16, 0); +- if (r != 0) ++ if (r != 0) { + dev_err(fbdev->dev, "unable to allocate color map memory\n"); ++ unregister_framebuffer(info); ++ } + + return r; + } +@@ -1773,15 +1782,8 @@ static int omapfb_do_probe(struct platform_device *pdev, + init_state++; + + vram = 0; +- for (i = 0; i < fbdev->mem_desc.region_cnt; i++) { +- r = register_framebuffer(fbdev->fb_info[i]); +- if (r != 0) { +- dev_err(fbdev->dev, +- "registering framebuffer %d failed\n", i); +- goto cleanup; +- } ++ for (i = 0; i < fbdev->mem_desc.region_cnt; i++) + vram += fbdev->mem_desc.region[i].size; +- } + + fbdev->state = OMAPFB_ACTIVE; + +-- +1.6.3.2 + +-- +To unsubscribe from this list: send the line "unsubscribe linux-omap" in +the body of a message to majordomo@vger.kernel.org +More majordomo info at http://vger.kernel.org/majordomo-info.html + diff --git a/recipes/linux/linux-omap-2.6.31/modedb-hd720.patch b/recipes/linux/linux-omap-2.6.31/modedb-hd720.patch new file mode 100644 index 0000000000..0166de651a --- /dev/null +++ b/recipes/linux/linux-omap-2.6.31/modedb-hd720.patch @@ -0,0 +1,13 @@ +--- orig/drivers/video/modedb.c.orig 2009-04-07 11:40:10.000000000 +0200 ++++ git/drivers/video/modedb.c 2009-04-07 10:35:29.000000000 +0200 +@@ -44,6 +44,10 @@ + NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, + 0, FB_VMODE_NONINTERLACED + }, { ++ /* 1280x720 @ 60 Hz, 45 kHz hsync, CEA 681-E Format 4 */ ++ "hd720", 60, 1280, 720, 13468, 220, 110, 20, 5, 40, 5, ++ 0, FB_VMODE_NONINTERLACED ++ }, { + /* 800x600 @ 56 Hz, 35.15 kHz hsync */ + NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2, + 0, FB_VMODE_NONINTERLACED diff --git a/recipes/linux/linux-omap_2.6.31.bb b/recipes/linux/linux-omap_2.6.31.bb index 70bd906f55..c0f1bc4c63 100644 --- a/recipes/linux/linux-omap_2.6.31.bb +++ b/recipes/linux/linux-omap_2.6.31.bb @@ -63,6 +63,9 @@ SRC_URI_append = " \ file://usb/0014-musb-disable-PING-on-status-phase-of-control-transf.patch;patch=1 \ file://usb/0015-musb-Add-context-save-and-restore-support.patch;patch=1 \ file://usb/0016-usb-update-defconfig.patch;patch=1 \ + file://modedb-hd720.patch;patch=1 \ + file://fix-omapfb.patch;patch=1 \ + file://dss2/beagle-dss2-support.patch;patch=1 \ " SRC_URI_append_beagleboard = " file://logo_linux_clut224.ppm \ -- cgit v1.2.3 From 8a40ec536fa7389c6ac39b4adb05332d023a9e36 Mon Sep 17 00:00:00 2001 From: Mario Domenech Goulart Date: Fri, 17 Jul 2009 20:03:32 -0300 Subject: uClibc: use __always_inline instead of __inline__ Signed-off-by: Otavio Salvador --- ...Use-__always_inline-instead-of-__inline__.patch | 393 +++++++++++++++++++++ recipes/uclibc/uclibc_0.9.30.1.bb | 1 + 2 files changed, 394 insertions(+) create mode 100644 recipes/uclibc/uclibc-0.9.30.1/0001-Use-__always_inline-instead-of-__inline__.patch diff --git a/recipes/uclibc/uclibc-0.9.30.1/0001-Use-__always_inline-instead-of-__inline__.patch b/recipes/uclibc/uclibc-0.9.30.1/0001-Use-__always_inline-instead-of-__inline__.patch new file mode 100644 index 0000000000..a9c7a4fb10 --- /dev/null +++ b/recipes/uclibc/uclibc-0.9.30.1/0001-Use-__always_inline-instead-of-__inline__.patch @@ -0,0 +1,393 @@ +From c190f738e1b0e87658ea5f86c057fb147dc19428 Mon Sep 17 00:00:00 2001 +From: Carmelo Amoroso +Date: Thu, 5 Mar 2009 13:28:55 +0000 +Subject: [PATCH] Use __always_inline instead of __inline__ + +--- + ldso/ldso/arm/dl-sysdep.h | 8 ++++---- + ldso/ldso/bfin/dl-sysdep.h | 2 +- + ldso/ldso/cris/dl-sysdep.h | 6 +++--- + ldso/ldso/i386/dl-sysdep.h | 10 +++++----- + ldso/ldso/m68k/dl-sysdep.h | 6 +++--- + ldso/ldso/mips/dl-sysdep.h | 8 ++++---- + ldso/ldso/powerpc/dl-sysdep.h | 8 ++++---- + ldso/ldso/sh/dl-sysdep.h | 8 ++++---- + ldso/ldso/sh64/dl-sysdep.h | 6 +++--- + ldso/ldso/sparc/dl-sysdep.h | 8 ++++---- + ldso/ldso/xtensa/dl-sysdep.h | 6 +++--- + 11 files changed, 38 insertions(+), 38 deletions(-) + +diff --git a/ldso/ldso/arm/dl-sysdep.h b/ldso/ldso/arm/dl-sysdep.h +index eea3b98..5191dd7 100644 +--- a/ldso/ldso/arm/dl-sysdep.h ++++ b/ldso/ldso/arm/dl-sysdep.h +@@ -15,7 +15,7 @@ + GOT_BASE[1] = (unsigned long) MODULE; \ + } + +-static __inline__ unsigned long arm_modulus(unsigned long m, unsigned long p) ++static __always_inline unsigned long arm_modulus(unsigned long m, unsigned long p) + { + unsigned long i,t,inc; + i=p; t=0; +@@ -67,7 +67,7 @@ unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); + first element of the GOT. We used to use the PIC register to do this + without a constant pool reference, but GCC 4.2 will use a pseudo-register + for the PIC base, so it may not be in r10. */ +-static __inline__ Elf32_Addr __attribute__ ((unused)) ++static __always_inline Elf32_Addr __attribute__ ((unused)) + elf_machine_dynamic (void) + { + Elf32_Addr dynamic; +@@ -99,7 +99,7 @@ elf_machine_dynamic (void) + } + + /* Return the run-time load address of the shared object. */ +-static __inline__ Elf32_Addr __attribute__ ((unused)) ++static __always_inline Elf32_Addr __attribute__ ((unused)) + elf_machine_load_address (void) + { + extern void __dl_start __asm__ ("_dl_start"); +@@ -123,7 +123,7 @@ elf_machine_load_address (void) + return pcrel_addr - got_addr; + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +diff --git a/ldso/ldso/bfin/dl-sysdep.h b/ldso/ldso/bfin/dl-sysdep.h +index 3c88da4..f0c5129 100644 +--- a/ldso/ldso/bfin/dl-sysdep.h ++++ b/ldso/ldso/bfin/dl-sysdep.h +@@ -210,7 +210,7 @@ while (0) + #endif + + #include +-static __inline__ void ++static __always_inline void + elf_machine_relative (DL_LOADADDR_TYPE load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +diff --git a/ldso/ldso/cris/dl-sysdep.h b/ldso/ldso/cris/dl-sysdep.h +index ffb763a..e454c10 100644 +--- a/ldso/ldso/cris/dl-sysdep.h ++++ b/ldso/ldso/cris/dl-sysdep.h +@@ -37,7 +37,7 @@ extern unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entr + || ((type) == R_CRIS_GLOB_DAT)) * ELF_RTYPE_CLASS_PLT) \ + | (((type) == R_CRIS_COPY) * ELF_RTYPE_CLASS_COPY)) + +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr + elf_machine_dynamic(void) + { + /* Don't just set this to an asm variable "r0" since that's not logical +@@ -59,7 +59,7 @@ elf_machine_dynamic(void) + there's some other symbol we could use, that we don't *have* to force a + GOT entry for. */ + +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr + elf_machine_load_address(void) + { + Elf32_Addr gotaddr_diff; +@@ -93,7 +93,7 @@ elf_machine_load_address(void) + return gotaddr_diff; + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative(Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +diff --git a/ldso/ldso/i386/dl-sysdep.h b/ldso/ldso/i386/dl-sysdep.h +index 77fa372..6e84861 100644 +--- a/ldso/ldso/i386/dl-sysdep.h ++++ b/ldso/ldso/i386/dl-sysdep.h +@@ -37,8 +37,8 @@ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_ent + /* Return the link-time address of _DYNAMIC. Conveniently, this is the + first element of the GOT. This must be inlined in a function which + uses global data. */ +-static __inline__ Elf32_Addr elf_machine_dynamic (void) attribute_unused; +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr elf_machine_dynamic (void) attribute_unused; ++static __always_inline Elf32_Addr + elf_machine_dynamic (void) + { + register Elf32_Addr *got __asm__ ("%ebx"); +@@ -47,8 +47,8 @@ elf_machine_dynamic (void) + + + /* Return the run-time load address of the shared object. */ +-static __inline__ Elf32_Addr elf_machine_load_address (void) attribute_unused; +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr elf_machine_load_address (void) attribute_unused; ++static __always_inline Elf32_Addr + elf_machine_load_address (void) + { + /* It doesn't matter what variable this is, the reference never makes +@@ -61,7 +61,7 @@ elf_machine_load_address (void) + return addr; + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +diff --git a/ldso/ldso/m68k/dl-sysdep.h b/ldso/ldso/m68k/dl-sysdep.h +index 8e26e20..259cb84 100644 +--- a/ldso/ldso/m68k/dl-sysdep.h ++++ b/ldso/ldso/m68k/dl-sysdep.h +@@ -39,7 +39,7 @@ extern unsigned long _dl_linux_resolver (struct elf_resolve *, int); + /* Return the link-time address of _DYNAMIC. Conveniently, this is the + first element of the GOT. This must be inlined in a function which + uses global data. */ +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr + elf_machine_dynamic (void) + { + register Elf32_Addr *got __asm__ ("%a5"); +@@ -48,7 +48,7 @@ elf_machine_dynamic (void) + + + /* Return the run-time load address of the shared object. */ +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr + elf_machine_load_address (void) + { + Elf32_Addr addr; +@@ -58,7 +58,7 @@ elf_machine_load_address (void) + return addr; + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +diff --git a/ldso/ldso/mips/dl-sysdep.h b/ldso/ldso/mips/dl-sysdep.h +index cf6b28b..30d84fb 100644 +--- a/ldso/ldso/mips/dl-sysdep.h ++++ b/ldso/ldso/mips/dl-sysdep.h +@@ -169,7 +169,7 @@ void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy) + + #define OFFSET_GP_GOT 0x7ff0 + +-static __inline__ ElfW(Addr) * ++static __always_inline ElfW(Addr) * + elf_mips_got_from_gpreg (ElfW(Addr) gpreg) + { + /* FIXME: the offset of gp from GOT may be system-dependent. */ +@@ -179,7 +179,7 @@ elf_mips_got_from_gpreg (ElfW(Addr) gpreg) + /* Return the link-time address of _DYNAMIC. Conveniently, this is the + first element of the GOT. This must be inlined in a function which + uses global data. We assume its $gp points to the primary GOT. */ +-static __inline__ ElfW(Addr) ++static __always_inline ElfW(Addr) + elf_machine_dynamic (void) + { + register ElfW(Addr) gp __asm__ ("$28"); +@@ -198,7 +198,7 @@ elf_machine_dynamic (void) + #endif + + /* Return the run-time load address of the shared object. */ +-static __inline__ ElfW(Addr) ++static __always_inline ElfW(Addr) + elf_machine_load_address (void) + { + ElfW(Addr) addr; +@@ -214,7 +214,7 @@ elf_machine_load_address (void) + return addr; + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative (ElfW(Addr) load_off, const ElfW(Addr) rel_addr, + ElfW(Word) relative_count) + { +diff --git a/ldso/ldso/powerpc/dl-sysdep.h b/ldso/ldso/powerpc/dl-sysdep.h +index fdbf564..f33214c 100644 +--- a/ldso/ldso/powerpc/dl-sysdep.h ++++ b/ldso/ldso/powerpc/dl-sysdep.h +@@ -85,7 +85,7 @@ void _dl_init_got(unsigned long *lpnt,struct elf_resolve *tpnt); + #define ELF_MACHINE_PLTREL_OVERLAP 1 + + /* Return the value of the GOT pointer. */ +-static __inline__ Elf32_Addr * __attribute__ ((const)) ++static __always_inline Elf32_Addr * __attribute__ ((const)) + ppc_got (void) + { + Elf32_Addr *got; +@@ -104,14 +104,14 @@ ppc_got (void) + + /* Return the link-time address of _DYNAMIC, stored as + the first value in the GOT. */ +-static __inline__ Elf32_Addr __attribute__ ((const)) ++static __always_inline Elf32_Addr __attribute__ ((const)) + elf_machine_dynamic (void) + { + return *ppc_got(); + } + + /* Return the run-time load address of the shared object. */ +-static __inline__ Elf32_Addr __attribute__ ((const)) ++static __always_inline Elf32_Addr __attribute__ ((const)) + elf_machine_load_address (void) + { + Elf32_Addr *branchaddr; +@@ -159,7 +159,7 @@ elf_machine_load_address (void) + return runtime_dynamic - elf_machine_dynamic (); + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +diff --git a/ldso/ldso/sh/dl-sysdep.h b/ldso/ldso/sh/dl-sysdep.h +index daedda5..d4fc784 100644 +--- a/ldso/ldso/sh/dl-sysdep.h ++++ b/ldso/ldso/sh/dl-sysdep.h +@@ -25,7 +25,7 @@ + struct elf_resolve; + extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); + +-static __inline__ unsigned int ++static __always_inline unsigned int + _dl_urem(unsigned int n, unsigned int base) + { + int res; +@@ -95,7 +95,7 @@ _dl_urem(unsigned int n, unsigned int base) + /* Return the link-time address of _DYNAMIC. Conveniently, this is the + first element of the GOT. This must be inlined in a function which + uses global data. */ +-static __inline__ Elf32_Addr __attribute__ ((unused)) ++static __always_inline Elf32_Addr __attribute__ ((unused)) + elf_machine_dynamic (void) + { + register Elf32_Addr *got; +@@ -104,7 +104,7 @@ elf_machine_dynamic (void) + } + + /* Return the run-time load address of the shared object. */ +-static __inline__ Elf32_Addr __attribute__ ((unused)) ++static __always_inline Elf32_Addr __attribute__ ((unused)) + elf_machine_load_address (void) + { + Elf32_Addr addr; +@@ -146,7 +146,7 @@ elf_machine_load_address (void) + } \ + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +diff --git a/ldso/ldso/sh64/dl-sysdep.h b/ldso/ldso/sh64/dl-sysdep.h +index fc67b12..15d9b5e 100644 +--- a/ldso/ldso/sh64/dl-sysdep.h ++++ b/ldso/ldso/sh64/dl-sysdep.h +@@ -41,7 +41,7 @@ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_ent + /* Return the link-time address of _DYNAMIC. Conveniently, this is the + first element of the GOT. This must be inlined in a function which + uses global data. */ +-static __inline__ Elf32_Addr elf_machine_dynamic(void) ++static __always_inline Elf32_Addr elf_machine_dynamic(void) + { + register Elf32_Addr *got; + +@@ -69,7 +69,7 @@ static __inline__ Elf32_Addr elf_machine_dynamic(void) + } + + /* Return the run-time load address of the shared object. */ +-static __inline__ Elf32_Addr elf_machine_load_address(void) ++static __always_inline Elf32_Addr elf_machine_load_address(void) + { + Elf32_Addr addr; + +@@ -122,7 +122,7 @@ static __inline__ Elf32_Addr elf_machine_load_address(void) + } \ + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative(Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +diff --git a/ldso/ldso/sparc/dl-sysdep.h b/ldso/ldso/sparc/dl-sysdep.h +index 7936517..ebfa268 100644 +--- a/ldso/ldso/sparc/dl-sysdep.h ++++ b/ldso/ldso/sparc/dl-sysdep.h +@@ -52,7 +52,7 @@ unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); + + #ifndef COMPILE_ASM + /* Cheap modulo implementation, taken from arm/ld_sysdep.h. */ +-static __inline__ unsigned long ++static __always_inline unsigned long + sparc_mod(unsigned long m, unsigned long p) + { + unsigned long i, t, inc; +@@ -118,7 +118,7 @@ do { register Elf32_Addr pc __asm__("o7"); \ + /* Return the link-time address of _DYNAMIC. Conveniently, this is the + first element of the GOT. This must be inlined in a function which + uses global data. */ +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr + elf_machine_dynamic (void) + { + register Elf32_Addr *got __asm__ ("%l7"); +@@ -129,7 +129,7 @@ elf_machine_dynamic (void) + } + + /* Return the run-time load address of the shared object. */ +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr + elf_machine_load_address (void) + { + register Elf32_Addr *pc __asm__ ("%o7"), *got __asm__ ("%l7"); +@@ -148,7 +148,7 @@ elf_machine_load_address (void) + return (Elf32_Addr) got - *got + (pc[2] - pc[3]) * 4 - 4; + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +diff --git a/ldso/ldso/xtensa/dl-sysdep.h b/ldso/ldso/xtensa/dl-sysdep.h +index daae428..07b9b79 100644 +--- a/ldso/ldso/xtensa/dl-sysdep.h ++++ b/ldso/ldso/xtensa/dl-sysdep.h +@@ -85,7 +85,7 @@ extern unsigned long _dl_linux_resolver (struct elf_resolve *, int); + (((type) == R_XTENSA_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) + + /* Return the link-time address of _DYNAMIC. */ +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr + elf_machine_dynamic (void) + { + /* This function is only used while bootstrapping the runtime linker. +@@ -95,7 +95,7 @@ elf_machine_dynamic (void) + } + + /* Return the run-time load address of the shared object. */ +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr + elf_machine_load_address (void) + { + Elf32_Addr addr, tmp; +@@ -116,7 +116,7 @@ elf_machine_load_address (void) + return addr - 3; + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +-- +1.6.3.3.444.g4ecbc + diff --git a/recipes/uclibc/uclibc_0.9.30.1.bb b/recipes/uclibc/uclibc_0.9.30.1.bb index ae558e01f1..ab5cdad7c3 100644 --- a/recipes/uclibc/uclibc_0.9.30.1.bb +++ b/recipes/uclibc/uclibc_0.9.30.1.bb @@ -21,6 +21,7 @@ SRC_URI += "file://uClibc.machine file://uClibc.distro \ file://ldso_use_arm_dl_linux_resolve_in_thumb_mode.patch;patch=1 \ file://gcc-4.4-fixlet.patch;patch=1 \ file://uclibc-c99-ldbl-math.patch;patch=1 \ + file://0001-Use-__always_inline-instead-of-__inline__.patch;patch=1 \ " #recent versions uclibc require real kernel headers PACKAGE_ARCH = "${MACHINE_ARCH}" -- cgit v1.2.3 From 55f42a3dd5b43c3ad4bb2425410f64a9e0dd924a Mon Sep 17 00:00:00 2001 From: Mario Domenech Goulart Date: Wed, 15 Jul 2009 16:52:28 -0300 Subject: Avoids overwriting Python's built-in `str' in get_devtable_list Signed-off-by: Otavio Salvador --- classes/image.bbclass | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/classes/image.bbclass b/classes/image.bbclass index f7afbab81e..f03a115388 100644 --- a/classes/image.bbclass +++ b/classes/image.bbclass @@ -72,13 +72,11 @@ def get_devtable_list(d): devtable = bb.data.getVar('IMAGE_DEVICE_TABLE', d, 1) if devtable != None: return devtable - str = "" devtables = bb.data.getVar('IMAGE_DEVICE_TABLES', d, 1) if devtables == None: devtables = 'files/device_table-minimal.txt' - for devtable in devtables.split(): - str += " %s" % bb.which(bb.data.getVar('BBPATH', d, 1), devtable) - return str + return " ".join([ bb.which(bb.data.getVar('BBPATH', d, 1), devtable) + for devtable in devtables.split() ]) def get_imagecmds(d): import bb -- cgit v1.2.3 From 4fdfbf9af2f4f1576b1ece20f43167f2c2d9f1c2 Mon Sep 17 00:00:00 2001 From: Otavio Salvador Date: Mon, 31 Aug 2009 18:52:19 -0300 Subject: preferred-xorg-versions-X11R7.5.inc: bump xf86-video-intel to 2.6.3 Signed-off-by: Otavio Salvador --- conf/distro/include/preferred-xorg-versions-X11R7.5.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/distro/include/preferred-xorg-versions-X11R7.5.inc b/conf/distro/include/preferred-xorg-versions-X11R7.5.inc index 4d62c487c7..de59bd07e2 100644 --- a/conf/distro/include/preferred-xorg-versions-X11R7.5.inc +++ b/conf/distro/include/preferred-xorg-versions-X11R7.5.inc @@ -108,7 +108,7 @@ PREFERRED_VERSION_xf86-video-glint ?= "1.2.1" PREFERRED_VERSION_xf86-video-i128 ?= "1.3.1" PREFERRED_VERSION_xf86-video-i740 ?= "1.2.0" PREFERRED_VERSION_xf86-video-impact ?= "0.2.0" -PREFERRED_VERSION_xf86-video-intel ?= "2.4.2" +PREFERRED_VERSION_xf86-video-intel ?= "2.6.3" PREFERRED_VERSION_xf86-video-mach64 ?= "6.8.0" PREFERRED_VERSION_xf86-video-mga ?= "1.4.9" PREFERRED_VERSION_xf86-video-neomagic ?= "1.2.1" -- cgit v1.2.3 From 7daf6b3e17b866ab2ca38b2c64d7722b4498a09a Mon Sep 17 00:00:00 2001 From: Otavio Salvador Date: Fri, 4 Sep 2009 18:23:02 -0300 Subject: pcmanfm: fix automounting support Signed-off-by: Otavio Salvador --- recipes/pcmanfm/files/auto_mount.patch | 28 ++++++++++++++++++---------- recipes/pcmanfm/pcmanfm_0.5.bb | 1 + 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/recipes/pcmanfm/files/auto_mount.patch b/recipes/pcmanfm/files/auto_mount.patch index b4a3125e3d..288dff4d47 100644 --- a/recipes/pcmanfm/files/auto_mount.patch +++ b/recipes/pcmanfm/files/auto_mount.patch @@ -1,10 +1,18 @@ ---- a/src/vfs/vfs-volume-hal.c 2008-12-16 17:39:21.000000000 -0200 -+++ b/src/vfs/vfs-volume-hal.c 2008-12-16 17:37:07.000000000 -0200 -@@ -1237,6 +1237,7 @@ - { - /* add the volume to the volume manager */ - vfs_volume_add (volume); -+ vfs_volume_mount (volume, NULL); - } - /* release the HAL drive */ - libhal_drive_free (hd); +commit 773ce494a6299e2fdc266e30bcb57305f13cc9d1 +Author: Luis Gustavo S. Barreto +Date: Mon Sep 7 09:27:35 2009 -0300 + + auto + +diff --git a/src/vfs/vfs-volume-hal.c b/src/vfs/vfs-volume-hal.c +index 761ac33..ec5c64f 100644 +--- a/src/vfs/vfs-volume-hal.c ++++ b/src/vfs/vfs-volume-hal.c +@@ -1177,6 +1177,7 @@ vfs_volume_update_volume_by_udi ( const gchar *udi) + static void vfs_volume_add( VFSVolume* volume ) + { + volumes = g_list_append( volumes, volume ); ++ vfs_volume_mount( volume, NULL ); + call_callbacks( volume, VFS_VOLUME_ADDED ); + } + diff --git a/recipes/pcmanfm/pcmanfm_0.5.bb b/recipes/pcmanfm/pcmanfm_0.5.bb index 489e95ee72..483acba4b2 100644 --- a/recipes/pcmanfm/pcmanfm_0.5.bb +++ b/recipes/pcmanfm/pcmanfm_0.5.bb @@ -4,6 +4,7 @@ SECTION = "x11" PRIORITY = "optional" DEPENDS = "gtk+ hal gamin startup-notification" RRECOMMENDS = "pmount-hal" +PR = "r3" SRC_URI = "${SOURCEFORGE_MIRROR}/pcmanfm/pcmanfm-${PV}.tar.gz \ file://desired_mount_point.patch;patch=1 \ -- cgit v1.2.3 From d96238b1773dabfdf3d6ea6ad7a2852d153416d4 Mon Sep 17 00:00:00 2001 From: Otavio Salvador Date: Thu, 17 Sep 2009 12:43:44 -0300 Subject: xf86-video-geode: update to 2.11.4.1 Since it is a bugfix release we updated from 2.11.2 to 2.11.4.1 and also set this as preferred version for the distros using the upcoming Xorg 7.5 release or the 7.4 (updates). Signed-off-by: Otavio Salvador --- conf/checksums.ini | 4 + .../preferred-xorg-versions-X11R7.4-updates.inc | 2 +- .../include/preferred-xorg-versions-X11R7.5.inc | 2 +- ...e-GPIO-device-before-asking-for-base_addr.patch | 30 ---- ...X-fix-RandR-to-properly-use-dixSetPrivate.patch | 56 ------- recipes/xorg-driver/xf86-video-geode/fixes.patch | 161 +++++++++++++++++++++ recipes/xorg-driver/xf86-video-geode_2.11.2.bb | 9 -- recipes/xorg-driver/xf86-video-geode_2.11.4.1.bb | 8 + 8 files changed, 175 insertions(+), 97 deletions(-) delete mode 100644 recipes/xorg-driver/xf86-video-geode/0001-probe-GPIO-device-before-asking-for-base_addr.patch delete mode 100644 recipes/xorg-driver/xf86-video-geode/0002-GX-fix-RandR-to-properly-use-dixSetPrivate.patch create mode 100644 recipes/xorg-driver/xf86-video-geode/fixes.patch delete mode 100644 recipes/xorg-driver/xf86-video-geode_2.11.2.bb create mode 100644 recipes/xorg-driver/xf86-video-geode_2.11.4.1.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index bf17d0ce55..0f57d97bec 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -26802,6 +26802,10 @@ sha256=d70c198cde981c3a53b1c41b717dea4bbf1d397d82957f584c641bb5fd02c82d md5=4c652ecba772f705296b8e52d746857c sha256=2d252847a410636b55bf80900d9432ca438775f70377ce81311282a2d12853b5 +[http://xorg.freedesktop.org/releases/individual/driver/xf86-video-geode-2.11.4.1.tar.bz2] +md5=05f85d897ef41d13de354ac0252bf923 +sha256=d739f6762fe3aa7ef7ca74f87fbe4d6ec3bb13a735e5dfb82b6748eda2b31138 + [http://xorg.freedesktop.org/releases/individual/driver/xf86-video-geode-2.8.0.tar.bz2] md5=a2b9c70a32b0a6436d837d67fa7aae18 sha256=f0b68171dd4256c927fbee91ecf84fa28c409b5b6b39cbf47eaa48fd73db305f diff --git a/conf/distro/include/preferred-xorg-versions-X11R7.4-updates.inc b/conf/distro/include/preferred-xorg-versions-X11R7.4-updates.inc index 6e42065aed..4acca00174 100644 --- a/conf/distro/include/preferred-xorg-versions-X11R7.4-updates.inc +++ b/conf/distro/include/preferred-xorg-versions-X11R7.4-updates.inc @@ -2,6 +2,6 @@ PREFERRED_VERSION_xserver-xorg ?= "1.5.3" PREFERRED_VERSION_xf86-input-evdev ?= "2.1.0" -PREFERRED_VERSION_xf86-video-geode ?= "2.11.2" +PREFERRED_VERSION_xf86-video-geode ?= "2.11.4.1" PREFERRED_VERSION_libxi ?= "1.2.0" PREFERRED_VERSION_inputproto ?= "1.5.0" diff --git a/conf/distro/include/preferred-xorg-versions-X11R7.5.inc b/conf/distro/include/preferred-xorg-versions-X11R7.5.inc index de59bd07e2..d3794834b9 100644 --- a/conf/distro/include/preferred-xorg-versions-X11R7.5.inc +++ b/conf/distro/include/preferred-xorg-versions-X11R7.5.inc @@ -102,7 +102,7 @@ PREFERRED_VERSION_xf86-video-chips ?= "1.2.0" PREFERRED_VERSION_xf86-video-cirrus ?= "1.2.1" PREFERRED_VERSION_xf86-video-dummy ?= "0.3.0" PREFERRED_VERSION_xf86-video-fbdev ?= "0.4.0" -PREFERRED_VERSION_xf86-video-geode ?= "2.11.2" +PREFERRED_VERSION_xf86-video-geode ?= "2.11.4.1" PREFERRED_VERSION_xf86-video-glide ?= "1.0.1" PREFERRED_VERSION_xf86-video-glint ?= "1.2.1" PREFERRED_VERSION_xf86-video-i128 ?= "1.3.1" diff --git a/recipes/xorg-driver/xf86-video-geode/0001-probe-GPIO-device-before-asking-for-base_addr.patch b/recipes/xorg-driver/xf86-video-geode/0001-probe-GPIO-device-before-asking-for-base_addr.patch deleted file mode 100644 index af267ba269..0000000000 --- a/recipes/xorg-driver/xf86-video-geode/0001-probe-GPIO-device-before-asking-for-base_addr.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 1c70b4d2b70155558a9b5edb79a172696c16e129 Mon Sep 17 00:00:00 2001 -From: Otavio Salvador -Date: Fri, 22 May 2009 18:02:04 -0300 -Subject: [PATCH] probe GPIO device before asking for base_addr - -After finding the PCI ISA device it is required to ask for the -resources to be read, before we use the base_addr for GPIO. - -Signed-off-by: Otavio Salvador ---- - src/geode_ddc.c | 3 +++ - 1 files changed, 3 insertions(+), 0 deletions(-) - -diff --git a/src/geode_ddc.c b/src/geode_ddc.c -index 2533488..086dbb1 100644 ---- a/src/geode_ddc.c -+++ b/src/geode_ddc.c -@@ -72,6 +72,9 @@ geode_gpio_iobase(void) - if (pci == NULL) - return 0; - -+ if (pci_device_probe(pci) != 0) -+ return 0; -+ - /* The GPIO I/O address is in resource 1 */ - return (unsigned short)pci->regions[1].base_addr; - #else --- -1.6.3.1.54.g99dd - diff --git a/recipes/xorg-driver/xf86-video-geode/0002-GX-fix-RandR-to-properly-use-dixSetPrivate.patch b/recipes/xorg-driver/xf86-video-geode/0002-GX-fix-RandR-to-properly-use-dixSetPrivate.patch deleted file mode 100644 index 7408473063..0000000000 --- a/recipes/xorg-driver/xf86-video-geode/0002-GX-fix-RandR-to-properly-use-dixSetPrivate.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 312b5ad7a3e1f92abaa113c3e72c8da5cb3e6cb0 Mon Sep 17 00:00:00 2001 -From: Otavio Salvador -Date: Fri, 22 May 2009 20:40:16 -0300 -Subject: [PATCH 2/2] [GX] fix RandR to properly use dixSetPrivate - -Signed-off-by: Otavio Salvador ---- - src/gx_randr.c | 13 +++---------- - 1 files changed, 3 insertions(+), 10 deletions(-) - -diff --git a/src/gx_randr.c b/src/gx_randr.c -index 6cdd244..68e1dbd 100644 ---- a/src/gx_randr.c -+++ b/src/gx_randr.c -@@ -57,18 +57,13 @@ typedef struct _GXRandRInfo - - #define AMD_OLDPRIV (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 4) - --#if AMD_OLDPRIV -- - static int GXRandRIndex; - -+#if AMD_OLDPRIV - #define XF86RANDRINFO(p) ((XF86RandRInfoPtr) (p)->devPrivates[GXRandRIndex].ptr) - #else -- --static DevPrivateKey GXRandRKey; -- - #define XF86RANDRINFO(p) ((XF86RandRInfoPtr) \ -- dixLookupPrivate(&(p)->devPrivates, GXRandRKey)); -- -+ dixLookupPrivate(&(p)->devPrivates, GXRandRIndex)); - #endif - - static int -@@ -333,8 +328,6 @@ GXRandRInit(ScreenPtr pScreen, int rotation) - } - #if AMD_OLDPRIV - GXRandRIndex = AllocateScreenPrivateIndex(); --#else -- GXRandRKey = &GXRandRKey; - #endif - - pRandr = xcalloc(sizeof(XF86RandRInfoRec), 1); -@@ -363,7 +356,7 @@ GXRandRInit(ScreenPtr pScreen, int rotation) - #if AMD_OLDPRIV - pScreen->devPrivates[GXRandRIndex].ptr = pRandr; - #else -- dixSetPrivate(&pScreen->devPrivates, GXRandRKey, pRandr); -+ dixSetPrivate(&pScreen->devPrivates, &GXRandRIndex, pRandr); - #endif - return TRUE; - } --- -1.6.3.1.54.g99dd - diff --git a/recipes/xorg-driver/xf86-video-geode/fixes.patch b/recipes/xorg-driver/xf86-video-geode/fixes.patch new file mode 100644 index 0000000000..b581b5668c --- /dev/null +++ b/recipes/xorg-driver/xf86-video-geode/fixes.patch @@ -0,0 +1,161 @@ +diff --git a/README b/README +index 8ae3ce7..74f3a9a 100644 +--- a/README ++++ b/README +@@ -1,6 +1,6 @@ + AMD Geode GX and LX graphics driver for X.Org + ============================================= +-README last updated: 2009-08-04 ++README last updated: 2009-09-03 + + GIT repository: + git://anongit.freedesktop.org/git/xorg/driver/xf86-video-geode +@@ -29,15 +29,23 @@ at which point xf86-video-cyrix and xf86-video-nsc will be retired. + + = Dependencies = + +-As of version 2.9.0, this driver depends on X.Org server 1.3 or newer, ++As of version 2.11.4, this driver depends upon X server 1.5 or newer, ++because the GX Randr code utilizes dixSetPrivate whose API was modified ++in a non backward-compatible way. ++ ++ #ifdef'ing the changes from f1268f3ba8404129d358db3bb1e66f3841f7018a ++ and b28abde0276ddd7f687242f3886f98b0e49a7fc2 might make it possible ++ to build this driver against older X servers. Patches are welcome. ++ ++As of version 2.9.0, this driver depends on X server 1.3 or newer, + because it utilizes the new common DDC probing libraries from X.Org. + +-If necessary, it might be possible to create autoconf macros to make +-this driver compile against older X servers, following this example: ++ If necessary, it might be possible to create autoconf macros to make ++ this driver compile against older X servers, following this example: + +-http://lists.freedesktop.org/archives/xorg-commit/2007-February/010341.html ++ http://lists.freedesktop.org/archives/xorg-commit/2007-February/010341.html + +-Patches accomplishing the same trick for the Geode driver are welcome. ++ Patches accomplishing the same trick for the Geode driver are welcome. + + = FAQ = + +diff --git a/src/geode.h b/src/geode.h +index 4f0b467..8fe67b5 100644 +--- a/src/geode.h ++++ b/src/geode.h +@@ -60,7 +60,7 @@ + #define LX 0x20 + + #define PCI_VENDOR_ID_CYRIX 0x1078 +-#define PCI_VENDOR_ID_NS 0x100B ++#define PCI_VENDOR_ID_NS 0x100b + #define PCI_VENDOR_ID_AMD 0x1022 + + #define PCI_CHIP_5530 0x0104 +diff --git a/src/gx_driver.c b/src/gx_driver.c +index 7ff5418..6f5767d 100644 +--- a/src/gx_driver.c ++++ b/src/gx_driver.c +@@ -464,7 +464,7 @@ GXPreInit(ScrnInfoPtr pScrni, int flags) + /* Fill in the monitor information */ + pScrni->monitor = pScrni->confScreen->monitor; + +- if (!xf86SetDepthBpp(pScrni, 16, 16, 16, Support24bppFb | Support32bppFb)) ++ if (!xf86SetDepthBpp(pScrni, 24, 16, 32, Support24bppFb | Support32bppFb)) + return FALSE; + + switch (pScrni->depth) { +diff --git a/src/gx_randr.c b/src/gx_randr.c +index 2669912..91ca43e 100644 +--- a/src/gx_randr.c ++++ b/src/gx_randr.c +@@ -56,15 +56,17 @@ typedef struct _GXRandRInfo + Rotation supported_rotations; /* driver supported */ + } XF86RandRInfoRec, *XF86RandRInfoPtr; + +-#define AMD_OLDPRIV (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 4) +- + static int GXRandRIndex; + +-#if AMD_OLDPRIV +-#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) (p)->devPrivates[GXRandRIndex].ptr) ++#define OLD_VIDEODRV_INTERFACE (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 4) ++ ++#if OLD_VIDEODRV_INTERFACE ++#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) (p)->devPrivates[GXRandRIndex].ptr) ++#define XF86RANDRSET(p, v) (p)->devPrivates[GXRandRIndex].ptr = v + #else +-#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) \ +- dixLookupPrivate(&(p)->devPrivates, &GXRandRIndex)); ++#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) \ ++ dixLookupPrivate(&(p)->devPrivates, &GXRandRIndex)) ++#define XF86RANDRSET(p, v) dixSetPrivate(&(p)->devPrivates, &GXRandRIndex, v) + #endif + + static int +@@ -327,7 +329,7 @@ GXRandRInit(ScreenPtr pScreen, int rotation) + if (GXRandRGeneration != serverGeneration) { + GXRandRGeneration = serverGeneration; + } +-#if AMD_OLDPRIV ++#if OLD_VIDEODRV_INTERFACE + GXRandRIndex = AllocateScreenPrivateIndex(); + #endif + +@@ -354,10 +356,7 @@ GXRandRInit(ScreenPtr pScreen, int rotation) + pRandr->supported_rotations = rotation; + pRandr->maxX = pRandr->maxY = 0; + +-#if AMD_OLDPRIV +- pScreen->devPrivates[GXRandRIndex].ptr = pRandr; +-#else +- dixSetPrivate(&pScreen->devPrivates, &GXRandRIndex, pRandr); +-#endif ++ XF86RANDRSET(pScreen, pRandr); ++ + return TRUE; + } +diff --git a/src/lx_driver.c b/src/lx_driver.c +index 08d1fdd..79ec15c 100644 +--- a/src/lx_driver.c ++++ b/src/lx_driver.c +@@ -331,7 +331,7 @@ LXPreInit(ScrnInfoPtr pScrni, int flags) + /* Fill in the monitor information */ + pScrni->monitor = pScrni->confScreen->monitor; + +- if (!xf86SetDepthBpp(pScrni, 16, 16, 16, Support24bppFb | Support32bppFb)) ++ if (!xf86SetDepthBpp(pScrni, 24, 16, 32, Support24bppFb | Support32bppFb)) + return FALSE; + + switch (pScrni->depth) { +diff --git a/src/lx_output.c b/src/lx_output.c +index 5508477..72e5e2a 100644 +--- a/src/lx_output.c ++++ b/src/lx_output.c +@@ -108,7 +108,7 @@ lx_output_set_property(xf86OutputPtr output, Atom property, + + if (!ret) { + xf86DrvMsg(pScrni->scrnIndex, X_ERROR, +- "Failed to set mode after propery change!\n"); ++ "Failed to set mode after property change!\n"); + + pGeode->Scale = scale; + return FALSE; +diff --git a/src/lx_output.c b/src/lx_output.c +index 72e5e2a..3eecc9e 100644 +--- a/src/lx_output.c ++++ b/src/lx_output.c +@@ -163,6 +163,13 @@ lx_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) + return MODE_BAD; + } + ++ if (gfx_is_display_mode_supported(pMode->HDisplay, ++ pMode->VDisplay, ++ pScrni->bitsPerPixel, ++ GeodeGetRefreshRate(pMode)) < 0) { ++ return MODE_BAD; ++ } ++ + return MODE_OK; + } + diff --git a/recipes/xorg-driver/xf86-video-geode_2.11.2.bb b/recipes/xorg-driver/xf86-video-geode_2.11.2.bb deleted file mode 100644 index e98c4fce09..0000000000 --- a/recipes/xorg-driver/xf86-video-geode_2.11.2.bb +++ /dev/null @@ -1,9 +0,0 @@ -require xorg-driver-video.inc -PE = "1" - -COMPATIBLE_HOST = 'i.86.*-linux' -DESCRIPTION = "X.org server -- Geode GX2/LX display driver" - -SRC_URI += "file://0001-probe-GPIO-device-before-asking-for-base_addr.patch;patch=1 \ - file://0002-GX-fix-RandR-to-properly-use-dixSetPrivate.patch;patch=1 \ - " diff --git a/recipes/xorg-driver/xf86-video-geode_2.11.4.1.bb b/recipes/xorg-driver/xf86-video-geode_2.11.4.1.bb new file mode 100644 index 0000000000..93f734b989 --- /dev/null +++ b/recipes/xorg-driver/xf86-video-geode_2.11.4.1.bb @@ -0,0 +1,8 @@ +require xorg-driver-video.inc +PE = "1" +PR = "r1" + +COMPATIBLE_HOST = 'i.86.*-linux' +DESCRIPTION = "X.org server -- Geode GX2/LX display driver" + +SRC_URI += "file://fixes.patch;patch=1" -- cgit v1.2.3 From b4aa04a13fe93a15d8735294a528e102132a44fc Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 17 Sep 2009 20:05:11 +0200 Subject: gstreamer-ti: only patch in omapfb for armv7a --- recipes/ti/gstreamer-ti_svn.bb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/recipes/ti/gstreamer-ti_svn.bb b/recipes/ti/gstreamer-ti_svn.bb index 537a2f9cd4..f8ae1e1b7e 100644 --- a/recipes/ti/gstreamer-ti_svn.bb +++ b/recipes/ti/gstreamer-ti_svn.bb @@ -11,10 +11,13 @@ SRCREV = "335" SRC_URI = "svn://gforge.ti.com/svn/gstreamer_ti/trunk;module=gstreamer_ti;proto=https;user=anonymous;pswd='' \ file://gstreamer-ti-tracker-824.patch;patch=1 \ file://gstreamer-ti-tracker-462.patch;patch=1 \ - file://gstreamer-ti-add-omapfb.patch;patch=1 \ file://gstreamer-ti-remove-mp3-decode-support-from-auddec1.patch;patch=1 \ " +SRC_URI_append_armv7a = " \ + file://gstreamer-ti-add-omapfb.patch;patch=1 \ +" + # Again, no '.' in PWD allowed :( PR = "r36" PV = "svnr${SRCREV}" -- cgit v1.2.3 From fde321de556abd8ce66e494ab21bc4a2d4e28699 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 17 Sep 2009 20:05:51 +0200 Subject: u-boot: if there's a fw-env in SRC_URI build and install tools as well --- recipes/u-boot/u-boot.inc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/recipes/u-boot/u-boot.inc b/recipes/u-boot/u-boot.inc index 294b4446c4..6c8566fb28 100644 --- a/recipes/u-boot/u-boot.inc +++ b/recipes/u-boot/u-boot.inc @@ -20,6 +20,17 @@ do_compile () { unset CPPFLAGS oe_runmake ${UBOOT_MACHINE} oe_runmake all + oe_runmake tools +} + +do_install () { + if [ -e ${WORKDIR}/fw_env.config ] ; then + install -d ${D}$base_sbindir} + install -d ${D}${sysconfdir} + install -m 644 ${WORKDIR}/fw_env.config ${D}${sysconfdir}/fw_env.config + install -m 755 ${S}/tools/env/fw_printenv ${D}${base_sbindir}/fw_printenv + install -m 755 ${S}/tools/env/fw_printenv ${D}${base_sbindir}/fw_setenv + fi } do_deploy () { -- cgit v1.2.3 From 8d8b1db7fc8a0abb9f5ba9d83e09c7b8082b7491 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 17 Sep 2009 20:06:33 +0200 Subject: libgles-omap3: switch to FLIP wsegl --- recipes/powervr-drivers/libgles-omap3.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/powervr-drivers/libgles-omap3.inc b/recipes/powervr-drivers/libgles-omap3.inc index c66309e827..23c084c207 100644 --- a/recipes/powervr-drivers/libgles-omap3.inc +++ b/recipes/powervr-drivers/libgles-omap3.inc @@ -111,7 +111,7 @@ do_install () { install -d ${D}${sysconfdir} echo "[default]" > ${D}${sysconfdir}/powervr.ini - echo "WindowSystem=libpvrPVR2D_FRONTWSEGL.so" >> ${D}${sysconfdir}/powervr.ini + echo "WindowSystem=libpvrPVR2D_FLIPWSEGL.so" >> ${D}${sysconfdir}/powervr.ini install -d ${D}${prefix}/demos/OGLES/ cp -pPR ${S}/GFX_Linux_SDK/OGLES/SDKPackage/Binaries/CommonX11/Demos/* ${D}${prefix}/demos/OGLES/ -- cgit v1.2.3 From 6092bf2816b8a97462e1b31e41b89d893af77925 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 17 Sep 2009 20:06:59 +0200 Subject: angstrom feed sorter: add omap3-touchbook support --- contrib/angstrom/sort.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/angstrom/sort.sh b/contrib/angstrom/sort.sh index 8dd1bdb4dc..b44b781e89 100755 --- a/contrib/angstrom/sort.sh +++ b/contrib/angstrom/sort.sh @@ -58,7 +58,7 @@ case "$arch" in "armv7") machines="" ;; "armv7a") - machines="beagleboard omap3evm omap3517-evm omap3-pandora omapzoom omapzoom2 overo" ;; + machines="omap3-touchbook beagleboard omap3evm omap3517-evm omap3-pandora omapzoom omapzoom2 overo" ;; "avr32") machines="atngw100 at32stk1000" ;; "bfin") -- cgit v1.2.3 From 3ecdded38aea32c9e18caa7218158d3acbd18883 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Thu, 17 Sep 2009 16:47:27 +0000 Subject: shr-autorev*: Soem auto and some fixed revs for upcoming SHR merge (from SHR) --- conf/distro/include/shr-autorev-unstable.inc | 128 ++++++++++++++++++++++++ conf/distro/include/shr-autorev.inc | 140 +++++++++++++++++++++++++++ 2 files changed, 268 insertions(+) create mode 100644 conf/distro/include/shr-autorev-unstable.inc create mode 100644 conf/distro/include/shr-autorev.inc diff --git a/conf/distro/include/shr-autorev-unstable.inc b/conf/distro/include/shr-autorev-unstable.inc new file mode 100644 index 0000000000..5e7a0ddfa3 --- /dev/null +++ b/conf/distro/include/shr-autorev-unstable.inc @@ -0,0 +1,128 @@ + +# SHR - override revs for shr-unstable + + +# KERNEL +SRCREV_pn-linux-openmoko-shr-devel = "${AUTOREV}" + +PREFERRED_VERSION_vala-native = "0.7.4+0.7.5-fso2" + + +# FSO stuff +SRCREV_pn-dbus-hlid = "${AUTOREV}" +SRCREV_pn-frameworkd = "${AUTOREV}" +SRCREV_pn-frameworkd-config-shr = "${AUTOREV}" +SRCREV_pn-frameworkd-config-shr_FSO_REV = "${AUTOREV}" +SRCREV_pn-frameworkd-config-shr_SHR_REV = "${AUTOREV}" +SRCREV_pn-fsod = "${AUTOREV}" +SRCREV_pn-fsodeviced = "${AUTOREV}" +SRCREV_pn-fsonetworkd = "${AUTOREV}" +SRCREV_pn-fsousaged = "${AUTOREV}" +SRCREV_pn-fsoraw = "${AUTOREV}" +SRCREV_pn-fso-abyss = "${AUTOREV}" +SRCREV_pn-fso-apm = "${AUTOREV}" +SRCREV_pn-fso-term = "${AUTOREV}" +SRCREV_pn-fso-gsm0710muxd = "${AUTOREV}" +SRCREV_pn-fso-gpsd = "${AUTOREV}" +SRCREV_pn-fso-monitord = "${AUTOREV}" +SRCREV_pn-fso-sounds = "${AUTOREV}" +SRCREV_pn-fso-specs = "${AUTOREV}" +SRCREV_pn-fso-term = "${AUTOREV}" +SRCREV_pn-gsmd2 = "${AUTOREV}" +SRCREV_pn-illume-theme-freesmartphone = "${AUTOREV}" +SRCREV_pn-libascenario = "${AUTOREV}" +SRCREV_pn-libfsobasics = "${AUTOREV}" +SRCREV_pn-libfsoframework = "${AUTOREV}" +SRCREV_pn-libfsotransport = "${AUTOREV}" +SRCREV_pn-libframeworkd-glib = "${AUTOREV}" +SRCREV_pn-libfso-glib = "${AUTOREV}" +SRCREV_pn-libgsm0710 = "${AUTOREV}" +SRCREV_pn-libgsm0710mux = "${AUTOREV}" +SRCREV_pn-mickeydbus = "${AUTOREV}" +SRCREV_pn-mickeyterm = "${AUTOREV}" +SRCREV_pn-misc-vapi = "${AUTOREV}" +SRCREV_pn-python-pytrc = "${AUTOREV}" +SRCREV_pn-vala-dbus-binding-tool-native = "6071da6ad645e1200eb2aee88d254ada348d361b" +SRCREV_pn-vala = "${AUTOREV}" +SRCREV_pn-zhone = "${AUTOREV}" + + +# SHR stuff +SRCREV_pn-libhito = "${AUTOREV}" +SRCREV_pn-neod = "${AUTOREV}" +SRCREV_pn-shr-settings = "${AUTOREV}" +SRCREV_pn-ophonekitd = "${AUTOREV}" +SRCREV_pn-ophonekitd-vala = "${AUTOREV}" +SRCREV_pn-libmodulo = "${AUTOREV}" +SRCREV_pn-shr-messages = "${AUTOREV}" +SRCREV_pn-shr-contacts = "${AUTOREV}" +SRCREV_pn-shr-dialer = "${AUTOREV}" +SRCREV_pn-libframeworkd-phonegui = "${AUTOREV}" +SRCREV_pn-libframeworkd-phonegui-efl = "${AUTOREV}" +SRCREV_pn-libframeworkd-phonegui-efl2 = "${AUTOREV}" +SRCREV_pn-libframeworkd-phonegui-gtk = "${AUTOREV}" +SRCREV_pn-libframeworkd-phonegui-gtk2 = "${AUTOREV}" +SRCREV_pn-opimd-utils = "${AUTOREV}" +SRCREV_pn-pyphonelog = "${AUTOREV}" +SRCREV_pn-shr-theme = "${AUTOREV}" +SRCREV_pn-shr-theme-brave = "${AUTOREV}" +SRCREV_pn-shr-theme-gtk-e17lookalike = "${AUTOREV}" +SRCREV_pn-shr-splash = "${AUTOREV}" +SRCREV_pn-shr-splash-theme-simple = "${AUTOREV}" +SRCREV_pn-shr-splash-theme-dontpanic = "${AUTOREV}" +SRCREV_pn-shr-splash-theme-handy = "${AUTOREV}" +SRCREV_pn-shr-splash-theme-dociswatchingyou = "${AUTOREV}" +SRCREV_pn-shr-installer = "${AUTOREV}" +SRCREV_pn-shr-config = "${AUTOREV}" +SRCREV_pn-alsa-scenarii-shr = "${AUTOREV}" +SRCREV_pn-libphone-utils = "${AUTOREV}" +SRCREV_pn-python-phoneutils = "${AUTOREV}" + + +# E17 stuff +EFL_SRCREV = "41040" +SRCREV_pn-python-elementary = "41040" +SRCREV_pn-e-wm-config-illume-shr = "${AUTOREV}" +SRCREV_pn-e-wm-sysactions-shr = "${AUTOREV}" +SRCREV_pn-e-wm-theme-illume-shr = "${AUTOREV}" +SRCREV_pn-e-wm-theme-illume-sixteen = "${AUTOREV}" +SRCREV_pn-elementary-theme-sixteen = "${AUTOREV}" +SRCREV_pn-e-wm-menu-shr = "${AUTOREV}" +SRCREV_pn-e-wm-illume-dict-pl = "${AUTOREV}" +SRCREV_pn-etk-theme-shr = "${AUTOREV}" +SRCREV_pn-libeflvala = "${AUTOREV}" + +SRCREV_pn-illume-keyboard-german = "${AUTOREV}" +SRCREV_pn-illume-keyboard-arabic = "${AUTOREV}" +SRCREV_pn-illume-keyboard-browse = "${AUTOREV}" +SRCREV_pn-illume-keyboard-danish = "${AUTOREV}" +SRCREV_pn-illume-keyboard-default-alt = "${AUTOREV}" +SRCREV_pn-illume-keyboard-dutch = "${AUTOREV}" +SRCREV_pn-illume-keyboard-dvorak = "${AUTOREV}" +SRCREV_pn-illume-keyboard-french = "${AUTOREV}" +SRCREV_pn-illume-keyboard-hebrew = "${AUTOREV}" +SRCREV_pn-illume-keyboard-numeric-alt = "${AUTOREV}" +SRCREV_pn-illume-keyboard-russian-terminal = "${AUTOREV}" +SRCREV_pn-illume-keyboard-russian = "${AUTOREV}" + +# Other stuff +SRCREV_pn-navit = "${AUTOREV}" +SRCREV_pn-omview = "${AUTOREV}" +SRCREV_pn-pythm = "${AUTOREV}" +SRCREV_pn-omoney = "29" +SRCREV_pn-enotes = "19" +SRCREV_pn-ebrainy = "${AUTOREV}" +SRCREV_pn-boost-signals2 = "52299" +SRCREV_pn-dbus-c++-native = "${AUTOREV}" +SRCREV_pn-dbus-c++ = "${AUTOREV}" +SRCREV_pn-openmoocow = "${AUTOREV}" +SRCREV_pn-libmokoui2 = "4695" +SRCREV_pn-intone = "${AUTOREV}" +SRCREV_pn-connman = "aac35324deb8c0b57f881338d87cb36b0979e7df" +SRCREV_pn-msn-pecan = "${AUTOREV}" +SRCREV_pn-omgps = "${AUTOREV}" +SRCREV_pn-shr-launcher = "${AUTOREV}" +SRCREV_pn-e-tasks = "${AUTOREV}" +SRCREV_pn-mokonnect = "${AUTOREV}" +SRCREV_pn-elmdentica = "${AUTOREV}" +SRCREV_pn-vala-terminal = "${AUTOREV}" diff --git a/conf/distro/include/shr-autorev.inc b/conf/distro/include/shr-autorev.inc new file mode 100644 index 0000000000..1605e8607a --- /dev/null +++ b/conf/distro/include/shr-autorev.inc @@ -0,0 +1,140 @@ +# SHR conf file + +# We need to override some machine stuff as well; include the machine- +# specific file here (if it exists). +#include conf/distro/include/shr-${MACHINE}.conf + +# Nail down some SRCREV's for the kernels. There is a real potential problem +# here, in that git hashes are hashes, not incrementing version numbers. Thus +# we need to have something else in the kernel version string that gets bumped +# with each change. So if you change one of these, go to the kernel recipe +# and bump the OEV value up as well. +SRCREV_pn-linux-eten = "df9715883efa3e6a88866813168fabb1c16b0b7a" +SRCREV_pn-linux-openmoko-shr-devel = "2d158aae9d8d36f575504f59884ed8e80802efe2" + +# FSO stuff +SRCREV_pn-dbus-hlid = "39e804f28808247df2573788cb99897d4d765e69" +SRCREV_pn-frameworkd = "e96a204768744130859ab091162ec5c976854d49" +SRCREV_pn-frameworkd-config-shr = "${AUTOREV}" +SRCREV_pn-frameworkd-config-shr_FSO_REV = "e96a204768744130859ab091162ec5c976854d49" +SRCREV_pn-frameworkd-config-shr_SHR_REV = "${AUTOREV}" +SRCREV_pn-fsod = "${AUTOREV}" +SRCREV_pn-fsodeviced = "${AUTOREV}" +SRCREV_pn-fsonetworkd = "${AUTOREV}" +SRCREV_pn-fsousaged = "3c3e1b862cdde806cef8f502dfe79f1d48f1c5d7" +SRCREV_pn-fsoraw = "${AUTOREV}" +SRCREV_pn-fso-abyss = "ff68be1581069ca494a559e85f6299246888d3b5" +SRCREV_pn-fso-apm = "${AUTOREV}" +SRCREV_pn-fso-term = "${AUTOREV}" +SRCREV_pn-fso-gsm0710muxd = "abcbcd7cc532a8834906de3fc24c8f8fe7643cd4" +SRCREV_pn-fso-gpsd = "78fe48dffb923175bde9f0aabc3500a9264a57e0" +SRCREV_pn-fso-monitord = "${AUTOREV}" +SRCREV_pn-fso-sounds = "3a4767ec01988bd0fd8f72f0c35d6d36e5fbc815" +SRCREV_pn-fso-specs = "${AUTOREV}" +SRCREV_pn-fso-term = "${AUTOREV}" +SRCREV_pn-gsmd2 = "${AUTOREV}" +SRCREV_pn-illume-theme-freesmartphone = "${AUTOREV}" +SRCREV_pn-libascenario = "${AUTOREV}" +SRCREV_pn-libfsobasics = "3c3e1b862cdde806cef8f502dfe79f1d48f1c5d7" +SRCREV_pn-libfsoframework = "3c3e1b862cdde806cef8f502dfe79f1d48f1c5d7" +SRCREV_pn-libfsotransport = "3c3e1b862cdde806cef8f502dfe79f1d48f1c5d7" +SRCREV_pn-libframeworkd-glib = "680276e4cddabeb1edd088ddd421f363dd106a50" +SRCREV_pn-libfso-glib = "9d292508739452b55b80ec40ec57405a5de2159f" +SRCREV_pn-libgsm0710 = "3bb80ba6cc9f86ed3996f88bfa2986cc572489d6" +SRCREV_pn-libgsm0710mux = "8e3e7533b286d8086bce8fa09bce23bb9f18bb98" +SRCREV_pn-mickeydbus = "6d7f51b5189a00a07d9b88100a565f46fcb62644" +SRCREV_pn-mickeyterm = "6d7f51b5189a00a07d9b88100a565f46fcb62644" +SRCREV_pn-misc-vapi = "${AUTOREV}" +SRCREV_pn-python-pytrc = "f15ff7c58946a2fd6ba767628b2fe5d6f46ff9bb" +SRCREV_pn-vala-dbus-binding-tool-native = "6071da6ad645e1200eb2aee88d254ada348d361b" +SRCREV_pn-vala = "${AUTOREV}" +SRCREV_pn-zhone = "${AUTOREV}" + + +# SHR stuff +SHRREV = "c3d97171723d8e824cb5acf58b711aa78b3b82d9" + +SRCREV_pn-libhito = "${AUTOREV}" +SRCREV_pn-neod = "${AUTOREV}" +SRCREV_pn-shr-settings = "4e0fbe17e4fddd18b0455ec4d007ab3f1d19918e" +SRCREV_pn-ophonekitd = "${SHRREV}" +SRCREV_pn-ophonekitd-vala = "${AUTOREV}" +SRCREV_pn-libmodulo = "${AUTOREV}" +SRCREV_pn-shr-messages = "${SHRREV}" +SRCREV_pn-shr-contacts = "${SHRREV}" +SRCREV_pn-shr-dialer = "${SHRREV}" +SRCREV_pn-libframeworkd-phonegui = "${SHRREV}" +SRCREV_pn-libframeworkd-phonegui-efl = "${SHRREV}" +SRCREV_pn-libframeworkd-phonegui-efl2 = "${AUTOREV}" +SRCREV_pn-libframeworkd-phonegui-gtk = "${AUTOREV}" +SRCREV_pn-libframeworkd-phonegui-gtk2 = "${AUTOREV}" +SRCREV_pn-opimd-utils = "${AUTOREV}" +SRCREV_pn-pyphonelog = "9da559f0242a32aa5d0b72c795f53d7d9ef8c973" +SRCREV_pn-shr-theme = "${AUTOREV}" +SRCREV_pn-shr-theme-brave = "${AUTOREV}" +SRCREV_pn-shr-theme-gtk-e17lookalike = "${AUTOREV}" +SRCREV_pn-shr-splash = "${AUTOREV}" +SRCREV_pn-shr-splash-theme-simple = "${AUTOREV}" +SRCREV_pn-shr-splash-theme-dontpanic = "${AUTOREV}" +SRCREV_pn-shr-splash-theme-handy = "${AUTOREV}" +SRCREV_pn-shr-splash-theme-niebiee = "${AUTOREV}" +SRCREV_pn-shr-installer = "${AUTOREV}" +SRCREV_pn-shr-config = "${AUTOREV}" +SRCREV_pn-alsa-scenarii-shr = "${AUTOREV}" +SRCREV_pn-libphone-utils = "${AUTOREV}" +SRCREV_pn-python-phoneutils = "${AUTOREV}" + + +# E17 stuff +EFL_SRCREV = "41040" +SRCREV_pn-python-elementary = "41040" +SRCREV_pn-e-wm-config-illume-shr = "${AUTOREV}" +SRCREV_pn-e-wm-sysactions-shr = "${AUTOREV}" +SRCREV_pn-e-wm-theme-illume-shr = "${AUTOREV}" +SRCREV_pn-e-wm-theme-illume-sixteen = "${AUTOREV}" +SRCREV_pn-e-wm-theme-illume-niebiee = "${AUTOREV}" +SRCREV_pn-elementary-theme-sixteen = "${AUTOREV}" +SRCREV_pn-elementary-theme-niebiee = "${AUTOREV}" +SRCREV_pn-e-wm-menu-shr = "${AUTOREV}" +SRCREV_pn-e-wm-illume-dict-pl = "${AUTOREV}" +SRCREV_pn-etk-theme-shr = "${AUTOREV}" +SRCREV_pn-libeflvala = "${AUTOREV}" + +SRCREV_pn-illume-keyboard-german = "${AUTOREV}" +SRCREV_pn-illume-keyboard-arabic = "${AUTOREV}" +SRCREV_pn-illume-keyboard-browse = "${AUTOREV}" +SRCREV_pn-illume-keyboard-danish = "${AUTOREV}" +SRCREV_pn-illume-keyboard-default-alt = "${AUTOREV}" +SRCREV_pn-illume-keyboard-dutch = "${AUTOREV}" +SRCREV_pn-illume-keyboard-dvorak = "${AUTOREV}" +SRCREV_pn-illume-keyboard-french = "${AUTOREV}" +SRCREV_pn-illume-keyboard-hebrew = "${AUTOREV}" +SRCREV_pn-illume-keyboard-numeric-alt = "${AUTOREV}" +SRCREV_pn-illume-keyboard-russian-terminal = "${AUTOREV}" +SRCREV_pn-illume-keyboard-russian = "${AUTOREV}" + + +# Other stuff +SRCREV_pn-bt-configure = "${AUTOREV}" +SRCREV_pn-navit = "2309" +SRCREV_pn-omview = "${AUTOREV}" +SRCREV_pn-pythm = "${AUTOREV}" +SRCREV_pn-omoney = "29" +SRCREV_pn-enotes = "19" +SRCREV_pn-ebrainy = "${AUTOREV}" +SRCREV_pn-boost-signals2 = "52299" +SRCREV_pn-dbus-c++-native = "${AUTOREV}" +SRCREV_pn-dbus-c++ = "${AUTOREV}" +SRCREV_pn-openmoocow = "${AUTOREV}" +SRCREV_pn-libmokoui2 = "4695" +SRCREV_pn-intone = "${AUTOREV}" +SRCREV_pn-connman = "aac35324deb8c0b57f881338d87cb36b0979e7df" +SRCREV_pn-msn-pecan = "${AUTOREV}" +SRCREV_pn-omgps = "${AUTOREV}" +SRCREV_pn-shr-today = "${AUTOREV}" +SRCREV_pn-shr-launcher = "${AUTOREV}" +SRCREV_pn-e-tasks = "${AUTOREV}" +SRCREV_pn-mokonnect = "${AUTOREV}" +SRCREV_pn-elmdentica = "${AUTOREV}" +SRCREV_pn-vala-terminal = "${AUTOREV}" + -- cgit v1.2.3 From 2ff4462e97f4da82b244a307b147f6e218cef1df Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Thu, 17 Sep 2009 16:50:39 +0000 Subject: e-wm-menu-shr: Add recipe (from SHR) --- recipes/shr/e-wm-menu-shr_git.bb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 recipes/shr/e-wm-menu-shr_git.bb diff --git a/recipes/shr/e-wm-menu-shr_git.bb b/recipes/shr/e-wm-menu-shr_git.bb new file mode 100644 index 0000000000..94529e335a --- /dev/null +++ b/recipes/shr/e-wm-menu-shr_git.bb @@ -0,0 +1,18 @@ +DESCRIPTION = "illume SHR applications.menu config" +SECTION = "e/utils" +LICENSE = "MIT BSD" +PV = "1.1-${EFL_SRCREV}-gitr${SRCREV}" + +RPROVIDES_${PN} = "e-wm-menu" +RCONFLICTS_${PN} = "e-wm-menu" + +SRC_URI = "git://git.shr-project.org/repo/shr-themes.git;protocol=http;branch=master" + +S = "${WORKDIR}/git/e-wm/${PN}" + +FILES_${PN} = "${sysconfdir}/xdg/menus/applications.menu" + +do_install() { + install -d ${D}${sysconfdir}/xdg/menus + install -m 0755 ${S}/applications.menu ${D}${sysconfdir}/xdg/menus/applications.menu +} -- cgit v1.2.3 From 0393c7cc15c233154ea0b8add2820eabf89d63b3 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Thu, 17 Sep 2009 16:51:49 +0000 Subject: e-wm-sysactions-shr: Add recipe (from SHR) --- recipes/shr/e-wm-sysactions-shr_git.bb | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 recipes/shr/e-wm-sysactions-shr_git.bb diff --git a/recipes/shr/e-wm-sysactions-shr_git.bb b/recipes/shr/e-wm-sysactions-shr_git.bb new file mode 100644 index 0000000000..293edaeba3 --- /dev/null +++ b/recipes/shr/e-wm-sysactions-shr_git.bb @@ -0,0 +1,21 @@ +DESCRIPTION = "illume SHR sysactions config" +SECTION = "e/utils" +LICENSE = "MIT BSD" +PV = "1.1-${EFL_SRCREV}-gitr${SRCREV}" +PR = "r3" + +RPROVIDES_${PN} = "e-wm-sysactions" +RCONFLICTS_${PN} = "e-wm-sysactions" +#RREPLACES_${PN} = "e-wm-sysactions" + +SRC_URI = "git://git.shr-project.org/repo/shr-themes.git;protocol=http;branch=master" + +S = "${WORKDIR}/git/e-wm/${PN}" + +FILES_${PN} = "${sysconfdir}/enlightenment" + +do_install() { + install -d ${D}${sysconfdir}/enlightenment/ + install -m 0755 ${S}/sysactions.conf ${D}${sysconfdir}/enlightenment/sysactions.conf + install -m 0755 ${S}/suspend.sh ${D}${sysconfdir}/enlightenment/suspend.sh +} -- cgit v1.2.3 From 80c55c2574e99f025d88608966b09fcc578ed4f5 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Thu, 17 Sep 2009 16:54:01 +0000 Subject: e-wm-theme-illume-shr: Add recipe (from SHR) --- recipes/shr/e-wm-theme-illume-shr_git.bb | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 recipes/shr/e-wm-theme-illume-shr_git.bb diff --git a/recipes/shr/e-wm-theme-illume-shr_git.bb b/recipes/shr/e-wm-theme-illume-shr_git.bb new file mode 100644 index 0000000000..0c59feb876 --- /dev/null +++ b/recipes/shr/e-wm-theme-illume-shr_git.bb @@ -0,0 +1,23 @@ +DESCRIPTION = "illume SHR theme" +SECTION = "e/utils" +DEPENDS = "edje-native" +LICENSE = "MIT BSD" +PV = "1.1-${EFL_SRCREV}-gitr${SRCREV}" +PR = "r6" + +SRC_URI = "git://git.shr-project.org/repo/shr-themes.git;protocol=http;branch=master" + +S = "${WORKDIR}/git/e-wm/${PN}" + +do_compile() { + ${STAGING_BINDIR_NATIVE}/edje_cc -id ${S}/images/. -fd ${S}/fonts/. ${S}/illume-shr.edc -o ${S}/illume-shr.edj +} + +do_install() { + install -d ${D}${datadir}/enlightenment/data/themes/ + install -m 0644 ${S}/illume-shr.edj ${D}${datadir}/enlightenment/data/themes/ +} + +FILES_${PN} = "${datadir}/enlightenment/data/themes/illume-shr.edj" + + -- cgit v1.2.3 From e8622747c60b148e94f095c4bb7fe40fc52bba0a Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Thu, 17 Sep 2009 18:01:23 +0000 Subject: initscripts-shr: Add SHR initscripts (from SHR) --- recipes/shr/initscripts-shr/alignment.sh | 6 + recipes/shr/initscripts-shr/bootmisc.sh | 47 +++++ recipes/shr/initscripts-shr/checkroot.sh | 45 ++++ recipes/shr/initscripts-shr/devpts | 5 + recipes/shr/initscripts-shr/finish.sh | 7 + recipes/shr/initscripts-shr/functions | 17 ++ recipes/shr/initscripts-shr/g_ether.sh | 93 +++++++++ recipes/shr/initscripts-shr/halt | 25 +++ recipes/shr/initscripts-shr/hostname.sh | 11 + recipes/shr/initscripts-shr/mountall.sh | 52 +++++ recipes/shr/initscripts-shr/mountdevsubfs.sh | 14 ++ recipes/shr/initscripts-shr/mountkernfs.sh | 33 +++ recipes/shr/initscripts-shr/mountnfs.sh | 87 ++++++++ recipes/shr/initscripts-shr/populate-volatile.sh | 248 +++++++++++++++++++++++ recipes/shr/initscripts-shr/reboot | 11 + recipes/shr/initscripts-shr/rmnologin | 14 ++ recipes/shr/initscripts-shr/save-rtc.sh | 5 + recipes/shr/initscripts-shr/sendsigs | 17 ++ recipes/shr/initscripts-shr/umountfs | 18 ++ recipes/shr/initscripts-shr/umountnfs.sh | 28 +++ recipes/shr/initscripts-shr/volatiles | 40 ++++ recipes/shr/initscripts-shr_git.bb | 107 ++++++++++ 22 files changed, 930 insertions(+) create mode 100644 recipes/shr/initscripts-shr/alignment.sh create mode 100644 recipes/shr/initscripts-shr/bootmisc.sh create mode 100644 recipes/shr/initscripts-shr/checkroot.sh create mode 100644 recipes/shr/initscripts-shr/devpts create mode 100644 recipes/shr/initscripts-shr/finish.sh create mode 100644 recipes/shr/initscripts-shr/functions create mode 100644 recipes/shr/initscripts-shr/g_ether.sh create mode 100644 recipes/shr/initscripts-shr/halt create mode 100644 recipes/shr/initscripts-shr/hostname.sh create mode 100644 recipes/shr/initscripts-shr/mountall.sh create mode 100644 recipes/shr/initscripts-shr/mountdevsubfs.sh create mode 100644 recipes/shr/initscripts-shr/mountkernfs.sh create mode 100644 recipes/shr/initscripts-shr/mountnfs.sh create mode 100644 recipes/shr/initscripts-shr/populate-volatile.sh create mode 100644 recipes/shr/initscripts-shr/reboot create mode 100644 recipes/shr/initscripts-shr/rmnologin create mode 100644 recipes/shr/initscripts-shr/save-rtc.sh create mode 100644 recipes/shr/initscripts-shr/sendsigs create mode 100644 recipes/shr/initscripts-shr/umountfs create mode 100644 recipes/shr/initscripts-shr/umountnfs.sh create mode 100644 recipes/shr/initscripts-shr/volatiles create mode 100644 recipes/shr/initscripts-shr_git.bb diff --git a/recipes/shr/initscripts-shr/alignment.sh b/recipes/shr/initscripts-shr/alignment.sh new file mode 100644 index 0000000000..4a66dc6bc8 --- /dev/null +++ b/recipes/shr/initscripts-shr/alignment.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +if [ -e /proc/cpu/alignment ]; then + echo "3" > /proc/cpu/alignment +fi + diff --git a/recipes/shr/initscripts-shr/bootmisc.sh b/recipes/shr/initscripts-shr/bootmisc.sh new file mode 100644 index 0000000000..4511e12fc1 --- /dev/null +++ b/recipes/shr/initscripts-shr/bootmisc.sh @@ -0,0 +1,47 @@ +# +# bootmisc.sh Miscellaneous things to be done during bootup. +# + +. /etc/default/rcS +# +# Put a nologin file in /etc to prevent people from logging in before +# system startup is complete. +# +if test "$DELAYLOGIN" = yes +then + echo "System bootup in progress - please wait" > /etc/nologin + cp /etc/nologin /etc/nologin.boot +fi + +# +# Update /etc/motd. +# +if test "$EDITMOTD" != no +then + uname -a > /etc/motd.tmp + sed 1d /etc/motd >> /etc/motd.tmp + mv /etc/motd.tmp /etc/motd +fi + +# +# Update dynamic library cache +# +#/sbin/ldconfig + +# Set the system clock from hardware clock +# If the timestamp is 1 day or more recent than the current time, +# use the timestamp instead. +[ "$UTC" = yes ] || /etc/init.d/hwclock.sh start + +if ! test -f /etc/.configured && test -e /etc/timestamp +then + SYSTEMDATE=`date "+%Y%m%d"` + TIMESTAMP=`cat /etc/timestamp | awk '{ print substr($0,9,4) substr($0,1,4);}'` + NEEDUPDATE=`expr \( $TIMESTAMP \> $SYSTEMDATE \)` + if [ $NEEDUPDATE -eq 1 ]; then + date `cat /etc/timestamp` + /etc/init.d/hwclock.sh stop + fi +fi + +: exit 0 diff --git a/recipes/shr/initscripts-shr/checkroot.sh b/recipes/shr/initscripts-shr/checkroot.sh new file mode 100644 index 0000000000..197a3a81d7 --- /dev/null +++ b/recipes/shr/initscripts-shr/checkroot.sh @@ -0,0 +1,45 @@ +# +# checkroot.sh Check to root filesystem. +# +# Version: @(#)checkroot.sh 2.84 25-Jan-2002 miquels@cistron.nl +# + +. /etc/default/rcS + +# +# Set SULOGIN in /etc/default/rcS to yes if you want a sulogin to be spawned +# from this script *before anything else* with a timeout, like SCO does. +# +test "$SULOGIN" = yes && sulogin -t 30 $CONSOLE + +# +# If the root filesystem was not marked as read-only in /etc/fstab, +# remount the rootfs rw but do not try to change mtab because it +# is on a ro fs until the remount succeeded. Then clean up old mtabs +# and finally write the new mtab. +# This part is only needed if the rootfs was mounted ro. +# +# Also attempt to remount if the noatime option is not present. +# +ROOTFSDEV="/dev/root" +if grep -q "^$ROOTFSDEV .* rw,.*noatime" /proc/mounts; then + echo "Root filesystem already read-write, not remounting" +else + rootmode=rw + + echo "Remounting root file system..." + mount -n -o remount,noatime,$rootmode / + if test "$rootmode" = rw + then + if test ! -L /etc/mtab + then + rm -f /etc/mtab~ /etc/nologin + : > /etc/mtab + fi + mount -f -o remount / + mount -f /proc + test "$devfs" && grep -q '^devfs /dev' /proc/mounts && mount -f "$devfs" + fi +fi + +: exit 0 diff --git a/recipes/shr/initscripts-shr/devpts b/recipes/shr/initscripts-shr/devpts new file mode 100644 index 0000000000..e10e371662 --- /dev/null +++ b/recipes/shr/initscripts-shr/devpts @@ -0,0 +1,5 @@ +# GID of the `tty' group +TTYGRP=5 + +# Set to 600 to have `mesg n' be the default +TTYMODE=620 diff --git a/recipes/shr/initscripts-shr/finish.sh b/recipes/shr/initscripts-shr/finish.sh new file mode 100644 index 0000000000..897f005310 --- /dev/null +++ b/recipes/shr/initscripts-shr/finish.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +if ! test -e /etc/.configured; then + opkg-cl configure + > /etc/.configured +fi + diff --git a/recipes/shr/initscripts-shr/functions b/recipes/shr/initscripts-shr/functions new file mode 100644 index 0000000000..fb9a914e4d --- /dev/null +++ b/recipes/shr/initscripts-shr/functions @@ -0,0 +1,17 @@ +# -*-Shell-script-*- +# +# functions This file contains functions to be used by most or all +# shell scripts in the /etc/init.d directory. +# + +machine_id() { # return the machine ID + awk 'BEGIN { FS=": " } /Hardware/ { gsub(" ", "_", $2); print tolower($2) } ' /etc/modprobe.d/g_ether.conf + +# And now, since this is first boot, we need to probe the module +modprobe g_ether 2>/dev/null || true + +fi diff --git a/recipes/shr/initscripts-shr/halt b/recipes/shr/initscripts-shr/halt new file mode 100644 index 0000000000..d8cab222ca --- /dev/null +++ b/recipes/shr/initscripts-shr/halt @@ -0,0 +1,25 @@ +#! /bin/sh +# +# halt Execute the halt command. +# +# Version: @(#)halt 2.84-2 07-Jan-2002 miquels@cistron.nl +# + +PATH=/sbin:/bin:/usr/sbin:/usr/bin + +# See if we need to cut the power. +if test -x /etc/init.d/ups-monitor +then + /etc/init.d/ups-monitor poweroff +fi + +# Don't shut down drives if we're using RAID. +hddown="-h" +if grep -qs '^md.*active' /proc/mdstat +then + hddown="" +fi + +halt -d -f -i -p $hddown + +: exit 0 diff --git a/recipes/shr/initscripts-shr/hostname.sh b/recipes/shr/initscripts-shr/hostname.sh new file mode 100644 index 0000000000..0f3d374286 --- /dev/null +++ b/recipes/shr/initscripts-shr/hostname.sh @@ -0,0 +1,11 @@ +# +# hostname.sh Set hostname. +# +# Version: @(#)hostname.sh 1.10 26-Feb-2001 miquels@cistron.nl +# + +if test -f /etc/hostname +then + hostname -F /etc/hostname +fi + diff --git a/recipes/shr/initscripts-shr/mountall.sh b/recipes/shr/initscripts-shr/mountall.sh new file mode 100644 index 0000000000..4bd7bbb02c --- /dev/null +++ b/recipes/shr/initscripts-shr/mountall.sh @@ -0,0 +1,52 @@ +# +# mountall.sh Mount all filesystems. +# +# Version: @(#)mountall.sh 2.83-2 01-Nov-2001 miquels@cistron.nl +# +. /etc/default/rcS +if test -f /etc/default/mountall; then + . /etc/default/mountall +fi + +# +# Mount local filesystems in /etc/fstab. For some reason, people +# might want to mount "proc" several times, and mount -v complains +# about this. So we mount "proc" filesystems without -v. +# +test "$VERBOSE" != no && echo "Mounting local filesystems..." +mount -a $MOUNTALL + +# +# We might have mounted something over /dev, see if /dev/initctl is there. +# +if test ! -p /dev/initctl +then + rm -f /dev/initctl + mknod -m 600 /dev/initctl p +fi +kill -USR1 1 + +# +# Execute swapon command again, in case we want to swap to +# a file on a now mounted filesystem. +# +doswap=yes +if test $doswap = yes +then + swapon -a 2> /dev/null +fi + +# A missing homedirectory for root can cause all sorts of problems. +# This can happen after user formats his /home partition for example + +if test -e /etc/passwd +then + ROOT_HOME="`grep root /etc/passwd | cut -d: -f6`" + + if test -n "$ROOT_HOME" + then + ! test -d "$ROOT_HOME" && mkdir -p "$ROOT_HOME" + fi +fi +: exit 0 + diff --git a/recipes/shr/initscripts-shr/mountdevsubfs.sh b/recipes/shr/initscripts-shr/mountdevsubfs.sh new file mode 100644 index 0000000000..c6cfb05af2 --- /dev/null +++ b/recipes/shr/initscripts-shr/mountdevsubfs.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. /etc/default/devpts + +test -c /dev/ptmx || mknod -m 666 /dev/ptmx c 5 2 + +if [ -d /dev/pts ]; then + mount -n -t devpts devpts /dev/pts -ogid=${TTYGRP},mode=${TTYMODE} +fi + + +if [ -d /dev/shm ]; then + mount -n -t tmpfs shmfs /dev/shm -omode=0777 +fi diff --git a/recipes/shr/initscripts-shr/mountkernfs.sh b/recipes/shr/initscripts-shr/mountkernfs.sh new file mode 100644 index 0000000000..1ed09fcf05 --- /dev/null +++ b/recipes/shr/initscripts-shr/mountkernfs.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +supported_kernel() { + case "$(uname -r)" in + 2.[012345].*|2.6.[0-9]|2.6.[0-9][!0-9]*) return 1 ;; + 2.6.1[0-7]|2.6.1[0-7][!0-9]*) return 1 ;; + esac + return 0 +} + +check_kernel() { + if ! supported_kernel; then + echo "WARNING: kernel < 2.6.18" + fi + + if ! grep -qs devpts /proc/filesystems; then + echo "WARNING: kernel does not support devpts" + fi + + if ! grep -qs tmpfs /proc/filesystems; then + echo "WARNING: kernel does not support tmpfs" + fi +} + +if [ -d /proc ]; then + mount -n -t proc proc /proc +fi + +check_kernel + +if [ -d /sys ]; then + mount -n -t sysfs sysfs /sys +fi diff --git a/recipes/shr/initscripts-shr/mountnfs.sh b/recipes/shr/initscripts-shr/mountnfs.sh new file mode 100644 index 0000000000..2631392483 --- /dev/null +++ b/recipes/shr/initscripts-shr/mountnfs.sh @@ -0,0 +1,87 @@ +# +# mountnfs.sh Now that TCP/IP is configured, mount the NFS file +# systems in /etc/fstab if needed. If possible, +# start the portmapper before mounting (this is needed for +# Linux 2.1.x and up). +# +# Also mounts SBM filesystems now, so the name of +# this script is getting increasingly inaccurate. +# +# Version: @(#)mountnfs.sh 2.83 05-Oct-2001 miquels@cistron.nl +# + +. /etc/default/rcS + +# +# Run in a subshell because of I/O redirection. +# +test -x /sbin/portmap && test -f /etc/fstab && ( + +# +# Read through fstab line by line. If it is NFS, set the flag +# for mounting NFS filesystems. If any NFS partition is found and it +# not mounted with the nolock option, we start the portmapper. +# +portmap=no +mount_nfs=no +mount_smb=no +mount_ncp=no +while read device mountpt fstype options +do + case "$device" in + ""|\#*) + continue + ;; + esac + + case "$options" in + *noauto*) + continue + ;; + esac + + if test "$fstype" = nfs + then + mount_nfs=yes + case "$options" in + *nolock*) + ;; + *) + portmap=yes + ;; + esac + fi + if test "$fstype" = smbfs + then + mount_smb=yes + fi + if test "$fstype" = ncpfs + then + mount_ncp=yes + fi +done + +exec 0>&1 + +if test "$portmap" = yes +then + if test -x /sbin/portmap + then + echo -n "Starting portmapper... " + start-stop-daemon --start --quiet --exec /sbin/portmap + sleep 2 + fi +fi + +if test "$mount_nfs" = yes || test "$mount_smb" = yes || test "$mount_ncp" = yes +then + echo "Mounting remote filesystems..." + test "$mount_nfs" = yes && mount -a -t nfs + test "$mount_smb" = yes && mount -a -t smbfs + test "$mount_ncp" = yes && mount -a -t ncpfs +fi + +) < /etc/fstab + +: exit 0 + diff --git a/recipes/shr/initscripts-shr/populate-volatile.sh b/recipes/shr/initscripts-shr/populate-volatile.sh new file mode 100644 index 0000000000..bf2cac76e2 --- /dev/null +++ b/recipes/shr/initscripts-shr/populate-volatile.sh @@ -0,0 +1,248 @@ +#!/bin/sh + +. /etc/default/rcS + +CFGDIR="/etc/default/volatiles" +TMPROOT="/var/tmp" +COREDEF="00_core" + +[ "${VERBOSE}" != "no" ] && echo "Populating volatile Filesystems." + +create_file() { + EXEC=" + touch \"$1\"; + chown ${TUSER}.${TGROUP} $1 || echo \"Failed to set owner -${TUSER}- for -$1-.\" >/dev/tty0 2>&1; + chmod ${TMODE} $1 || echo \"Failed to set mode -${TMODE}- for -$1-.\" >/dev/tty0 2>&1 " + + test "$VOLATILE_ENABLE_CACHE" = yes && echo "$EXEC" >> /etc/volatile.cache + + [ -e "$1" ] && { + [ "${VERBOSE}" != "no" ] && echo "Target already exists. Skipping." + } || { + eval $EXEC + } +} + +mk_dir() { + EXEC=" + mkdir -p \"$1\"; + chown ${TUSER}.${TGROUP} $1 || echo \"Failed to set owner -${TUSER}- for -$1-.\" >/dev/tty0 2>&1; + chmod ${TMODE} $1 || echo \"Failed to set mode -${TMODE}- for -$1-.\" >/dev/tty0 2>&1 " + + test "$VOLATILE_ENABLE_CACHE" = yes && echo "$EXEC" >> /etc/volatile.cache + + [ -e "$1" ] && { + [ "${VERBOSE}" != "no" ] && echo "Target already exists. Skipping." + } || { + eval $EXEC + } +} + +link_file() { + EXEC="test -e \"$2\" -o -L $2 || ln -s \"$1\" \"$2\" >/dev/tty0 2>&1" + + test "$VOLATILE_ENABLE_CACHE" = yes && echo " $EXEC" >> /etc/volatile.cache + + [ -e "$2" ] && { + echo "Cannot create link over existing -${TNAME}-." >&2 + } || { + eval $EXEC + } +} + +check_requirements() { + + cleanup() { + rm "${TMP_INTERMED}" + rm "${TMP_DEFINED}" + rm "${TMP_COMBINED}" + } + + CFGFILE="$1" + + [ `basename "${CFGFILE}"` = "${COREDEF}" ] && return 0 + + TMP_INTERMED="${TMPROOT}/tmp.$$" + TMP_DEFINED="${TMPROOT}/tmpdefined.$$" + TMP_COMBINED="${TMPROOT}/tmpcombined.$$" + + + cat /etc/passwd | sed 's@\(^:\)*:.*@\1@' | sort | uniq > "${TMP_DEFINED}" + cat ${CFGFILE} | grep -v "^#" | cut -d " " -f 2 > "${TMP_INTERMED}" + cat "${TMP_DEFINED}" "${TMP_INTERMED}" | sort | uniq > "${TMP_COMBINED}" + + NR_DEFINED_USERS="`cat "${TMP_DEFINED}" | wc -l`" + NR_COMBINED_USERS="`cat "${TMP_COMBINED}" | wc -l`" + + [ "${NR_DEFINED_USERS}" -ne "${NR_COMBINED_USERS}" ] && { + echo "Undefined users:" + diff "${TMP_DEFINED}" "${TMP_COMBINED}" | grep "^>" + cleanup + return 1 + } + + + cat /etc/group | sed 's@\(^:\)*:.*@\1@' | sort | uniq > "${TMP_DEFINED}" + cat ${CFGFILE} | grep -v "^#" | cut -d " " -f 3 > "${TMP_INTERMED}" + cat "${TMP_DEFINED}" "${TMP_INTERMED}" | sort | uniq > "${TMP_COMBINED}" + + NR_DEFINED_GROUPS="`cat "${TMP_DEFINED}" | wc -l`" + NR_COMBINED_GROUPS="`cat "${TMP_COMBINED}" | wc -l`" + + [ "${NR_DEFINED_GROUPS}" -ne "${NR_COMBINED_GROUPS}" ] && { + echo "Undefined groups:" + diff "${TMP_DEFINED}" "${TMP_COMBINED}" | grep "^>" + cleanup + return 1 + } + + # Add checks for required directories here + + cleanup + return 0 + } + +apply_cfgfile() { + + CFGFILE="$1" + + check_requirements "${CFGFILE}" || { + echo "Skipping ${CFGFILE}" + return 1 + } + + cat ${CFGFILE} | grep -v "^#" | \ + while read LINE; do + + eval `echo "$LINE" | sed -n "s/\(.*\)\ \(.*\) \(.*\)\ \(.*\)\ \(.*\)\ \(.*\)/TTYPE=\1 ; TUSER=\2; TGROUP=\3; TMODE=\4; TNAME=\5 TLTARGET=\6/p"` + + [ "${VERBOSE}" != "no" ] && echo "Checking for -${TNAME}-." + + + [ "${TTYPE}" = "l" ] && { + TSOURCE="$TLTARGET" + [ -L "${TNAME}" ] || { + [ "${VERBOSE}" != "no" ] && echo "Creating link -${TNAME}- pointing to -${TSOURCE}-." + link_file "${TSOURCE}" "${TNAME}" + } + continue + } + + [ -L "${TNAME}" ] && { + [ "${VERBOSE}" != "no" ] && echo "Found link." + NEWNAME=`ls -l "${TNAME}" | sed -e 's/^.*-> \(.*\)$/\1/'` + echo ${NEWNAME} | grep -v "^/" >/dev/null && { + TNAME="`echo ${TNAME} | sed -e 's@\(.*\)/.*@\1@'`/${NEWNAME}" + [ "${VERBOSE}" != "no" ] && echo "Converted relative linktarget to absolute path -${TNAME}-." + } || { + TNAME="${NEWNAME}" + [ "${VERBOSE}" != "no" ] && echo "Using absolute link target -${TNAME}-." + } + } + + case "${TTYPE}" in + "f") [ "${VERBOSE}" != "no" ] && echo "Creating file -${TNAME}-." + create_file "${TNAME}" + ;; + "d") [ "${VERBOSE}" != "no" ] && echo "Creating directory -${TNAME}-." + mk_dir "${TNAME}" + # Add check to see if there's an entry in fstab to mount. + ;; + *) [ "${VERBOSE}" != "no" ] && echo "Invalid type -${TTYPE}-." + continue + ;; + esac + + + done + + return 0 + + } + +SKEL_DIR="/etc/volatile/skel" + +skel_mount() { + VOLATILE="$1" + + [ -d "$VOLATILE" ] || mkdir -p "$VOLATILE" + + mount -t tmpfs volatile "$VOLATILE" -omode=0755 +} + +skel_load() { + VOLATILE="$1" + + if ! skel_mount "$VOLATILE"; then + echo "failed to mount $VOLATILE" + return 1 + fi + + cp -a "$SKEL_DIR"/* "$VOLATILE"/ +} + +skel_update() { + VOLATILE="$1" + + if ! skel_mount "$VOLATILE"; then + echo "failed to update" + return 1 + fi + + echo -n "Populating volatile directory..." + for file in `ls -1 "${CFGDIR}" | sort`; do + apply_cfgfile "${CFGDIR}/${file}" + done + echo "done" + + if [ -d "$SKEL_DIR" ]; then + rm -rf "$SKEL_DIR" + fi + + mkdir -p "$SKEL_DIR"/tmp + cp -a "$VOLATILE"/* "$SKEL_DIR"/ +} + +populate() { + if [ -d "$SKEL_DIR"/tmp ]; then + skel_load /var/volatile + else + skel_update /var/volatile + fi + + for d in /var/volatile/* + do + ln -sf "$d" /var + done + + if ! test -L /tmp; then + rm -rf /tmp + ln -sf /var/tmp /tmp + fi +} + +case "$1" in + start) + if grep -q "^volatile " /proc/mounts; then + echo "volatile directory is already mounted" + else + populate + fi + ;; + stop) + : # no-op + ;; + update) + if skel_update /var/volatile; then + umount /var/volatile + if grep -q "^volatile " /proc/mounts; then + cp -a "$SKEL_DIR"/* /var/volatile + fi + fi + ;; + *) + echo "Usage: /etc/init.d/populate-volatile {start|stop|update}" + ;; +esac + +: exit 0 diff --git a/recipes/shr/initscripts-shr/reboot b/recipes/shr/initscripts-shr/reboot new file mode 100644 index 0000000000..56278199be --- /dev/null +++ b/recipes/shr/initscripts-shr/reboot @@ -0,0 +1,11 @@ +#! /bin/sh +# +# reboot Execute the reboot command. +# +# Version: @(#)reboot 2.75 22-Jun-1998 miquels@cistron.nl +# + +PATH=/sbin:/bin:/usr/sbin:/usr/bin + +echo -n "Rebooting... " +reboot -d -f -i diff --git a/recipes/shr/initscripts-shr/rmnologin b/recipes/shr/initscripts-shr/rmnologin new file mode 100644 index 0000000000..444145a26a --- /dev/null +++ b/recipes/shr/initscripts-shr/rmnologin @@ -0,0 +1,14 @@ +#! /bin/sh +# +# rmnologin This script removes the /etc/nologin file as the last +# step in the boot process. +# +# Version: @(#)rmnologin 1.00 22-Jun-1998 miquels@cistron.nl +# + +if test -f /etc/nologin.boot +then + rm -f /etc/nologin /etc/nologin.boot +fi + +: exit 0 diff --git a/recipes/shr/initscripts-shr/save-rtc.sh b/recipes/shr/initscripts-shr/save-rtc.sh new file mode 100644 index 0000000000..e786073051 --- /dev/null +++ b/recipes/shr/initscripts-shr/save-rtc.sh @@ -0,0 +1,5 @@ +#! /bin/sh +/etc/init.d/hwclock.sh stop + +# Update the timestamp +date +%2m%2d%2H%2M%Y > /etc/timestamp diff --git a/recipes/shr/initscripts-shr/sendsigs b/recipes/shr/initscripts-shr/sendsigs new file mode 100644 index 0000000000..c62a5cd37d --- /dev/null +++ b/recipes/shr/initscripts-shr/sendsigs @@ -0,0 +1,17 @@ +#! /bin/sh +# +# sendsigs Kill all remaining processes. +# +# Version: @(#)sendsigs 2.75 22-Jun-1998 miquels@cistron.nl +# + +PATH=/sbin:/bin:/usr/sbin:/usr/bin + +# Kill all processes. +echo "Sending all processes the TERM signal..." +killall5 -15 +sleep 5 +echo "Sending all processes the KILL signal..." +killall5 -9 + +: exit 0 diff --git a/recipes/shr/initscripts-shr/umountfs b/recipes/shr/initscripts-shr/umountfs new file mode 100644 index 0000000000..ec75b0c4a4 --- /dev/null +++ b/recipes/shr/initscripts-shr/umountfs @@ -0,0 +1,18 @@ +#! /bin/sh +# +# umountfs Turn off swap and unmount all local filesystems. +# + +PATH=/sbin:/bin:/usr/sbin:/usr/bin + +echo "Deactivating swap..." +swapoff -a + +# We leave /proc mounted. +echo "Unmounting local filesystems..." +mount -o remount,ro /mnt/ram +umount -f -a -r + +mount -o remount,ro / + +: exit 0 diff --git a/recipes/shr/initscripts-shr/umountnfs.sh b/recipes/shr/initscripts-shr/umountnfs.sh new file mode 100644 index 0000000000..f5fe48aa74 --- /dev/null +++ b/recipes/shr/initscripts-shr/umountnfs.sh @@ -0,0 +1,28 @@ +#! /bin/sh +# +# umountnfs.sh Unmount all network filesystems. +# + +PATH=/sbin:/bin:/usr/sbin:/usr/bin + +# Write a reboot record to /var/log/wtmp before unmounting +halt -w + +echo "Unmounting remote filesystems..." + +test -f /etc/fstab && ( + +# +# Read through fstab line by line and unount network file systems +# +while read device mountpt fstype options +do + if test "$fstype" = nfs || test "$fstype" = smbfs || test "$fstype" = ncpfs + then + umount -f $mountpt + fi +done +) < /etc/fstab + +: exit 0 + diff --git a/recipes/shr/initscripts-shr/volatiles b/recipes/shr/initscripts-shr/volatiles new file mode 100644 index 0000000000..fbcc858226 --- /dev/null +++ b/recipes/shr/initscripts-shr/volatiles @@ -0,0 +1,40 @@ +# This configuration file lists filesystem objects that should get verified +# during startup and be created if missing. +# +# Every line must either be a comment starting with # +# or a definition of format: +# +# where the items are separated by whitespace ! +# +# : d|f|l : (d)irectory|(f)ile|(l)ink +# +# A linking example: +# l root root 0777 /var/test /tmp/testfile +# f root root 0644 /var/test none +# +# Understanding links: +# When populate-volatile is to verify/create a directory or file, it will first +# check it's existence. If a link is found to exist in the place of the target, +# the path of the target is replaced with the target the link points to. +# Thus, if a link is in the place to be verified, the object will be created +# in the place the link points to instead. +# This explains the order of "link before object" as in the example above, where +# a link will be created at /var/test pointing to /tmp/testfile and due to this +# link the file defined as /var/test will actually be created as /tmp/testfile. +d root root 0755 /var/volatile/cache none +d root root 1777 /var/volatile/lock none +d root root 0755 /var/volatile/log none +d root root 0755 /var/volatile/run none +d root root 1777 /var/volatile/tmp none +l root root 0755 /var/cache /var/volatile/cache +l root root 1777 /var/lock /var/volatile/lock +l root root 0755 /var/log /var/volatile/log +l root root 0755 /var/run /var/volatile/run +l root root 1777 /var/tmp /var/volatile/tmp +d root root 0755 /var/lock/subsys none +f root root 0664 /var/log/wtmp none +f root root 0644 /var/log/lastlog none +f root root 0664 /var/run/utmp none +l root root 0644 /etc/resolv.conf /var/run/resolv.conf +f root root 0644 /var/run/resolv.conf none + diff --git a/recipes/shr/initscripts-shr_git.bb b/recipes/shr/initscripts-shr_git.bb new file mode 100644 index 0000000000..46ea6529ba --- /dev/null +++ b/recipes/shr/initscripts-shr_git.bb @@ -0,0 +1,107 @@ +DESCRIPTION = "SHR init scripts" +SECTION = "base" +PRIORITY = "required" +DEPENDS = "" +RDEPENDS = "" +LICENSE = "GPL" +PV = "0.0.1+${PR}-gitr${SRCREV}" +PR = "r11" + +RPROVIDES_${PN} = "initscripts" +RCONFLICTS_${PN} = "initscripts" +RREPLACES_${PN} = "initscripts" + +SRC_URI = "file://alignment.sh \ + file://bootmisc.sh \ + file://checkroot.sh \ + file://finish.sh \ + file://functions \ + file://g_ether.sh \ + file://hostname.sh \ + file://mountall.sh \ + file://mountdevsubfs.sh \ + file://mountkernfs.sh \ + file://mountnfs.sh \ + file://populate-volatile.sh \ + file://devpts \ + file://volatiles \ + file://halt \ + file://reboot \ + file://rmnologin \ + file://save-rtc.sh \ + file://sendsigs \ + file://umountfs \ + file://umountnfs.sh \ + " + +inherit base + +do_install () { +# +# Create directories and install device independent scripts +# + install -d ${D}${sysconfdir}/init.d + install -d ${D}${sysconfdir}/rcS.d + install -d ${D}${sysconfdir}/rc0.d + install -d ${D}${sysconfdir}/rc1.d + install -d ${D}${sysconfdir}/rc2.d + install -d ${D}${sysconfdir}/rc3.d + install -d ${D}${sysconfdir}/rc4.d + install -d ${D}${sysconfdir}/rc5.d + install -d ${D}${sysconfdir}/rc6.d + install -d ${D}${sysconfdir}/default + install -d ${D}${sysconfdir}/default/volatiles + + install -m 0755 ${WORKDIR}/alignment.sh ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/bootmisc.sh ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/checkroot.sh ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/finish.sh ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/functions ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/g_ether.sh ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/hostname.sh ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/mountall.sh ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/mountnfs.sh ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/mountdevsubfs.sh ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/mountkernfs.sh ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/populate-volatile.sh ${D}${sysconfdir}/init.d + + install -m 0644 ${WORKDIR}/devpts ${D}${sysconfdir}/default/devpts + install -m 0644 ${WORKDIR}/volatiles ${D}${sysconfdir}/default/volatiles/00_core + + install -m 0755 ${WORKDIR}/halt ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/reboot ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/rmnologin ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/save-rtc.sh ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/sendsigs ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/umountfs ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/umountnfs.sh ${D}${sysconfdir}/init.d + +# +# Create runlevel links +# + ln -sf ../init.d/mountkernfs.sh ${D}${sysconfdir}/rcS.d/S01mountkernfs.sh + ln -sf ../init.d/g_ether.sh ${D}${sysconfdir}/rcS.d/S02g_ether.sh + ln -sf ../init.d/hostname.sh ${D}${sysconfdir}/rcS.d/S02hostname.sh + ln -sf ../init.d/checkroot.sh ${D}${sysconfdir}/rcS.d/S02checkroot.sh + ln -sf ../init.d/mountdevsubfs.sh ${D}${sysconfdir}/rcS.d/S04mountdevsubfs.sh + ln -sf ../init.d/alignment.sh ${D}${sysconfdir}/rcS.d/S06alignment.sh + ln -sf ../init.d/mountall.sh ${D}${sysconfdir}/rcS.d/S35mountall.sh + ln -sf ../init.d/populate-volatile.sh ${D}${sysconfdir}/rcS.d/S37populate-volatile.sh + ln -sf ../init.d/mountnfs.sh ${D}${sysconfdir}/rcS.d/S45mountnfs.sh + ln -sf ../init.d/bootmisc.sh ${D}${sysconfdir}/rcS.d/S55bootmisc.sh + ln -sf ../init.d/finish.sh ${D}${sysconfdir}/rcS.d/S99finish.sh + + ln -sf ../init.d/rmnologin ${D}${sysconfdir}/rc5.d/S99rmnologin + + ln -sf ../init.d/sendsigs ${D}${sysconfdir}/rc0.d/S20sendsigs + ln -sf ../init.d/save-rtc.sh ${D}${sysconfdir}/rc0.d/S25save-rtc.sh + ln -sf ../init.d/umountnfs.sh ${D}${sysconfdir}/rc6.d/S31umountnfs.sh + ln -sf ../init.d/umountfs ${D}${sysconfdir}/rc0.d/S40umountfs + ln -sf ../init.d/halt ${D}${sysconfdir}/rc0.d/S90halt + + ln -sf ../init.d/sendsigs ${D}${sysconfdir}/rc6.d/S20sendsigs + ln -sf ../init.d/save-rtc.sh ${D}${sysconfdir}/rc6.d/S25save-rtc.sh + ln -sf ../init.d/umountnfs.sh ${D}${sysconfdir}/rc6.d/S31umountnfs.sh + ln -sf ../init.d/umountfs ${D}${sysconfdir}/rc6.d/S40umountfs + ln -sf ../init.d/reboot ${D}${sysconfdir}/rc6.d/S90reboot +} -- cgit v1.2.3 From a318f679fc23e7d7f4fc03d833ff50d3a2061f12 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Thu, 17 Sep 2009 18:05:46 +0000 Subject: bphone-utils: Add recipe (from SHR) --- recipes/shr/libphone-utils_git.bb | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 recipes/shr/libphone-utils_git.bb diff --git a/recipes/shr/libphone-utils_git.bb b/recipes/shr/libphone-utils_git.bb new file mode 100644 index 0000000000..7cf26ffec1 --- /dev/null +++ b/recipes/shr/libphone-utils_git.bb @@ -0,0 +1,12 @@ +DESCRIPTION = "phone-utils library" +SECTION = "libs" +PV = "0.0.2+gitr${SRCREV}" +PR = "r2" + +DEPENDS="glib-2.0" + +inherit pkgconfig autotools autotools_stage + +CONFFILES_${PN} = "${sysconfdir}/phone-utils.conf" +SRC_URI = "git://git.shr-project.org/repo/libphone-utils.git;protocol=http;branch=master" +S="${WORKDIR}/git" -- cgit v1.2.3 From a86973493bcff0d87c1beb8302ab7cf8f499b8bc Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Thu, 17 Sep 2009 18:08:03 +0000 Subject: alsa-scenarii-shr: Add recipe (from SHR) --- recipes/shr/alsa-scenarii-shr_git.bb | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 recipes/shr/alsa-scenarii-shr_git.bb diff --git a/recipes/shr/alsa-scenarii-shr_git.bb b/recipes/shr/alsa-scenarii-shr_git.bb new file mode 100644 index 0000000000..97b4393459 --- /dev/null +++ b/recipes/shr/alsa-scenarii-shr_git.bb @@ -0,0 +1,25 @@ +DESCRIPTION = "Package for the different scenarios used by Openmoko" +SECTION = "openmoko/base" +PV = "1.0+gitr${SRCREV}" +PR = "r1" + +COMPATIBLE_MACHINE = "(om-gta01|om-gta02|om-3d7k)" + +SRC_URI = "git://git.shr-project.org/repo/shr-themes.git;protocol=http;branch=master" + +S = "${WORKDIR}/git/${PN}/${MACHINE_ARCH}" + +do_install() { + install -d ${D}${datadir}/shr/scenarii/ + install -m 644 ${S}/*.state ${D}${datadir}/shr/scenarii/ + install -d ${D}${sysconfdir}/ + install -m 644 ${S}/stereoout.state ${D}${sysconfdir}/asound.state +} + +PACKAGE_ARCH_${PN} = "${MACHINE_ARCH}" + +FILES_${PN} += "${datadir}/shr" + +CONFFILES_${PN} += "${datadir}/shr/scenarii/*" +RPROVIDES_${PN} = "openmoko-alsa-scenarios" + -- cgit v1.2.3 From 08678a65e417b0826a088c3f787180ed7d77497d Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Thu, 17 Sep 2009 18:12:18 +0000 Subject: etk-theme-shr: Add recipe (from SHR) --- recipes/shr/etk-theme-shr_git.bb | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 recipes/shr/etk-theme-shr_git.bb diff --git a/recipes/shr/etk-theme-shr_git.bb b/recipes/shr/etk-theme-shr_git.bb new file mode 100644 index 0000000000..d146765c94 --- /dev/null +++ b/recipes/shr/etk-theme-shr_git.bb @@ -0,0 +1,22 @@ +DESCRIPTION = "etk SHR theme" +SECTION = "e/utils" +DEPENDS = "edje-native" +LICENSE = "MIT BSD" +PV = "1.1-${EFL_SRCREV}-gitr${SRCREV}" + +SRC_URI = "git://git.shr-project.org/repo/shr-themes.git;protocol=http;branch=master" + +S = "${WORKDIR}/git/etk/${PN}" + +do_compile() { + ${STAGING_BINDIR_NATIVE}/edje_cc -id ${S}/. -fd ${S}/. ${S}/default.edc -o ${S}/default.edj +} + +do_install() { + install -d ${D}${datadir}/etk/themes/ + install -m 0644 ${S}/default.edj ${D}${datadir}/etk/themes/ +} + +FILES_${PN} = "${datadir}/etk/themes/default.edj" + + -- cgit v1.2.3 From 0c186bfb52995ccaede61d0b310886e7eeca6e0d Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Thu, 17 Sep 2009 18:37:33 +0000 Subject: illume-keyboard*: A bunch of illume keyboard layouts. (from SHR) --- recipes/efl1/illume-keyboard-arabic_git.bb | 11 +++++++++++ recipes/efl1/illume-keyboard-browse_git.bb | 19 +++++++++++++++++++ recipes/efl1/illume-keyboard-danish_git.bb | 11 +++++++++++ recipes/efl1/illume-keyboard-default-alt_git.bb | 11 +++++++++++ recipes/efl1/illume-keyboard-dutch_git.bb | 21 +++++++++++++++++++++ recipes/efl1/illume-keyboard-dvorak_git.bb | 11 +++++++++++ recipes/efl1/illume-keyboard-french_git.bb | 10 ++++++++++ recipes/efl1/illume-keyboard-german_git.bb | 11 +++++++++++ recipes/efl1/illume-keyboard-hebrew_git.bb | 11 +++++++++++ recipes/efl1/illume-keyboard-numeric-alt_git.bb | 18 ++++++++++++++++++ .../efl1/illume-keyboard-russian-terminal_git.bb | 9 +++++++++ recipes/efl1/illume-keyboard-russian_git.bb | 11 +++++++++++ recipes/efl1/illume-keyboard.inc | 14 ++++++++++++++ 13 files changed, 168 insertions(+) create mode 100644 recipes/efl1/illume-keyboard-arabic_git.bb create mode 100644 recipes/efl1/illume-keyboard-browse_git.bb create mode 100644 recipes/efl1/illume-keyboard-danish_git.bb create mode 100644 recipes/efl1/illume-keyboard-default-alt_git.bb create mode 100644 recipes/efl1/illume-keyboard-dutch_git.bb create mode 100644 recipes/efl1/illume-keyboard-dvorak_git.bb create mode 100644 recipes/efl1/illume-keyboard-french_git.bb create mode 100644 recipes/efl1/illume-keyboard-german_git.bb create mode 100644 recipes/efl1/illume-keyboard-hebrew_git.bb create mode 100644 recipes/efl1/illume-keyboard-numeric-alt_git.bb create mode 100644 recipes/efl1/illume-keyboard-russian-terminal_git.bb create mode 100644 recipes/efl1/illume-keyboard-russian_git.bb create mode 100644 recipes/efl1/illume-keyboard.inc diff --git a/recipes/efl1/illume-keyboard-arabic_git.bb b/recipes/efl1/illume-keyboard-arabic_git.bb new file mode 100644 index 0000000000..41ea9e1cd4 --- /dev/null +++ b/recipes/efl1/illume-keyboard-arabic_git.bb @@ -0,0 +1,11 @@ +AUTHOR = "Mohammad Fahmi / Tom Hacohen" +DESCRIPTION = "Illume keyboard with arabic layout" +PV = "0.0-gitr${SRCREV}" +PR = "r0" + +BASEDIR = "arabic" +INSTFILES = "Arabic.kbd Arabic.png" + +require illume-keyboard.inc + + diff --git a/recipes/efl1/illume-keyboard-browse_git.bb b/recipes/efl1/illume-keyboard-browse_git.bb new file mode 100644 index 0000000000..268140c75a --- /dev/null +++ b/recipes/efl1/illume-keyboard-browse_git.bb @@ -0,0 +1,19 @@ +AUTHOR = "Pander" +DESCRIPTION = "Illume keyboard with a layout optimized for browsing" +PV = "0.0-gitr${SRCREV}" +PR = "r0" + +BASEDIR = "browse" +INSTFILES = "\ +Browse.kbd \ +end-browse.png \ +pagedown-browse.png \ +browse.png \ +home-browse.png \ +pageup-browse.png \ +space-browse.png \ +" + +require illume-keyboard.inc + + diff --git a/recipes/efl1/illume-keyboard-danish_git.bb b/recipes/efl1/illume-keyboard-danish_git.bb new file mode 100644 index 0000000000..21f8ff954a --- /dev/null +++ b/recipes/efl1/illume-keyboard-danish_git.bb @@ -0,0 +1,11 @@ +AUTHOR = "Esben Damgaard" +DESCRIPTION = "Illume keyboard with danish layout" +PV = "0.0-gitr${SRCREV}" +PR = "r0" + +BASEDIR = "danish" +INSTFILES = "Danish.kbd danish.png" + +require illume-keyboard.inc + + diff --git a/recipes/efl1/illume-keyboard-default-alt_git.bb b/recipes/efl1/illume-keyboard-default-alt_git.bb new file mode 100644 index 0000000000..34c3c299bb --- /dev/null +++ b/recipes/efl1/illume-keyboard-default-alt_git.bb @@ -0,0 +1,11 @@ +AUTHOR = "Pander" +DESCRIPTION = "Illume keyboard with an alternative default layout" +PV = "0.0-gitr${SRCREV}" +PR = "r0" + +BASEDIR = "default-alt" +INSTFILES = "Default-alt.kbd" + +require illume-keyboard.inc + + diff --git a/recipes/efl1/illume-keyboard-dutch_git.bb b/recipes/efl1/illume-keyboard-dutch_git.bb new file mode 100644 index 0000000000..2300ac7101 --- /dev/null +++ b/recipes/efl1/illume-keyboard-dutch_git.bb @@ -0,0 +1,21 @@ +AUTHOR = "Pander" +DESCRIPTION = "Illume keyboard with dutch layout" +PV = "0.0-gitr${SRCREV}" +PR = "r0" + +BASEDIR = "dutch" +INSTFILES = "\ +capslock-negative.png \ +end.png \ +pagedown.png \ +qwerty-dutch-nl.png \ +Terminal-dutch-nl.kbd \ +capslock.png \ +home.png \ +pageup.png \ +space.png \ +" + +require illume-keyboard.inc + + diff --git a/recipes/efl1/illume-keyboard-dvorak_git.bb b/recipes/efl1/illume-keyboard-dvorak_git.bb new file mode 100644 index 0000000000..795d78dcc7 --- /dev/null +++ b/recipes/efl1/illume-keyboard-dvorak_git.bb @@ -0,0 +1,11 @@ +AUTHOR = "Gabor Adam TOTH" +DESCRIPTION = "Illume keyboard with dvorak layout" +PV = "0.0-gitr${SRCREV}" +PR = "r0" + +BASEDIR = "dvorak" +INSTFILES = "Dvorak.kbd dvorak.png" + +require illume-keyboard.inc + + diff --git a/recipes/efl1/illume-keyboard-french_git.bb b/recipes/efl1/illume-keyboard-french_git.bb new file mode 100644 index 0000000000..205a6ad991 --- /dev/null +++ b/recipes/efl1/illume-keyboard-french_git.bb @@ -0,0 +1,10 @@ +DESCRIPTION = "Illume keyboard with french layout" +PV = "0.0-gitr${SRCREV}" +PR = "r0" + +BASEDIR = "french" +INSTFILES = "Azerty.kbd Azerty.png" + +require illume-keyboard.inc + + diff --git a/recipes/efl1/illume-keyboard-german_git.bb b/recipes/efl1/illume-keyboard-german_git.bb new file mode 100644 index 0000000000..0252932116 --- /dev/null +++ b/recipes/efl1/illume-keyboard-german_git.bb @@ -0,0 +1,11 @@ +AUTHOR = "Florian Hackenberger" +DESCRIPTION = "Illume keyboard with german layout" +PV = "0.0-gitr${SRCREV}" +PR = "r0" + +BASEDIR = "german" +INSTFILES = "German.kbd German.png" + +require illume-keyboard.inc + + diff --git a/recipes/efl1/illume-keyboard-hebrew_git.bb b/recipes/efl1/illume-keyboard-hebrew_git.bb new file mode 100644 index 0000000000..8d408b4a91 --- /dev/null +++ b/recipes/efl1/illume-keyboard-hebrew_git.bb @@ -0,0 +1,11 @@ +AUTHOR = "Tom Hacohen" +DESCRIPTION = "Illume keyboard with hebrew layout" +PV = "0.0-gitr${SRCREV}" +PR = "r0" + +BASEDIR = "hebrew" +INSTFILES = "Hebrew.kbd Alpha-hebrew-il.png" + +require illume-keyboard.inc + + diff --git a/recipes/efl1/illume-keyboard-numeric-alt_git.bb b/recipes/efl1/illume-keyboard-numeric-alt_git.bb new file mode 100644 index 0000000000..f2d2487386 --- /dev/null +++ b/recipes/efl1/illume-keyboard-numeric-alt_git.bb @@ -0,0 +1,18 @@ +AUTHOR = "Pander" +DESCRIPTION = "Illume keyboard with an alternative numeric layout" +PV = "0.0-gitr${SRCREV}" +PR = "r0" + +BASEDIR = "numeric-alt" +INSTFILES = "\ +end-alt.png \ +home-alt.png \ +Numbers-alt.kbd \ +numeric-alt.png \ +pagedown-alt.png \ +pageup-alt.png \ +" + +require illume-keyboard.inc + + diff --git a/recipes/efl1/illume-keyboard-russian-terminal_git.bb b/recipes/efl1/illume-keyboard-russian-terminal_git.bb new file mode 100644 index 0000000000..f0a4508d98 --- /dev/null +++ b/recipes/efl1/illume-keyboard-russian-terminal_git.bb @@ -0,0 +1,9 @@ +AUTHOR = "lucky" +DESCRIPTION = "Illume keyboard with russian layout for the Terminal" +PV = "0.0-gitr${SRCREV}" +PR = "r0" + +BASEDIR = "russian-terminal" +INSTFILES = "Terminal_Russian.kbd Terminal-russian-ru.png" + +require illume-keyboard.inc diff --git a/recipes/efl1/illume-keyboard-russian_git.bb b/recipes/efl1/illume-keyboard-russian_git.bb new file mode 100644 index 0000000000..517956bb2b --- /dev/null +++ b/recipes/efl1/illume-keyboard-russian_git.bb @@ -0,0 +1,11 @@ +AUTHOR = "lucky" +DESCRIPTION = "Illume keyboard with russian layout" +PV = "0.0-gitr${SRCREV}" +PR = "r0" + +BASEDIR = "russian" +INSTFILES = "X8_Russian.kbd X8-russian-ru.png" + +require illume-keyboard.inc + + diff --git a/recipes/efl1/illume-keyboard.inc b/recipes/efl1/illume-keyboard.inc new file mode 100644 index 0000000000..4003352cc1 --- /dev/null +++ b/recipes/efl1/illume-keyboard.inc @@ -0,0 +1,14 @@ +SECTION = "x11/data" + +SRC_URI = "git://git.shr-project.org/repo/illume-keyboards.git;protocol=http;branch=master" +S = "${WORKDIR}/git" + +FILES_${PN} = "${libdir}/enlightenment/modules/illume/keyboards/*" +PACKAGE_ARCH = "all" + +do_install() { + install -d ${D}${libdir}/enlightenment/modules/illume/keyboards + for f in ${INSTFILES}; do + install -m 0644 ${S}/${BASEDIR}/${f} ${D}${libdir}/enlightenment/modules/illume/keyboards/ + done +} -- cgit v1.2.3 From 83688479d4e4d31dbbbcb0413b76e2c393449b07 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Thu, 17 Sep 2009 18:51:20 +0000 Subject: e-wm-illume-dict-pl: Polish dict for the illume keyboard (from SHR) --- recipes/efl1/e-wm-illume-dict-pl_git.bb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 recipes/efl1/e-wm-illume-dict-pl_git.bb diff --git a/recipes/efl1/e-wm-illume-dict-pl_git.bb b/recipes/efl1/e-wm-illume-dict-pl_git.bb new file mode 100644 index 0000000000..a5cf1938c4 --- /dev/null +++ b/recipes/efl1/e-wm-illume-dict-pl_git.bb @@ -0,0 +1,15 @@ +DESCRIPTION = "Polish dictionary for Illume keyboard" +SECTION = "x11/data" +PV = "1.0-gitr${SRCREV}" +PR = "r0" + +SRC_URI = "git://git.shr-project.org/repo/shr-themes.git;protocol=http;branch=master" + +S = "${WORKDIR}/git/e-wm/${PN}" + +FILES_${PN} = "${libdir}/enlightenment/modules/illume/dicts/Polish.dic" + +do_install() { + install -d ${D}${libdir}/enlightenment/modules/illume/dicts + install -m 0644 ${S}/Polish.dic ${D}${libdir}/enlightenment/modules/illume/dicts/Polish.dic +} -- cgit v1.2.3 From 60a62492379f4e012be9041ab6886b57bf026854 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Thu, 17 Sep 2009 18:57:25 +0000 Subject: e-wm-theme-illume-niebiee: Add recipe (from SHR) --- recipes/shr/e-wm-theme-illume-niebiee_git.bb | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 recipes/shr/e-wm-theme-illume-niebiee_git.bb diff --git a/recipes/shr/e-wm-theme-illume-niebiee_git.bb b/recipes/shr/e-wm-theme-illume-niebiee_git.bb new file mode 100644 index 0000000000..bd3412d0ff --- /dev/null +++ b/recipes/shr/e-wm-theme-illume-niebiee_git.bb @@ -0,0 +1,23 @@ +DESCRIPTION = "Extremely blue Illume theme - Niebiee" +SECTION = "e/utils" +DEPENDS = "edje-native" +LICENSE = "MIT BSD" +PV = "0.1-${EFL_SRCREV}-gitr${SRCREV}" +PR = "r0" + +SRC_URI = "git://git.shr-project.org/repo/shr-themes.git;protocol=http;branch=master" + +S = "${WORKDIR}/git/e-wm/${PN}" + +do_compile() { + ${STAGING_BINDIR_NATIVE}/edje_cc -id ${S}/images/. -fd ${S}/fonts/. ${S}/illume-niebiee.edc -o ${S}/illume-niebiee.edj +} + +do_install() { + install -d ${D}${datadir}/enlightenment/data/themes/ + install -m 0644 ${S}/illume-niebiee.edj ${D}${datadir}/enlightenment/data/themes/ +} + +FILES_${PN} = "${datadir}/enlightenment/data/themes/illume-niebiee.edj" + + -- cgit v1.2.3 From dd9df493e158e09f9379d8232678f7616cbca762 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Thu, 17 Sep 2009 18:57:53 +0000 Subject: e-wm-theme-illume-sixteen: Add recipe (from SHR) --- recipes/shr/e-wm-theme-illume-sixteen_git.bb | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 recipes/shr/e-wm-theme-illume-sixteen_git.bb diff --git a/recipes/shr/e-wm-theme-illume-sixteen_git.bb b/recipes/shr/e-wm-theme-illume-sixteen_git.bb new file mode 100644 index 0000000000..5c3d65825e --- /dev/null +++ b/recipes/shr/e-wm-theme-illume-sixteen_git.bb @@ -0,0 +1,23 @@ +DESCRIPTION = "illume SHR theme" +SECTION = "e/utils" +DEPENDS = "edje-native" +LICENSE = "MIT BSD" +PV = "0.1-${EFL_SRCREV}-gitr${SRCREV}" +PR = "r0" + +SRC_URI = "git://git.shr-project.org/repo/shr-themes.git;protocol=http;branch=master" + +S = "${WORKDIR}/git/e-wm/${PN}" + +do_compile() { + ${STAGING_BINDIR_NATIVE}/edje_cc -id ${S}/images/. -fd ${S}/fonts/. ${S}/illume-sixteen.edc -o ${S}/illume-sixteen.edj +} + +do_install() { + install -d ${D}${datadir}/enlightenment/data/themes/ + install -m 0644 ${S}/illume-sixteen.edj ${D}${datadir}/enlightenment/data/themes/ +} + +FILES_${PN} = "${datadir}/enlightenment/data/themes/illume-sixteen.edj" + + -- cgit v1.2.3 From d56ffbe90a9e19915f7bbe1de559438946daa916 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Thu, 17 Sep 2009 19:05:23 +0000 Subject: elementary-theme-*: Elementary themes (from SHR) --- recipes/shr/elementary-theme-niebiee_git.bb | 21 +++++++++++++++++++++ recipes/shr/elementary-theme-sixteen_git.bb | 23 +++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 recipes/shr/elementary-theme-niebiee_git.bb create mode 100644 recipes/shr/elementary-theme-sixteen_git.bb diff --git a/recipes/shr/elementary-theme-niebiee_git.bb b/recipes/shr/elementary-theme-niebiee_git.bb new file mode 100644 index 0000000000..f58257d48c --- /dev/null +++ b/recipes/shr/elementary-theme-niebiee_git.bb @@ -0,0 +1,21 @@ +DESCRIPTION = "Extremely blue elementary theme - Niebiee" +SECTION = "e/utils" +DEPENDS = "edje-native" +LICENSE = "MIT BSD" +PV = "0.1-${EFL_SRCREV}-gitr${SRCREV}" +PR = "r0" + +SRC_URI = "git://git.shr-project.org/repo/shr-themes.git;protocol=http;branch=master" + +S = "${WORKDIR}/git/elementary/${PN}" + +do_compile() { + ${STAGING_BINDIR_NATIVE}/edje_cc -id ${S}/images/. -fd ${S}/fonts/. ${S}/niebiee.edc -o ${S}/niebiee.edj +} + +do_install() { + install -d ${D}${datadir}/elementary/themes/ + install -m 0644 ${S}/niebiee.edj ${D}${datadir}/elementary/themes/ +} + +FILES_${PN} = "${datadir}/elementary/themes/niebiee.edj" diff --git a/recipes/shr/elementary-theme-sixteen_git.bb b/recipes/shr/elementary-theme-sixteen_git.bb new file mode 100644 index 0000000000..48cbc615fa --- /dev/null +++ b/recipes/shr/elementary-theme-sixteen_git.bb @@ -0,0 +1,23 @@ +DESCRIPTION = "elementary SHR theme" +SECTION = "e/utils" +DEPENDS = "edje-native" +LICENSE = "MIT BSD" +PV = "0.1-${EFL_SRCREV}-gitr${SRCREV}" +PR = "r2" + +SRC_URI = "git://git.shr-project.org/repo/shr-themes.git;protocol=http;branch=master" + +S = "${WORKDIR}/git/elementary/${PN}" + +do_compile() { + ${STAGING_BINDIR_NATIVE}/edje_cc -id ${S}/images/. -fd ${S}/fonts/. ${S}/sixteen.edc -o ${S}/sixteen.edj +} + +do_install() { + install -d ${D}${datadir}/elementary/themes/ + install -m 0644 ${S}/sixteen.edj ${D}${datadir}/elementary/themes/ +} + +FILES_${PN} = "${datadir}/elementary/themes/sixteen.edj" + + -- cgit v1.2.3 From 62b5c01bde0a1e5769ab4dba184be51d2907933a Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 17 Sep 2009 21:51:47 +0200 Subject: gst-rtsp: add 0.10.4 * vala and python binding haven't been enabled, they most likely require some patching --- conf/checksums.ini | 25 ++++++++++++++++++++----- recipes/gstreamer/gst-rtsp_0.10.4.bb | 12 ++++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 recipes/gstreamer/gst-rtsp_0.10.4.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index 0f57d97bec..c0527325db 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -2918,6 +2918,10 @@ sha256=31f058fb722dfb96a7b496a064e0c46d634d7dffdd5b64c7dce3ab6ec2fa48bc md5=b54a199004b578ec5652014a5e62aeaa sha256=830bb7da6836b0c709abee212ed8387e1ad8cd7087ed0b925fad3d16b0113b76 +[http://www.kernel.org/pub/linux/bluetooth/bluez-4.53.tar.gz] +md5=432509193ea508da5ce23fe056625d0f +sha256=bef741e8538f99baad6c32b4026cdecc636e8fa0c9f549542a4451e0987ceccf + [http://www.kernel.org/pub/linux/bluetooth/bluez-4.7.tar.gz] md5=2aa806940d2c841e57a9b2ab7302b750 sha256=ed384dea4f5f21157758fcd7db64db19ce0b410509c26630706e4a3c779287a0 @@ -4346,6 +4350,10 @@ sha256=8b718c344cf19417447cbc16867d2e04434654c13b330598b96720ead146b961 md5=0aa2f94c39123f1a0352983e5366179c sha256=4bab529afa00cafde3bc5df2769578c88438f80c5152d4257cd0e86986f95bc4 +[http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/dvsdk/DVSDK_3_00/latest//exports/cs1omap3530_setuplinux_1_00_01-42.bin] +md5=a1e19ef37638e977d059fd22af666301 +sha256=fc7ac2829df8d394635aa1cc704b78e93ca287111df1001e5738ae2282691219 + [http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/dvsdk/DVSDK_3_00/latest//exports/cs1omap3530_setuplinux_1_00_01.bin] md5=779415872c771b580e4c6d10346b3a79 sha256=0903c37aaa9ced2c12a9e7d4a418b7d57d5a92a0f1451afd29f70bd0da240bc8 @@ -10266,6 +10274,10 @@ sha256=24520b3e33f98a3bcc79ad68f7d426475cbacf12e4c56338f58a05158523d71d md5=c9a7a6324104dc84502fc066c4fc4220 sha256=f1aeb28d27ea4078467125e7eb5ee2b16b08443c9f5f3aa1010d262c37aacc0b +[http://people.freedesktop.org/~wtay/gst-rtsp-0.10.4.tar.bz2] +md5=8daaca1299aeb42c6aac47b30291005b +sha256=1ebf3571d16dbab401f2ebf0362e3d67457fb88711ad15a4ab51bd3730267fb7 + [http://gstreamer.freedesktop.org/src/gstreamer/gstreamer-0.10.11.tar.bz2] md5=67240094e08c845b7bbcfba755c95695 sha256=d7130fbcbcac945c28402361b60e8d24d97f75d795ba91401617f81e595a7dd5 @@ -25026,6 +25038,14 @@ sha256=10263676cb872ca48d8d605be44eb1e6260419675409732e7e5a76eb41843cee md5=c7929eefe38cab5985834d5163292121 sha256=6f37a0a9a5deb501176bc119b2df61746ccdd6ba95c80f179d8fff1ed323371e +[http://garage.maemo.org/frs/download.php/4505/vagalume_0.7.orig.tar.gz] +md5=97e1497eed21ef0ac82514ead94c5ee4 +sha256=82b42534276018809aec934b572845e495ea19fc0c6abf6b6ef1e8571b91ccee + +[http://people.igalia.com/berto/files/vagalume/source/vagalume_0.7.orig.tar.gz] +md5=97e1497eed21ef0ac82514ead94c5ee4 +sha256=82b42534276018809aec934b572845e495ea19fc0c6abf6b6ef1e8571b91ccee + [http://download.gnome.org/sources/vala/0.1/vala-0.1.5.tar.bz2] md5=4e082ecb7f60ebdc49f3bd19ae7ebca2 sha256=20c577c9130f114dda24fd5a1c19cd477679553c4e2e7c8362471ae1f21b6836 @@ -29030,8 +29050,3 @@ sha256=f57c4e33eb2cdd87a6c2f01bfa4794340fbe61ea1a1cfc7dac3b6671e1dd22af md5=5f7b88ebb2bcd7e8044328482d079661 sha256=f57c4e33eb2cdd87a6c2f01bfa4794340fbe61ea1a1cfc7dac3b6671e1dd22af -[http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/dvsdk/DVSDK_3_00/latest//exports/cs1omap3530_setuplinux_1_00_01-42.bin] -md5=a1e19ef37638e977d059fd22af666301 -sha256=fc7ac2829df8d394635aa1cc704b78e93ca287111df1001e5738ae2282691219 - - diff --git a/recipes/gstreamer/gst-rtsp_0.10.4.bb b/recipes/gstreamer/gst-rtsp_0.10.4.bb new file mode 100644 index 0000000000..11c57aa71f --- /dev/null +++ b/recipes/gstreamer/gst-rtsp_0.10.4.bb @@ -0,0 +1,12 @@ +DESCRIPTION = "Gstreamer RTSP server" +LICENSE = "LGPLv2" + +DEPENDS = "gst-plugins-base gstreamer" + +SRC_URI = "http://people.freedesktop.org/~wtay/gst-rtsp-${PV}.tar.bz2" + +inherit autotools_stage + +AUTOTOOLS_STAGE_PKGCONFIG = "1" + + -- cgit v1.2.3 From 33cee0586991e235d0fe3d984f822ef2f310e7c3 Mon Sep 17 00:00:00 2001 From: Stanislav Brabec Date: Thu, 17 Sep 2009 20:35:50 +0000 Subject: autoconf: Fixed calling of perl and m4: * removed path_prog_fixes.patch * set needed ac_cv_* variables for non-native builds * depend on perl * for more see http://thread.gmane.org/gmane.comp.handhelds.openembedded/26476 --- .../autoconf/autoconf-2.59/path_prog_fixes.patch | 126 --------------------- .../autoconf/autoconf-2.61/path_prog_fixes.patch | 126 --------------------- .../autoconf/autoconf-2.63/path_prog_fixes.patch | 126 --------------------- recipes/autoconf/autoconf.inc | 12 +- recipes/autoconf/autoconf_2.59.bb | 3 +- recipes/autoconf/autoconf_2.63.bb | 12 +- 6 files changed, 16 insertions(+), 389 deletions(-) delete mode 100644 recipes/autoconf/autoconf-2.59/path_prog_fixes.patch delete mode 100644 recipes/autoconf/autoconf-2.61/path_prog_fixes.patch delete mode 100644 recipes/autoconf/autoconf-2.63/path_prog_fixes.patch diff --git a/recipes/autoconf/autoconf-2.59/path_prog_fixes.patch b/recipes/autoconf/autoconf-2.59/path_prog_fixes.patch deleted file mode 100644 index 5f0d055a48..0000000000 --- a/recipes/autoconf/autoconf-2.59/path_prog_fixes.patch +++ /dev/null @@ -1,126 +0,0 @@ -Index: autoconf-2.59/bin/autoheader.in -=================================================================== ---- autoconf-2.59.orig/bin/autoheader.in 2005-03-09 16:27:17.933878952 -0500 -+++ autoconf-2.59/bin/autoheader.in 2005-03-09 16:29:57.360642400 -0500 -@@ -1,8 +1,8 @@ --#! @PERL@ -+#! @bindir@/env perl - # -*- Perl -*- - # @configure_input@ - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @bindir@/env perl -S "$0" "$@";; esac' - if 0; - - # autoheader -- create `config.h.in' from `configure.ac' -Index: autoconf-2.59/bin/autom4te.in -=================================================================== ---- autoconf-2.59.orig/bin/autom4te.in 2003-10-28 03:48:36.000000000 -0500 -+++ autoconf-2.59/bin/autom4te.in 2005-03-09 16:30:14.957967200 -0500 -@@ -1,8 +1,10 @@ --#! @PERL@ -w -+#! @bindir@/env perl - # -*- perl -*- - # @configure_input@ - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+use warnings; -+ -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' - if 0; - - # autom4te - Wrapper around M4 libraries. -@@ -87,7 +89,7 @@ - my $freeze = 0; - - # $M4. --my $m4 = $ENV{"M4"} || '@M4@'; -+my $m4 = $ENV{"M4"} || '@bindir@/env m4'; - # Some non-GNU m4's don't reject the --help option, so give them /dev/null. - fatal "need GNU m4 1.4 or later: $m4" - if system "$m4 --help &1 | grep reload-state >/dev/null"; -Index: autoconf-2.59/bin/autoreconf.in -=================================================================== ---- autoconf-2.59.orig/bin/autoreconf.in 2005-03-09 16:27:17.354966960 -0500 -+++ autoconf-2.59/bin/autoreconf.in 2005-03-09 16:31:19.572144352 -0500 -@@ -1,8 +1,10 @@ --#! @PERL@ -w -+#! @bindir@/env perl - # -*- perl -*- - # @configure_input@ - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+use warnings; -+ -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' - if 0; - - # autoreconf - install the GNU Build System in a directory tree -Index: autoconf-2.59/bin/autoscan.in -=================================================================== ---- autoconf-2.59.orig/bin/autoscan.in 2003-09-26 08:57:49.000000000 -0400 -+++ autoconf-2.59/bin/autoscan.in 2005-03-09 16:30:18.136483992 -0500 -@@ -1,4 +1,4 @@ --#! @PERL@ -w -+#! @bindir@/env perl - # -*- perl -*- - # autoscan - Create configure.scan (a preliminary configure.ac) for a package. - # Copyright (C) 1994, 1999, 2000, 2001, 2002, 2003 -@@ -21,7 +21,9 @@ - - # Written by David MacKenzie . - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+use warnings; -+ -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' - if 0; - - BEGIN -Index: autoconf-2.59/bin/autoupdate.in -=================================================================== ---- autoconf-2.59.orig/bin/autoupdate.in 2003-08-27 07:26:32.000000000 -0400 -+++ autoconf-2.59/bin/autoupdate.in 2005-03-09 16:30:19.912214040 -0500 -@@ -1,4 +1,4 @@ --#! @PERL@ -w -+#! @bindir@/env perl - # -*- perl -*- - # autoupdate - modernize an Autoconf file. - # Copyright (C) 1994, 1999, 2000, 2001, 2002, 2003 -@@ -22,7 +22,9 @@ - # Originally written by David MacKenzie . - # Rewritten by Akim Demaille . - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+use warnings; -+ -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' - if 0; - - BEGIN -@@ -54,7 +56,7 @@ - my @include = ('@datadir@'); - my $force = 0; - # m4. --my $m4 = $ENV{"M4"} || '@M4@'; -+my $m4 = $ENV{"M4"} || '@bindir@/env m4'; - - - # $HELP -Index: autoconf-2.59/bin/ifnames.in -=================================================================== ---- autoconf-2.59.orig/bin/ifnames.in 2003-10-10 09:52:56.000000000 -0400 -+++ autoconf-2.59/bin/ifnames.in 2005-03-09 16:30:22.656796800 -0500 -@@ -1,8 +1,10 @@ --#! @PERL@ -w -+#! @bindir@/env perl - # -*- perl -*- - # @configure_input@ - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+use warnings; -+ -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' - if 0; - - # ifnames - print the identifiers used in C preprocessor conditionals diff --git a/recipes/autoconf/autoconf-2.61/path_prog_fixes.patch b/recipes/autoconf/autoconf-2.61/path_prog_fixes.patch deleted file mode 100644 index 5f0d055a48..0000000000 --- a/recipes/autoconf/autoconf-2.61/path_prog_fixes.patch +++ /dev/null @@ -1,126 +0,0 @@ -Index: autoconf-2.59/bin/autoheader.in -=================================================================== ---- autoconf-2.59.orig/bin/autoheader.in 2005-03-09 16:27:17.933878952 -0500 -+++ autoconf-2.59/bin/autoheader.in 2005-03-09 16:29:57.360642400 -0500 -@@ -1,8 +1,8 @@ --#! @PERL@ -+#! @bindir@/env perl - # -*- Perl -*- - # @configure_input@ - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @bindir@/env perl -S "$0" "$@";; esac' - if 0; - - # autoheader -- create `config.h.in' from `configure.ac' -Index: autoconf-2.59/bin/autom4te.in -=================================================================== ---- autoconf-2.59.orig/bin/autom4te.in 2003-10-28 03:48:36.000000000 -0500 -+++ autoconf-2.59/bin/autom4te.in 2005-03-09 16:30:14.957967200 -0500 -@@ -1,8 +1,10 @@ --#! @PERL@ -w -+#! @bindir@/env perl - # -*- perl -*- - # @configure_input@ - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+use warnings; -+ -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' - if 0; - - # autom4te - Wrapper around M4 libraries. -@@ -87,7 +89,7 @@ - my $freeze = 0; - - # $M4. --my $m4 = $ENV{"M4"} || '@M4@'; -+my $m4 = $ENV{"M4"} || '@bindir@/env m4'; - # Some non-GNU m4's don't reject the --help option, so give them /dev/null. - fatal "need GNU m4 1.4 or later: $m4" - if system "$m4 --help &1 | grep reload-state >/dev/null"; -Index: autoconf-2.59/bin/autoreconf.in -=================================================================== ---- autoconf-2.59.orig/bin/autoreconf.in 2005-03-09 16:27:17.354966960 -0500 -+++ autoconf-2.59/bin/autoreconf.in 2005-03-09 16:31:19.572144352 -0500 -@@ -1,8 +1,10 @@ --#! @PERL@ -w -+#! @bindir@/env perl - # -*- perl -*- - # @configure_input@ - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+use warnings; -+ -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' - if 0; - - # autoreconf - install the GNU Build System in a directory tree -Index: autoconf-2.59/bin/autoscan.in -=================================================================== ---- autoconf-2.59.orig/bin/autoscan.in 2003-09-26 08:57:49.000000000 -0400 -+++ autoconf-2.59/bin/autoscan.in 2005-03-09 16:30:18.136483992 -0500 -@@ -1,4 +1,4 @@ --#! @PERL@ -w -+#! @bindir@/env perl - # -*- perl -*- - # autoscan - Create configure.scan (a preliminary configure.ac) for a package. - # Copyright (C) 1994, 1999, 2000, 2001, 2002, 2003 -@@ -21,7 +21,9 @@ - - # Written by David MacKenzie . - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+use warnings; -+ -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' - if 0; - - BEGIN -Index: autoconf-2.59/bin/autoupdate.in -=================================================================== ---- autoconf-2.59.orig/bin/autoupdate.in 2003-08-27 07:26:32.000000000 -0400 -+++ autoconf-2.59/bin/autoupdate.in 2005-03-09 16:30:19.912214040 -0500 -@@ -1,4 +1,4 @@ --#! @PERL@ -w -+#! @bindir@/env perl - # -*- perl -*- - # autoupdate - modernize an Autoconf file. - # Copyright (C) 1994, 1999, 2000, 2001, 2002, 2003 -@@ -22,7 +22,9 @@ - # Originally written by David MacKenzie . - # Rewritten by Akim Demaille . - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+use warnings; -+ -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' - if 0; - - BEGIN -@@ -54,7 +56,7 @@ - my @include = ('@datadir@'); - my $force = 0; - # m4. --my $m4 = $ENV{"M4"} || '@M4@'; -+my $m4 = $ENV{"M4"} || '@bindir@/env m4'; - - - # $HELP -Index: autoconf-2.59/bin/ifnames.in -=================================================================== ---- autoconf-2.59.orig/bin/ifnames.in 2003-10-10 09:52:56.000000000 -0400 -+++ autoconf-2.59/bin/ifnames.in 2005-03-09 16:30:22.656796800 -0500 -@@ -1,8 +1,10 @@ --#! @PERL@ -w -+#! @bindir@/env perl - # -*- perl -*- - # @configure_input@ - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+use warnings; -+ -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' - if 0; - - # ifnames - print the identifiers used in C preprocessor conditionals diff --git a/recipes/autoconf/autoconf-2.63/path_prog_fixes.patch b/recipes/autoconf/autoconf-2.63/path_prog_fixes.patch deleted file mode 100644 index 5f0d055a48..0000000000 --- a/recipes/autoconf/autoconf-2.63/path_prog_fixes.patch +++ /dev/null @@ -1,126 +0,0 @@ -Index: autoconf-2.59/bin/autoheader.in -=================================================================== ---- autoconf-2.59.orig/bin/autoheader.in 2005-03-09 16:27:17.933878952 -0500 -+++ autoconf-2.59/bin/autoheader.in 2005-03-09 16:29:57.360642400 -0500 -@@ -1,8 +1,8 @@ --#! @PERL@ -+#! @bindir@/env perl - # -*- Perl -*- - # @configure_input@ - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @bindir@/env perl -S "$0" "$@";; esac' - if 0; - - # autoheader -- create `config.h.in' from `configure.ac' -Index: autoconf-2.59/bin/autom4te.in -=================================================================== ---- autoconf-2.59.orig/bin/autom4te.in 2003-10-28 03:48:36.000000000 -0500 -+++ autoconf-2.59/bin/autom4te.in 2005-03-09 16:30:14.957967200 -0500 -@@ -1,8 +1,10 @@ --#! @PERL@ -w -+#! @bindir@/env perl - # -*- perl -*- - # @configure_input@ - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+use warnings; -+ -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' - if 0; - - # autom4te - Wrapper around M4 libraries. -@@ -87,7 +89,7 @@ - my $freeze = 0; - - # $M4. --my $m4 = $ENV{"M4"} || '@M4@'; -+my $m4 = $ENV{"M4"} || '@bindir@/env m4'; - # Some non-GNU m4's don't reject the --help option, so give them /dev/null. - fatal "need GNU m4 1.4 or later: $m4" - if system "$m4 --help &1 | grep reload-state >/dev/null"; -Index: autoconf-2.59/bin/autoreconf.in -=================================================================== ---- autoconf-2.59.orig/bin/autoreconf.in 2005-03-09 16:27:17.354966960 -0500 -+++ autoconf-2.59/bin/autoreconf.in 2005-03-09 16:31:19.572144352 -0500 -@@ -1,8 +1,10 @@ --#! @PERL@ -w -+#! @bindir@/env perl - # -*- perl -*- - # @configure_input@ - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+use warnings; -+ -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' - if 0; - - # autoreconf - install the GNU Build System in a directory tree -Index: autoconf-2.59/bin/autoscan.in -=================================================================== ---- autoconf-2.59.orig/bin/autoscan.in 2003-09-26 08:57:49.000000000 -0400 -+++ autoconf-2.59/bin/autoscan.in 2005-03-09 16:30:18.136483992 -0500 -@@ -1,4 +1,4 @@ --#! @PERL@ -w -+#! @bindir@/env perl - # -*- perl -*- - # autoscan - Create configure.scan (a preliminary configure.ac) for a package. - # Copyright (C) 1994, 1999, 2000, 2001, 2002, 2003 -@@ -21,7 +21,9 @@ - - # Written by David MacKenzie . - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+use warnings; -+ -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' - if 0; - - BEGIN -Index: autoconf-2.59/bin/autoupdate.in -=================================================================== ---- autoconf-2.59.orig/bin/autoupdate.in 2003-08-27 07:26:32.000000000 -0400 -+++ autoconf-2.59/bin/autoupdate.in 2005-03-09 16:30:19.912214040 -0500 -@@ -1,4 +1,4 @@ --#! @PERL@ -w -+#! @bindir@/env perl - # -*- perl -*- - # autoupdate - modernize an Autoconf file. - # Copyright (C) 1994, 1999, 2000, 2001, 2002, 2003 -@@ -22,7 +22,9 @@ - # Originally written by David MacKenzie . - # Rewritten by Akim Demaille . - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+use warnings; -+ -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' - if 0; - - BEGIN -@@ -54,7 +56,7 @@ - my @include = ('@datadir@'); - my $force = 0; - # m4. --my $m4 = $ENV{"M4"} || '@M4@'; -+my $m4 = $ENV{"M4"} || '@bindir@/env m4'; - - - # $HELP -Index: autoconf-2.59/bin/ifnames.in -=================================================================== ---- autoconf-2.59.orig/bin/ifnames.in 2003-10-10 09:52:56.000000000 -0400 -+++ autoconf-2.59/bin/ifnames.in 2005-03-09 16:30:22.656796800 -0500 -@@ -1,8 +1,10 @@ --#! @PERL@ -w -+#! @bindir@/env perl - # -*- perl -*- - # @configure_input@ - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+use warnings; -+ -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' - if 0; - - # ifnames - print the identifiers used in C preprocessor conditionals diff --git a/recipes/autoconf/autoconf.inc b/recipes/autoconf/autoconf.inc index a05f2ae7db..5bdc7e17ee 100644 --- a/recipes/autoconf/autoconf.inc +++ b/recipes/autoconf/autoconf.inc @@ -4,10 +4,18 @@ LICENSE = "GPL" HOMEPAGE = "http://www.gnu.org/software/autoconf/" SECTION = "devel" DEPENDS += "m4-native" -RDEPENDS_${PN} = "m4 gnu-config" +RDEPENDS_${PN} = "m4 perl gnu-config" +INC_PR = "r7" SRC_URI = "${GNU_MIRROR}/autoconf/autoconf-${PV}.tar.bz2 \ file://program_prefix.patch;patch=1" inherit autotools -INC_PR = "r6" + +do_configure_prepend () { + if ${@['true', 'false'][bb.data.inherits_class('native', d)]} + then + export ac_cv_path_PERL="${ac_cv_path_PERL=${bindir}/perl}" + export ac_cv_path_M4="${ac_cv_path_M4=${bindir}/m4}" + fi +} diff --git a/recipes/autoconf/autoconf_2.59.bb b/recipes/autoconf/autoconf_2.59.bb index a8f357fc5f..e9149df44c 100644 --- a/recipes/autoconf/autoconf_2.59.bb +++ b/recipes/autoconf/autoconf_2.59.bb @@ -10,5 +10,4 @@ SRC_URI += "file://autoreconf-include.patch;patch=1 \ file://autoheader-nonfatal-warnings.patch;patch=1 \ file://sizeof_types.patch;patch=1 \ file://autoconf-x.patch;patch=1 \ - file://autoconf-sh.patch;patch=1 \ - ${@['file://path_prog_fixes.patch;patch=1', ''][bb.data.inherits_class('native', d)]}" + file://autoconf-sh.patch;patch=1" diff --git a/recipes/autoconf/autoconf_2.63.bb b/recipes/autoconf/autoconf_2.63.bb index 6963baf169..e26c004f64 100644 --- a/recipes/autoconf/autoconf_2.63.bb +++ b/recipes/autoconf/autoconf_2.63.bb @@ -6,10 +6,8 @@ DEFAULT_PREFERENCE = "-1" PARALLEL_MAKE = "" -SRC_URI += " \ - file://autoreconf-exclude.patch;patch=1 \ - file://autoreconf-foreign.patch;patch=1 \ - file://autoheader-nonfatal-warnings.patch;patch=1 \ - file://autoreconf-gnuconfigize.patch;patch=1 \ - file://config-site.patch;patch=1 \ - ${@['file://path_prog_fixes.patch;patch=1', ''][bb.data.inherits_class('native', d)]}" +SRC_URI += "file://autoreconf-exclude.patch;patch=1 \ + file://autoreconf-foreign.patch;patch=1 \ + file://autoheader-nonfatal-warnings.patch;patch=1 \ + file://autoreconf-gnuconfigize.patch;patch=1 \ + file://config-site.patch;patch=1" -- cgit v1.2.3 From b0a80126c9dce4500a2c5da945fdb53aecf2a507 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Thu, 17 Sep 2009 22:00:02 +0100 Subject: libsdl-x11_1.2.11.bb : remove asm/page.h as its no longer there --- recipes/libsdl/files/libsdl-1.2.11-pagesize.patch | 44 +++++++++++++++++++++++ recipes/libsdl/libsdl-x11_1.2.11.bb | 3 +- 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100755 recipes/libsdl/files/libsdl-1.2.11-pagesize.patch diff --git a/recipes/libsdl/files/libsdl-1.2.11-pagesize.patch b/recipes/libsdl/files/libsdl-1.2.11-pagesize.patch new file mode 100755 index 0000000000..1d606d1af9 --- /dev/null +++ b/recipes/libsdl/files/libsdl-1.2.11-pagesize.patch @@ -0,0 +1,44 @@ +From Mandriva. Realigned for Gentoo by Peter Alfredsen + +Index: SDL-1.2.11/src/video/fbcon/SDL_fbvideo.c +=================================================================== +--- SDL-1.2.11.orig/src/video/fbcon/SDL_fbvideo.c ++++ SDL-1.2.11/src/video/fbcon/SDL_fbvideo.c +@@ -29,7 +29,6 @@ + #include + #include + #include +-#include /* For definition of PAGE_SIZE */ + #include + + #include "SDL_video.h" +@@ -547,7 +546,7 @@ static int FB_VideoInit(_THIS, SDL_Pixel + + /* Memory map the device, compensating for buggy PPC mmap() */ + mapped_offset = (((long)finfo.smem_start) - +- (((long)finfo.smem_start)&~(getpagesize()-1))); ++ (((long)finfo.smem_start)&~((int)sysconf(_SC_PAGE_SIZE)-1))); + mapped_memlen = finfo.smem_len+mapped_offset; + mapped_mem = do_mmap(NULL, mapped_memlen, + PROT_READ|PROT_WRITE, MAP_SHARED, console_fd, 0); +Index: SDL-1.2.11/src/video/ps2gs/SDL_gsyuv.c +=================================================================== +--- SDL-1.2.11.orig/src/video/ps2gs/SDL_gsyuv.c ++++ SDL-1.2.11/src/video/ps2gs/SDL_gsyuv.c +@@ -27,7 +27,6 @@ + #include + #include + #include +-#include /* For definition of PAGE_SIZE */ + + #include "SDL_video.h" + #include "SDL_gsyuv_c.h" +@@ -180,7 +179,7 @@ SDL_Overlay *GS_CreateYUVOverlay(_THIS, + + /* Allocate a DMA area for pixel conversion */ + bpp = this->screen->format->BytesPerPixel; +- map_offset = (mapped_len + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); ++ map_offset = (mapped_len + ((int)sysconf(_SC_PAGE_SIZE) - 1)) & ~((int)sysconf(_SC_PAGE_SIZE) - 1); + hwdata->dma_len = hwdata->macroblocks * (16 * 16 + 8 * 8 + 8 * 8) + + width * height * bpp + + hwdata->macroblocks * (16 * sizeof(long long)) + diff --git a/recipes/libsdl/libsdl-x11_1.2.11.bb b/recipes/libsdl/libsdl-x11_1.2.11.bb index ab349d6306..0dffe4ab3f 100644 --- a/recipes/libsdl/libsdl-x11_1.2.11.bb +++ b/recipes/libsdl/libsdl-x11_1.2.11.bb @@ -3,7 +3,7 @@ require libsdl.inc # extra-keys.patch is missing DEFAULT_PREFERENCE = "-1" -PR = "r7" +PR = "r8" SRC_URI = "\ http://www.libsdl.org/release/SDL-${PV}.tar.gz \ @@ -13,6 +13,7 @@ SRC_URI = "\ file://kernel-asm-page.patch;patch=1 \ file://sdl-cdfix.patch;patch=1 \ file://fixmfour.patch;patch=1 \ + file://libsdl-1.2.11-pagesize.patch;patch=1 \ " EXTRA_OECONF = "--disable-static --disable-debug --enable-cdrom --enable-threads --enable-timers --enable-endian \ -- cgit v1.2.3 From 0159d8fb1eca071c9fd74c2fc99e3ef8b4c38085 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Thu, 17 Sep 2009 22:23:09 +0100 Subject: mplayer/files/pld-onlyarm5-svn.patch : refresh for newest svn --- recipes/mplayer/files/pld-onlyarm5-svn.patch | 126 +++++++++++++-------------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/recipes/mplayer/files/pld-onlyarm5-svn.patch b/recipes/mplayer/files/pld-onlyarm5-svn.patch index 0924060c6c..349fb9df90 100644 --- a/recipes/mplayer/files/pld-onlyarm5-svn.patch +++ b/recipes/mplayer/files/pld-onlyarm5-svn.patch @@ -1,7 +1,9 @@ ---- MPlayer-1.0pre8/libavcodec/arm/dsputil_arm_s.S.orig 2006-07-03 09:53:33.000000000 +0100 -+++ MPlayer-1.0pre8/libavcodec/arm/dsputil_arm_s.S 2006-07-03 10:06:58.000000000 +0100 -@@ -16,6 +16,13 @@ - @ License along with this library; if not, write to the Free Software +Index: trunk/libavcodec/arm/dsputil_arm_s.S +=================================================================== +--- trunk.orig/libavcodec/arm/dsputil_arm_s.S ++++ trunk/libavcodec/arm/dsputil_arm_s.S +@@ -18,6 +18,13 @@ + @ License along with FFmpeg; if not, write to the Free Software @ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA @ +#if defined(__ARM_ARCH_5__) || \ @@ -12,18 +14,17 @@ +#define PLD(code...) +#endif - .macro ADJ_ALIGN_QUADWORD_D shift, Rd0, Rd1, Rd2, Rd3, Rn0, Rn1, Rn2, Rn3, Rn4 - mov \Rd0, \Rn0, lsr #(\shift * 8) -@@ -74,7 +81,7 @@ - put_pixels16_arm: + #include "config.h" + #include "asm.S" +@@ -106,14 +113,14 @@ function ff_prefetch_arm, export=1 + function put_pixels16_arm, export=1 @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) @ block = word aligned, pixles = unaligned - pld [r1] + PLD ( pld [r1] ) stmfd sp!, {r4-r11, lr} @ R14 is also called LR - adr r5, 5f - ands r4, r1, #3 -@@ -85,7 +92,7 @@ + JMP_ALIGN r5, r1 + 1: ldmia r1, {r4-r7} add r1, r1, r2 stmia r0, {r4-r7} @@ -32,7 +33,7 @@ subs r3, r3, #1 add r0, r0, r2 bne 1b -@@ -95,7 +102,7 @@ +@@ -123,7 +130,7 @@ function put_pixels16_arm, export=1 ldmia r1, {r4-r8} add r1, r1, r2 ADJ_ALIGN_QUADWORD_D 1, r9, r10, r11, r12, r4, r5, r6, r7, r8 @@ -41,7 +42,7 @@ subs r3, r3, #1 stmia r0, {r9-r12} add r0, r0, r2 -@@ -106,7 +113,7 @@ +@@ -134,7 +141,7 @@ function put_pixels16_arm, export=1 ldmia r1, {r4-r8} add r1, r1, r2 ADJ_ALIGN_QUADWORD_D 2, r9, r10, r11, r12, r4, r5, r6, r7, r8 @@ -50,7 +51,7 @@ subs r3, r3, #1 stmia r0, {r9-r12} add r0, r0, r2 -@@ -117,7 +124,7 @@ +@@ -145,7 +152,7 @@ function put_pixels16_arm, export=1 ldmia r1, {r4-r8} add r1, r1, r2 ADJ_ALIGN_QUADWORD_D 3, r9, r10, r11, r12, r4, r5, r6, r7, r8 @@ -59,16 +60,15 @@ subs r3, r3, #1 stmia r0, {r9-r12} add r0, r0, r2 -@@ -136,7 +143,7 @@ - put_pixels8_arm: +@@ -158,14 +165,14 @@ function put_pixels16_arm, export=1 + function put_pixels8_arm, export=1 @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) @ block = word aligned, pixles = unaligned - pld [r1] + PLD ( pld [r1] ) stmfd sp!, {r4-r5,lr} @ R14 is also called LR - adr r5, 5f - ands r4, r1, #3 -@@ -147,7 +154,7 @@ + JMP_ALIGN r5, r1 + 1: ldmia r1, {r4-r5} add r1, r1, r2 subs r3, r3, #1 @@ -77,7 +77,7 @@ stmia r0, {r4-r5} add r0, r0, r2 bne 1b -@@ -157,7 +164,7 @@ +@@ -175,7 +182,7 @@ function put_pixels8_arm, export=1 ldmia r1, {r4-r5, r12} add r1, r1, r2 ADJ_ALIGN_DOUBLEWORD 1, r4, r5, r12 @@ -86,7 +86,7 @@ subs r3, r3, #1 stmia r0, {r4-r5} add r0, r0, r2 -@@ -168,7 +175,7 @@ +@@ -186,7 +193,7 @@ function put_pixels8_arm, export=1 ldmia r1, {r4-r5, r12} add r1, r1, r2 ADJ_ALIGN_DOUBLEWORD 2, r4, r5, r12 @@ -95,7 +95,7 @@ subs r3, r3, #1 stmia r0, {r4-r5} add r0, r0, r2 -@@ -179,7 +186,7 @@ +@@ -197,7 +204,7 @@ function put_pixels8_arm, export=1 ldmia r1, {r4-r5, r12} add r1, r1, r2 ADJ_ALIGN_DOUBLEWORD 3, r4, r5, r12 @@ -104,16 +104,16 @@ subs r3, r3, #1 stmia r0, {r4-r5} add r0, r0, r2 -@@ -198,7 +205,7 @@ - put_pixels8_x2_arm: +@@ -210,7 +217,7 @@ function put_pixels8_arm, export=1 + function put_pixels8_x2_arm, export=1 @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) @ block = word aligned, pixles = unaligned - pld [r1] + PLD ( pld [r1] ) stmfd sp!, {r4-r10,lr} @ R14 is also called LR - adr r5, 5f - ands r4, r1, #3 -@@ -210,7 +217,7 @@ + ldr r12, =0xfefefefe + JMP_ALIGN r5, r1 +@@ -218,7 +225,7 @@ function put_pixels8_x2_arm, export=1 ldmia r1, {r4-r5, r10} add r1, r1, r2 ADJ_ALIGN_DOUBLEWORD_D 1, r6, r7, r4, r5, r10 @@ -122,7 +122,7 @@ RND_AVG32 r8, r9, r4, r5, r6, r7, r12 subs r3, r3, #1 stmia r0, {r8-r9} -@@ -223,7 +230,7 @@ +@@ -231,7 +238,7 @@ function put_pixels8_x2_arm, export=1 add r1, r1, r2 ADJ_ALIGN_DOUBLEWORD_D 1, r6, r7, r4, r5, r10 ADJ_ALIGN_DOUBLEWORD_D 2, r8, r9, r4, r5, r10 @@ -131,7 +131,7 @@ RND_AVG32 r4, r5, r6, r7, r8, r9, r12 subs r3, r3, #1 stmia r0, {r4-r5} -@@ -236,7 +243,7 @@ +@@ -244,7 +251,7 @@ function put_pixels8_x2_arm, export=1 add r1, r1, r2 ADJ_ALIGN_DOUBLEWORD_D 2, r6, r7, r4, r5, r10 ADJ_ALIGN_DOUBLEWORD_D 3, r8, r9, r4, r5, r10 @@ -140,7 +140,7 @@ RND_AVG32 r4, r5, r6, r7, r8, r9, r12 subs r3, r3, #1 stmia r0, {r4-r5} -@@ -248,7 +255,7 @@ +@@ -256,7 +263,7 @@ function put_pixels8_x2_arm, export=1 ldmia r1, {r4-r5, r10} add r1, r1, r2 ADJ_ALIGN_DOUBLEWORD_D 3, r6, r7, r4, r5, r10 @@ -149,16 +149,16 @@ RND_AVG32 r8, r9, r6, r7, r5, r10, r12 subs r3, r3, #1 stmia r0, {r8-r9} -@@ -267,7 +274,7 @@ - put_no_rnd_pixels8_x2_arm: +@@ -269,7 +276,7 @@ function put_pixels8_x2_arm, export=1 + function put_no_rnd_pixels8_x2_arm, export=1 @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) @ block = word aligned, pixles = unaligned - pld [r1] + PLD ( pld [r1] ) stmfd sp!, {r4-r10,lr} @ R14 is also called LR - adr r5, 5f - ands r4, r1, #3 -@@ -279,7 +286,7 @@ + ldr r12, =0xfefefefe + JMP_ALIGN r5, r1 +@@ -277,7 +284,7 @@ function put_no_rnd_pixels8_x2_arm, expo ldmia r1, {r4-r5, r10} add r1, r1, r2 ADJ_ALIGN_DOUBLEWORD_D 1, r6, r7, r4, r5, r10 @@ -167,7 +167,7 @@ NO_RND_AVG32 r8, r9, r4, r5, r6, r7, r12 subs r3, r3, #1 stmia r0, {r8-r9} -@@ -292,7 +299,7 @@ +@@ -290,7 +297,7 @@ function put_no_rnd_pixels8_x2_arm, expo add r1, r1, r2 ADJ_ALIGN_DOUBLEWORD_D 1, r6, r7, r4, r5, r10 ADJ_ALIGN_DOUBLEWORD_D 2, r8, r9, r4, r5, r10 @@ -176,7 +176,7 @@ NO_RND_AVG32 r4, r5, r6, r7, r8, r9, r12 subs r3, r3, #1 stmia r0, {r4-r5} -@@ -305,7 +312,7 @@ +@@ -303,7 +310,7 @@ function put_no_rnd_pixels8_x2_arm, expo add r1, r1, r2 ADJ_ALIGN_DOUBLEWORD_D 2, r6, r7, r4, r5, r10 ADJ_ALIGN_DOUBLEWORD_D 3, r8, r9, r4, r5, r10 @@ -185,7 +185,7 @@ NO_RND_AVG32 r4, r5, r6, r7, r8, r9, r12 subs r3, r3, #1 stmia r0, {r4-r5} -@@ -317,7 +324,7 @@ +@@ -315,7 +322,7 @@ function put_no_rnd_pixels8_x2_arm, expo ldmia r1, {r4-r5, r10} add r1, r1, r2 ADJ_ALIGN_DOUBLEWORD_D 3, r6, r7, r4, r5, r10 @@ -194,16 +194,16 @@ NO_RND_AVG32 r8, r9, r6, r7, r5, r10, r12 subs r3, r3, #1 stmia r0, {r8-r9} -@@ -338,7 +345,7 @@ - put_pixels8_y2_arm: +@@ -330,7 +337,7 @@ function put_no_rnd_pixels8_x2_arm, expo + function put_pixels8_y2_arm, export=1 @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) @ block = word aligned, pixles = unaligned - pld [r1] + PLD ( pld [r1] ) stmfd sp!, {r4-r11,lr} @ R14 is also called LR - adr r5, 5f - ands r4, r1, #3 -@@ -352,13 +359,13 @@ + mov r3, r3, lsr #1 + ldr r12, =0xfefefefe +@@ -340,13 +347,13 @@ function put_pixels8_y2_arm, export=1 add r1, r1, r2 6: ldmia r1, {r6-r7} add r1, r1, r2 @@ -219,7 +219,7 @@ RND_AVG32 r8, r9, r6, r7, r4, r5, r12 subs r3, r3, #1 stmia r0, {r8-r9} -@@ -369,18 +376,18 @@ +@@ -357,18 +364,18 @@ function put_pixels8_y2_arm, export=1 2: ldmia r1, {r4-r6} add r1, r1, r2 @@ -241,7 +241,7 @@ ADJ_ALIGN_DOUBLEWORD 1, r4, r5, r6 subs r3, r3, #1 RND_AVG32 r10, r11, r7, r8, r4, r5, r12 -@@ -392,18 +399,18 @@ +@@ -380,18 +387,18 @@ function put_pixels8_y2_arm, export=1 3: ldmia r1, {r4-r6} add r1, r1, r2 @@ -263,7 +263,7 @@ ADJ_ALIGN_DOUBLEWORD 2, r4, r5, r6 subs r3, r3, #1 RND_AVG32 r10, r11, r7, r8, r4, r5, r12 -@@ -415,18 +422,18 @@ +@@ -403,18 +410,18 @@ function put_pixels8_y2_arm, export=1 4: ldmia r1, {r4-r6} add r1, r1, r2 @@ -285,16 +285,16 @@ ADJ_ALIGN_DOUBLEWORD 3, r4, r5, r6 subs r3, r3, #1 RND_AVG32 r10, r11, r7, r8, r4, r5, r12 -@@ -447,7 +454,7 @@ - put_no_rnd_pixels8_y2_arm: +@@ -428,7 +435,7 @@ function put_pixels8_y2_arm, export=1 + function put_no_rnd_pixels8_y2_arm, export=1 @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) @ block = word aligned, pixles = unaligned - pld [r1] + PLD ( pld [r1] ) stmfd sp!, {r4-r11,lr} @ R14 is also called LR - adr r5, 5f - ands r4, r1, #3 -@@ -461,13 +468,13 @@ + mov r3, r3, lsr #1 + ldr r12, =0xfefefefe +@@ -438,13 +445,13 @@ function put_no_rnd_pixels8_y2_arm, expo add r1, r1, r2 6: ldmia r1, {r6-r7} add r1, r1, r2 @@ -310,7 +310,7 @@ NO_RND_AVG32 r8, r9, r6, r7, r4, r5, r12 subs r3, r3, #1 stmia r0, {r8-r9} -@@ -478,18 +485,18 @@ +@@ -455,18 +462,18 @@ function put_no_rnd_pixels8_y2_arm, expo 2: ldmia r1, {r4-r6} add r1, r1, r2 @@ -332,7 +332,7 @@ ADJ_ALIGN_DOUBLEWORD 1, r4, r5, r6 subs r3, r3, #1 NO_RND_AVG32 r10, r11, r7, r8, r4, r5, r12 -@@ -501,18 +508,18 @@ +@@ -478,18 +485,18 @@ function put_no_rnd_pixels8_y2_arm, expo 3: ldmia r1, {r4-r6} add r1, r1, r2 @@ -354,7 +354,7 @@ ADJ_ALIGN_DOUBLEWORD 2, r4, r5, r6 subs r3, r3, #1 NO_RND_AVG32 r10, r11, r7, r8, r4, r5, r12 -@@ -524,18 +531,18 @@ +@@ -501,18 +508,18 @@ function put_no_rnd_pixels8_y2_arm, expo 4: ldmia r1, {r4-r6} add r1, r1, r2 @@ -376,7 +376,7 @@ ADJ_ALIGN_DOUBLEWORD 3, r4, r5, r6 subs r3, r3, #1 NO_RND_AVG32 r10, r11, r7, r8, r4, r5, r12 -@@ -562,7 +569,7 @@ +@@ -536,7 +543,7 @@ function put_no_rnd_pixels8_y2_arm, expo ldmia r1, {r8-r10} .endif add r1, r1, r2 @@ -385,21 +385,21 @@ .if \align == 0 ADJ_ALIGN_DOUBLEWORD_D 1, r4, r5, r6, r7, r8 .elseif \align == 1 -@@ -624,7 +631,7 @@ - put_pixels8_xy2_arm: +@@ -593,7 +600,7 @@ function put_no_rnd_pixels8_y2_arm, expo + function put_pixels8_xy2_arm, export=1 @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) @ block = word aligned, pixles = unaligned - pld [r1] + PLD ( pld [r1] ) stmfd sp!, {r4-r11,lr} @ R14 is also called LR - adrl r12, 5f - ands r4, r1, #3 -@@ -661,7 +668,7 @@ - put_no_rnd_pixels8_xy2_arm: + JMP_ALIGN r5, r1 + 1: +@@ -616,7 +623,7 @@ function put_pixels8_xy2_arm, export=1 + function put_no_rnd_pixels8_xy2_arm, export=1 @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) @ block = word aligned, pixles = unaligned - pld [r1] + PLD ( pld [r1] ) stmfd sp!, {r4-r11,lr} @ R14 is also called LR - adrl r12, 5f - ands r4, r1, #3 + JMP_ALIGN r5, r1 + 1: -- cgit v1.2.3 From 0bea79bae67c907cfad13b62c2df51b280d9b83d Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Thu, 17 Sep 2009 19:08:42 +0000 Subject: frameworkd-config-shr: SHR specific frameworkd config (from SHR) --- recipes/shr/frameworkd-config-shr_git.bb | 87 ++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 recipes/shr/frameworkd-config-shr_git.bb diff --git a/recipes/shr/frameworkd-config-shr_git.bb b/recipes/shr/frameworkd-config-shr_git.bb new file mode 100644 index 0000000000..0727091f0b --- /dev/null +++ b/recipes/shr/frameworkd-config-shr_git.bb @@ -0,0 +1,87 @@ +DESCRIPTION = "SHR Configuration for frameworkd" +HOMEPAGE = "http://www.freesmartphone.org" +AUTHOR = "Michael 'Mickey' Lauer et. al." +SECTION = "console/network" +DEPENDS = "python-cython-native python-pyrex-native" +LICENSE = "GPL" +SRCREV_FORMAT = "gitrFSO_REV-SHR_REV" +PV = "0.9.5.9+${SRCREV}" +PR = "r7" + +SRC_URI = "${FREESMARTPHONE_GIT}/framework.git;protocol=git;branch=master;name=FSO_REV \ + git://git.shr-project.org/repo/shr-themes.git;protocol=http;branch=master;name=SHR_REV" +S = "${WORKDIR}/git" + +PROVIDES_${PN} = "frameworkd-config" +RPROVIDES_${PN} = "frameworkd-config" +CONF_PATH = "${S}/frameworkd/${PN}" + +do_install_append() { + install -d ${D}${sysconfdir} + install -d ${D}${sysconfdir}/freesmartphone/opreferences/schema/ + install -d ${D}${sysconfdir}/freesmartphone/opreferences/conf/profiles/ + install -d ${D}${sysconfdir}/freesmartphone/opreferences/conf/phone/ + install -d ${D}${sysconfdir}/freesmartphone/opreferences/conf/rules/ + install -d ${D}${sysconfdir}/freesmartphone/oevents/ + install -d ${D}${sysconfdir}/freesmartphone/ogsmd/ + install -d ${D}${sysconfdir}/freesmartphone/persist/ + install -d ${D}${sysconfdir}/freesmartphone/opim/ + install -m 0644 ${S}/etc/freesmartphone/opreferences/schema/phone.yaml ${D}${sysconfdir}/freesmartphone/opreferences/schema/ + install -m 0644 ${S}/etc/freesmartphone/opreferences/schema/profiles.yaml ${D}${sysconfdir}/freesmartphone/opreferences/schema/ + install -m 0644 ${S}/etc/freesmartphone/opreferences/schema/rules.yaml ${D}${sysconfdir}/freesmartphone/opreferences/schema/ + install -m 0644 ${S}/etc/freesmartphone/persist/README ${D}${sysconfdir}/freesmartphone/persist/ + install -m 0644 ${S}/etc/freesmartphone/ogsmd/networks.tab ${D}${sysconfdir}/freesmartphone/ogsmd/ + install -m 0644 ${S}/etc/freesmartphone/ogsmd/cell.db ${D}${sysconfdir}/freesmartphone/ogsmd/ + install -m 0644 ${S}/etc/freesmartphone/ogsmd/la.db ${D}${sysconfdir}/freesmartphone/ogsmd/ + + #Check for machine specific conf. + CONF_PATH_MACHINE="${CONF_PATH}" + if [ -d "${CONF_PATH}/${MACHINE}" ] ; then + CONF_PATH_MACHINE="${CONF_PATH}/${MACHINE}" + fi + # Install SHR custom files + install -m 0644 ${CONF_PATH_MACHINE}/frameworkd.conf ${D}${sysconfdir} + install -m 0644 ${CONF_PATH_MACHINE}/rules.yaml ${D}${sysconfdir}/freesmartphone/oevents/ + install -m 0644 ${CONF_PATH}/profiles/profiles/default.yaml ${D}${sysconfdir}/freesmartphone/opreferences/conf/profiles/ + + install -m 0644 ${CONF_PATH}/profiles/phone/default.yaml ${D}${sysconfdir}/freesmartphone/opreferences/conf/phone/ + install -m 0644 ${CONF_PATH}/profiles/rules/default.yaml ${D}${sysconfdir}/freesmartphone/opreferences/conf/rules/ + + install -m 0644 ${CONF_PATH}/profiles/phone/ring.yaml ${D}${sysconfdir}/freesmartphone/opreferences/conf/phone/ + install -m 0644 ${CONF_PATH}/profiles/rules/ring.yaml ${D}${sysconfdir}/freesmartphone/opreferences/conf/rules/ + + install -m 0644 ${CONF_PATH}/profiles/phone/vibrate.yaml ${D}${sysconfdir}/freesmartphone/opreferences/conf/phone/ + install -m 0644 ${CONF_PATH}/profiles/rules/vibrate.yaml ${D}${sysconfdir}/freesmartphone/opreferences/conf/rules/ + + install -m 0644 ${CONF_PATH}/profiles/phone/silent.yaml ${D}${sysconfdir}/freesmartphone/opreferences/conf/phone/ + install -m 0644 ${CONF_PATH}/profiles/rules/silent.yaml ${D}${sysconfdir}/freesmartphone/opreferences/conf/rules/ + + install -d ${D}${datadir}/sounds + install -m 0644 ${CONF_PATH}/*.wav ${D}${datadir}/sounds/ +} + +PACKAGE_ARCH_${PN} = "${MACHINE_ARCH}" + +# machine specific stuff, should ideally be elsewhere +# - recommend MUXer on platforms that require one +RDEPENDS_${PN}_append_om-gta01 = " fso-abyss" +RDEPENDS_${PN}_append_om-gta02 = " fso-abyss" +RDEPENDS_${PN}_append-om-3d7k = " fso-abyss" +# - add wmiconfig for wireless configuration +RDEPENDS_${PN}_append_om-gta02 = " wmiconfig" + +FILES_${PN} = "\ + ${sysconfdir}/frameworkd.conf \ + ${sysconfdir}/freesmartphone \ + ${datadir}/sounds \ +" +CONFFILES_${PN} = "\ + ${sysconfdir}/frameworkd.conf \ + ${sysconfdir}/freesmartphone/opreferences/conf/phone/silent.yaml \ + ${sysconfdir}/freesmartphone/opreferences/conf/phone/default.yaml \ + ${sysconfdir}/freesmartphone/opreferences/conf/profiles/default.yaml \ + ${sysconfdir}/freesmartphone/opreferences/conf/rules/silent.yaml \ + ${sysconfdir}/freesmartphone/opreferences/conf/rules/default.yaml \ + ${sysconfdir}/freesmartphone/oevents/rules.yaml \ + ${sysconfdir}/freesmartphone/ogsmd/networks.tab \ +" -- cgit v1.2.3 From 4884db8974dd9d3e157d9692d10266384ad5e5b7 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Thu, 17 Sep 2009 21:21:29 +0000 Subject: libframeworkd-phonegui*: Abstraction libs for fso and efl (from SHR) --- recipes/shr/libframeworkd-phonegui-efl2_git.bb | 18 ++++++++++++++++++ recipes/shr/libframeworkd-phonegui-efl_git.bb | 19 +++++++++++++++++++ recipes/shr/libframeworkd-phonegui_git.bb | 15 +++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 recipes/shr/libframeworkd-phonegui-efl2_git.bb create mode 100644 recipes/shr/libframeworkd-phonegui-efl_git.bb create mode 100644 recipes/shr/libframeworkd-phonegui_git.bb diff --git a/recipes/shr/libframeworkd-phonegui-efl2_git.bb b/recipes/shr/libframeworkd-phonegui-efl2_git.bb new file mode 100644 index 0000000000..207658f807 --- /dev/null +++ b/recipes/shr/libframeworkd-phonegui-efl2_git.bb @@ -0,0 +1,18 @@ +DESCRIPTION = "frameworkd EFL phonegui 2" +SECTION = "e/apps" +DEPENDS += " dbus-glib libframeworkd-glib libframeworkd-phonegui etk evas ecore edje edje-native elementary" +PV = "0.0.1+gitr${SRCREV}" +PR = "r1" + +SRC_URI = "git://shr.bearstech.com/repo/libframeworkd-phonegui-efl2.git;protocol=http;branch=master" +S = "${WORKDIR}/git" + +inherit pkgconfig autotools autotools_stage + +EXTRA_OECONF = "--with-edje-cc=${STAGING_BINDIR_NATIVE}/edje_cc" + + +do_configure_prepend() { + autopoint --force +} + diff --git a/recipes/shr/libframeworkd-phonegui-efl_git.bb b/recipes/shr/libframeworkd-phonegui-efl_git.bb new file mode 100644 index 0000000000..f8adabf415 --- /dev/null +++ b/recipes/shr/libframeworkd-phonegui-efl_git.bb @@ -0,0 +1,19 @@ +DESCRIPTION = "frameworkd EFL phonegui" +HOMEPAGE = "http://shr-project.org/" +LICENSE = "GPL" +SECTION = "e/apps" +DEPENDS += " dbus-glib libframeworkd-glib libframeworkd-phonegui etk evas ecore edje edje-native elementary" +PV = "0.0.2+gitr${SRCREV}" +PR = "r33" + +inherit pkgconfig autotools autotools_stage + +SRC_URI = "git://git.shr-project.org/repo/shr.git;protocol=http;branch=master" +S = "${WORKDIR}/git/${PN}" + +EXTRA_OECONF = "--with-edje-cc=${STAGING_BINDIR_NATIVE}/edje_cc" + +do_configure_prepend() { + autopoint --force +} + diff --git a/recipes/shr/libframeworkd-phonegui_git.bb b/recipes/shr/libframeworkd-phonegui_git.bb new file mode 100644 index 0000000000..50b546512a --- /dev/null +++ b/recipes/shr/libframeworkd-phonegui_git.bb @@ -0,0 +1,15 @@ +DESCRIPTION = "Frameworkd phonegui library" +HOMEPAGE = "http://shr-project.org/" +LICENSE = "GPL" +SECTION = "libs" +PV = "0.0.2+gitr${SRCREV}" +PR = "r10" + +DEPENDS="glib-2.0 dbus-glib libframeworkd-glib libphone-utils" + +inherit pkgconfig autotools autotools_stage + +SRC_URI = "git://git.shr-project.org/repo/shr.git;protocol=http;branch=master" +S = "${WORKDIR}/git/${PN}" + +CONFFILES_${PN} = "${sysconfdir}/frameworkd-phonegui.conf" -- cgit v1.2.3 From 5a790b1f8eaf649d9000f8834967870de5129286 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 17 Sep 2009 23:48:55 +0200 Subject: angstrom-eglibc: fix eabi target os assignment --- conf/distro/include/angstrom-eglibc.inc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/conf/distro/include/angstrom-eglibc.inc b/conf/distro/include/angstrom-eglibc.inc index e947833453..2a1b7b059c 100644 --- a/conf/distro/include/angstrom-eglibc.inc +++ b/conf/distro/include/angstrom-eglibc.inc @@ -1,9 +1,10 @@ # eglibc: require conf/distro/include/eglibc.inc -TARGET_OS = "linux${@['','-gnueabi'][bb.data.getVar('TARGET_ARCH',d,1) in ['arm', 'armeb'] and bb.data.getVar('MACHINE',d) not in ['collie','h3600', 'h3800', 'simpad', 'htcwallaby']]}" +TARGET_OS = "linux" -TARGET_OS = "linux${@['','-gnuspe'][bb.data.getVar('TARGET_ARCH',d,1) in ['ppc', 'powerpc'] and bb.data.getVar('MACHINE',d) in ['calamari']]}" +TARGET_OS .= "${@['','-gnueabi'][bb.data.getVar('TARGET_ARCH',d,1) in ['arm', 'armeb'] and bb.data.getVar('MACHINE',d) not in ['collie','h3600', 'h3800', 'simpad', 'htcwallaby']]}" +TARGET_OS .= "${@['','-gnuspe'][bb.data.getVar('TARGET_ARCH',d,1) in ['ppc', 'powerpc'] and bb.data.getVar('MACHINE',d) in ['calamari']]}" #TARGET_OS = "linux-gnuspe" -- cgit v1.2.3 From 698ae87ee44a2fa5bd427bf15052d17e43d6d311 Mon Sep 17 00:00:00 2001 From: Stanislav Brabec Date: Thu, 17 Sep 2009 22:28:27 +0000 Subject: libtool: Use more clean way to set ac_cv_path_* variables. Never load libtool.inc twice. --- recipes/libtool/libtool-cross_1.5.10.bb | 1 - recipes/libtool/libtool-cross_1.5.22.bb | 1 - recipes/libtool/libtool-cross_1.5.24.bb | 1 - recipes/libtool/libtool-cross_2.2.4.bb | 6 ------ recipes/libtool/libtool-cross_2.2.6a.bb | 6 ------ recipes/libtool/libtool-native_1.5.10.bb | 1 - recipes/libtool/libtool-native_1.5.22.bb | 1 - recipes/libtool/libtool-native_1.5.24.bb | 1 - recipes/libtool/libtool-native_2.2.4.bb | 1 - recipes/libtool/libtool-native_2.2.6a.bb | 1 - recipes/libtool/libtool-sdk_1.5.10.bb | 1 - recipes/libtool/libtool-sdk_2.2.4.bb | 6 ------ recipes/libtool/libtool-sdk_2.2.6a.bb | 6 ------ recipes/libtool/libtool.inc | 12 +++++++++++- recipes/libtool/libtool_2.2.4.bb | 12 ------------ recipes/libtool/libtool_2.2.6a.bb | 12 ------------ 16 files changed, 11 insertions(+), 58 deletions(-) diff --git a/recipes/libtool/libtool-cross_1.5.10.bb b/recipes/libtool/libtool-cross_1.5.10.bb index 256e71c05a..910ff12066 100644 --- a/recipes/libtool/libtool-cross_1.5.10.bb +++ b/recipes/libtool/libtool-cross_1.5.10.bb @@ -1,4 +1,3 @@ -require libtool.inc require libtool_${PV}.bb PR = "${INC_PR}.0" diff --git a/recipes/libtool/libtool-cross_1.5.22.bb b/recipes/libtool/libtool-cross_1.5.22.bb index 949031146c..b0cee4eebb 100644 --- a/recipes/libtool/libtool-cross_1.5.22.bb +++ b/recipes/libtool/libtool-cross_1.5.22.bb @@ -1,6 +1,5 @@ DEFAULT_PREFERENCE = "-1" -require libtool.inc require libtool_${PV}.bb PR = "${INC_PR}.0" diff --git a/recipes/libtool/libtool-cross_1.5.24.bb b/recipes/libtool/libtool-cross_1.5.24.bb index 2a7e4d7288..1f8527873f 100644 --- a/recipes/libtool/libtool-cross_1.5.24.bb +++ b/recipes/libtool/libtool-cross_1.5.24.bb @@ -1,4 +1,3 @@ -require libtool.inc require libtool_${PV}.bb PR = "${INC_PR}.0" diff --git a/recipes/libtool/libtool-cross_2.2.4.bb b/recipes/libtool/libtool-cross_2.2.4.bb index e2c6bbeb6a..31a67f5bd1 100644 --- a/recipes/libtool/libtool-cross_2.2.4.bb +++ b/recipes/libtool/libtool-cross_2.2.4.bb @@ -1,4 +1,3 @@ -require libtool.inc require libtool_${PV}.bb PR = "${INC_PR}.0" @@ -22,11 +21,6 @@ prefix = "${STAGING_DIR_NATIVE}${layout_prefix}" exec_prefix = "${STAGING_DIR_NATIVE}${layout_exec_prefix}" bindir = "${STAGING_BINDIR_NATIVE}" -# skip ac_cv_... setting for cross build: host paths must be used -do_configure_prepend () { - export LIBTOOL_BB_DO_NOT_SET_PATHS=1 -} - do_compile () { : } diff --git a/recipes/libtool/libtool-cross_2.2.6a.bb b/recipes/libtool/libtool-cross_2.2.6a.bb index b26e7cc26a..23c16829ab 100644 --- a/recipes/libtool/libtool-cross_2.2.6a.bb +++ b/recipes/libtool/libtool-cross_2.2.6a.bb @@ -1,4 +1,3 @@ -require libtool.inc require libtool_${PV}.bb PR = "${INC_PR}.0" @@ -20,11 +19,6 @@ prefix = "${STAGING_DIR_NATIVE}${layout_prefix}" exec_prefix = "${STAGING_DIR_NATIVE}${layout_exec_prefix}" bindir = "${STAGING_BINDIR_NATIVE}" -# skip ac_cv_... setting for cross build: host paths must be used -do_configure_prepend () { - export LIBTOOL_BB_DO_NOT_SET_PATHS=1 -} - do_compile () { : } diff --git a/recipes/libtool/libtool-native_1.5.10.bb b/recipes/libtool/libtool-native_1.5.10.bb index 362aea22f7..76cbb4baf0 100644 --- a/recipes/libtool/libtool-native_1.5.10.bb +++ b/recipes/libtool/libtool-native_1.5.10.bb @@ -1,4 +1,3 @@ -require libtool.inc require libtool_${PV}.bb PR = "${INC_PR}.0" diff --git a/recipes/libtool/libtool-native_1.5.22.bb b/recipes/libtool/libtool-native_1.5.22.bb index 4d660f4965..3aadb2be01 100644 --- a/recipes/libtool/libtool-native_1.5.22.bb +++ b/recipes/libtool/libtool-native_1.5.22.bb @@ -1,6 +1,5 @@ DEFAULT_PREFERENCE = "-1" -require libtool.inc require libtool_${PV}.bb PR = "${INC_PR}.0" diff --git a/recipes/libtool/libtool-native_1.5.24.bb b/recipes/libtool/libtool-native_1.5.24.bb index 95368819bb..f767afcd63 100644 --- a/recipes/libtool/libtool-native_1.5.24.bb +++ b/recipes/libtool/libtool-native_1.5.24.bb @@ -1,6 +1,5 @@ SECTION = "devel" -require libtool.inc require libtool_${PV}.bb PR = "${INC_PR}.0" diff --git a/recipes/libtool/libtool-native_2.2.4.bb b/recipes/libtool/libtool-native_2.2.4.bb index 06564c74c3..a7ad685909 100644 --- a/recipes/libtool/libtool-native_2.2.4.bb +++ b/recipes/libtool/libtool-native_2.2.4.bb @@ -1,4 +1,3 @@ -require libtool.inc require libtool_${PV}.bb PR = "${INC_PR}.0" diff --git a/recipes/libtool/libtool-native_2.2.6a.bb b/recipes/libtool/libtool-native_2.2.6a.bb index e699a2f33c..082663a280 100644 --- a/recipes/libtool/libtool-native_2.2.6a.bb +++ b/recipes/libtool/libtool-native_2.2.6a.bb @@ -1,4 +1,3 @@ -require libtool.inc require libtool_${PV}.bb PR = "${INC_PR}.0" diff --git a/recipes/libtool/libtool-sdk_1.5.10.bb b/recipes/libtool/libtool-sdk_1.5.10.bb index 21e408dc73..ac188bdecd 100644 --- a/recipes/libtool/libtool-sdk_1.5.10.bb +++ b/recipes/libtool/libtool-sdk_1.5.10.bb @@ -1,4 +1,3 @@ -require libtool.inc require libtool_${PV}.bb PR = "${INC_PR}.0" diff --git a/recipes/libtool/libtool-sdk_2.2.4.bb b/recipes/libtool/libtool-sdk_2.2.4.bb index 0e9ae9b66e..c934a6e390 100644 --- a/recipes/libtool/libtool-sdk_2.2.4.bb +++ b/recipes/libtool/libtool-sdk_2.2.4.bb @@ -1,4 +1,3 @@ -require libtool.inc require libtool_${PV}.bb PR = "${INC_PR}.0" @@ -9,11 +8,6 @@ S = "${WORKDIR}/libtool-${PV}" inherit sdk -# skip ac_cv_... setting for cross build: host paths must be used -do_configure_prepend () { - export LIBTOOL_BB_DO_NOT_SET_PATHS=1 -} - do_install () { install -d ${D}${bindir}/ install -m 0755 libtool ${D}${bindir}/ diff --git a/recipes/libtool/libtool-sdk_2.2.6a.bb b/recipes/libtool/libtool-sdk_2.2.6a.bb index 263879beeb..7e269ef381 100644 --- a/recipes/libtool/libtool-sdk_2.2.6a.bb +++ b/recipes/libtool/libtool-sdk_2.2.6a.bb @@ -1,4 +1,3 @@ -require libtool.inc require libtool_${PV}.bb PR = "${INC_PR}.0" @@ -6,11 +5,6 @@ SRC_URI_append = " file://cross_compile.patch;patch=1" inherit sdk -# skip ac_cv_... setting for cross build: host paths must be used -do_configure_prepend () { - export LIBTOOL_BB_DO_NOT_SET_PATHS=1 -} - do_install () { install -d ${D}${bindir}/ install -m 0755 libtool ${D}${bindir}/ diff --git a/recipes/libtool/libtool.inc b/recipes/libtool/libtool.inc index 9cc74010c6..838f029236 100644 --- a/recipes/libtool/libtool.inc +++ b/recipes/libtool/libtool.inc @@ -6,6 +6,16 @@ HOMEPAGE = "http://www.gnu.org/software/libtool/libtool.html" LICENSE = "GPL" SECTION = "devel" -INC_PR = "r24" +INC_PR = "r25" FILESPATHPKG=. "libtool-${PV}:" + +do_configure_prepend () { + if ${@['true', 'false'][bb.data.inherits_class('native', d) or bb.data.inherits_class('sdk', d) or (bb.data.getVar('PN', d, 1) == 'libtool-cross')]} + then + export ac_cv_path_SED="${ac_cv_path_SED=${base_bindir}/sed}" + export ac_cv_path_GREP="${ac_cv_path_GREP=${base_bindir}/grep}" + export ac_cv_path_EGREP="${ac_cv_path_EGREP=${base_bindir}/grep -E}" + export ac_cv_path_FGREP="${ac_cv_path_FGREP=${base_bindir}/grep -F}" + fi +} diff --git a/recipes/libtool/libtool_2.2.4.bb b/recipes/libtool/libtool_2.2.4.bb index 6de7336406..65c2d178ab 100644 --- a/recipes/libtool/libtool_2.2.4.bb +++ b/recipes/libtool/libtool_2.2.4.bb @@ -14,18 +14,6 @@ inherit autotools EXTRA_AUTORECONF = "--exclude=libtoolize" -do_configure_prepend () { - # Skip this for native build: - if test -n "$CONFIG_SITE" ; then - if test -z "$LIBTOOL_BB_DO_NOT_SET_PATHS" ; then - export ac_cv_path_SED="${ac_cv_path_SED=/bin/sed}" - export ac_cv_path_GREP="${ac_cv_path_GREP=/bin/grep}" - export ac_cv_path_EGREP="${ac_cv_path_EGREP=/bin/grep -E}" - export ac_cv_path_FGREP="${ac_cv_path_FGREP=/bin/grep -F}" - fi - fi -} - do_stage () { install -d ${STAGING_INCDIR}/libltdl install -m 0644 libltdl/ltdl.h ${STAGING_INCDIR}/ diff --git a/recipes/libtool/libtool_2.2.6a.bb b/recipes/libtool/libtool_2.2.6a.bb index c69a937f16..0595613159 100644 --- a/recipes/libtool/libtool_2.2.6a.bb +++ b/recipes/libtool/libtool_2.2.6a.bb @@ -16,18 +16,6 @@ inherit autotools EXTRA_AUTORECONF = "--exclude=libtoolize" -do_configure_prepend () { - # Skip this for native build: - if test -n "$CONFIG_SITE" ; then - if test -z "$LIBTOOL_BB_DO_NOT_SET_PATHS" ; then - export ac_cv_path_SED="${ac_cv_path_SED=/bin/sed}" - export ac_cv_path_GREP="${ac_cv_path_GREP=/bin/grep}" - export ac_cv_path_EGREP="${ac_cv_path_EGREP=/bin/grep -E}" - export ac_cv_path_FGREP="${ac_cv_path_FGREP=/bin/grep -F}" - fi - fi -} - do_stage () { install -d ${STAGING_INCDIR}/libltdl install -m 0644 libltdl/ltdl.h ${STAGING_INCDIR}/ -- cgit v1.2.3 From a2b8a408e9141091efc87e568641ed81f6767ce2 Mon Sep 17 00:00:00 2001 From: Omar Barron Date: Thu, 17 Sep 2009 16:17:24 -0500 Subject: linux-omap-zoomsync_2.6.31.bb : added new kernel for omapzoom2 Move to linux-omap kernel TI sync at git://dev.omapzoom.org/pub/scm/integration/kernel-omap3.git Signed-off-by: Omar Barron --- .../linux/linux-omap-zoomsync/omapzoom2/defconfig | 1888 ++++++++++++++++++++ recipes/linux/linux-omap-zoomsync_2.6.31.bb | 24 + 2 files changed, 1912 insertions(+) create mode 100755 recipes/linux/linux-omap-zoomsync/omapzoom2/defconfig create mode 100644 recipes/linux/linux-omap-zoomsync_2.6.31.bb diff --git a/recipes/linux/linux-omap-zoomsync/omapzoom2/defconfig b/recipes/linux/linux-omap-zoomsync/omapzoom2/defconfig new file mode 100755 index 0000000000..f38376d09e --- /dev/null +++ b/recipes/linux/linux-omap-zoomsync/omapzoom2/defconfig @@ -0,0 +1,1888 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.31-rc7-omap1 +# Thu Sep 17 13:41:00 2009 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Performance Counters +# +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_FREEZER=y + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_DAVINCI is not set +CONFIG_ARCH_OMAP=y + +# +# TI OMAP Implementations +# +CONFIG_ARCH_OMAP_OTG=y +# CONFIG_ARCH_OMAP1 is not set +# CONFIG_ARCH_OMAP2 is not set +CONFIG_ARCH_OMAP3=y +# CONFIG_ARCH_OMAP4 is not set + +# +# OMAP Feature Selections +# +# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set +# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set +# CONFIG_OMAP_SMARTREFLEX is not set +# CONFIG_OMAP_RESET_CLOCKS is not set +CONFIG_OMAP_MUX=y +CONFIG_OMAP_MUX_DEBUG=y +CONFIG_OMAP_MUX_WARNINGS=y +CONFIG_OMAP_MCBSP=y +# CONFIG_OMAP_MBOX_FWK is not set +CONFIG_OMAP_IOMMU=y +# CONFIG_OMAP_MPU_TIMER is not set +CONFIG_OMAP_32K_TIMER=y +# CONFIG_OMAP3_DEBOBS is not set +CONFIG_OMAP_32K_TIMER_HZ=128 +CONFIG_OMAP_DM_TIMER=y +# CONFIG_OMAP_LL_DEBUG_UART1 is not set +# CONFIG_OMAP_LL_DEBUG_UART2 is not set +# CONFIG_OMAP_LL_DEBUG_UART3 is not set +CONFIG_OMAP_LL_DEBUG_UART_EXT=y +# CONFIG_OMAP_PM_NONE is not set +CONFIG_OMAP_PM_NOOP=y +# CONFIG_OMAP_PM_SRF is not set +CONFIG_ARCH_OMAP34XX=y +CONFIG_ARCH_OMAP3430=y + +# +# OMAP Board Type +# +# CONFIG_MACH_OMAP3_BEAGLE is not set +# CONFIG_MACH_OMAP_LDP is not set +# CONFIG_MACH_OVERO is not set +# CONFIG_MACH_OMAP3EVM is not set +# CONFIG_MACH_OMAP3_PANDORA is not set +# CONFIG_MACH_OMAP_3430SDP is not set +# CONFIG_MACH_NOKIA_RX51 is not set +CONFIG_MACH_OMAP_ZOOM2=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_V7=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_IFAR=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_ARM_THUMBEE is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_HAS_TLS_REG=y +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_458693 is not set +# CONFIG_ARM_ERRATA_460075 is not set +CONFIG_COMMON_CLKDEV=y + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PREEMPT is not set +CONFIG_HZ=128 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.1:/home/user/buildroot ip=192.168.0.2:192.168.0.1:192.168.0.1:255.255.255.0:tgt:eth0:off rw console=ttyS2,115200n8" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +# CONFIG_CPU_FREQ is not set +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_VERBOSE=y +CONFIG_CAN_PM_TRACE=y +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_SUSPEND_FREEZER=y +# CONFIG_APM_EMULATION is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=y +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_MIGRATE=y +# CONFIG_XFRM_STATISTICS is not set +CONFIG_NET_KEY=y +CONFIG_NET_KEY_MIGRATE=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_VERIFY_WRITE=y +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_OMAP2=y +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ICS932S401 is not set +# CONFIG_OMAP_STI is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +CONFIG_SMSC_PHY=y +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +CONFIG_SMSC911X=y +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879_SPI is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI=y +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=32 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +CONFIG_I2C_OMAP=y +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_PCF8575 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +CONFIG_SPI_OMAP24XX=y + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +CONFIG_GPIO_TWL4030=y + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +CONFIG_W1=y +CONFIG_W1_CON=y + +# +# 1-wire Bus Masters +# +# CONFIG_W1_MASTER_DS2490 is not set +# CONFIG_W1_MASTER_DS2482 is not set +# CONFIG_W1_MASTER_DS1WM is not set +# CONFIG_W1_MASTER_GPIO is not set +# CONFIG_HDQ_MASTER_OMAP is not set + +# +# 1-wire Slaves +# +# CONFIG_W1_SLAVE_THERM is not set +# CONFIG_W1_SLAVE_SMEM is not set +# CONFIG_W1_SLAVE_DS2431 is not set +# CONFIG_W1_SLAVE_DS2433 is not set +# CONFIG_W1_SLAVE_DS2760 is not set +# CONFIG_W1_SLAVE_BQ27000 is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_OMAP_WATCHDOG=y +# CONFIG_TWL4030_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_TPS65010 is not set +CONFIG_TWL4030_CORE=y +# CONFIG_TWL4030_POWER is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +# CONFIG_VIDEO_ALLOW_V4L1 is not set +CONFIG_VIDEO_V4L1_COMPAT=y +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=y +# CONFIG_MEDIA_TUNER_CUSTOMISE is not set +CONFIG_MEDIA_TUNER_SIMPLE=y +CONFIG_MEDIA_TUNER_TDA8290=y +CONFIG_MEDIA_TUNER_TDA9887=y +CONFIG_MEDIA_TUNER_TEA5761=y +CONFIG_MEDIA_TUNER_TEA5767=y +CONFIG_MEDIA_TUNER_MT20XX=y +CONFIG_MEDIA_TUNER_XC2028=y +CONFIG_MEDIA_TUNER_XC5000=y +CONFIG_MEDIA_TUNER_MC44S803=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEOBUF_GEN=y +CONFIG_VIDEOBUF_DMA_SG=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set + +# +# Encoders/decoders and other helper chips +# + +# +# Audio decoders +# +# CONFIG_VIDEO_TVAUDIO is not set +# CONFIG_VIDEO_TDA7432 is not set +# CONFIG_VIDEO_TDA9840 is not set +# CONFIG_VIDEO_TDA9875 is not set +# CONFIG_VIDEO_TEA6415C is not set +# CONFIG_VIDEO_TEA6420 is not set +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_CS5345 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_M52790 is not set +# CONFIG_VIDEO_TLV320AIC23B is not set +# CONFIG_VIDEO_WM8775 is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_VP27SMPX is not set + +# +# RDS decoders +# +# CONFIG_VIDEO_SAA6588 is not set + +# +# Video decoders +# +# CONFIG_VIDEO_BT819 is not set +# CONFIG_VIDEO_BT856 is not set +# CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_KS0127 is not set +# CONFIG_VIDEO_OV7670 is not set +# CONFIG_VIDEO_MT9V011 is not set +# CONFIG_VIDEO_TCM825X is not set +# CONFIG_VIDEO_MT9P012 is not set +# CONFIG_VIDEO_DW9710 is not set +# CONFIG_VIDEO_OV3640 is not set +CONFIG_VIDEO_IMX046=y +CONFIG_VIDEO_LV8093=y +# CONFIG_VIDEO_SAA7110 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_SAA717X is not set +# CONFIG_VIDEO_TVP514X is not set +# CONFIG_VIDEO_TVP5150 is not set +# CONFIG_VIDEO_VPX3220 is not set + +# +# Video and audio decoders +# +# CONFIG_VIDEO_CX25840 is not set + +# +# MPEG video encoders +# +# CONFIG_VIDEO_CX2341X is not set + +# +# Video encoders +# +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_SAA7185 is not set +# CONFIG_VIDEO_ADV7170 is not set +# CONFIG_VIDEO_ADV7175 is not set +# CONFIG_VIDEO_THS7303 is not set +# CONFIG_VIDEO_ADV7343 is not set + +# +# Video improvement chips +# +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +CONFIG_VIDEO_OMAP3=y +CONFIG_VIDEO_OMAP_VIDEOOUT=y +CONFIG_NTSC_M=y +# CONFIG_PAL_BDGHI is not set +CONFIG_VIDEO_OMAP34XX_ISP_PREVIEWER=y +CONFIG_VIDEO_OMAP34XX_ISP_RESIZER=y +# CONFIG_SOC_CAMERA is not set +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_USB_VIDEO_CLASS is not set +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +# CONFIG_USB_M5602 is not set +# CONFIG_USB_STV06XX is not set +# CONFIG_USB_GSPCA_CONEX is not set +# CONFIG_USB_GSPCA_ETOMS is not set +# CONFIG_USB_GSPCA_FINEPIX is not set +# CONFIG_USB_GSPCA_MARS is not set +# CONFIG_USB_GSPCA_MR97310A is not set +# CONFIG_USB_GSPCA_OV519 is not set +# CONFIG_USB_GSPCA_OV534 is not set +# CONFIG_USB_GSPCA_PAC207 is not set +# CONFIG_USB_GSPCA_PAC7311 is not set +# CONFIG_USB_GSPCA_SN9C20X is not set +# CONFIG_USB_GSPCA_SONIXB is not set +# CONFIG_USB_GSPCA_SONIXJ is not set +# CONFIG_USB_GSPCA_SPCA500 is not set +# CONFIG_USB_GSPCA_SPCA501 is not set +# CONFIG_USB_GSPCA_SPCA505 is not set +# CONFIG_USB_GSPCA_SPCA506 is not set +# CONFIG_USB_GSPCA_SPCA508 is not set +# CONFIG_USB_GSPCA_SPCA561 is not set +# CONFIG_USB_GSPCA_SQ905 is not set +# CONFIG_USB_GSPCA_SQ905C is not set +# CONFIG_USB_GSPCA_STK014 is not set +# CONFIG_USB_GSPCA_SUNPLUS is not set +# CONFIG_USB_GSPCA_T613 is not set +# CONFIG_USB_GSPCA_TV8532 is not set +# CONFIG_USB_GSPCA_VC032X is not set +# CONFIG_USB_GSPCA_ZC3XX is not set +# CONFIG_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_HDPVR is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_CX231XX is not set +# CONFIG_VIDEO_USBVISION is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_ZC0301 is not set +CONFIG_USB_PWC_INPUT_EVDEV=y +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +CONFIG_RADIO_ADAPTERS=y +# CONFIG_USB_DSBR is not set +# CONFIG_USB_SI470X is not set +# CONFIG_USB_MR800 is not set +# CONFIG_RADIO_TEA5764 is not set +CONFIG_DAB=y +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_UVESA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set +CONFIG_OMAP2_VRAM=y +CONFIG_OMAP2_VRFB=y +CONFIG_OMAP2_DSS=y +CONFIG_OMAP2_VRAM_SIZE=4 +CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y +# CONFIG_OMAP2_DSS_RFBI is not set +CONFIG_OMAP2_DSS_VENC=y +# CONFIG_OMAP2_DSS_SDI is not set +# CONFIG_OMAP2_DSS_DSI is not set +# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set +CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0 +CONFIG_FB_OMAP2=y +CONFIG_FB_OMAP2_DEBUG_SUPPORT=y +# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set +CONFIG_FB_OMAP2_NUM_FBS=1 + +# +# OMAP2/3 Display Device Drivers +# +# CONFIG_PANEL_GENERIC is not set +# CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C is not set +# CONFIG_PANEL_SHARP_LS037V7DW01 is not set +CONFIG_PANEL_NEC=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_JACK=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +CONFIG_SND_ARM=y +CONFIG_SND_SPI=y +CONFIG_SND_USB=y +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_CAIAQ is not set +CONFIG_SND_SOC=y +CONFIG_SND_OMAP_SOC=y +CONFIG_SND_OMAP_SOC_MCBSP=y +CONFIG_SND_OMAP_SOC_ZOOM2=y +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SOC_TWL4030=y +# CONFIG_SOUND_PRIME is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_ZEROPLUS is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +CONFIG_USB_DEBUG=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y +CONFIG_USB_OTG=y +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_SOC=y + +# +# OMAP 343x high speed USB support +# +# CONFIG_USB_MUSB_HOST is not set +# CONFIG_USB_MUSB_PERIPHERAL is not set +CONFIG_USB_MUSB_OTG=y +CONFIG_USB_GADGET_MUSB_HDRC=y +CONFIG_USB_MUSB_HDRC_HCD=y +# CONFIG_MUSB_PIO_ONLY is not set +CONFIG_USB_INVENTRA_DMA=y +# CONFIG_USB_TI_CPPI_DMA is not set +CONFIG_USB_MUSB_DEBUG=y + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DEBUG=y +CONFIG_USB_GADGET_DEBUG_FILES=y +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_ZERO=m +# CONFIG_USB_ZERO_HNPTEST is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_ISP1301_OMAP is not set +CONFIG_TWL4030_USB=y +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_UNSAFE_RESUME=y + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +CONFIG_MMC_OMAP_HS=y +# CONFIG_MMC_SPI is not set +# CONFIG_MEMSTICK is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +CONFIG_RTC_DRV_TWL4030=y +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +# CONFIG_REGULATOR_BQ24022 is not set +# CONFIG_REGULATOR_MAX1586 is not set +CONFIG_REGULATOR_TWL4030=y +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_UIO is not set +# CONFIG_STAGING is not set + +# +# CBUS support +# +# CONFIG_CBUS is not set +CONFIG_MPU_BRIDGE=y +CONFIG_BRIDGE_MEMPOOL_SIZE=0x600000 +# CONFIG_BRIDGE_DEBUG is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_QUOTA_TREE=y +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=y +CONFIG_QUOTACTL=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +# CONFIG_NFS_V4_1 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_ARM_UNWIND=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +CONFIG_CRC_T10DIF=y +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/recipes/linux/linux-omap-zoomsync_2.6.31.bb b/recipes/linux/linux-omap-zoomsync_2.6.31.bb new file mode 100644 index 0000000000..63f9462633 --- /dev/null +++ b/recipes/linux/linux-omap-zoomsync_2.6.31.bb @@ -0,0 +1,24 @@ +require linux.inc + +DESCRIPTION = "Linux kernel for OMAP processors" +KERNEL_IMAGETYPE = "uImage" + +COMPATIBLE_MACHINE = "omapzoom2" + +DEFAULT_PREFERENCE = "-1" +DEFAULT_PREFERENCE_omapzoom2 = "1" + +SRCREV = "3823238fe2e56f60b9c6c085d3f1cfa720ae89b8" + +# The main PR is now using MACHINE_KERNEL_PR, for omap3 see conf/machine/include/omap3.inc +PV = "2.6.30+2.6.31-rc7" +PR_append = "+gitr${SRCREV}" + +SRC_URI = "git://dev.omapzoom.org/pub/scm/integration/kernel-omap3.git;branch=lo-sync-v2.6.31-rc7-7a8d53a0;protocol=git \ + file://defconfig" + +SRC_URI_append = " \ +" + +S = "${WORKDIR}/git" + -- cgit v1.2.3 From 41f2f6a12495fd1ab628b889892e7d4552dd5d50 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 18 Sep 2009 09:45:17 +0200 Subject: xserver-xorg-conf: add omap3517-evm support * This fixes the "blank screen" problem Frank Walzer reported --- .../xserver-xorg-conf/omap3517-evm/xorg.conf | 29 ++++++++++++++++++++++ recipes/xorg-xserver/xserver-xorg-conf_0.1.bb | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 recipes/xorg-xserver/xserver-xorg-conf/omap3517-evm/xorg.conf diff --git a/recipes/xorg-xserver/xserver-xorg-conf/omap3517-evm/xorg.conf b/recipes/xorg-xserver/xserver-xorg-conf/omap3517-evm/xorg.conf new file mode 100644 index 0000000000..983bb0823a --- /dev/null +++ b/recipes/xorg-xserver/xserver-xorg-conf/omap3517-evm/xorg.conf @@ -0,0 +1,29 @@ +Section "Module" + Load "extmod" + Load "dbe" + Load "glx" + Load "freetype" + Load "type1" + Load "record" + Load "dri" +EndSection + +Section "Monitor" + Identifier "Builtin Default Monitor" +EndSection + +Section "Device" + Identifier "Builtin Default fbdev Device 0" + Driver "omapfb" +EndSection + +Section "Screen" + Identifier "Builtin Default fbdev Screen 0" + Device "Builtin Default fbdev Device 0" + Monitor "Builtin Default Monitor" +EndSection + +Section "ServerLayout" + Identifier "Builtin Default Layout" + Screen "Builtin Default fbdev Screen 0" +EndSection diff --git a/recipes/xorg-xserver/xserver-xorg-conf_0.1.bb b/recipes/xorg-xserver/xserver-xorg-conf_0.1.bb index b572eab734..995cd8b20f 100644 --- a/recipes/xorg-xserver/xserver-xorg-conf_0.1.bb +++ b/recipes/xorg-xserver/xserver-xorg-conf_0.1.bb @@ -1,5 +1,5 @@ DESCRIPTION = "Machine specific xorg.conf files" -PR = "r9" +PR = "r10" SRC_URI = "file://xorg.conf" -- cgit v1.2.3 From 90746f3032489227e221e8b1f8e160857f74c046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20L=C3=BCbbe?= Date: Wed, 9 Sep 2009 11:23:16 +0000 Subject: libpoe-perl: add recipe --- conf/checksums.ini | 4 ++++ recipes/perl/libpoe-perl_1.007.bb | 10 ++++++++++ 2 files changed, 14 insertions(+) create mode 100644 recipes/perl/libpoe-perl_1.007.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index c0527325db..af76b072d7 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -718,6 +718,10 @@ sha256=987eeb9460185950e066e5db3b5fa531e53e213742b545288405552a5a7bb704 md5=210b764fca7c791f4387717185f589b5 sha256=09917ebe3b088649f0767723a7e25ae08fb8db921a85183e2e8c3d2e79ae6d10 +[http://backpan.cpan.org/modules/by-module/POE/RCAPUTO/POE-1.007.tar.gz] +md5=c7e8822bd11ed36a2f716f60e58da2e6 +sha256=5506b4e59aa455b026c4d92db083e7d6d36021b21a13be43d177276ab7d56a84 + [http://www.packagekit.org/releases/PackageKit-0.2.4.tar.gz] md5=87bf41fd021077c93549d47de6d5fe07 sha256=3b1a6f451928ca7e36d25e6e5a2e3dec2adae11c20770406f8bdc484f38b1600 diff --git a/recipes/perl/libpoe-perl_1.007.bb b/recipes/perl/libpoe-perl_1.007.bb new file mode 100644 index 0000000000..0ff7ccba8a --- /dev/null +++ b/recipes/perl/libpoe-perl_1.007.bb @@ -0,0 +1,10 @@ +DESCRIPTION = "Event-driven component architecture for Perl" +SECTION = "libs" +LICENSE = "Artistic|GPL" +PR = "r0" + +SRC_URI = "http://backpan.cpan.org/modules/by-module/POE/RCAPUTO/POE-${PV}.tar.gz" + +S = "${WORKDIR}/POE-${PV}" + +inherit cpan -- cgit v1.2.3 From ca309af34a87bfaf5beb3ae78a15617b865c2fe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20L=C3=BCbbe?= Date: Wed, 9 Sep 2009 11:25:23 +0000 Subject: net-snmp: switch to INC_PR --- recipes/net-snmp/net-snmp.inc | 1 + recipes/net-snmp/net-snmp_5.1.2.bb | 2 +- recipes/net-snmp/net-snmp_5.4.1.bb | 2 +- recipes/net-snmp/net-snmp_5.4.2.1.bb | 1 + recipes/net-snmp/net-snmp_svn.bb | 2 +- 5 files changed, 5 insertions(+), 3 deletions(-) diff --git a/recipes/net-snmp/net-snmp.inc b/recipes/net-snmp/net-snmp.inc index dcc02e7f67..769eb68294 100644 --- a/recipes/net-snmp/net-snmp.inc +++ b/recipes/net-snmp/net-snmp.inc @@ -6,6 +6,7 @@ RDEPENDS_${PN}-server += "net-snmp-mibs" RDEPENDS_${PN}-client += "net-snmp-mibs" RDEPENDS_${PN}-dev = "net-snmp-client (= ${EXTENDPV}) net-snmp-server (= ${EXTENDPV})" RRECOMMENDS_${PN}-dbg = "net-snmp-client (= ${EXTENDPV}) net-snmp-server (= ${EXTENDPV})" +INC_PR = "r5" inherit autotools update-rc.d diff --git a/recipes/net-snmp/net-snmp_5.1.2.bb b/recipes/net-snmp/net-snmp_5.1.2.bb index 527c9e33b1..b221c48169 100644 --- a/recipes/net-snmp/net-snmp_5.1.2.bb +++ b/recipes/net-snmp/net-snmp_5.1.2.bb @@ -1,5 +1,5 @@ require net-snmp.inc -PR = "r4" +PR = "${INC_PR}.0" SRC_URI = "${SOURCEFORGE_MIRROR}/net-snmp/net-snmp-${PV}.tar.gz \ file://uclibc-fix.patch;patch=1 \ diff --git a/recipes/net-snmp/net-snmp_5.4.1.bb b/recipes/net-snmp/net-snmp_5.4.1.bb index f76005b435..943e5f772b 100644 --- a/recipes/net-snmp/net-snmp_5.4.1.bb +++ b/recipes/net-snmp/net-snmp_5.4.1.bb @@ -1,5 +1,5 @@ require net-snmp.inc -PR = "r2" +PR = "${INC_PR}.0" SRC_URI = "${SOURCEFORGE_MIRROR}/net-snmp/net-snmp-${PV}.tar.gz \ file://configure-tail.patch;patch=1 \ diff --git a/recipes/net-snmp/net-snmp_5.4.2.1.bb b/recipes/net-snmp/net-snmp_5.4.2.1.bb index 3c51a5fa3c..7e81151c6d 100644 --- a/recipes/net-snmp/net-snmp_5.4.2.1.bb +++ b/recipes/net-snmp/net-snmp_5.4.2.1.bb @@ -1,4 +1,5 @@ require net-snmp.inc +PR = "${INC_PR}.0" SRC_URI = "${SOURCEFORGE_MIRROR}/net-snmp/net-snmp-${PV}.tar.gz \ file://configure-tail.patch;patch=1 \ diff --git a/recipes/net-snmp/net-snmp_svn.bb b/recipes/net-snmp/net-snmp_svn.bb index 2f82865aaa..c8c39fa819 100644 --- a/recipes/net-snmp/net-snmp_svn.bb +++ b/recipes/net-snmp/net-snmp_svn.bb @@ -1,7 +1,7 @@ require net-snmp.inc DEPENDS += "libtool libtool-native libtool-cross" +PR = "${INC_PR}.0" -PR = "r3" S = "${WORKDIR}/net-snmp" SRC_URI = "svn://net-snmp.svn.sourceforge.net/svnroot/net-snmp/trunk;rev=17367;module=net-snmp;proto=https \ -- cgit v1.2.3 From 07f750c6382476b799201b5ca47f93a5f7aa7e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20L=C3=BCbbe?= Date: Wed, 9 Sep 2009 11:25:39 +0000 Subject: net-snmp: use LDFLAGS (fixes QA error) --- recipes/net-snmp/net-snmp.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/recipes/net-snmp/net-snmp.inc b/recipes/net-snmp/net-snmp.inc index 769eb68294..7ba48c6dec 100644 --- a/recipes/net-snmp/net-snmp.inc +++ b/recipes/net-snmp/net-snmp.inc @@ -10,6 +10,7 @@ INC_PR = "r5" inherit autotools update-rc.d +TARGET_CC_ARCH += "${LDFLAGS}" do_configure() { # Additional flag based on target endiness (see siteinfo.bbclass) -- cgit v1.2.3 From 6adf15ce211e6111567fa66a282ffcaae4fa58c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20L=C3=BCbbe?= Date: Wed, 9 Sep 2009 13:57:50 +0000 Subject: net-snmp: add recipe for perl bindings It seems hard to convince net-snmp's build system to crossbuild the perl bindings, so i use a new recipe. --- recipes/net-snmp/libsnmp-perl_5.4.2.1.bb | 13 +++++++++++++ recipes/net-snmp/libsnmp-perl_svn.bb | 13 +++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 recipes/net-snmp/libsnmp-perl_5.4.2.1.bb create mode 100644 recipes/net-snmp/libsnmp-perl_svn.bb diff --git a/recipes/net-snmp/libsnmp-perl_5.4.2.1.bb b/recipes/net-snmp/libsnmp-perl_5.4.2.1.bb new file mode 100644 index 0000000000..135260132a --- /dev/null +++ b/recipes/net-snmp/libsnmp-perl_5.4.2.1.bb @@ -0,0 +1,13 @@ +DESCRIPTION = "Perl module from net-snmp" +SECTION = "libs" +LICENSE = "BSD" +DEPENDS = "net-snmp" +PR = "r0" + +SRC_URI = "${SOURCEFORGE_MIRROR}/net-snmp/net-snmp-${PV}.tar.gz" + +S = "${WORKDIR}/net-snmp-${PV}/perl" + +inherit cpan + +EXTRA_CPANFLAGS = "-NET-SNMP-CONFIG=\"sh ${STAGING_BINDIR}/net-snmp-config\"" diff --git a/recipes/net-snmp/libsnmp-perl_svn.bb b/recipes/net-snmp/libsnmp-perl_svn.bb new file mode 100644 index 0000000000..729a3d944b --- /dev/null +++ b/recipes/net-snmp/libsnmp-perl_svn.bb @@ -0,0 +1,13 @@ +DESCRIPTION = "Perl module from net-snmp" +SECTION = "libs" +LICENSE = "BSD" +DEPENDS = "net-snmp" +PR = "r2" + +SRC_URI = "svn://net-snmp.svn.sourceforge.net/svnroot/net-snmp/trunk;rev=17367;module=net-snmp;proto=https" + +S = "${WORKDIR}/net-snmp/perl" + +inherit cpan + +EXTRA_CPANFLAGS = "-NET-SNMP-CONFIG=${STAGING_BINDIR}/net-snmp-config -NET-SNMP-IN-SOURCE=false" -- cgit v1.2.3 From 277333bc80a22c4bff8f2a611d67be0856507bdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20L=C3=BCbbe?= Date: Thu, 17 Sep 2009 13:13:16 +0000 Subject: net-snmp: move svn srcrev to sane-srcrevs --- conf/distro/include/sane-srcrevs.inc | 2 ++ recipes/net-snmp/libsnmp-perl_svn.bb | 2 +- recipes/net-snmp/net-snmp_svn.bb | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/conf/distro/include/sane-srcrevs.inc b/conf/distro/include/sane-srcrevs.inc index e3400a213b..8c6737c938 100644 --- a/conf/distro/include/sane-srcrevs.inc +++ b/conf/distro/include/sane-srcrevs.inc @@ -95,6 +95,7 @@ SRCREV_pn-libmokopanelui2 ?= "4568" SRCREV_pn-libmokoui2 ?= "4342" SRCREV_pn-libowl ?= "277" SRCREV_pn-librfid ?= "2094" +SRCREV_pn-libsnmp-perl ?= "17367" SRCREV_pn-libsynthesis ?= "70f0065aa3b085bdf059830f95e5b5766eecb0bb" SRCREV_pn-libw100 ?= "47" SRCREV_pn-libxcalibrate ?= "209d83af61ed38a002c8096377deac292b3e396c" @@ -131,6 +132,7 @@ SRCREV_pn-multitap-pad ?= "373" SRCREV_pn-mux ?= "72460e890dbb15edbf7dc193116be0dcf9794a8b" SRCREV_pn-navit ?= "1096" SRCREV_pn-neod ?= "4617" +SRCREV_pn-net-snmp ?= "17367" SRCREV_pn-netsurf ?= "3859" SRCREV_pn-networkmanager ?= "3202" SRCREV_pn-networkmanager-applet ?= "200" diff --git a/recipes/net-snmp/libsnmp-perl_svn.bb b/recipes/net-snmp/libsnmp-perl_svn.bb index 729a3d944b..5355f1d7aa 100644 --- a/recipes/net-snmp/libsnmp-perl_svn.bb +++ b/recipes/net-snmp/libsnmp-perl_svn.bb @@ -4,7 +4,7 @@ LICENSE = "BSD" DEPENDS = "net-snmp" PR = "r2" -SRC_URI = "svn://net-snmp.svn.sourceforge.net/svnroot/net-snmp/trunk;rev=17367;module=net-snmp;proto=https" +SRC_URI = "svn://net-snmp.svn.sourceforge.net/svnroot/net-snmp/trunk;module=net-snmp;proto=https" S = "${WORKDIR}/net-snmp/perl" diff --git a/recipes/net-snmp/net-snmp_svn.bb b/recipes/net-snmp/net-snmp_svn.bb index c8c39fa819..0d27d0682c 100644 --- a/recipes/net-snmp/net-snmp_svn.bb +++ b/recipes/net-snmp/net-snmp_svn.bb @@ -4,7 +4,7 @@ PR = "${INC_PR}.0" S = "${WORKDIR}/net-snmp" -SRC_URI = "svn://net-snmp.svn.sourceforge.net/svnroot/net-snmp/trunk;rev=17367;module=net-snmp;proto=https \ +SRC_URI = "svn://net-snmp.svn.sourceforge.net/svnroot/net-snmp/trunk;module=net-snmp;proto=https \ file://init \ file://snmpd.conf \ file://snmptrapd.conf" -- cgit v1.2.3 From 8f10e06e417cabc19e49bc55eeed47ac52640e1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20L=C3=BCbbe?= Date: Thu, 17 Sep 2009 11:00:29 +0000 Subject: gnupg: split gpgv off into its own package --- recipes/gnupg/gnupg.inc | 5 +++++ recipes/gnupg/gnupg_1.4.2.2.bb | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/recipes/gnupg/gnupg.inc b/recipes/gnupg/gnupg.inc index 2d8e37605f..f41dbdc73c 100644 --- a/recipes/gnupg/gnupg.inc +++ b/recipes/gnupg/gnupg.inc @@ -71,6 +71,11 @@ do_install () { mv ${D}${prefix}/doc/* ${D}/${docdir}/${PN}/ || : } +# split out gpgv from main package +RDEPENDS_gnupg = "gpgv" +PACKAGES =+ "gpgv" +FILES_gpgv = "${bindir}/gpgv" + # Exclude debug files from the main packages FILES_${PN} = "${bindir}/* ${datadir}/${PN} ${libexecdir}/${PN}/*" FILES_${PN}-dbg += "${libexecdir}/${PN}/.debug" diff --git a/recipes/gnupg/gnupg_1.4.2.2.bb b/recipes/gnupg/gnupg_1.4.2.2.bb index 8492617683..6f63649b6f 100644 --- a/recipes/gnupg/gnupg_1.4.2.2.bb +++ b/recipes/gnupg/gnupg_1.4.2.2.bb @@ -12,4 +12,4 @@ SRC_URI += "file://15_free_caps.patch;patch=1 \ S = "${WORKDIR}/gnupg-${PV}" -PR = "r2" +PR = "r3" -- cgit v1.2.3 From 6063eff6c64831b2e9834d505b641342d7b292d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20L=C3=BCbbe?= Date: Thu, 10 Sep 2009 13:52:28 +0000 Subject: libexpect-perl: add recipe --- conf/checksums.ini | 4 ++++ recipes/perl/libexpect-perl_1.20.bb | 10 ++++++++++ 2 files changed, 14 insertions(+) create mode 100644 recipes/perl/libexpect-perl_1.20.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index af76b072d7..09e4796607 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -294,6 +294,10 @@ sha256=f464f0068772c276b81a7345f6788bdc3a243c13de24563346043d049a5497ba md5=560b42c0cf8b795bdc793459edb7ec13 sha256=9ad5a063bac80f3e77a179c91b7ea4490181640c8c1893292fdc6f2d92f40406 +[http://www.cpan.org/modules/by-module/Expect/Expect-1.20.tar.gz] +md5=9134ae3778285bcf8c3ffdba1a177886 +sha256=bbf70ce7cb39425a0f72c252491826747983ee82fb2d7b0a8a99d8940a58392f + [http://search.cpan.org/CPAN/authors/id/K/KW/KWILLIAMS/ExtUtils-CBuilder-0.18.tar.gz] md5=d119f0c6c12787a8d5b255208c3c74c5 sha256=fb707b2026de62c1de6ce7fb67e9f82d586211ac09c70e81b83631e77cb47fd1 diff --git a/recipes/perl/libexpect-perl_1.20.bb b/recipes/perl/libexpect-perl_1.20.bb new file mode 100644 index 0000000000..c5d369d5e3 --- /dev/null +++ b/recipes/perl/libexpect-perl_1.20.bb @@ -0,0 +1,10 @@ +DESCRIPTION = "Expect.pm - Perl Expect interface" +SECTION = "libs" +LICENSE = "Artistic" +PR = "r0" + +SRC_URI = "http://www.cpan.org/modules/by-module/Expect/Expect-${PV}.tar.gz" + +S = "${WORKDIR}/Expect-${PV}" + +inherit cpan -- cgit v1.2.3 From 6d66985c2607f4026671c9efdb40716aa1b33f0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20L=C3=BCbbe?= Date: Thu, 10 Sep 2009 15:18:38 +0000 Subject: aufs2-util: add recipe for userspace tools --- conf/distro/include/sane-srcrevs.inc | 1 + recipes/aufs/aufs2-util_git.bb | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 recipes/aufs/aufs2-util_git.bb diff --git a/conf/distro/include/sane-srcrevs.inc b/conf/distro/include/sane-srcrevs.inc index 8c6737c938..956e1fbe22 100644 --- a/conf/distro/include/sane-srcrevs.inc +++ b/conf/distro/include/sane-srcrevs.inc @@ -17,6 +17,7 @@ SRCREV_pn-alsa-scenario ?= "8bd7f83d847424eb44704cf1649974b2fda8d8f1" SRCREV_pn-app-restarter ?= "4552" SRCREV_pn-assassin ?= "268" SRCREV_pn-assassin-thumbnail ?= "4690" +SRCREV_pn-aufs2-util ?= "f35ba2292fe40aa94aa83713e0b2719f35a25768" SRCREV_pn-bfin-uclibc ?= "1857" SRCREV_pn-bootchart-lite ?= "4" SRCREV_pn-bubble-keyboard ?= "194" diff --git a/recipes/aufs/aufs2-util_git.bb b/recipes/aufs/aufs2-util_git.bb new file mode 100644 index 0000000000..deb5c6005e --- /dev/null +++ b/recipes/aufs/aufs2-util_git.bb @@ -0,0 +1,28 @@ +DESCRIPTION = "userspace utils for aufs2" +LICENSE = "GPL" +DEPENDS = "virtual/kernel" +PR = "r1" + +PACKAGE_ARCH = "${MACHINE_ARCH}" + +SRC_URI = "git://git.c3sl.ufpr.br/pub/scm/aufs/aufs2-util.git;protocol=http" + +S = "${WORKDIR}/git" + +EXTRA_OEMAKE = "KDIR=${STAGING_KERNEL_DIR} DESTDIR=${D}" + +do_compile () { + # c2tmac and c2sh need to be BUILD-arch + ${BUILD_CC} -I${STAGING_KERNEL_DIR}/include c2tmac.c -o c2tmac + ${BUILD_CC} -I${STAGING_KERNEL_DIR}/include c2sh.c -o c2sh + oe_runmake +} + +do_install () { + install -d ${D}/${base_sbindir} + install -m 0755 mount.aufs umount.aufs auplink ${D}/${base_sbindir} + install -d ${D}/${base_bindir} + install -m 0755 auchk aubrsync ${D}/${base_bindir} + install -d ${D}/${sysconfdir}/default + install -m 0644 -T etc_default_aufs ${D}/${sysconfdir}/default/aufs +} -- cgit v1.2.3 From 7a930238abfac90b5021781e870cfc71185c28c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20L=C3=BCbbe?= Date: Thu, 10 Sep 2009 15:45:54 +0000 Subject: libsoap-lite-perl: add recipe --- conf/checksums.ini | 4 ++++ recipes/perl/libsoap-lite-perl_0.710.08.bb | 14 ++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 recipes/perl/libsoap-lite-perl_0.710.08.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index 09e4796607..2b8ec2028a 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -998,6 +998,10 @@ sha256=f06895c0206dada9f9e7f07ecaeb6a3651fd648f4820f49c1f76bfeaec2f2913 md5=5f6b365b4c3815b13d7a902d94e254af sha256=957053683ca36129565db5018dd219bcc740ae781c4fbc9bc03f263f691730e8 +[http://www.cpan.org/authors/id/M/MK/MKUTTER/SOAP-Lite-0.710.08.tar.gz] +md5=e7869ad91fee76cc1782fe29fe3a989d +sha256=efe7dd9a1c6993d475ae1a653c5fa97a76a36accd468d49b030d81880ca11bef + [http://downloads.sourceforge.net/pywebsvcs/SOAPpy-0.11.3.tar.gz] md5=dbdcafe76f73dffaa6948b026607d51b sha256=a4a0984583c32fbf69e6f9495590b9e0c8a2a4aa42cb83f20b63a75208590845 diff --git a/recipes/perl/libsoap-lite-perl_0.710.08.bb b/recipes/perl/libsoap-lite-perl_0.710.08.bb new file mode 100644 index 0000000000..4cde3c945d --- /dev/null +++ b/recipes/perl/libsoap-lite-perl_0.710.08.bb @@ -0,0 +1,14 @@ +DESCRIPTION = "Client and server side SOAP implementation" +SECTION = "libs" +LICENSE = "Artistic|GPL" +PR = "r0" + +SRC_URI = "http://www.cpan.org/authors/id/M/MK/MKUTTER/SOAP-Lite-${PV}.tar.gz" + +S = "${WORKDIR}/SOAP-Lite-${PV}" + +inherit cpan + +do_configure_prepend () { + sed -i '/^use diagnostics;$/d' Makefile.PL +} -- cgit v1.2.3 From 7c54aba8056c12678e6225418f889348c3e06b72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20L=C3=BCbbe?= Date: Wed, 9 Sep 2009 18:17:01 +0000 Subject: linux_2.6.30: use debian's defconfig for i686 --- recipes/linux/linux-2.6.30/i686/defconfig | 4640 +++++++++++++++++++++++++++++ recipes/linux/linux_2.6.30.bb | 2 +- 2 files changed, 4641 insertions(+), 1 deletion(-) create mode 100644 recipes/linux/linux-2.6.30/i686/defconfig diff --git a/recipes/linux/linux-2.6.30/i686/defconfig b/recipes/linux/linux-2.6.30/i686/defconfig new file mode 100644 index 0000000000..21157c49e1 --- /dev/null +++ b/recipes/linux/linux-2.6.30/i686/defconfig @@ -0,0 +1,4640 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.30 +# Sat Aug 15 17:22:38 2009 +# +# CONFIG_64BIT is not set +CONFIG_X86_32=y +# CONFIG_X86_64 is not set +CONFIG_X86=y +CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig" +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_FAST_CMPXCHG_LOCAL=y +CONFIG_MMU=y +CONFIG_ZONE_DMA=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +# CONFIG_GENERIC_TIME_VSYSCALL is not set +CONFIG_ARCH_HAS_CPU_RELAX=y +CONFIG_ARCH_HAS_DEFAULT_IDLE=y +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +CONFIG_HAVE_DYNAMIC_PER_CPU_AREA=y +# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# CONFIG_ZONE_DMA32 is not set +CONFIG_ARCH_POPULATES_NODE_MAP=y +# CONFIG_AUDIT_ARCH is not set +CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_X86_32_SMP=y +CONFIG_X86_HT=y +CONFIG_X86_TRAMPOLINE=y +CONFIG_X86_32_LAZY_GS=y +CONFIG_KTIME_SCALAR=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +CONFIG_AUDIT_TREE=y + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +# CONFIG_USER_SCHED is not set +CONFIG_CGROUP_SCHED=y +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_NS=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_CPUACCT=y +# CONFIG_RESOURCE_COUNTERS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +CONFIG_RELAY=y +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +CONFIG_USER_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_STRIP_ASM_SYMS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_PCSPKR_PLATFORM=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_PCI_QUIRKS=y +# CONFIG_COMPAT_BRK is not set +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_MARKERS=y +CONFIG_OPROFILE=m +CONFIG_OPROFILE_IBS=y +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_SLOW_WORK=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +CONFIG_LBD=y +CONFIG_BLK_DEV_BSG=y +CONFIG_BLK_DEV_INTEGRITY=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_PREEMPT_NOTIFIERS=y +CONFIG_FREEZER=y + +# +# Processor type and features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_SMP=y +# CONFIG_SPARSE_IRQ is not set +CONFIG_X86_MPPARSE=y +CONFIG_X86_BIGSMP=y +# CONFIG_X86_EXTENDED_PLATFORM is not set +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_PARAVIRT_GUEST=y +CONFIG_VMI=y +CONFIG_KVM_CLOCK=y +CONFIG_KVM_GUEST=y +CONFIG_LGUEST_GUEST=y +CONFIG_PARAVIRT=y +# CONFIG_PARAVIRT_SPINLOCKS is not set +CONFIG_PARAVIRT_CLOCK=y +# CONFIG_PARAVIRT_DEBUG is not set +# CONFIG_MEMTEST is not set +# CONFIG_M386 is not set +# CONFIG_M486 is not set +# CONFIG_M586 is not set +# CONFIG_M586TSC is not set +# CONFIG_M586MMX is not set +CONFIG_M686=y +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +# CONFIG_MPENTIUM4 is not set +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +# CONFIG_MCRUSOE is not set +# CONFIG_MEFFICEON is not set +# CONFIG_MWINCHIPC6 is not set +# CONFIG_MWINCHIP3D is not set +# CONFIG_MGEODEGX1 is not set +# CONFIG_MGEODE_LX is not set +# CONFIG_MCYRIXIII is not set +# CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set +# CONFIG_MPSC is not set +# CONFIG_MCORE2 is not set +# CONFIG_GENERIC_CPU is not set +CONFIG_X86_GENERIC=y +CONFIG_X86_CPU=y +CONFIG_X86_L1_CACHE_BYTES=64 +CONFIG_X86_INTERNODE_CACHE_BYTES=64 +CONFIG_X86_CMPXCHG=y +CONFIG_X86_L1_CACHE_SHIFT=5 +CONFIG_X86_XADD=y +# CONFIG_X86_PPRO_FENCE is not set +CONFIG_X86_WP_WORKS_OK=y +CONFIG_X86_INVLPG=y +CONFIG_X86_BSWAP=y +CONFIG_X86_POPAD_OK=y +CONFIG_X86_INTEL_USERCOPY=y +CONFIG_X86_USE_PPRO_CHECKSUM=y +CONFIG_X86_TSC=y +CONFIG_X86_CMOV=y +CONFIG_X86_MINIMUM_CPU_FAMILY=4 +CONFIG_X86_DEBUGCTLMSR=y +CONFIG_CPU_SUP_INTEL=y +CONFIG_CPU_SUP_CYRIX_32=y +CONFIG_CPU_SUP_AMD=y +CONFIG_CPU_SUP_CENTAUR=y +CONFIG_CPU_SUP_TRANSMETA_32=y +CONFIG_CPU_SUP_UMC_32=y +# CONFIG_X86_DS is not set +CONFIG_HPET_TIMER=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_DMI=y +# CONFIG_IOMMU_HELPER is not set +CONFIG_IOMMU_API=y +CONFIG_NR_CPUS=32 +CONFIG_SCHED_SMT=y +CONFIG_SCHED_MC=y +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_IO_APIC=y +CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y +CONFIG_X86_MCE=y +CONFIG_X86_MCE_NONFATAL=m +CONFIG_X86_MCE_P4THERMAL=y +CONFIG_VM86=y +CONFIG_TOSHIBA=m +CONFIG_I8K=m +# CONFIG_X86_REBOOTFIXUPS is not set +CONFIG_MICROCODE=m +CONFIG_MICROCODE_INTEL=y +CONFIG_MICROCODE_AMD=y +CONFIG_MICROCODE_OLD_INTERFACE=y +CONFIG_X86_MSR=m +CONFIG_X86_CPUID=m +CONFIG_X86_CPU_DEBUG=m +# CONFIG_NOHIGHMEM is not set +CONFIG_HIGHMEM4G=y +# CONFIG_HIGHMEM64G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_HIGHMEM=y +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_SPARSEMEM_STATIC=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +CONFIG_MMU_NOTIFIER=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_HIGHPTE=y +# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set +CONFIG_X86_RESERVE_LOW_64K=y +# CONFIG_MATH_EMULATION is not set +CONFIG_MTRR=y +CONFIG_MTRR_SANITIZER=y +CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0 +CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1 +CONFIG_X86_PAT=y +CONFIG_EFI=y +CONFIG_SECCOMP=y +# CONFIG_CC_STACKPROTECTOR is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SCHED_HRTICK=y +CONFIG_KEXEC=y +# CONFIG_CRASH_DUMP is not set +# CONFIG_KEXEC_JUMP is not set +CONFIG_PHYSICAL_START=0x100000 +CONFIG_RELOCATABLE=y +CONFIG_PHYSICAL_ALIGN=0x100000 +CONFIG_HOTPLUG_CPU=y +# CONFIG_COMPAT_VDSO is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y + +# +# Power management and ACPI options +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP_SMP=y +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="" +CONFIG_ACPI=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_PROCFS=y +# CONFIG_ACPI_PROCFS_POWER is not set +CONFIG_ACPI_SYSFS_POWER=y +# CONFIG_ACPI_PROC_EVENT is not set +CONFIG_ACPI_AC=m +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_VIDEO=m +CONFIG_ACPI_FAN=m +CONFIG_ACPI_DOCK=y +CONFIG_ACPI_PROCESSOR=m +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_THERMAL=m +# CONFIG_ACPI_CUSTOM_DSDT is not set +CONFIG_ACPI_BLACKLIST_YEAR=0 +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_PCI_SLOT=m +CONFIG_X86_PM_TIMER=y +CONFIG_ACPI_CONTAINER=m +CONFIG_ACPI_SBS=m +CONFIG_X86_APM_BOOT=y +CONFIG_APM=m +# CONFIG_APM_IGNORE_USER_SUSPEND is not set +# CONFIG_APM_DO_ENABLE is not set +# CONFIG_APM_CPU_IDLE is not set +# CONFIG_APM_DISPLAY_BLANK is not set +# CONFIG_APM_ALLOW_INTS is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=m +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m + +# +# CPUFreq processor drivers +# +CONFIG_X86_ACPI_CPUFREQ=m +CONFIG_X86_POWERNOW_K6=m +CONFIG_X86_POWERNOW_K7=m +CONFIG_X86_POWERNOW_K7_ACPI=y +CONFIG_X86_POWERNOW_K8=m +CONFIG_X86_GX_SUSPMOD=m +CONFIG_X86_SPEEDSTEP_CENTRINO=m +CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y +CONFIG_X86_SPEEDSTEP_ICH=m +CONFIG_X86_SPEEDSTEP_SMI=m +CONFIG_X86_P4_CLOCKMOD=m +CONFIG_X86_CPUFREQ_NFORCE2=m +CONFIG_X86_LONGRUN=m +CONFIG_X86_LONGHAUL=m +CONFIG_X86_E_POWERSAVER=m + +# +# shared options +# +CONFIG_X86_SPEEDSTEP_LIB=m +CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# Bus options (PCI etc.) +# +CONFIG_PCI=y +# CONFIG_PCI_GOBIOS is not set +# CONFIG_PCI_GOMMCONFIG is not set +# CONFIG_PCI_GODIRECT is not set +# CONFIG_PCI_GOOLPC is not set +CONFIG_PCI_GOANY=y +CONFIG_PCI_BIOS=y +CONFIG_PCI_DIRECT=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_DOMAINS=y +CONFIG_DMAR=y +# CONFIG_DMAR_DEFAULT_ON is not set +CONFIG_DMAR_GFX_WA=y +CONFIG_DMAR_FLOPPY_WA=y +CONFIG_PCIEPORTBUS=y +CONFIG_HOTPLUG_PCI_PCIE=m +CONFIG_PCIEAER=y +# CONFIG_PCIEASPM is not set +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_PCI_MSI=y +CONFIG_PCI_LEGACY=y +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_STUB=m +CONFIG_HT_IRQ=y +CONFIG_PCI_IOV=y +CONFIG_ISA_DMA_API=y +CONFIG_ISA=y +# CONFIG_EISA is not set +# CONFIG_MCA is not set +CONFIG_SCx200=m +CONFIG_SCx200HR_TIMER=m +# CONFIG_OLPC is not set +CONFIG_K8_NB=y +CONFIG_PCCARD=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=m +CONFIG_PCMCIA_LOAD_CIS=y +# CONFIG_PCMCIA_IOCTL is not set +CONFIG_CARDBUS=y + +# +# PC-card bridges +# +CONFIG_YENTA=m +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_PD6729=m +CONFIG_I82092=m +CONFIG_I82365=m +CONFIG_TCIC=m +CONFIG_PCMCIA_PROBE=y +CONFIG_PCCARD_NONSTATIC=m +CONFIG_HOTPLUG_PCI=m +CONFIG_HOTPLUG_PCI_FAKE=m +CONFIG_HOTPLUG_PCI_COMPAQ=m +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +CONFIG_HOTPLUG_PCI_IBM=m +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m +CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m +CONFIG_HOTPLUG_PCI_SHPC=m + +# +# Executable file formats / Emulations +# +CONFIG_BINFMT_ELF=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_HAVE_AOUT=y +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_MISC=m +CONFIG_HAVE_ATOMIC_IOMAP=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_MD5SIG=y +CONFIG_IPV6=y +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=y +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_PIMSM_V2=y +# CONFIG_NETLABEL is not set +CONFIG_NETWORK_SECMARK=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NETFILTER_TPROXY=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_VS=m +# CONFIG_IP_VS_IPV6 is not set +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_DCCP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m + +# +# DECnet: Netfilter Configuration +# +CONFIG_DECNET_NF_GRABULATOR=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_NFLOG=m +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m + +# +# DCCP CCIDs Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=y +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +CONFIG_IP_DCCP_TFRC_LIB=y + +# +# DCCP Kernel Hacking +# +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +CONFIG_RDS=m +# CONFIG_RDS_DEBUG is not set +CONFIG_TIPC=m +CONFIG_TIPC_ADVANCED=y +CONFIG_TIPC_ZONES=3 +CONFIG_TIPC_CLUSTERS=1 +CONFIG_TIPC_NODES=255 +CONFIG_TIPC_SLAVE_NODES=0 +CONFIG_TIPC_PORTS=8191 +CONFIG_TIPC_LOG=0 +# CONFIG_TIPC_DEBUG is not set +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_STP=m +CONFIG_GARP=m +CONFIG_BRIDGE=m +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_DECNET=m +# CONFIG_DECNET_ROUTER is not set +CONFIG_LLC=y +CONFIG_LLC2=m +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=m +CONFIG_LTPC=m +CONFIG_IPDDP=m +CONFIG_IPDDP_ENCAP=y +CONFIG_IPDDP_DECAP=y +CONFIG_X25=m +CONFIG_LAPB=m +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_WAN_ROUTER=m +CONFIG_PHONET=m +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_INGRESS=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_CLS_IND=y +CONFIG_NET_SCH_FIFO=y +CONFIG_DCB=y + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +# CONFIG_NET_DROP_MONITOR is not set +CONFIG_HAMRADIO=y + +# +# Packet Radio protocols +# +CONFIG_AX25=m +# CONFIG_AX25_DAMA_SLAVE is not set +CONFIG_NETROM=m +CONFIG_ROSE=m + +# +# AX.25 network device drivers +# +CONFIG_MKISS=m +CONFIG_6PACK=m +CONFIG_BPQETHER=m +CONFIG_SCC=m +# CONFIG_SCC_DELAY is not set +# CONFIG_SCC_TRXECHO is not set +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_EPP=m +CONFIG_YAM=m +CONFIG_CAN=m +CONFIG_CAN_RAW=m +CONFIG_CAN_BCM=m + +# +# CAN Device Drivers +# +CONFIG_CAN_VCAN=m +# CONFIG_CAN_DEBUG_DEVICES is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TOIM3232_DONGLE=m +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_ACT200L_DONGLE=m +CONFIG_KINGSUN_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KS959_DONGLE=m + +# +# FIR device drivers +# +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_NSC_FIR=m +CONFIG_WINBOND_FIR=m +CONFIG_TOSHIBA_FIR=m +CONFIG_SMC_IRCC_FIR=m +CONFIG_ALI_FIR=m +CONFIG_VLSI_FIR=m +CONFIG_VIA_FIR=m +CONFIG_MCS_FIR=m +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_CMTP=m +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIVHCI=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_RXKAD=m +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_CFG80211=m +# CONFIG_CFG80211_REG_DEBUG is not set +CONFIG_WIRELESS_OLD_REGULATORY=y +CONFIG_WIRELESS_EXT=y +# CONFIG_WIRELESS_EXT_SYSFS is not set +CONFIG_LIB80211=m +CONFIG_LIB80211_CRYPT_WEP=m +CONFIG_LIB80211_CRYPT_CCMP=m +CONFIG_LIB80211_CRYPT_TKIP=m +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=m + +# +# Rate control algorithm selection +# +CONFIG_MAC80211_RC_MINSTREL=y +# CONFIG_MAC80211_RC_DEFAULT_PID is not set +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel" +CONFIG_MAC80211_MESH=y +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_WIMAX=m +CONFIG_WIMAX_DEBUG_LEVEL=8 +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +CONFIG_RFKILL_LEDS=y +CONFIG_NET_9P=m +CONFIG_NET_9P_VIRTIO=m +CONFIG_NET_9P_RDMA=m +# CONFIG_NET_9P_DEBUG is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=m +CONFIG_MTD=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=m +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_TESTS is not set +CONFIG_MTD_REDBOOT_PARTS=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_AR7_PARTS=m + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_FTL=m +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_INFTL=m +CONFIG_RFD_FTL=m +CONFIG_SSFDC=m +CONFIG_MTD_OOPS=m + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_RAM=m +CONFIG_MTD_ROM=m +CONFIG_MTD_ABSENT=m + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=m +# CONFIG_MTD_PHYSMAP_COMPAT is not set +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_NETSC520=m +CONFIG_MTD_TS5500=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_SCx200_DOCFLASH=m +# CONFIG_MTD_AMD76XROM is not set +# CONFIG_MTD_ICHXROM is not set +# CONFIG_MTD_ESB2ROM is not set +# CONFIG_MTD_CK804XROM is not set +# CONFIG_MTD_SCB2_FLASH is not set +CONFIG_MTD_NETtel=m +CONFIG_MTD_DILNETPC=m +CONFIG_MTD_DILNETPC_BOOTSIZE=0x80000 +# CONFIG_MTD_L440GX is not set +CONFIG_MTD_PCI=m +CONFIG_MTD_INTEL_VR_NOR=m +CONFIG_MTD_PLATRAM=m + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +# CONFIG_MTD_DATAFLASH_OTP is not set +CONFIG_MTD_M25P80=m +CONFIG_M25PXX_USE_FAST_READ=y +CONFIG_MTD_SLRAM=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_MTDRAM=m +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTD_BLOCK2MTD=m + +# +# Disk-On-Chip Device Drivers +# +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCECC=m +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_DOCPROBE_ADDRESS=0 +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_CS553X=m +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +CONFIG_MTD_ALAUDA=m +CONFIG_MTD_ONENAND=m +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_2X_PROGRAM=y +CONFIG_MTD_ONENAND_SIM=m + +# +# LPDDR flash memory drivers +# +CONFIG_MTD_LPDDR=m +CONFIG_MTD_QINFO_PROBE=m + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_GLUEBI is not set + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_SERIAL=m +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_AX88796=m +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_NOT_PC=y +CONFIG_PNP=y +# CONFIG_PNP_DEBUG_MESSAGES is not set + +# +# Protocols +# +CONFIG_ISAPNP=y +CONFIG_PNPBIOS=y +CONFIG_PNPBIOS_PROC_FS=y +CONFIG_PNPACPI=y +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_FD=m +CONFIG_BLK_DEV_XD=m +CONFIG_PARIDE=m + +# +# Parallel IDE high-level drivers +# +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PT=m +CONFIG_PARIDE_PG=m + +# +# Parallel IDE protocol modules +# +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_BPCK6=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_CISS_SCSI_TAPE=y +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_UMEM=m +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_SX8=m +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_XIP is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_VIRTIO_BLK=m +# CONFIG_BLK_DEV_HD is not set +CONFIG_MISC_DEVICES=y +CONFIG_IBM_ASM=m +CONFIG_PHANTOM=m +CONFIG_SGI_IOC4=m +CONFIG_TIFM_CORE=m +CONFIG_TIFM_7XX1=m +CONFIG_ICS932S401=m +CONFIG_ENCLOSURE_SERVICES=m +CONFIG_HP_ILO=m +CONFIG_DELL_LAPTOP=m +CONFIG_ISL29003=m +CONFIG_C2PORT=m +CONFIG_C2PORT_DURAMAR_2150=m + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=m +CONFIG_EEPROM_AT25=m +CONFIG_EEPROM_LEGACY=m +CONFIG_EEPROM_93CX6=m +CONFIG_HAVE_IDE=y +CONFIG_IDE=m + +# +# Please see Documentation/ide/ide.txt for help/info on IDE drives +# +CONFIG_IDE_XFER_MODE=y +CONFIG_IDE_TIMINGS=y +CONFIG_IDE_ATAPI=y +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_IDE_GD=m +CONFIG_IDE_GD_ATA=y +CONFIG_IDE_GD_ATAPI=y +CONFIG_BLK_DEV_IDECS=m +CONFIG_BLK_DEV_DELKIN=m +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IDEACPI=y +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=m +# CONFIG_BLK_DEV_PLATFORM is not set +CONFIG_BLK_DEV_CMD640=m +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +CONFIG_BLK_DEV_IDEPNP=m +CONFIG_BLK_DEV_IDEDMA_SFF=y + +# +# PCI IDE chipsets support +# +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=m +CONFIG_BLK_DEV_OPTI621=m +CONFIG_BLK_DEV_RZ1000=m +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_AEC62XX=m +CONFIG_BLK_DEV_ALI15X3=m +CONFIG_BLK_DEV_AMD74XX=m +CONFIG_BLK_DEV_ATIIXP=m +CONFIG_BLK_DEV_CMD64X=m +CONFIG_BLK_DEV_TRIFLEX=m +CONFIG_BLK_DEV_CS5520=m +CONFIG_BLK_DEV_CS5530=m +CONFIG_BLK_DEV_CS5535=m +CONFIG_BLK_DEV_CS5536=m +CONFIG_BLK_DEV_HPT366=m +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_SC1200=m +CONFIG_BLK_DEV_PIIX=m +CONFIG_BLK_DEV_IT8172=m +CONFIG_BLK_DEV_IT8213=m +CONFIG_BLK_DEV_IT821X=m +CONFIG_BLK_DEV_NS87415=m +CONFIG_BLK_DEV_PDC202XX_OLD=m +CONFIG_BLK_DEV_PDC202XX_NEW=m +CONFIG_BLK_DEV_SVWKS=m +CONFIG_BLK_DEV_SIIMAGE=m +CONFIG_BLK_DEV_SIS5513=m +CONFIG_BLK_DEV_SLC90E66=m +CONFIG_BLK_DEV_TRM290=m +CONFIG_BLK_DEV_VIA82CXXX=m +CONFIG_BLK_DEV_TC86C001=m + +# +# Other IDE chipsets support +# + +# +# Note: most of these also require special kernel boot parameters +# +# CONFIG_BLK_DEV_4DRIVES is not set +# CONFIG_BLK_DEV_ALI14XX is not set +# CONFIG_BLK_DEV_DTC2278 is not set +# CONFIG_BLK_DEV_HT6560B is not set +# CONFIG_BLK_DEV_QD65XX is not set +# CONFIG_BLK_DEV_UMC8672 is not set +CONFIG_BLK_DEV_IDEDMA=y + +# +# SCSI device support +# +CONFIG_RAID_ATTRS=m +CONFIG_SCSI=m +CONFIG_SCSI_DMA=y +CONFIG_SCSI_TGT=m +CONFIG_SCSI_NETLINK=y +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_SCH=m +CONFIG_SCSI_ENCLOSURE=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_FC_TGT_ATTRS=y +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SAS_HOST_SMP=y +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=m +CONFIG_SCSI_CXGB3_ISCSI=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_7000FASST=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AHA152X=m +CONFIG_SCSI_AHA1542=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +CONFIG_SCSI_AIC7XXX_OLD=m +CONFIG_SCSI_AIC79XX=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC79XX_DEBUG_ENABLE=y +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_SCSI_AIC94XX=m +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_IN2000=m +CONFIG_SCSI_ARCMSR=m +# CONFIG_SCSI_ARCMSR_AER is not set +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_SAS=m +CONFIG_SCSI_MPT2SAS=m +CONFIG_SCSI_MPT2SAS_MAX_SGE=128 +# CONFIG_SCSI_MPT2SAS_LOGGING is not set +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_BUSLOGIC=m +# CONFIG_SCSI_FLASHPOINT is not set +CONFIG_LIBFC=m +CONFIG_LIBFCOE=m +CONFIG_FCOE=m +CONFIG_FCOE_FNIC=m +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_DTC3280=m +CONFIG_SCSI_EATA=m +CONFIG_SCSI_EATA_TAGGED_QUEUE=y +CONFIG_SCSI_EATA_LINKED_COMMANDS=y +CONFIG_SCSI_EATA_MAX_TAGS=16 +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +CONFIG_SCSI_IPS=m +CONFIG_SCSI_INITIO=m +# CONFIG_SCSI_INIA100 is not set +CONFIG_SCSI_PPA=m +CONFIG_SCSI_IMM=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_MVSAS=m +CONFIG_SCSI_NCR53C406A=m +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_TRACE is not set +# CONFIG_SCSI_IPR_DUMP is not set +CONFIG_SCSI_PAS16=m +CONFIG_SCSI_QLOGIC_FAS=m +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_LPFC=m +# CONFIG_SCSI_LPFC_DEBUG_FS is not set +CONFIG_SCSI_SYM53C416=m +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_T128=m +CONFIG_SCSI_U14_34F=m +CONFIG_SCSI_U14_34F_TAGGED_QUEUE=y +CONFIG_SCSI_U14_34F_LINKED_COMMANDS=y +CONFIG_SCSI_U14_34F_MAX_TAGS=8 +CONFIG_SCSI_ULTRASTOR=m +CONFIG_SCSI_NSP32=m +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_LOWLEVEL_PCMCIA=y +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_SCSI_DH=m +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DH_HP_SW=m +CONFIG_SCSI_DH_EMC=m +CONFIG_SCSI_DH_ALUA=m +CONFIG_SCSI_OSD_INITIATOR=m +CONFIG_SCSI_OSD_ULD=m +CONFIG_SCSI_OSD_DPRINT_SENSE=1 +# CONFIG_SCSI_OSD_DEBUG is not set +CONFIG_ATA=m +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_ACPI=y +CONFIG_SATA_PMP=y +CONFIG_SATA_AHCI=m +CONFIG_SATA_SIL24=m +CONFIG_ATA_SFF=y +CONFIG_SATA_SVW=m +CONFIG_ATA_PIIX=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_PDC_ADMA=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_SX4=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIS=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +CONFIG_SATA_INIC162X=m +# CONFIG_PATA_ACPI is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +CONFIG_PATA_ARTOP=m +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CS5535 is not set +# CONFIG_PATA_CS5536 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +CONFIG_ATA_GENERIC=m +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_ISAPNP is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_IT8213 is not set +CONFIG_PATA_JMICRON=m +# CONFIG_PATA_LEGACY is not set +# CONFIG_PATA_TRIFLEX is not set +CONFIG_PATA_MARVELL=m +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PCMCIA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_QDI is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_SIL680 is not set +CONFIG_PATA_SIS_STUB=m +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set +# CONFIG_PATA_WINBOND_VLB is not set +CONFIG_PATA_SCH=m +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID6_PQ=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_DELAY=m +CONFIG_DM_UEVENT=y +CONFIG_FUSION=y +CONFIG_FUSION_SPI=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_SAS=m +CONFIG_FUSION_MAX_SGE=40 +CONFIG_FUSION_CTL=m +CONFIG_FUSION_LAN=m +# CONFIG_FUSION_LOGGING is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# Enable only one of the two stacks, unless you know what you are doing +# +CONFIG_FIREWIRE=m +CONFIG_FIREWIRE_OHCI=m +CONFIG_FIREWIRE_OHCI_DEBUG=y +CONFIG_FIREWIRE_SBP2=m +# CONFIG_IEEE1394 is not set +CONFIG_I2O=m +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_BUS=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_SCSI=m +CONFIG_I2O_PROC=m +# CONFIG_MACINTOSH_DRIVERS is not set +CONFIG_NETDEVICES=y +CONFIG_COMPAT_NET_DEV_OPS=y +CONFIG_IFB=m +CONFIG_DUMMY=m +CONFIG_BONDING=m +CONFIG_MACVLAN=m +CONFIG_EQUALIZER=m +CONFIG_TUN=m +CONFIG_VETH=m +CONFIG_NET_SB1000=m +CONFIG_ARCNET=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_RAW=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM90xx=m +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RIM_I=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_ISA=m +CONFIG_ARCNET_COM20020_PCI=m +CONFIG_PHYLIB=m + +# +# MII PHY device drivers +# +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m +CONFIG_VITESSE_PHY=m +CONFIG_SMSC_PHY=m +CONFIG_BROADCOM_PHY=m +CONFIG_ICPLUS_PHY=m +CONFIG_REALTEK_PHY=m +CONFIG_NATIONAL_PHY=m +CONFIG_STE10XP=m +CONFIG_LSI_ET1011C_PHY=m +CONFIG_MDIO_BITBANG=m +CONFIG_NET_ETHERNET=y +CONFIG_MII=m +CONFIG_HAPPYMEAL=m +CONFIG_SUNGEM=m +CONFIG_CASSINI=m +CONFIG_NET_VENDOR_3COM=y +CONFIG_EL1=m +CONFIG_EL2=m +CONFIG_ELPLUS=m +CONFIG_EL16=m +CONFIG_EL3=m +CONFIG_3C515=m +CONFIG_VORTEX=m +CONFIG_TYPHOON=m +CONFIG_LANCE=m +CONFIG_NET_VENDOR_SMC=y +CONFIG_WD80x3=m +CONFIG_ULTRA=m +CONFIG_SMC9194=m +CONFIG_ENC28J60=m +# CONFIG_ENC28J60_WRITEVERIFY is not set +CONFIG_ETHOC=m +CONFIG_NET_VENDOR_RACAL=y +CONFIG_NI52=m +CONFIG_NI65=m +CONFIG_DNET=m +CONFIG_NET_TULIP=y +CONFIG_DE2104X=m +CONFIG_TULIP=m +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +CONFIG_TULIP_NAPI=y +CONFIG_TULIP_NAPI_HW_MITIGATION=y +CONFIG_DE4X5=m +CONFIG_WINBOND_840=m +CONFIG_DM9102=m +CONFIG_ULI526X=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_AT1700=m +CONFIG_DEPCA=m +CONFIG_HP100=m +CONFIG_NET_ISA=y +CONFIG_E2100=m +CONFIG_EWRK3=m +CONFIG_EEXPRESS=m +CONFIG_EEXPRESS_PRO=m +CONFIG_HPLAN_PLUS=m +CONFIG_HPLAN=m +CONFIG_LP486E=m +CONFIG_ETH16I=m +CONFIG_NE2000=m +CONFIG_ZNET=m +CONFIG_SEEQ8005=m +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=m +CONFIG_AMD8111_ETH=m +CONFIG_ADAPTEC_STARFIRE=m +CONFIG_AC3200=m +CONFIG_APRICOT=m +CONFIG_B44=m +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI=y +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +CONFIG_CS89x0=m +CONFIG_E100=m +CONFIG_FEALNX=m +CONFIG_NATSEMI=m +CONFIG_NE2K_PCI=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_PIO=y +CONFIG_8139TOO_TUNE_TWISTER=y +CONFIG_8139TOO_8129=y +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_R6040=m +CONFIG_SIS900=m +CONFIG_EPIC100=m +CONFIG_SMSC9420=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_TLAN=m +CONFIG_VIA_RHINE=m +# CONFIG_VIA_RHINE_MMIO is not set +CONFIG_SC92031=m +# CONFIG_NET_POCKET is not set +CONFIG_ATL2=m +CONFIG_NETDEV_1000=y +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_DL2K=m +CONFIG_E1000=m +CONFIG_E1000E=m +CONFIG_IP1000=m +CONFIG_IGB=m +CONFIG_IGB_DCA=y +CONFIG_IGBVF=m +CONFIG_NS83820=m +CONFIG_HAMACHI=m +CONFIG_YELLOWFIN=m +CONFIG_R8169=m +CONFIG_R8169_VLAN=y +CONFIG_SIS190=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +CONFIG_VIA_VELOCITY=m +CONFIG_TIGON3=m +CONFIG_BNX2=m +CONFIG_QLA3XXX=m +CONFIG_ATL1=m +CONFIG_ATL1E=m +CONFIG_ATL1C=m +CONFIG_JME=m +CONFIG_NETDEV_10000=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T3_DEPENDS=y +CONFIG_CHELSIO_T3=m +CONFIG_ENIC=m +CONFIG_IXGBE=m +CONFIG_IXGBE_DCA=y +CONFIG_IXGBE_DCB=y +CONFIG_IXGB=m +CONFIG_S2IO=m +CONFIG_VXGE=m +# CONFIG_VXGE_DEBUG_TRACE_ALL is not set +CONFIG_MYRI10GE=m +CONFIG_MYRI10GE_DCA=y +CONFIG_NETXEN_NIC=m +CONFIG_NIU=m +CONFIG_MLX4_EN=m +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_TEHUTI=m +CONFIG_BNX2X=m +CONFIG_QLGE=m +CONFIG_SFC=m +CONFIG_SFC_MTD=y +CONFIG_BE2NET=m +CONFIG_TR=y +CONFIG_IBMTR=m +CONFIG_IBMOL=m +CONFIG_IBMLS=m +CONFIG_3C359=m +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +CONFIG_SKISA=m +CONFIG_PROTEON=m +CONFIG_ABYSS=m +# CONFIG_SMCTR is not set + +# +# Wireless LAN +# +CONFIG_WLAN_PRE80211=y +CONFIG_STRIP=m +CONFIG_ARLAN=m +CONFIG_WAVELAN=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_NETWAVE=m +CONFIG_WLAN_80211=y +CONFIG_PCMCIA_RAYCS=m +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_CS=m +CONFIG_LIBERTAS_SDIO=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_THINFIRM=m +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_AIRO=m +CONFIG_ATMEL=m +CONFIG_PCI_ATMEL=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_AT76C50X_USB=m +CONFIG_AIRO_CS=m +CONFIG_PCMCIA_WL3501=m +# CONFIG_PRISM54 is not set +CONFIG_USB_ZD1201=m +CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_RTL8180=m +CONFIG_RTL8187=m +CONFIG_ADM8211=m +CONFIG_MAC80211_HWSIM=m +CONFIG_MWL8K=m +CONFIG_P54_COMMON=m +CONFIG_P54_USB=m +CONFIG_P54_PCI=m +CONFIG_P54_SPI=m +CONFIG_P54_LEDS=y +CONFIG_ATH5K=m +# CONFIG_ATH5K_DEBUG is not set +CONFIG_ATH9K=m +# CONFIG_ATH9K_DEBUG is not set +CONFIG_AR9170_USB=m +CONFIG_AR9170_LEDS=y +CONFIG_IPW2100=m +CONFIG_IPW2100_MONITOR=y +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2200=m +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +# CONFIG_IPW2200_DEBUG is not set +CONFIG_LIBIPW=m +# CONFIG_LIBIPW_DEBUG is not set +CONFIG_IWLWIFI=m +CONFIG_IWLWIFI_LEDS=y +CONFIG_IWLWIFI_RFKILL=y +CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT=y +# CONFIG_IWLWIFI_DEBUG is not set +CONFIG_IWLAGN=m +CONFIG_IWL4965=y +CONFIG_IWL5000=y +CONFIG_IWL3945=m +CONFIG_IWL3945_SPECTRUM_MEASUREMENT=y +CONFIG_HOSTAP=m +CONFIG_HOSTAP_FIRMWARE=y +# CONFIG_HOSTAP_FIRMWARE_NVRAM is not set +CONFIG_HOSTAP_PLX=m +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_CS=m +CONFIG_B43=m +CONFIG_B43_PCI_AUTOSELECT=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_PCMCIA=y +CONFIG_B43_PIO=y +CONFIG_B43_LEDS=y +CONFIG_B43_RFKILL=y +# CONFIG_B43_DEBUG is not set +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_LEDS=y +CONFIG_B43LEGACY_RFKILL=y +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_PIO=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_RT2X00=m +CONFIG_RT2400PCI=m +CONFIG_RT2500PCI=m +CONFIG_RT61PCI=m +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_RFKILL=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set +CONFIG_HERMES=m +CONFIG_HERMES_CACHE_FW_ON_INIT=y +CONFIG_PLX_HERMES=m +CONFIG_TMD_HERMES=m +CONFIG_NORTEL_HERMES=m +CONFIG_PCI_HERMES=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_SPECTRUM=m + +# +# WiMAX Wireless Broadband devices +# +CONFIG_WIMAX_I2400M=m +CONFIG_WIMAX_I2400M_USB=m +CONFIG_WIMAX_I2400M_SDIO=m +CONFIG_WIMAX_I2400M_DEBUG_LEVEL=8 + +# +# USB Network Adapters +# +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +CONFIG_USB_NET_ZAURUS=m +CONFIG_USB_HSO=m +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_AXNET=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_PCMCIA_IBMTR=m +CONFIG_WAN=y +CONFIG_HOSTESS_SV11=m +CONFIG_COSA=m +CONFIG_LANMEDIA=m +CONFIG_SEALEVEL_4021=m +CONFIG_HDLC=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_X25=m +CONFIG_PCI200SYN=m +CONFIG_WANXL=m +# CONFIG_PC300TOO is not set +CONFIG_N2=m +CONFIG_C101=m +CONFIG_FARSYNC=m +CONFIG_DSCC4=m +CONFIG_DSCC4_PCISYNC=y +CONFIG_DSCC4_PCI_RST=y +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_SDLA=m +CONFIG_WAN_ROUTER_DRIVERS=m +CONFIG_CYCLADES_SYNC=m +CONFIG_CYCLOMX_X25=y +CONFIG_LAPBETHER=m +CONFIG_X25_ASY=m +CONFIG_SBNI=m +# CONFIG_SBNI_MULTILINE is not set +CONFIG_ATM_DRIVERS=y +CONFIG_ATM_DUMMY=m +CONFIG_ATM_TCP=m +CONFIG_ATM_LANAI=m +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FIRESTREAM=m +CONFIG_ATM_ZATM=m +# CONFIG_ATM_ZATM_DEBUG is not set +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_IA=m +# CONFIG_ATM_IA_DEBUG is not set +CONFIG_ATM_FORE200E=m +# CONFIG_ATM_FORE200E_USE_TASKLET is not set +CONFIG_ATM_FORE200E_TX_RETRY=16 +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_HE=m +CONFIG_ATM_HE_USE_SUNI=y +CONFIG_ATM_SOLOS=m +CONFIG_FDDI=y +CONFIG_DEFXX=m +# CONFIG_DEFXX_MMIO is not set +CONFIG_SKFP=m +CONFIG_HIPPI=y +CONFIG_ROADRUNNER=m +# CONFIG_ROADRUNNER_LARGE_RINGS is not set +CONFIG_PLIP=m +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +CONFIG_PPPOATM=m +CONFIG_PPPOL2TP=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLHC=m +CONFIG_SLIP_SMART=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_NET_FC=y +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_VIRTIO_NET=m +CONFIG_ISDN=y +CONFIG_MISDN=m +CONFIG_MISDN_DSP=m +CONFIG_MISDN_L1OIP=m + +# +# mISDN hardware drivers +# +CONFIG_MISDN_HFCPCI=m +CONFIG_MISDN_HFCMULTI=m +CONFIG_MISDN_HFCUSB=m +CONFIG_ISDN_I4L=m +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_MPP=y +CONFIG_IPPP_FILTER=y +CONFIG_ISDN_PPP_BSDCOMP=m +CONFIG_ISDN_AUDIO=y +CONFIG_ISDN_TTY_FAX=y +CONFIG_ISDN_X25=y + +# +# ISDN feature submodules +# +# CONFIG_ISDN_DIVERSION is not set + +# +# ISDN4Linux hardware drivers +# + +# +# Passive cards +# +CONFIG_ISDN_DRV_HISAX=m + +# +# D-channel protocol features +# +CONFIG_HISAX_EURO=y +CONFIG_DE_AOC=y +# CONFIG_HISAX_NO_SENDCOMPLETE is not set +# CONFIG_HISAX_NO_LLC is not set +# CONFIG_HISAX_NO_KEYPAD is not set +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_MAX_CARDS=8 + +# +# HiSax supported cards +# +CONFIG_HISAX_16_0=y +CONFIG_HISAX_16_3=y +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_AVM_A1=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_IX1MICROR2=y +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_ASUSCOM=y +CONFIG_HISAX_TELEINT=y +CONFIG_HISAX_HFCS=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_SPORTSTER=y +CONFIG_HISAX_MIC=y +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NICCY=y +CONFIG_HISAX_ISURF=y +CONFIG_HISAX_HSTSAPHIR=y +CONFIG_HISAX_BKM_A4T=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_W6692=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_ENTERNOW_PCI=y +# CONFIG_HISAX_DEBUG is not set + +# +# HiSax PCMCIA card service modules +# +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_TELES_CS=m + +# +# HiSax sub driver modules +# +CONFIG_HISAX_ST5481=m +CONFIG_HISAX_HFCUSB=m +CONFIG_HISAX_HFC4S8S=m +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_HDLC=y + +# +# Active cards +# +CONFIG_ISDN_DRV_ICN=m +CONFIG_ISDN_DRV_PCBIT=m +CONFIG_ISDN_DRV_SC=m +CONFIG_ISDN_DRV_ACT2000=m +CONFIG_HYSDN=m +CONFIG_HYSDN_CAPI=y +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_GIGASET_BASE=m +CONFIG_GIGASET_M105=m +CONFIG_GIGASET_M101=m +# CONFIG_GIGASET_DEBUG is not set +# CONFIG_GIGASET_UNDOCREQ is not set +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_CAPI_TRACE=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_CAPIFS=m +CONFIG_ISDN_CAPI_CAPIDRV=m + +# +# CAPI hardware drivers +# +CONFIG_CAPI_AVM=y +CONFIG_ISDN_DRV_AVMB1_B1ISA=m +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_T1ISA=m +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_C4=m +CONFIG_CAPI_EICON=y +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVAS_MAINT=m +CONFIG_PHONE=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_POLLDEV=m + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_BCM5974=m +CONFIG_MOUSE_INPORT=m +# CONFIG_MOUSE_ATIXL is not set +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_ZHENHUA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_JOYSTICK_WALKERA0701=m +CONFIG_INPUT_TABLET=y +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_AD7877=m +CONFIG_TOUCHSCREEN_AD7879_I2C=m +CONFIG_TOUCHSCREEN_AD7879=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_WACOM_W8001=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_INEXIO=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_HTCPEN=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_WM97XX=m +CONFIG_TOUCHSCREEN_WM9705=y +CONFIG_TOUCHSCREEN_WM9712=y +CONFIG_TOUCHSCREEN_WM9713=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_TOUCHIT213=m +CONFIG_TOUCHSCREEN_TSC2007=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_APANEL=m +CONFIG_INPUT_WISTRON_BTNS=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_YEALINK=m +CONFIG_INPUT_CM109=m +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_PCF50633_PMU=m + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=m +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=m +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_COMPUTONE=m +CONFIG_ROCKETPORT=m +CONFIG_CYCLADES=m +# CONFIG_CYZ_INTR is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_MOXA_INTELLIO is not set +CONFIG_MOXA_SMARTIO=m +# CONFIG_ISI is not set +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_GT=m +CONFIG_N_HDLC=m +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +CONFIG_SX=m +# CONFIG_RIO is not set +CONFIG_STALDRV=y +# CONFIG_STALLION is not set +# CONFIG_ISTALLION is not set +CONFIG_NOZOMI=m + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_NR_UARTS=32 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_FOURPORT=m +CONFIG_SERIAL_8250_ACCENT=m +CONFIG_SERIAL_8250_BOCA=m +CONFIG_SERIAL_8250_EXAR_ST16C554=m +CONFIG_SERIAL_8250_HUB6=m +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_MAX3100=m +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_UNIX98_PTYS=y +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +CONFIG_PPDEV=m +CONFIG_HVC_DRIVER=y +CONFIG_VIRTIO_CONSOLE=y +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m +CONFIG_HW_RANDOM=m +CONFIG_HW_RANDOM_TIMERIOMEM=m +CONFIG_HW_RANDOM_INTEL=m +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_GEODE=m +CONFIG_HW_RANDOM_VIA=m +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_NVRAM=m +CONFIG_DTLK=m +CONFIG_R3964=m +CONFIG_APPLICOM=m +CONFIG_SONYPI=m + +# +# PCMCIA character devices +# +CONFIG_SYNCLINK_CS=m +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +CONFIG_IPWIRELESS=m +CONFIG_MWAVE=m +CONFIG_SCx200_GPIO=m +CONFIG_PC8736x_GPIO=m +CONFIG_NSC_GPIO=m +CONFIG_CS5535_GPIO=m +CONFIG_RAW_DRIVER=m +CONFIG_MAX_RAW_DEVS=256 +CONFIG_HPET=y +CONFIG_HPET_MMAP=y +CONFIG_HANGCHECK_TIMER=m +CONFIG_TCG_TPM=m +CONFIG_TCG_TIS=m +CONFIG_TCG_NSC=m +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TELCLOCK=m +CONFIG_DEVPORT=y +CONFIG_I2C=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_ISCH=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_NFORCE2_S4985=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +CONFIG_I2C_OCORES=m +CONFIG_I2C_SIMTEC=m + +# +# External I2C/SMBus adapter drivers +# +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_TAOS_EVM=m +CONFIG_I2C_TINY_USB=m + +# +# Graphics adapter I2C/DDC channel drivers +# +CONFIG_I2C_VOODOO3=m + +# +# Other I2C/SMBus bus drivers +# +CONFIG_I2C_PCA_ISA=m +CONFIG_I2C_PCA_PLATFORM=m +CONFIG_I2C_STUB=m +CONFIG_SCx200_I2C=m +CONFIG_SCx200_I2C_SCL=12 +CONFIG_SCx200_I2C_SDA=13 +CONFIG_SCx200_ACB=m + +# +# Miscellaneous I2C Chip support +# +CONFIG_DS1682=m +CONFIG_SENSORS_PCF8574=m +CONFIG_PCF8575=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_TSL2550=m +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +CONFIG_SPI_LM70_LLP=m + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +CONFIG_SPI_TLE62X0=m +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +# CONFIG_GPIOLIB is not set +CONFIG_W1=m +CONFIG_W1_CON=y + +# +# 1-wire Bus Masters +# +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_DS2482=m + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2431=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_DS2760=m +CONFIG_W1_SLAVE_BQ27000=m +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_PDA_POWER=m +CONFIG_WM8350_POWER=m +CONFIG_BATTERY_DS2760=m +CONFIG_BATTERY_BQ27x00=m +CONFIG_CHARGER_PCF50633=m +CONFIG_HWMON=y +CONFIG_HWMON_VID=m +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_ABITUGURU3=m +CONFIG_SENSORS_AD7414=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADCXX=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7462=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ADT7473=m +CONFIG_SENSORS_ADT7475=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATK0110=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_FSCHMD=m +CONFIG_SENSORS_G760A=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_IBMAEM=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_LTC4215=m +CONFIG_SENSORS_LTC4245=m +CONFIG_SENSORS_LM95241=m +CONFIG_SENSORS_MAX1111=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_ADS7828=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83L786NG=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_HDAPS=m +CONFIG_SENSORS_LIS3LV02D=m +CONFIG_SENSORS_APPLESMC=m +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_THERMAL=m +CONFIG_THERMAL_HWMON=y +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +CONFIG_WM8350_WATCHDOG=m +CONFIG_ACQUIRE_WDT=m +CONFIG_ADVANTECH_WDT=m +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_SC520_WDT=m +CONFIG_EUROTECH_WDT=m +CONFIG_IB700_WDT=m +CONFIG_IBMASR=m +CONFIG_WAFER_WDT=m +CONFIG_I6300ESB_WDT=m +CONFIG_ITCO_WDT=m +# CONFIG_ITCO_VENDOR_SUPPORT is not set +CONFIG_IT8712F_WDT=m +CONFIG_IT87_WDT=m +CONFIG_HP_WATCHDOG=m +CONFIG_SC1200_WDT=m +CONFIG_SCx200_WDT=m +CONFIG_PC87413_WDT=m +CONFIG_60XX_WDT=m +CONFIG_SBC8360_WDT=m +CONFIG_SBC7240_WDT=m +CONFIG_CPU5_WDT=m +CONFIG_SMSC_SCH311X_WDT=m +CONFIG_SMSC37B787_WDT=m +CONFIG_W83627HF_WDT=m +CONFIG_W83697HF_WDT=m +CONFIG_W83697UG_WDT=m +CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_MACHZ_WDT=m +CONFIG_SBC_EPX_C3_WATCHDOG=m + +# +# ISA-based Watchdog Cards +# +CONFIG_PCWATCHDOG=m +CONFIG_MIXCOMWD=m +CONFIG_WDT=m + +# +# PCI-based Watchdog Cards +# +CONFIG_PCIPCWATCHDOG=m +CONFIG_WDTPCI=m +CONFIG_WDT_501_PCI=y + +# +# USB-based Watchdog Cards +# +CONFIG_USBPCWATCHDOG=m +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +CONFIG_SSB=m +CONFIG_SSB_SPROM=y +CONFIG_SSB_BLOCKIO=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_B43_PCI_BRIDGE=y +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +CONFIG_SSB_PCMCIAHOST=y +# CONFIG_SSB_DEBUG is not set +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_DRIVER_PCICORE=y + +# +# Multifunction device drivers +# +CONFIG_MFD_CORE=m +CONFIG_MFD_SM501=m +CONFIG_HTC_PASIC3=m +# CONFIG_MFD_TMIO is not set +CONFIG_MFD_WM8400=m +CONFIG_MFD_WM8350=m +CONFIG_MFD_WM8350_I2C=m +CONFIG_MFD_PCF50633=m +CONFIG_PCF50633_ADC=m +CONFIG_PCF50633_GPIO=m +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +CONFIG_REGULATOR_FIXED_VOLTAGE=m +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +CONFIG_REGULATOR_BQ24022=m +CONFIG_REGULATOR_WM8350=m +CONFIG_REGULATOR_WM8400=m +CONFIG_REGULATOR_PCF50633=m + +# +# Multimedia devices +# + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L2_COMMON=m +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_DVB_CORE=m +CONFIG_VIDEO_MEDIA=m + +# +# Multimedia drivers +# +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_MEDIA_ATTACH=y +CONFIG_MEDIA_TUNER=m +# CONFIG_MEDIA_TUNER_CUSTOMISE is not set +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_MT2131=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L1=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_DMA_SG=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS5345=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_M52790=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_VP27SMPX=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA717X=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_PMS=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_MEYE=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_MXB=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_MPEG=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_CX23885=m +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_FB_IVTV=m +CONFIG_VIDEO_CX18=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_SOC_CAMERA=m +CONFIG_SOC_CAMERA_MT9M001=m +CONFIG_SOC_CAMERA_MT9M111=m +CONFIG_SOC_CAMERA_MT9T031=m +CONFIG_SOC_CAMERA_MT9V022=m +CONFIG_SOC_CAMERA_TW9910=m +CONFIG_SOC_CAMERA_PLATFORM=m +CONFIG_SOC_CAMERA_OV772X=m +CONFIG_V4L_USB_DRIVERS=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_MR97310A=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_SQ905=m +CONFIG_USB_GSPCA_SQ905C=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_PVRUSB2_DVB=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_HDPVR=m +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_VIDEO_CX231XX=m +CONFIG_VIDEO_CX231XX_ALSA=m +CONFIG_VIDEO_CX231XX_DVB=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_USB_VICAM=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_ET61X251=m +CONFIG_VIDEO_OVCAMCHIP=m +# CONFIG_USB_W9968CF is not set +CONFIG_USB_OV511=m +CONFIG_USB_SE401=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STV680=m +CONFIG_USB_ZC0301=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_PWC_INPUT_EVDEV=y +CONFIG_USB_ZR364XX=m +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_S2255=m +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_CADET=m +CONFIG_RADIO_RTRACK=m +CONFIG_RADIO_RTRACK2=m +CONFIG_RADIO_AZTECH=m +CONFIG_RADIO_GEMTEK=m +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_SF16FMI=m +CONFIG_RADIO_SF16FMR2=m +CONFIG_RADIO_TERRATEC=m +CONFIG_RADIO_TRUST=m +CONFIG_RADIO_TYPHOON=m +CONFIG_RADIO_TYPHOON_PROC_FS=y +CONFIG_RADIO_ZOLTRIX=m +CONFIG_USB_DSBR=m +CONFIG_USB_SI470X=m +CONFIG_USB_MR800=m +CONFIG_RADIO_TEA5764=m +# CONFIG_DVB_DYNAMIC_MINORS is not set +CONFIG_DVB_CAPTURE_DRIVERS=y + +# +# Supported SAA7146 based PCI Adapters +# +CONFIG_TTPCI_EEPROM=m +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_BUDGET_CORE=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_PATCH=m + +# +# Supported USB Adapters +# +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_SIANO_SMS1XXX=m +CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS=y + +# +# Supported FlexCopII (B2C2) Adapters +# +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set + +# +# Supported BT878 Adapters +# +CONFIG_DVB_BT8XX=m + +# +# Supported Pluto2 Adapters +# +CONFIG_DVB_PLUTO2=m + +# +# Supported SDMC DM1105 Adapters +# +CONFIG_DVB_DM1105=m + +# +# Supported DVB Frontends +# +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_STB0899=m +CONFIG_DVB_STB6100=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_MT312=m +CONFIG_DVB_ZL10036=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_STV6110=m +CONFIG_DVB_STV0900=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8261=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_L64781=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_AF9013=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGDT3305=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_S5H1411=m +CONFIG_DVB_PLL=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_ISL6405=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_LGS8GL5=m +CONFIG_DAB=y +CONFIG_USB_DABUSB=m + +# +# Graphics support +# +CONFIG_AGP=m +CONFIG_AGP_ALI=m +CONFIG_AGP_ATI=m +CONFIG_AGP_AMD=m +CONFIG_AGP_AMD64=m +CONFIG_AGP_INTEL=m +CONFIG_AGP_NVIDIA=m +CONFIG_AGP_SIS=m +CONFIG_AGP_SWORKS=m +CONFIG_AGP_VIA=m +CONFIG_AGP_EFFICEON=m +CONFIG_DRM=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_I810=m +CONFIG_DRM_I830=m +CONFIG_DRM_I915=m +# CONFIG_DRM_I915_KMS is not set +CONFIG_DRM_MGA=m +CONFIG_DRM_SIS=m +CONFIG_DRM_VIA=m +CONFIG_DRM_SAVAGE=m +CONFIG_VGASTATE=m +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +CONFIG_FB_DDC=m +CONFIG_FB_BOOT_VESA_SUPPORT=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_SYS_FILLRECT=m +CONFIG_FB_SYS_COPYAREA=m +CONFIG_FB_SYS_IMAGEBLIT=m +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_SYS_FOPS=m +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_HECUBA=m +CONFIG_FB_SVGALIB=m +# CONFIG_FB_MACMODES is not set +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y + +# +# Frame buffer hardware drivers +# +CONFIG_FB_CIRRUS=m +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_CYBER2000=m +CONFIG_FB_ARC=m +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +CONFIG_FB_VGA16=m +CONFIG_FB_UVESA=m +CONFIG_FB_VESA=y +CONFIG_FB_EFI=y +CONFIG_FB_N411=m +CONFIG_FB_HGA=m +# CONFIG_FB_HGA_ACCEL is not set +CONFIG_FB_S1D13XXX=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_I2C=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_RIVA is not set +CONFIG_FB_I810=m +# CONFIG_FB_I810_GTF is not set +CONFIG_FB_LE80578=m +CONFIG_FB_CARILLO_RANCH=m +CONFIG_FB_INTEL=m +# CONFIG_FB_INTEL_DEBUG is not set +CONFIG_FB_INTEL_I2C=y +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_ATY128=m +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY=m +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_I2C=y +# CONFIG_FB_SAVAGE_ACCEL is not set +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_VIA=m +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_KYRO=m +CONFIG_FB_3DFX=m +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_3DFX_I2C=y +CONFIG_FB_VOODOO1=m +CONFIG_FB_VT8623=m +CONFIG_FB_TRIDENT=m +CONFIG_FB_ARK=m +CONFIG_FB_PM3=m +# CONFIG_FB_CARMINE is not set +CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_LX=m +CONFIG_FB_GEODE_GX=m +CONFIG_FB_GEODE_GX1=m +# CONFIG_FB_TMIO is not set +CONFIG_FB_SM501=m +CONFIG_FB_VIRTUAL=m +CONFIG_FB_METRONOME=m +CONFIG_FB_MB862XX=m +CONFIG_FB_MB862XX_PCI_GDC=y +# CONFIG_FB_BROADSHEET is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_PROGEAR=m +CONFIG_BACKLIGHT_MBP_NVIDIA=m +# CONFIG_BACKLIGHT_SAHARA is not set + +# +# Display device support +# +CONFIG_DISPLAY_SUPPORT=m + +# +# Display hardware drivers +# + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_MDA_CONSOLE=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_LOGO is not set +CONFIG_SOUND=m +CONFIG_SOUND_OSS_CORE=y +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_JACK=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_SEQUENCER_OSS is not set +CONFIG_SND_HRTIMER=m +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +CONFIG_SND_MPU401_UART=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_OPL4_LIB=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_DRIVERS=y +CONFIG_SND_PCSP=m +CONFIG_SND_DUMMY=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0 +CONFIG_SND_WSS_LIB=m +CONFIG_SND_SB_COMMON=m +CONFIG_SND_SB8_DSP=m +CONFIG_SND_SB16_DSP=m +CONFIG_SND_ISA=y +CONFIG_SND_ADLIB=m +CONFIG_SND_AD1816A=m +CONFIG_SND_AD1848=m +CONFIG_SND_ALS100=m +CONFIG_SND_AZT2320=m +CONFIG_SND_CMI8330=m +CONFIG_SND_CS4231=m +CONFIG_SND_CS4236=m +CONFIG_SND_DT019X=m +CONFIG_SND_ES968=m +CONFIG_SND_ES1688=m +CONFIG_SND_ES18XX=m +CONFIG_SND_SC6000=m +CONFIG_SND_GUSCLASSIC=m +CONFIG_SND_GUSEXTREME=m +CONFIG_SND_GUSMAX=m +CONFIG_SND_INTERWAVE=m +CONFIG_SND_INTERWAVE_STB=m +CONFIG_SND_OPL3SA2=m +CONFIG_SND_OPTI92X_AD1848=m +CONFIG_SND_OPTI92X_CS4231=m +CONFIG_SND_OPTI93X=m +CONFIG_SND_MIRO=m +CONFIG_SND_SB8=m +CONFIG_SND_SB16=m +CONFIG_SND_SBAWE=m +CONFIG_SND_SB16_CSP=y +CONFIG_SND_SGALAXY=m +CONFIG_SND_SSCAPE=m +CONFIG_SND_WAVEFRONT=m +# CONFIG_SND_MSND_PINNACLE is not set +# CONFIG_SND_MSND_CLASSIC is not set +CONFIG_SND_PCI=y +CONFIG_SND_AD1889=m +CONFIG_SND_ALS300=m +CONFIG_SND_ALS4000=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +# CONFIG_SND_AW2 is not set +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set +CONFIG_SND_CA0106=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_OXYGEN_LIB=m +CONFIG_SND_OXYGEN=m +CONFIG_SND_CS4281=m +CONFIG_SND_CS5530=m +CONFIG_SND_CS5535AUDIO=m +CONFIG_SND_DARLA20=m +CONFIG_SND_GINA20=m +CONFIG_SND_LAYLA20=m +CONFIG_SND_DARLA24=m +CONFIG_SND_GINA24=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MONA=m +CONFIG_SND_MIA=m +CONFIG_SND_ECHO3G=m +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGOIO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIOX=m +CONFIG_SND_INDIGODJX=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X_BOOL=y +CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_HDA_INTEL=m +CONFIG_SND_HDA_HWDEP=y +CONFIG_SND_HDA_RECONFIG=y +CONFIG_SND_HDA_INPUT_BEEP=y +CONFIG_SND_HDA_CODEC_REALTEK=y +CONFIG_SND_HDA_CODEC_ANALOG=y +CONFIG_SND_HDA_CODEC_SIGMATEL=y +CONFIG_SND_HDA_CODEC_VIA=y +CONFIG_SND_HDA_CODEC_ATIHDMI=y +CONFIG_SND_HDA_CODEC_NVHDMI=y +CONFIG_SND_HDA_CODEC_INTELHDMI=y +CONFIG_SND_HDA_ELD=y +CONFIG_SND_HDA_CODEC_CONEXANT=y +CONFIG_SND_HDA_CODEC_CMEDIA=y +CONFIG_SND_HDA_CODEC_SI3054=y +CONFIG_SND_HDA_GENERIC=y +CONFIG_SND_HDA_POWER_SAVE=y +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_HIFIER=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_KORG1212=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MIXART=m +CONFIG_SND_NM256=m +CONFIG_SND_PCXHR=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_SIS7019=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VIRTUOSO=m +CONFIG_SND_VX222=m +CONFIG_SND_YMFPCI=m +CONFIG_SND_SPI=y +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_USX2Y=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_US122L=m +CONFIG_SND_PCMCIA=y +CONFIG_SND_VXPOCKET=m +CONFIG_SND_PDAUDIOCF=m +# CONFIG_SND_SOC is not set +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=m +# CONFIG_HID_DEBUG is not set +CONFIG_HIDRAW=y + +# +# USB Input Devices +# +CONFIG_USB_HID=m +CONFIG_HID_PID=y +CONFIG_USB_HIDDEV=y + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CYPRESS=m +CONFIG_DRAGONRISE_FF=m +CONFIG_HID_EZKEY=m +CONFIG_HID_KYE=m +CONFIG_HID_GYRATION=m +CONFIG_HID_KENSINGTON=m +CONFIG_HID_LOGITECH=m +CONFIG_LOGITECH_FF=y +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_NTRIG=m +CONFIG_HID_PANTHERLORD=m +CONFIG_PANTHERLORD_FF=y +CONFIG_HID_PETALYNX=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +CONFIG_GREENASIA_FF=m +CONFIG_HID_TOPSEED=m +CONFIG_THRUSTMASTER_FF=m +CONFIG_ZEROPLUS_FF=m +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y +# CONFIG_USB_OTG is not set +CONFIG_USB_MON=m +CONFIG_USB_WUSB=m +CONFIG_USB_WUSB_CBAF=m +# CONFIG_USB_WUSB_CBAF_DEBUG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_C67X00_HCD=m +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_OXU210HP_HCD is not set +CONFIG_USB_ISP116X_HCD=m +# CONFIG_USB_ISP1760_HCD is not set +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_HCD_SSB is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SL811_CS=m +CONFIG_USB_R8A66597_HCD=m +CONFIG_USB_WHCI_HCD=m +CONFIG_USB_HWA_HCD=m + +# +# Enable Host or Gadget support to see Inventra options +# + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_WDM=m +CONFIG_USB_TMC=m + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_USB_STORAGE_ALAUDA=m +CONFIG_USB_STORAGE_ONETOUCH=m +CONFIG_USB_STORAGE_KARMA=m +CONFIG_USB_STORAGE_CYPRESS_ATACB=m +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m + +# +# USB port drivers +# +CONFIG_USB_USS720=m +CONFIG_USB_SERIAL=m +CONFIG_USB_EZUSB=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +# CONFIG_USB_SERIAL_WHITEHEAT is not set +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MOTOROLA=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIEMENS_MPI=m +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_SYMBOL=m +# CONFIG_USB_SERIAL_TI is not set +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTICON=m +CONFIG_USB_SERIAL_DEBUG=m + +# +# USB Miscellaneous drivers +# +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_SEVSEG=m +CONFIG_USB_RIO500=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_LED=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_SISUSBVGA=m +CONFIG_USB_SISUSBVGA_CON=y +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_TEST=m +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_VST=m +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +CONFIG_NOP_USB_XCEIV=m +CONFIG_UWB=m +CONFIG_UWB_HWA=m +CONFIG_UWB_WHCI=m +CONFIG_UWB_WLP=m +CONFIG_UWB_I1480U=m +CONFIG_UWB_I1480U_WLP=m +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_BOUNCE=y +CONFIG_SDIO_UART=m +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +CONFIG_MMC_SDHCI=m +CONFIG_MMC_SDHCI_PCI=m +CONFIG_MMC_RICOH_MMC=m +CONFIG_MMC_WBSD=m +CONFIG_MMC_TIFM_SD=m +CONFIG_MMC_SDRICOH_CS=m +CONFIG_MEMSTICK=m +# CONFIG_MEMSTICK_DEBUG is not set + +# +# MemoryStick drivers +# +# CONFIG_MEMSTICK_UNSAFE_RESUME is not set +CONFIG_MSPRO_BLOCK=m + +# +# MemoryStick Host Controller Drivers +# +CONFIG_MEMSTICK_TIFM_MS=m +CONFIG_MEMSTICK_JMICRON_38X=m +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=m + +# +# LED drivers +# +CONFIG_LEDS_NET48XX=m +CONFIG_LEDS_WRAP=m +CONFIG_LEDS_ALIX2=m +CONFIG_LEDS_PCA9532=m +CONFIG_LEDS_LP5521=m +CONFIG_LEDS_CLEVO_MAIL=m +CONFIG_LEDS_PCA955X=m +CONFIG_LEDS_WM8350=m +CONFIG_LEDS_DAC124S085=m +CONFIG_LEDS_BD2802=m + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_BACKLIGHT=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m + +# +# iptables trigger is under Netfilter config (LED target) +# +CONFIG_ACCESSIBILITY=y +CONFIG_A11Y_BRAILLE_CONSOLE=y +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_AMSO1100=m +# CONFIG_INFINIBAND_AMSO1100_DEBUG is not set +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_MLX4_INFINIBAND=m +CONFIG_INFINIBAND_NES=m +# CONFIG_INFINIBAND_NES_DEBUG is not set +CONFIG_INFINIBAND_IPOIB=m +# CONFIG_INFINIBAND_IPOIB_CM is not set +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_ISER=m +CONFIG_EDAC=y + +# +# Reporting subsystems +# +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_AMD76X=m +CONFIG_EDAC_E7XXX=m +CONFIG_EDAC_E752X=m +CONFIG_EDAC_I82875P=m +CONFIG_EDAC_I82975X=m +CONFIG_EDAC_I3000=m +CONFIG_EDAC_X38=m +CONFIG_EDAC_I5400=m +CONFIG_EDAC_I82860=m +CONFIG_EDAC_R82600=m +CONFIG_EDAC_I5000=m +CONFIG_EDAC_I5100=m +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_M41T80=m +# CONFIG_RTC_DRV_M41T80_WDT is not set +CONFIG_RTC_DRV_S35390A=m +CONFIG_RTC_DRV_FM3130=m +CONFIG_RTC_DRV_RX8581=m + +# +# SPI RTC drivers +# +CONFIG_RTC_DRV_M41T94=m +CONFIG_RTC_DRV_DS1305=m +CONFIG_RTC_DRV_DS1390=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_R9701=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_DS3234=m + +# +# Platform RTC drivers +# +CONFIG_RTC_DRV_CMOS=y +CONFIG_RTC_DRV_DS1286=m +CONFIG_RTC_DRV_DS1511=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_M48T35=m +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_BQ4802=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_WM8350=m +CONFIG_RTC_DRV_PCF50633=m + +# +# on-CPU RTC drivers +# +CONFIG_DMADEVICES=y + +# +# DMA Devices +# +CONFIG_INTEL_IOATDMA=m +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +CONFIG_NET_DMA=y +CONFIG_ASYNC_TX_DMA=y +# CONFIG_DMATEST is not set +CONFIG_DCA=m +# CONFIG_AUXDISPLAY is not set +CONFIG_UIO=m +CONFIG_UIO_CIF=m +CONFIG_UIO_PDRV=m +CONFIG_UIO_PDRV_GENIRQ=m +CONFIG_UIO_SMX=m +CONFIG_UIO_AEC=m +CONFIG_UIO_SERCOS3=m +CONFIG_STAGING=y +# CONFIG_STAGING_EXCLUDE_BUILD is not set +CONFIG_ET131X=m +# CONFIG_ET131X_DEBUG is not set +# CONFIG_SLICOSS is not set +# CONFIG_SXG is not set +# CONFIG_MEILHAUS is not set +# CONFIG_VIDEO_GO7007 is not set +# CONFIG_USB_IP_COMMON is not set +# CONFIG_W35UND is not set +CONFIG_PRISM2_USB=m +# CONFIG_ECHO is not set +# CONFIG_USB_ATMEL is not set +# CONFIG_POCH is not set +# CONFIG_AGNX is not set +CONFIG_RT2860=m +CONFIG_RT2870=m +CONFIG_COMEDI=m +# CONFIG_COMEDI_DEBUG is not set +CONFIG_COMEDI_PCI_DRIVERS=m +CONFIG_COMEDI_USB_DRIVERS=m +# CONFIG_ASUS_OLED is not set +# CONFIG_PANEL is not set +# CONFIG_ALTERA_PCIE_CHDMA is not set +CONFIG_RTL8187SE=m +# CONFIG_INPUT_MIMIO is not set +# CONFIG_TRANZPORT is not set +# CONFIG_EPL is not set + +# +# Android +# +# CONFIG_ANDROID is not set +# CONFIG_ANDROID_BINDER_IPC is not set +# CONFIG_ANDROID_LOGGER is not set +# CONFIG_ANDROID_RAM_CONSOLE is not set +# CONFIG_ANDROID_LOW_MEMORY_KILLER is not set +# CONFIG_DST is not set +CONFIG_POHMELFS=m +# CONFIG_POHMELFS_DEBUG is not set +CONFIG_POHMELFS_CRYPTO=y +# CONFIG_STLC45XX is not set +# CONFIG_USB_SERIAL_ATEN2011 is not set +# CONFIG_B3DFG is not set +# CONFIG_IDE_PHISON is not set +# CONFIG_PLAN9AUTH is not set +# CONFIG_HECI is not set +# CONFIG_LINE6_USB is not set +# CONFIG_USB_SERIAL_QUATECH_ESU100 is not set +CONFIG_X86_PLATFORM_DEVICES=y +CONFIG_ACER_WMI=m +CONFIG_ASUS_LAPTOP=m +CONFIG_DELL_WMI=m +CONFIG_FUJITSU_LAPTOP=m +# CONFIG_FUJITSU_LAPTOP_DEBUG is not set +CONFIG_TC1100_WMI=m +CONFIG_HP_WMI=m +CONFIG_MSI_LAPTOP=m +CONFIG_PANASONIC_LAPTOP=m +CONFIG_COMPAL_LAPTOP=m +CONFIG_SONY_LAPTOP=m +CONFIG_SONYPI_COMPAT=y +CONFIG_THINKPAD_ACPI=m +# CONFIG_THINKPAD_ACPI_DEBUGFACILITIES is not set +# CONFIG_THINKPAD_ACPI_DEBUG is not set +# CONFIG_THINKPAD_ACPI_UNSAFE_LEDS is not set +CONFIG_THINKPAD_ACPI_BAY=y +CONFIG_THINKPAD_ACPI_VIDEO=y +CONFIG_THINKPAD_ACPI_HOTKEY_POLL=y +# CONFIG_INTEL_MENLOW is not set +CONFIG_EEEPC_LAPTOP=m +CONFIG_ACPI_WMI=m +CONFIG_ACPI_ASUS=m +CONFIG_ACPI_TOSHIBA=m + +# +# Firmware Drivers +# +CONFIG_EDD=m +# CONFIG_EDD_OFF is not set +CONFIG_FIRMWARE_MEMMAP=y +CONFIG_EFI_VARS=m +CONFIG_DELL_RBU=m +CONFIG_DCDBAS=m +CONFIG_DMIID=y +CONFIG_ISCSI_IBFT_FIND=y +CONFIG_ISCSI_IBFT=y + +# +# File systems +# +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_DEFAULTS_TO_ORDERED=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=m +CONFIG_EXT4DEV_COMPAT=y +CONFIG_EXT4_FS_XATTR=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_JBD2=m +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=m +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +# CONFIG_XFS_DEBUG is not set +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=y +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +CONFIG_OCFS2_FS_STATS=y +CONFIG_OCFS2_DEBUG_MASKLOG=y +# CONFIG_OCFS2_DEBUG_FS is not set +CONFIG_OCFS2_FS_POSIX_ACL=y +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_FILE_LOCKING=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_QUOTA_TREE=m +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QUOTACTL=y +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m +CONFIG_GENERIC_ACL=y + +# +# Caches +# +CONFIG_FSCACHE=m +CONFIG_FSCACHE_STATS=y +# CONFIG_FSCACHE_HISTOGRAM is not set +# CONFIG_FSCACHE_DEBUG is not set +CONFIG_CACHEFILES=m +# CONFIG_CACHEFILES_DEBUG is not set +# CONFIG_CACHEFILES_HISTOGRAM is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="utf8" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_CONFIGFS_FS=m +CONFIG_MISC_FILESYSTEMS=y +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BFS_FS=m +CONFIG_EFS_FS=m +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_FS_POSIX_ACL=y +CONFIG_JFFS2_FS_SECURITY=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +# CONFIG_JFFS2_CMODE_FAVOURLZO is not set +CONFIG_UBIFS_FS=m +CONFIG_UBIFS_FS_XATTR=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +# CONFIG_UBIFS_FS_DEBUG is not set +CONFIG_CRAMFS=m +CONFIG_SQUASHFS=m +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +CONFIG_VXFS_FS=m +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m +CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_ROMFS_FS=m +# CONFIG_ROMFS_BACKED_BY_BLOCK is not set +# CONFIG_ROMFS_BACKED_BY_MTD is not set +CONFIG_ROMFS_BACKED_BY_BOTH=y +CONFIG_ROMFS_ON_BLOCK=y +CONFIG_ROMFS_ON_MTD=y +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +CONFIG_EXOFS_FS=m +# CONFIG_EXOFS_DEBUG is not set +CONFIG_NILFS2_FS=m +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_FSCACHE=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_SUNRPC_XPRT_RDMA=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +# CONFIG_SMB_FS is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_WEAK_PW_HASH=y +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_DEBUG2 is not set +CONFIG_CIFS_DFS_UPCALL=y +CONFIG_CIFS_EXPERIMENTAL=y +CONFIG_NCP_FS=m +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_OS2_NS=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_EXTRAS=y +CONFIG_CODA_FS=m +CONFIG_AFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FSCACHE=y +CONFIG_9P_FS=m + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ATARI_PARTITION=y +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_LDM_PARTITION=y +# CONFIG_LDM_DEBUG is not set +CONFIG_SGI_PARTITION=y +CONFIG_ULTRIX_PARTITION=y +CONFIG_SUN_PARTITION=y +CONFIG_KARMA_PARTITION=y +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=m +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +CONFIG_DLM=m +CONFIG_DLM_DEBUG=y + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_PRINTK_TIME=y +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +CONFIG_TIMER_STATS=y +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_VIRTUAL is not set +# CONFIG_DEBUG_WRITECOUNT is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +CONFIG_ARCH_WANT_FRAME_POINTERS=y +# CONFIG_FRAME_POINTER is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_USER_STACKTRACE_SUPPORT=y +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FTRACE_SYSCALLS=y +CONFIG_RING_BUFFER=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SYSPROF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +CONFIG_CONTEXT_SWITCH_TRACER=y +# CONFIG_EVENT_TRACER is not set +# CONFIG_FTRACE_SYSCALLS is not set +CONFIG_BOOT_TRACER=y +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_POWER_TRACER is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_MMIOTRACE is not set +# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set +# CONFIG_FIREWIRE_OHCI_REMOTE_DMA is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_STRICT_DEVMEM=y +CONFIG_X86_VERBOSE_BOOTUP=y +CONFIG_EARLY_PRINTK=y +# CONFIG_EARLY_PRINTK_DBGP is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_X86_PTDUMP is not set +CONFIG_DEBUG_RODATA=y +# CONFIG_DEBUG_RODATA_TEST is not set +# CONFIG_DEBUG_NX_TEST is not set +# CONFIG_4KSTACKS is not set +CONFIG_DOUBLEFAULT=y +CONFIG_HAVE_MMIOTRACE_SUPPORT=y +CONFIG_IO_DELAY_TYPE_0X80=0 +CONFIG_IO_DELAY_TYPE_0XED=1 +CONFIG_IO_DELAY_TYPE_UDELAY=2 +CONFIG_IO_DELAY_TYPE_NONE=3 +CONFIG_IO_DELAY_0X80=y +# CONFIG_IO_DELAY_0XED is not set +# CONFIG_IO_DELAY_UDELAY is not set +# CONFIG_IO_DELAY_NONE is not set +CONFIG_DEFAULT_IO_DELAY_TYPE=0 +# CONFIG_DEBUG_BOOT_PARAMS is not set +# CONFIG_CPA_DEBUG is not set +CONFIG_OPTIMIZE_INLINING=y + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_NETWORK_XFRM=y +# CONFIG_SECURITY_PATH is not set +CONFIG_SECURITY_FILE_CAPABILITIES=y +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +# CONFIG_SECURITY_TOMOYO is not set +# CONFIG_IMA is not set +CONFIG_XOR_BLOCKS=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_FIPS=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=m + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=m +CONFIG_CRYPTO_XCBC=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRC32C_INTEL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_AES_586=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SALSA20_586=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_TWOFISH_586=m + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_ZLIB=m +CONFIG_CRYPTO_LZO=m + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_DEV_PADLOCK=m +CONFIG_CRYPTO_DEV_PADLOCK_AES=m +CONFIG_CRYPTO_DEV_PADLOCK_SHA=m +CONFIG_CRYPTO_DEV_GEODE=m +CONFIG_CRYPTO_DEV_HIFN_795X=m +CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y +CONFIG_HAVE_KVM=y +CONFIG_HAVE_KVM_IRQCHIP=y +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=m +CONFIG_KVM_INTEL=m +CONFIG_KVM_AMD=m +# CONFIG_KVM_TRACE is not set +CONFIG_LGUEST=m +CONFIG_VIRTIO=y +CONFIG_VIRTIO_RING=y +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_BALLOON=m +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_FIRST_BIT=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +CONFIG_CRC_T10DIF=m +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +CONFIG_CRC7=m +CONFIG_LIBCRC32C=m +CONFIG_AUDIT_GENERIC=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_CHECK_SIGNATURE=y +CONFIG_NLATTR=y diff --git a/recipes/linux/linux_2.6.30.bb b/recipes/linux/linux_2.6.30.bb index 0e18f17cb8..706b48bbff 100644 --- a/recipes/linux/linux_2.6.30.bb +++ b/recipes/linux/linux_2.6.30.bb @@ -1,6 +1,6 @@ require linux.inc -PR = "r1" +PR = "r2" S = "${WORKDIR}/linux-${PV}" -- cgit v1.2.3 From b60e3a3e546091edaa9a85cada6b044c7ae89368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20L=C3=BCbbe?= Date: Thu, 10 Sep 2009 13:06:15 +0000 Subject: linux_2.6.30: add and enable aufs2 --- recipes/linux/linux-2.6.30/aufs2-30.patch | 26318 ++++++++++++++++++++++++++++ recipes/linux/linux-2.6.30/i686/defconfig | 14 +- recipes/linux/linux_2.6.30.bb | 3 +- 3 files changed, 26333 insertions(+), 2 deletions(-) create mode 100644 recipes/linux/linux-2.6.30/aufs2-30.patch diff --git a/recipes/linux/linux-2.6.30/aufs2-30.patch b/recipes/linux/linux-2.6.30/aufs2-30.patch new file mode 100644 index 0000000000..2ab5e8eb49 --- /dev/null +++ b/recipes/linux/linux-2.6.30/aufs2-30.patch @@ -0,0 +1,26318 @@ +diff --git a/Documentation/ABI/testing/debugfs-aufs b/Documentation/ABI/testing/debugfs-aufs +new file mode 100644 +index 0000000..4110b94 +--- /dev/null ++++ b/Documentation/ABI/testing/debugfs-aufs +@@ -0,0 +1,40 @@ ++What: /debug/aufs/si_/ ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ Under /debug/aufs, a directory named si_ is created ++ per aufs mount, where is a unique id generated ++ internally. ++ ++What: /debug/aufs/si_/xib ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ It shows the consumed blocks by xib (External Inode Number ++ Bitmap), its block size and file size. ++ When the aufs mount option 'noxino' is specified, it ++ will be empty. About XINO files, see ++ Documentation/filesystems/aufs/aufs.5 in detail. ++ ++What: /debug/aufs/si_/xino0, xino1 ... xinoN ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ It shows the consumed blocks by xino (External Inode Number ++ Translation Table), its link count, block size and file ++ size. ++ When the aufs mount option 'noxino' is specified, it ++ will be empty. About XINO files, see ++ Documentation/filesystems/aufs/aufs.5 in detail. ++ ++What: /debug/aufs/si_/xigen ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ It shows the consumed blocks by xigen (External Inode ++ Generation Table), its block size and file size. ++ If CONFIG_AUFS_EXPORT is disabled, this entry will not ++ be created. ++ When the aufs mount option 'noxino' is specified, it ++ will be empty. About XINO files, see ++ Documentation/filesystems/aufs/aufs.5 in detail. +diff --git a/Documentation/ABI/testing/sysfs-aufs b/Documentation/ABI/testing/sysfs-aufs +new file mode 100644 +index 0000000..ca49330 +--- /dev/null ++++ b/Documentation/ABI/testing/sysfs-aufs +@@ -0,0 +1,25 @@ ++What: /sys/fs/aufs/si_/ ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ Under /sys/fs/aufs, a directory named si_ is created ++ per aufs mount, where is a unique id generated ++ internally. ++ ++What: /sys/fs/aufs/si_/br0, br1 ... brN ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ It shows the abolute path of a member directory (which ++ is called branch) in aufs, and its permission. ++ ++What: /sys/fs/aufs/si_/xi_path ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ It shows the abolute path of XINO (External Inode Number ++ Bitmap, Translation Table and Generation Table) file ++ even if it is the default path. ++ When the aufs mount option 'noxino' is specified, it ++ will be empty. About XINO files, see ++ Documentation/filesystems/aufs/aufs.5 in detail. +diff --git a/Documentation/filesystems/aufs/README b/Documentation/filesystems/aufs/README +new file mode 100644 +index 0000000..83089b7 +--- /dev/null ++++ b/Documentation/filesystems/aufs/README +@@ -0,0 +1,342 @@ ++ ++Aufs2 -- advanced multi layered unification filesystem version 2 ++http://aufs.sf.net ++Junjiro R. Okajima ++ ++ ++0. Introduction ++---------------------------------------- ++In the early days, aufs was entirely re-designed and re-implemented ++Unionfs Version 1.x series. After many original ideas, approaches, ++improvements and implementations, it becomes totally different from ++Unionfs while keeping the basic features. ++Recently, Unionfs Version 2.x series begin taking some of the same ++approaches to aufs1's. ++Unionfs is being developed by Professor Erez Zadok at Stony Brook ++University and his team. ++ ++This version of AUFS, aufs2 has several purposes. ++- to be reviewed easily and widely. ++- to make the source files simpler and smaller by dropping several ++ original features. ++ ++Through this work, I found some bad things in aufs1 source code and ++fixed them. Some of the dropped features will be reverted in the future, ++but not all I'm afraid. ++Aufs2 supports linux-2.6.27 and later. If you want older kernel version ++support, try aufs1 from CVS on SourceForge. ++ ++Note: it becomes clear that "Aufs was rejected. Let's give it up." ++According to Christoph Hellwig, linux rejects all union-type filesystems ++but UnionMount. ++ ++ ++ ++1. Features ++---------------------------------------- ++- unite several directories into a single virtual filesystem. The member ++ directory is called as a branch. ++- you can specify the permission flags to the branch, which are 'readonly', ++ 'readwrite' and 'whiteout-able.' ++- by upper writable branch, internal copyup and whiteout, files/dirs on ++ readonly branch are modifiable logically. ++- dynamic branch manipulation, add, del. ++- etc... ++ ++Also there are many enhancements in aufs1, such as: ++- readdir(3) in userspace. ++- keep inode number by external inode number table ++- keep the timestamps of file/dir in internal copyup operation ++- seekable directory, supporting NFS readdir. ++- support mmap(2) including /proc/PID/exe symlink, without page-copy ++- whiteout is hardlinked in order to reduce the consumption of inodes ++ on branch ++- do not copyup, nor create a whiteout when it is unnecessary ++- revert a single systemcall when an error occurs in aufs ++- remount interface instead of ioctl ++- maintain /etc/mtab by an external command, /sbin/mount.aufs. ++- loopback mounted filesystem as a branch ++- kernel thread for removing the dir who has a plenty of whiteouts ++- support copyup sparse file (a file which has a 'hole' in it) ++- default permission flags for branches ++- selectable permission flags for ro branch, whether whiteout can ++ exist or not ++- export via NFS. ++- support /fs/aufs and /aufs. ++- support multiple writable branches, some policies to select one ++ among multiple writable branches. ++- a new semantics for link(2) and rename(2) to support multiple ++ writable branches. ++- no glibc changes are required. ++- pseudo hardlink (hardlink over branches) ++- allow a direct access manually to a file on branch, e.g. bypassing aufs. ++ including NFS or remote filesystem branch. ++- and more... ++ ++Currently these features are dropped temporary from this version, aufs2. ++See design/08plan.txt in detail. ++- test only the highest one for the directory permission (dirperm1) ++- show whiteout mode (shwh) ++- copyup on open (coo=) ++- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs ++ (robr) ++- statistics of aufs thread (/sys/fs/aufs/stat) ++- delegation mode (dlgt) ++ a delegation of the internal branch access to support task I/O ++ accounting, which also supports Linux Security Modules (LSM) mainly ++ for Suse AppArmor. ++- intent.open/create (file open in a single lookup) ++ ++Features or just an idea in the future (see also design/*.txt), ++- reorder the branch index without del/re-add. ++- permanent xino files for NFSD ++- an option for refreshing the opened files after add/del branches ++- 'move' policy for copy-up between two writable branches, after ++ checking free space. ++- O_DIRECT ++- light version, without branch manipulation. (unnecessary?) ++- copyup in userspace ++- inotify in userspace ++- readv/writev ++- xattr, acl ++ ++ ++2. Download ++---------------------------------------- ++Kindly one of aufs user, the Center for Scientific Computing and Free ++Software (C3SL), Federal University of Parana offered me a public GIT ++tree space. ++ ++There are three GIT trees, aufs2-2.6, aufs2-standalone and aufs2-util. ++While the aufs2-util is always necessary, you need either of aufs2-2.6 ++or aufs2-standalone. ++ ++The aufs2-2.6 tree includes the whole linux-2.6 GIT tree, ++git://git.kernel.org/.../torvalds/linux-2.6.git. ++And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot ++build aufs2 as an externel kernel module. ++If you already have linux-2.6 GIT tree, you may want to pull and merge ++the "aufs2" branch from this tree. ++ ++On the other hand, the aufs2-standalone tree has only aufs2 source files ++and a necessary patch, and you can select CONFIG_AUFS_FS=m. In other ++words, the aufs2-standalone tree is generated from aufs2-2.6 tree by, ++- extract new files and modifications. ++- generate some patch files from modifications. ++- generate a ChangeLog file from git-log. ++- commit the files newly and no log messages. this is not git-pull. ++ ++Both of aufs2-2.6 and aufs2-standalone trees have a branch whose name is ++in form of "aufs2-xx" where "xx" represents the linux kernel version, ++"linux-2.6.xx". ++ ++o aufs2-2.6 tree ++$ git clone --reference /your/linux-2.6/git/tree \ ++ http://git.c3sl.ufpr.br/pub/scm/aufs/aufs2-2.6.git \ ++ aufs2-2.6.git ++- if you don't have linux-2.6 GIT tree, then remove "--reference ..." ++$ cd aufs2-2.6.git ++$ git checkout origin/aufs2-xx # for instance, aufs2-27 for linux-2.6.27 ++ # aufs2 (no -xx) for the latest -rc version. ++ ++o aufs2-standalone tree ++$ git clone http://git.c3sl.ufpr.br/pub/scm/aufs/aufs2-standalone.git \ ++ aufs2-standalone.git ++$ cd aufs2-standalone.git ++$ git checkout origin/aufs2-xx # for instance, aufs2-27 for linux-2.6.27 ++ # aufs2 (no -xx) for the latest -rc version. ++ ++o aufs2-util tree ++$ git clone http://git.c3sl.ufpr.br/pub/scm/aufs/aufs2-util.git \ ++ aufs2-util.git ++$ cd aufs2-util.git ++- no particular tag/branch currently. ++ ++o for advanced users ++$ git clone git://git.kernel.org/.../torvalds/linux-2.6.git linux-2.6.git ++ It will take very long time. ++ ++$ cd linux-2.6.git ++$ git remote add aufs2 http://git.c3sl.ufpr.br/pub/scm/aufs/aufs2-2.6.git ++$ git checkout -b aufs2-27 v2.6.27 ++$ git pull aufs2 aufs2-27 ++ It may take long time again. ++ Once pulling completes, you've got linux-2.6.27 and aufs2 for it in a ++ branch named aufs2-27, and you can configure and build it. ++ ++Or ++ ++$ git checkout -t -b aufs2 master ++$ git pull aufs2 aufs2 ++ then you've got the latest linux kernel and the latest aufs2 in a ++ branch named aufs2, and you can configure and build it. ++ But aufs is released once a week, so you may meet a compilation error ++ due to mismatching between the mainline and aufs2. ++ ++Or you may want build linux-2.6.xx.yy instead of linux-2.6.xx, then here ++is an approach using linux-2.6-stable GIT tree. ++ ++$ cd linux-2.6.git/.. ++$ git clone -q --reference ./linux-2.6.git git://git.kernel.org/.../linux-2.6-stable.git \ ++ linux-2.6-stable.git ++ It will take very long time. ++ ++$ cd linux-2.6-stable.git ++$ git remote add aufs2 http://git.c3sl.ufpr.br/pub/scm/aufs/aufs2-2.6.git ++$ git checkout -b aufs2-27.1 v2.6.27.1 ++$ git pull aufs2 aufs2-27 ++ then you've got linux-2.6.27.1 and aufs2 for 2.6.27 in a branch named ++ aufs2-27.1, and you can configure and build it. ++ But the changes made by v2.6.xx.yy may conflict with aufs2-xx, since ++ aufs2-xx is for v2.6.xx only. In this case, you may find some patchces ++ for v2.6.xx.yy in aufs2-standalone.git#aufs2-xx branch if someone else ++ have ever requested me to support v2.6.xx.yy and I did it. ++ ++You can also check what was changed by pulling aufs2. ++$ git diff v2.6.27.1..aufs2-27.1 ++ ++If you want to check the changed files other than fs/aufs, then try this. ++$ git diff v2.6.27.1..aufs2-27.1 | ++> awk ' ++> /^diff / {new=1} ++> /^diff.*aufs/ {new=0} ++> new {print} ++> ' ++ ++ ++3. Configuration and Compilation ++---------------------------------------- ++For aufs2-2.6 tree, ++- enable CONFIG_EXPERIMENTAL and CONFIG_AUFS_FS. ++- set other aufs configurations if necessary. ++ ++For aufs2-standalone tree, ++There are several ways to build. ++ ++You may feel why aufs2-standalone.patch needs to export so many kernel ++symbols. Because you selected aufs2-standalone tree instead of aufs2-2.6 ++tree. The number of necessary symbols to export essentially is zero. ++All other symbols are for the external module. ++If you don't like aufs2-standalone.patch, then try aufs2-2.6 tree. ++ ++1. ++- apply ./aufs2-kbuild.patch to your kernel source files. ++- apply ./aufs2-base.patch too. ++- apply ./aufs2-standalone.patch too, if you have a plan to set ++ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs2-standalone.patch. ++- copy ./{Documentation,fs,include} files to your kernel source tree. ++- enable CONFIG_EXPERIMENTAL and CONFIG_AUFS_FS, you can select either ++ =m or =y. ++- and build your kernel as usual. ++- install it and reboot your system. ++ ++2. ++- module only (CONFIG_AUFS_FS=m). ++- apply ./aufs2-base.patch to your kernel source files. ++- apply ./aufs2-standalone.patch too. ++- build your kernel and reboot. ++- edit ./config.mk and set other aufs configurations if necessary. ++ Note: You should read ./fs/aufs/Kconfig carefully which describes ++ every aufs configurations. ++- build the module by simple "make". ++- you can specify ${KDIR} make variable which points to your kernel ++ source tree. ++- copy the build ./aufs.ko to /lib/modules/..., and run depmod -a (or ++ reboot simply). ++- no need to apply aufs2-kbuild.patch, nor copying source files to your ++ kernel source tree. ++ ++And then, ++- read README in aufs2-util, build and install it ++- if you want to use readdir(3) in userspace, then run ++ "make install_ulib" too. And refer to the aufs manual in detail. ++ ++ ++4. Usage ++---------------------------------------- ++At first, make sure aufs2-util are installed, and please read the aufs ++manual, aufs.5 in aufs2-util.git tree. ++$ man -l aufs.5 ++ ++And then, ++$ mkdir /tmp/rw /tmp/aufs ++# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs ++ ++Here is another example. The result is equivalent. ++# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs ++ Or ++# mount -t aufs -o br:/tmp/rw none /tmp/aufs ++# mount -o remount,append:${HOME} /tmp/aufs ++ ++Then, you can see whole tree of your home dir through /tmp/aufs. If ++you modify a file under /tmp/aufs, the one on your home directory is ++not affected, instead the same named file will be newly created under ++/tmp/rw. And all of your modification to a file will be applied to ++the one under /tmp/rw. This is called the file based Copy on Write ++(COW) method. ++Aufs mount options are described in aufs.5. ++ ++Additionally, there are some sample usages of aufs which are a ++diskless system with network booting, and LiveCD over NFS. ++See sample dir in CVS tree on SourceForge. ++ ++ ++5. Contact ++---------------------------------------- ++When you have any problems or strange behaviour in aufs, please let me ++know with: ++- /proc/mounts (instead of the output of mount(8)) ++- /sys/module/aufs/* ++- /sys/fs/aufs/* (if you have them) ++- /debug/aufs/* (if you have them) ++- linux kernel version ++ if your kernel is not plain, for example modified by distributor, ++ the url where i can download its source is necessary too. ++- aufs version which was printed at loading the module or booting the ++ system, instead of the date you downloaded. ++- configuration (define/undefine CONFIG_AUFS_xxx) ++- kernel configuration or /proc/config.gz (if you have it) ++- behaviour which you think to be incorrect ++- actual operation, reproducible one is better ++- mailto: aufs-users at lists.sourceforge.net ++ ++Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches, ++and Feature Requests) on SourceForge. Please join and write to ++aufs-users ML. ++ ++ ++6. Acknowledgements ++---------------------------------------- ++Thanks to everyone who have tried and are using aufs, whoever ++have reported a bug or any feedback. ++ ++Especially donors: ++Tomas Matejicek(slax.org) made a donation (much more than once). ++Dai Itasaka made a donation (2007/8). ++Chuck Smith made a donation (2008/4, 10 and 12). ++Henk Schoneveld made a donation (2008/9). ++Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10). ++Francois Dupoux made a donation (2008/11). ++Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public ++aufs2 GIT tree (2009/2). ++William Grant made a donation (2009/3). ++Patrick Lane made a donation (2009/4). ++The Mail Archive (mail-archive.com) made donations (2009/5). ++Nippy Networks (Ed Wildgoose) a donation (2009/7). ++ ++Thank you very much. ++Donations are always, including future donations, very important and ++helpful for me to keep on developing aufs. ++ ++ ++7. ++---------------------------------------- ++If you are an experienced user, no explanation is needed. Aufs is ++just a linux filesystem. ++ ++ ++Enjoy! ++ ++# Local variables: ; ++# mode: text; ++# End: ; +diff --git a/Documentation/filesystems/aufs/design/01intro.txt b/Documentation/filesystems/aufs/design/01intro.txt +new file mode 100644 +index 0000000..ac678c0 +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/01intro.txt +@@ -0,0 +1,137 @@ ++ ++# Copyright (C) 2005-2009 Junjiro R. Okajima ++# ++# 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 ++ ++Introduction ++---------------------------------------- ++ ++aufs [ei ju: ef es] | [a u f s] ++1. abbrev. for "advanced multi-layered unification filesystem". ++2. abbrev. for "another unionfs". ++3. abbrev. for "auf das" in German which means "on the" in English. ++ Ex. "Butter aufs Brot"(G) means "butter onto bread"(E). ++ But "Filesystem aufs Filesystem" is hard to understand. ++ ++AUFS is a filesystem with features: ++- multi layered stackable unification filesystem, the member directory ++ is called as a branch. ++- branch permission and attribute, 'readonly', 'real-readonly', ++ 'readwrite', 'whiteout-able', 'link-able whiteout' and their ++ combination. ++- internal "file copy-on-write". ++- logical deletion, whiteout. ++- dynamic branch manipulation, adding, deleting and changing permission. ++- allow bypassing aufs, user's direct branch access. ++- external inode number translation table and bitmap which maintains the ++ persistent aufs inode number. ++- seekable directory, including NFS readdir. ++- file mapping, mmap and sharing pages. ++- pseudo-link, hardlink over branches. ++- loopback mounted filesystem as a branch. ++- several policies to select one among multiple writable branches. ++- revert a single systemcall when an error occurs in aufs. ++- and more... ++ ++ ++Multi Layered Stackable Unification Filesystem ++---------------------------------------------------------------------- ++Most people already knows what it is. ++It is a filesystem which unifies several directories and provides a ++merged single directory. When users access a file, the access will be ++passed/re-directed/converted (sorry, I am not sure which English word is ++correct) to the real file on the member filesystem. The member ++filesystem is called 'lower filesystem' or 'branch' and has a mode ++'readonly' and 'readwrite.' And the deletion for a file on the lower ++readonly branch is handled by creating 'whiteout' on the upper writable ++branch. ++ ++On LKML, there have been discussions about UnionMount (Jan Blunck and ++Bharata B Rao) and Unionfs (Erez Zadok). They took different approaches ++to implement the merged-view. ++The former tries putting it into VFS, and the latter implements as a ++separate filesystem. ++(If I misunderstand about these implementations, please let me know and ++I shall correct it. Because it is a long time ago when I read their ++source files last time). ++UnionMount's approach will be able to small, but may be hard to share ++branches between several UnionMount since the whiteout in it is ++implemented in the inode on branch filesystem and always ++shared. According to Bharata's post, readdir does not seems to be ++finished yet. ++Unionfs has a longer history. When I started implementing a stacking filesystem ++(Aug 2005), it already existed. It has virtual super_block, inode, ++dentry and file objects and they have an array pointing lower same kind ++objects. After contributing many patches for Unionfs, I re-started my ++project AUFS (Jun 2006). ++ ++In AUFS, the structure of filesystem resembles to Unionfs, but I ++implemented my own ideas, approaches and enhancements and it became ++totally different one. ++ ++ ++Several characters/aspects of aufs ++---------------------------------------------------------------------- ++ ++Aufs has several characters or aspects. ++1. a filesystem, callee of VFS helper ++2. sub-VFS, caller of VFS helper for branches ++3. a virtual filesystem which maintains persistent inode number ++4. reader/writer of files on branches such like an application ++ ++1. Caller of VFS Helper ++As an ordinary linux filesystem, aufs is a callee of VFS. For instance, ++unlink(2) from an application reaches sys_unlink() kernel function and ++then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it ++calls filesystem specific unlink operation. Actually aufs implements the ++unlink operation but it behaves like a redirector. ++ ++2. Caller of VFS Helper for Branches ++aufs_unlink() passes the unlink request to the branch filesystem as if ++it were called from VFS. So the called unlink operation of the branch ++filesystem acts as usual. As a caller of VFS helper, aufs should handle ++every necessary pre/post operation for the branch filesystem. ++- acquire the lock for the parent dir on a branch ++- lookup in a branch ++- revalidate dentry on a branch ++- mnt_want_write() for a branch ++- vfs_unlink() for a branch ++- mnt_drop_write() for a branch ++- release the lock on a branch ++ ++3. Persistent Inode Number ++One of the most important issue for a filesystem is to maintain inode ++numbers. This is particularly important to support exporting a ++filesystem via NFS. Aufs is a virtual filesystem which doesn't have a ++backend block device for its own. But some storage is necessary to ++maintain inode number. It may be a large space and may not suit to keep ++in memory. Aufs rents some space from its first writable branch ++filesystem (by default) and creates file(s) on it. These files are ++created by aufs internally and removed soon (currently) keeping opened. ++Note: Because these files are removed, they are totally gone after ++ unmounting aufs. It means the inode numbers are not persistent ++ across unmount or reboot. I have a plan to make them really ++ persistent which will be important for aufs on NFS server. ++ ++4. Read/Write Files Internally (copy-on-write) ++Because a branch can be readonly, when you write a file on it, aufs will ++"copy-up" it to the upper writable branch internally. And then write the ++originally requested thing to the file. Generally kernel doesn't ++open/read/write file actively. In aufs, even a single write may cause a ++internal "file copy". This behaviour is very similar to cp(1) command. ++ ++Some people may think it is better to pass such work to user space ++helper, instead of doing in kernel space. Actually I am still thinking ++about it. But currently I have implemented it in kernel space. +diff --git a/Documentation/filesystems/aufs/design/02struct.txt b/Documentation/filesystems/aufs/design/02struct.txt +new file mode 100644 +index 0000000..11cee07 +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/02struct.txt +@@ -0,0 +1,218 @@ ++ ++# Copyright (C) 2005-2009 Junjiro R. Okajima ++# ++# 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 ++ ++Basic Aufs Internal Structure ++ ++Superblock/Inode/Dentry/File Objects ++---------------------------------------------------------------------- ++As like an ordinary filesystem, aufs has its own ++superblock/inode/dentry/file objects. All these objects have a ++dynamically allocated array and store the same kind of pointers to the ++lower filesystem, branch. ++For example, when you build a union with one readwrite branch and one ++readonly, mounted /au, /rw and /ro respectively. ++- /au = /rw + /ro ++- /ro/fileA exists but /rw/fileA ++ ++Aufs lookup operation finds /ro/fileA and gets dentry for that. These ++pointers are stored in a aufs dentry. The array in aufs dentry will be, ++- [0] = NULL ++- [1] = /ro/fileA ++ ++This style of an array is essentially same to the aufs ++superblock/inode/dentry/file objects. ++ ++Because aufs supports manipulating branches, ie. add/delete/change ++dynamically, these objects has its own generation. When branches are ++changed, the generation in aufs superblock is incremented. And a ++generation in other object are compared when it is accessed. ++When a generation in other objects are obsoleted, aufs refreshes the ++internal array. ++ ++ ++Superblock ++---------------------------------------------------------------------- ++Additionally aufs superblock has some data for policies to select one ++among multiple writable branches, XIB files, pseudo-links and kobject. ++See below in detail. ++About the policies which supports copy-down a directory, see policy.txt ++too. ++ ++ ++Branch and XINO(External Inode Number Translation Table) ++---------------------------------------------------------------------- ++Every branch has its own xino (external inode number translation table) ++file. The xino file is created and unlinked by aufs internally. When two ++members of a union exist on the same filesystem, they share the single ++xino file. ++The struct of a xino file is simple, just a sequence of aufs inode ++numbers which is indexed by the lower inode number. ++In the above sample, assume the inode number of /ro/fileA is i111 and ++aufs assigns the inode number i999 for fileA. Then aufs writes 999 as ++4(8) bytes at 111 * 4(8) bytes offset in the xino file. ++ ++When the inode numbers are not contiguous, the xino file will be sparse ++which has a hole in it and doesn't consume as much disk space as it ++might appear. If your branch filesystem consumes disk space for such ++holes, then you should specify 'xino=' option at mounting aufs. ++ ++Also a writable branch has three kinds of "whiteout bases". All these ++are existed when the branch is joined to aufs and the names are ++whiteout-ed doubly, so that users will never see their names in aufs ++hierarchy. ++1. a regular file which will be linked to all whiteouts. ++2. a directory to store a pseudo-link. ++3. a directory to store an "orphan-ed" file temporary. ++ ++1. Whiteout Base ++ When you remove a file on a readonly branch, aufs handles it as a ++ logical deletion and creates a whiteout on the upper writable branch ++ as a hardlink of this file in order not to consume inode on the ++ writable branch. ++2. Pseudo-link Dir ++ See below, Pseudo-link. ++3. Step-Parent Dir ++ When "fileC" exists on the lower readonly branch only and it is ++ opened and removed with its parent dir, and then user writes ++ something into it, then aufs copies-up fileC to this ++ directory. Because there is no other dir to store fileC. After ++ creating a file under this dir, the file is unlinked. ++ ++Because aufs supports manipulating branches, ie. add/delete/change ++dynamically, a branch has its own id. When the branch order changes, aufs ++finds the new index by searching the branch id. ++ ++ ++Pseudo-link ++---------------------------------------------------------------------- ++Assume "fileA" exists on the lower readonly branch only and it is ++hardlinked to "fileB" on the branch. When you write something to fileA, ++aufs copies-up it to the upper writable branch. Additionally aufs ++creates a hardlink under the Pseudo-link Directory of the writable ++branch. The inode of a pseudo-link is kept in aufs super_block as a ++simple list. If fileB is read after unlinking fileA, aufs returns ++filedata from the pseudo-link instead of the lower readonly ++branch. Because the pseudo-link is based upon the inode, to keep the ++inode number by xino (see above) is important. ++ ++All the hardlinks under the Pseudo-link Directory of the writable branch ++should be restored in a proper location later. Aufs provides a utility ++to do this. The userspace helpers executed at remounting and unmounting ++aufs by default. ++ ++ ++XIB(external inode number bitmap) ++---------------------------------------------------------------------- ++Addition to the xino file per a branch, aufs has an external inode number ++bitmap in a superblock object. It is also a file such like a xino file. ++It is a simple bitmap to mark whether the aufs inode number is in-use or ++not. ++To reduce the file I/O, aufs prepares a single memory page to cache xib. ++ ++Aufs implements a feature to truncate/refresh both of xino and xib to ++reduce the number of consumed disk blocks for these files. ++ ++ ++Virtual or Vertical Dir ++---------------------------------------------------------------------- ++In order to support multiple layers (branches), aufs readdir operation ++constructs a virtual dir block on memory. For readdir, aufs calls ++vfs_readdir() internally for each dir on branches, merges their entries ++with eliminating the whiteout-ed ones, and sets it to file (dir) ++object. So the file object has its entry list until it is closed. The ++entry list will be updated when the file position is zero and becomes ++old. This decision is made in aufs automatically. ++ ++The dynamically allocated memory block for the name of entries has a ++unit of 512 bytes (by default) and stores the names contiguously (no ++padding). Another block for each entry is handled by kmem_cache too. ++During building dir blocks, aufs creates hash list and judging whether ++the entry is whiteouted by its upper branch or already listed. ++ ++Some people may call it can be a security hole or invite DoS attack ++since the opened and once readdir-ed dir (file object) holds its entry ++list and becomes a pressure for system memory. But I'd say it is similar ++to files under /proc or /sys. The virtual files in them also holds a ++memory page (generally) while they are opened. When an idea to reduce ++memory for them is introduced, it will be applied to aufs too. ++For those who really hate this situation, I've developed readdir(3) ++library which operates this merging in userspace. You just need to set ++LD_PRELOAD environment variable, and aufs will not consume no memory in ++kernel space for readdir(3). ++ ++ ++Workqueue ++---------------------------------------------------------------------- ++Aufs sometimes requires privilege access to a branch. For instance, ++in copy-up/down operation. When a user process is going to make changes ++to a file which exists in the lower readonly branch only, and the mode ++of one of ancestor directories may not be writable by a user ++process. Here aufs copy-up the file with its ancestors and they may ++require privilege to set its owner/group/mode/etc. ++This is a typical case of a application character of aufs (see ++Introduction). ++ ++Aufs uses workqueue synchronously for this case. It creates its own ++workqueue. The workqueue is a kernel thread and has privilege. Aufs ++passes the request to call mkdir or write (for example), and wait for ++its completion. This approach solves a problem of a signal handler ++simply. ++If aufs didn't adopt the workqueue and changed the privilege of the ++process, and if the mkdir/write call arises SIGXFSZ or other signal, ++then the user process might gain a privilege or the generated core file ++was owned by a superuser. But I have a plan to switch to a new ++credential approach which will be introduced in linux-2.6.29. ++ ++Also aufs uses the system global workqueue ("events" kernel thread) too ++for asynchronous tasks, such like handling inotify, re-creating a ++whiteout base and etc. This is unrelated to a privilege. ++Most of aufs operation tries acquiring a rw_semaphore for aufs ++superblock at the beginning, at the same time waits for the completion ++of all queued asynchronous tasks. ++ ++ ++Whiteout ++---------------------------------------------------------------------- ++The whiteout in aufs is very similar to Unionfs's. That is represented ++by its filename. UnionMount takes an approach of a file mode, but I am ++afraid several utilities (find(1) or something) will have to support it. ++ ++Basically the whiteout represents "logical deletion" which stops aufs to ++lookup further, but also it represents "dir is opaque" which also stop ++lookup. ++ ++In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively. ++In order to make several functions in a single systemcall to be ++revertible, aufs adopts an approach to rename a directory to a temporary ++unique whiteouted name. ++For example, in rename(2) dir where the target dir already existed, aufs ++renames the target dir to a temporary unique whiteouted name before the ++actual rename on a branch and then handles other actions (make it opaque, ++update the attributes, etc). If an error happens in these actions, aufs ++simply renames the whiteouted name back and returns an error. If all are ++succeeded, aufs registers a function to remove the whiteouted unique ++temporary name completely and asynchronously to the system global ++workqueue. ++ ++ ++Copy-up ++---------------------------------------------------------------------- ++It is a well-known feature or concept. ++When user modifies a file on a readonly branch, aufs operate "copy-up" ++internally and makes change to the new file on the upper writable branch. ++When the trigger systemcall does not update the timestamps of the parent ++dir, aufs reverts it after copy-up. +diff --git a/Documentation/filesystems/aufs/design/03lookup.txt b/Documentation/filesystems/aufs/design/03lookup.txt +new file mode 100644 +index 0000000..7510fdb +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/03lookup.txt +@@ -0,0 +1,104 @@ ++ ++# Copyright (C) 2005-2009 Junjiro R. Okajima ++# ++# 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 ++ ++Lookup in a Branch ++---------------------------------------------------------------------- ++Since aufs has a character of sub-VFS (see Introduction), it operates ++lookup for branches as VFS does. It may be a heavy work. Generally ++speaking struct nameidata is a bigger structure and includes many ++information. But almost all lookup operation in aufs is the simplest ++case, ie. lookup only an entry directly connected to its parent. Digging ++down the directory hierarchy is unnecessary. ++ ++VFS has a function lookup_one_len() for that use, but it is not usable ++for a branch filesystem which requires struct nameidata. So aufs ++implements a simple lookup wrapper function. When a branch filesystem ++allows NULL as nameidata, it calls lookup_one_len(). Otherwise it builds ++a simplest nameidata and calls lookup_hash(). ++Here aufs applies "a principle in NFSD", ie. if the filesystem supports ++NFS-export, then it has to support NULL as a nameidata parameter for ++->create(), ->lookup() and ->d_revalidate(). So the lookup wrapper in ++aufs tests if ->s_export_op in the branch is NULL or not. ++ ++When a branch is a remote filesystem, aufs trusts its ->d_revalidate(). ++For d_revalidate, aufs implements three levels of revalidate tests. See ++"Revalidate Dentry and UDBA" in detail. ++ ++ ++Loopback Mount ++---------------------------------------------------------------------- ++Basically aufs supports any type of filesystem and block device for a ++branch (actually there are some exceptions). But it is prohibited to add ++a loopback mounted one whose backend file exists in a filesystem which is ++already added to aufs. The reason is to protect aufs from a recursive ++lookup. If it was allowed, the aufs lookup operation might re-enter a ++lookup for the loopback mounted branch in the same context, and will ++cause a deadlock. ++ ++ ++Revalidate Dentry and UDBA (User's Direct Branch Access) ++---------------------------------------------------------------------- ++Generally VFS helpers re-validate a dentry as a part of lookup. ++0. digging down the directory hierarchy. ++1. lock the parent dir by its i_mutex. ++2. lookup the final (child) entry. ++3. revalidate it. ++4. call the actual operation (create, unlink, etc.) ++5. unlock the parent dir ++ ++If the filesystem implements its ->d_revalidate() (step 3), then it is ++called. Actually aufs implements it and checks the dentry on a branch is ++still valid. ++But it is not enough. Because aufs has to release the lock for the ++parent dir on a branch at the end of ->lookup() (step 2) and ++->d_revalidate() (step 3) while the i_mutex of the aufs dir is still ++held by VFS. ++If the file on a branch is changed directly, eg. bypassing aufs, after ++aufs released the lock, then the subsequent operation may cause ++something unpleasant result. ++ ++This situation is a result of VFS architecture, ->lookup() and ++->d_revalidate() is separated. But I never say it is wrong. It is a good ++design from VFS's point of view. It is just not suitable for sub-VFS ++character in aufs. ++ ++Aufs supports such case by three level of revalidation which is ++selectable by user. ++1. Simple Revalidate ++ Addition to the native flow in VFS's, confirm the child-parent ++ relationship on the branch just after locking the parent dir on the ++ branch in the "actual operation" (step 4). When this validation ++ fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still ++ checks the validation of the dentry on branches. ++2. Monitor Changes Internally by Inotify ++ Addition to above, in the "actual operation" (step 4) aufs re-lookup ++ the dentry on the branch, and returns EBUSY if it finds different ++ dentry. ++ Additionally, aufs sets the inotify watch for every dir on branches ++ during it is in cache. When the event is notified, aufs registers a ++ function to kernel 'events' thread by schedule_work(). And the ++ function sets some special status to the cached aufs dentry and inode ++ private data. If they are not cached, then aufs has nothing to ++ do. When the same file is accessed through aufs (step 0-3) later, ++ aufs will detect the status and refresh all necessary data. ++ In this mode, aufs has to ignore the event which is fired by aufs ++ itself. ++3. No Extra Validation ++ This is the simplest test and doesn't add any additional revalidation ++ test, and skip therevalidatin in step 4. It is useful and improves ++ aufs performance when system surely hide the aufs branches from user, ++ by over-mounting something (or another method). +diff --git a/Documentation/filesystems/aufs/design/04branch.txt b/Documentation/filesystems/aufs/design/04branch.txt +new file mode 100644 +index 0000000..5529d6a +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/04branch.txt +@@ -0,0 +1,76 @@ ++ ++# Copyright (C) 2005-2009 Junjiro R. Okajima ++# ++# 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 ++ ++Branch Manipulation ++ ++Since aufs supports dynamic branch manipulation, ie. add/remove a branch ++and changing its permission/attribute, there are a lot of works to do. ++ ++ ++Add a Branch ++---------------------------------------------------------------------- ++o Confirm the adding dir exists outside of aufs, including loopback ++ mount. ++- and other various attributes... ++o Initialize the xino file and whiteout bases if necessary. ++ See struct.txt. ++ ++o Check the owner/group/mode of the directory ++ When the owner/group/mode of the adding directory differs from the ++ existing branch, aufs issues a warning because it may impose a ++ security risk. ++ For example, when a upper writable branch has a world writable empty ++ top directory, a malicious user can create any files on the writable ++ branch directly, like copy-up and modify manually. If something like ++ /etc/{passwd,shadow} exists on the lower readonly branch but the upper ++ writable branch, and the writable branch is world-writable, then a ++ malicious guy may create /etc/passwd on the writable branch directly ++ and the infected file will be valid in aufs. ++ I am afraid it can be a security issue, but nothing to do except ++ producing a warning. ++ ++ ++Delete a Branch ++---------------------------------------------------------------------- ++o Confirm the deleting branch is not busy ++ To be general, there is one merit to adopt "remount" interface to ++ manipulate branches. It is to discard caches. At deleting a branch, ++ aufs checks the still cached (and connected) dentries and inodes. If ++ there are any, then they are all in-use. An inode without its ++ corresponding dentry can be alive alone (for example, inotify case). ++ ++ For the cached one, aufs checks whether the same named entry exists on ++ other branches. ++ If the cached one is a directory, because aufs provides a merged view ++ to users, as long as one dir is left on any branch aufs can show the ++ dir to users. In this case, the branch can be removed from aufs. ++ Otherwise aufs rejects deleting the branch. ++ ++ If any file on the deleting branch is opened by aufs, then aufs ++ rejects deleting. ++ ++ ++Modify the Permission of a Branch ++---------------------------------------------------------------------- ++o Re-initialize or remove the xino file and whiteout bases if necessary. ++ See struct.txt. ++ ++o rw --> ro: Confirm the modifying branch is not busy ++ Aufs rejects the request if any of these conditions are true. ++ - a file on the branch is mmap-ed. ++ - a regular file on the branch is opened for write and there is no ++ same named entry on the upper branch. +diff --git a/Documentation/filesystems/aufs/design/05wbr_policy.txt b/Documentation/filesystems/aufs/design/05wbr_policy.txt +new file mode 100644 +index 0000000..5f25684 +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/05wbr_policy.txt +@@ -0,0 +1,65 @@ ++ ++# Copyright (C) 2005-2009 Junjiro R. Okajima ++# ++# 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 ++ ++Policies to Select One among Multiple Writable Branches ++---------------------------------------------------------------------- ++When the number of writable branch is more than one, aufs has to decide ++the target branch for file creation or copy-up. By default, the highest ++writable branch which has the parent (or ancestor) dir of the target ++file is chosen (top-down-parent policy). ++By user's request, aufs implements some other policies to select the ++writable branch, for file creation two policies, round-robin and ++most-free-space policies. For copy-up three policies, top-down-parent, ++bottom-up-parent and bottom-up policies. ++ ++As expected, the round-robin policy selects the branch in circular. When ++you have two writable branches and creates 10 new files, 5 files will be ++created for each branch. mkdir(2) systemcall is an exception. When you ++create 10 new directories, all will be created on the same branch. ++And the most-free-space policy selects the one which has most free ++space among the writable branches. The amount of free space will be ++checked by aufs internally, and users can specify its time interval. ++ ++The policies for copy-up is more simple, ++top-down-parent is equivalent to the same named on in create policy, ++bottom-up-parent selects the writable branch where the parent dir ++exists and the nearest upper one from the copyup-source, ++bottom-up selects the nearest upper writable branch from the ++copyup-source, regardless the existence of the parent dir. ++ ++There are some rules or exceptions to apply these policies. ++- If there is a readonly branch above the policy-selected branch and ++ the parent dir is marked as opaque (a variation of whiteout), or the ++ target (creating) file is whiteout-ed on the upper readonly branch, ++ then the result of the policy is ignored and the target file will be ++ created on the nearest upper writable branch than the readonly branch. ++- If there is a writable branch above the policy-selected branch and ++ the parent dir is marked as opaque or the target file is whiteouted ++ on the branch, then the result of the policy is ignored and the target ++ file will be created on the highest one among the upper writable ++ branches who has diropq or whiteout. In case of whiteout, aufs removes ++ it as usual. ++- link(2) and rename(2) systemcalls are exceptions in every policy. ++ They try selecting the branch where the source exists as possible ++ since copyup a large file will take long time. If it can't be, ++ ie. the branch where the source exists is readonly, then they will ++ follow the copyup policy. ++- There is an exception for rename(2) when the target exists. ++ If the rename target exists, aufs compares the index of the branches ++ where the source and the target exists and selects the higher ++ one. If the selected branch is readonly, then aufs follows the ++ copyup policy. +diff --git a/Documentation/filesystems/aufs/design/06fmode_exec.txt b/Documentation/filesystems/aufs/design/06fmode_exec.txt +new file mode 100644 +index 0000000..ebc311d +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/06fmode_exec.txt +@@ -0,0 +1,33 @@ ++ ++# Copyright (C) 2005-2009 Junjiro R. Okajima ++# ++# 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 ++ ++FMODE_EXEC and deny_write() ++---------------------------------------------------------------------- ++Generally Unix prevents an executing file from writing its filedata. ++In linux it is implemented by deny_write() and allow_write(). ++When a file is executed by exec() family, open_exec() (and sys_uselib()) ++they opens the file and calls deny_write(). If the file is aufs's virtual ++one, it has no meaning. The file which deny_write() is really necessary ++is the file on a branch. But the FMODE_EXEC flag is not passed to ++->open() operation. So aufs adopt a dirty trick. ++ ++- in order to get FMODE_EXEC, aufs ->lookup() and ->d_revalidate() set ++ nd->intent.open.file->private_data to nd->intent.open.flags temporary. ++- in aufs ->open(), when FMODE_EXEC is set in file->private_data, it ++ calls deny_write() for the file on a branch. ++- when the aufs file is released, allow_write() for the file on a branch ++ is called. +diff --git a/Documentation/filesystems/aufs/design/07mmap.txt b/Documentation/filesystems/aufs/design/07mmap.txt +new file mode 100644 +index 0000000..5d60fb9 +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/07mmap.txt +@@ -0,0 +1,53 @@ ++ ++# Copyright (C) 2005-2009 Junjiro R. Okajima ++# ++# 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 ++ ++mmap(2) -- File Memory Mapping ++---------------------------------------------------------------------- ++In aufs, the file-mapped pages are shared between the file on a branch ++and the virtual one in aufs by overriding vm_operation, particularly ++->fault(). ++ ++In aufs_mmap(), ++- get and store vm_ops of the real file on a branch. ++- map the file of aufs by generic_file_mmap() and set aufs's vm ++ operations. ++ ++In aufs_fault(), ++- get the file of aufs from the passed vma, sleep if needed. ++- get the real file on a branch from the aufs file. ++- a race may happen. for instance a multithreaded library. so some lock ++ is implemented. ++- call ->fault() in the previously stored vm_ops with setting the ++ real file on a branch to vm_file. ++- restore vm_file and wake_up if someone else got sleep. ++ ++When a branch is added to or deleted from aufs, the same-named file may ++unveil and its contents will be replaced by the new one when a process ++read(2) through previously opened file. ++(Some users may not want to refresh the filedata. For such users, I ++have a plan to implement a mount option 'refrof' which decides to ++refresh the opened files or not. See plan.txt too.) ++In this case, an already mapped file will not be updated since the ++contents are a part of a process already and it should not be changed by ++aufs branch manipulation. (Even if MAP_SHARED is specified, currently). ++Of course, in case of the deleting branch has a busy file, it cannot be ++deleted from the union. ++ ++In Unionfs, it took an approach which the memory pages mapped to ++filedata are copied from the lower (real) file into the Unionfs's ++virtual one and handles it by address_space operations. Recently Unionfs ++changed it to this approach which aufs adopted since Jul 2006. +diff --git a/Documentation/filesystems/aufs/design/08export.txt b/Documentation/filesystems/aufs/design/08export.txt +new file mode 100644 +index 0000000..8394348 +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/08export.txt +@@ -0,0 +1,59 @@ ++ ++# Copyright (C) 2005-2009 Junjiro R. Okajima ++# ++# 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 ++ ++Export Aufs via NFS ++---------------------------------------------------------------------- ++Here is an approach. ++- like xino/xib, add a new file 'xigen' which stores aufs inode ++ generation. ++- iget_locked(): initialize aufs inode generation for a new inode, and ++ store it in xigen file. ++- destroy_inode(): increment aufs inode generation and store it in xigen ++ file. it is necessary even if it is not unlinked, because any data of ++ inode may be changed by UDBA. ++- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise ++ build file handle by ++ + branch id (4 bytes) ++ + superblock generation (4 bytes) ++ + inode number (4 or 8 bytes) ++ + parent dir inode number (4 or 8 bytes) ++ + inode generation (4 bytes)) ++ + return value of exportfs_encode_fh() for the parent on a branch (4 ++ bytes) ++ + file handle for a branch (by exportfs_encode_fh()) ++- fh_to_dentry(): ++ + find the index of a branch from its id in handle, and check it is ++ still exist in aufs. ++ + 1st level: get the inode number from handle and search it in cache. ++ + 2nd level: if not found, get the parent inode number from handle and ++ search it in cache. and then open the parent dir, find the matching ++ inode number by vfs_readdir() and get its name, and call ++ lookup_one_len() for the target dentry. ++ + 3rd level: if the parent dir is not cached, call ++ exportfs_decode_fh() for a branch and get the parent on a branch, ++ build a pathname of it, convert it a pathname in aufs, call ++ path_lookup(). now aufs gets a parent dir dentry, then handle it as ++ the 2nd level. ++ + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount ++ for every branch, but not itself. to get this, (currently) aufs ++ searches in current->nsproxy->mnt_ns list. it may not be a good ++ idea, but I didn't get other approach. ++ + test the generation of the gotten inode. ++- every inode operation: they may get EBUSY due to UDBA. in this case, ++ convert it into ESTALE for NFSD. ++- readdir(): call lockdep_on/off() because filldir in NFSD calls ++ lookup_one_len(), vfs_getattr(), encode_fh() and others. +diff --git a/Documentation/filesystems/aufs/design/09shwh.txt b/Documentation/filesystems/aufs/design/09shwh.txt +new file mode 100644 +index 0000000..ce0c633 +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/09shwh.txt +@@ -0,0 +1,53 @@ ++ ++# Copyright (C) 2005-2009 Junjiro R. Okajima ++# ++# 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 ++ ++Show Whiteout Mode (shwh) ++---------------------------------------------------------------------- ++Generally aufs hides the name of whiteouts. But in some cases, to show ++them is very useful for users. For instance, creating a new middle layer ++(branch) by merging existing layers. ++ ++(borrowing aufs1 HOW-TO from a user, Michael Towers) ++When you have three branches, ++- Bottom: 'system', squashfs (underlying base system), read-only ++- Middle: 'mods', squashfs, read-only ++- Top: 'overlay', ram (tmpfs), read-write ++ ++The top layer is loaded at boot time and saved at shutdown, to preserve ++the changes made to the system during the session. ++When larger changes have been made, or smaller changes have accumulated, ++the size of the saved top layer data grows. At this point, it would be ++nice to be able to merge the two overlay branches ('mods' and 'overlay') ++and rewrite the 'mods' squashfs, clearing the top layer and thus ++restoring save and load speed. ++ ++This merging is simplified by the use of another aufs mount, of just the ++two overlay branches using the 'shwh' option. ++# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \ ++ aufs /livesys/merge_union ++ ++A merged view of these two branches is then available at ++/livesys/merge_union, and the new feature is that the whiteouts are ++visible! ++Note that in 'shwh' mode the aufs mount must be 'ro', which will disable ++writing to all branches. Also the default mode for all branches is 'ro'. ++It is now possible to save the combined contents of the two overlay ++branches to a new squashfs, e.g.: ++# mksquashfs /livesys/merge_union /path/to/newmods.squash ++ ++This new squashfs archive can be stored on the boot device and the ++initramfs will use it to replace the old one at the next boot. +diff --git a/Documentation/filesystems/aufs/design/99plan.txt b/Documentation/filesystems/aufs/design/99plan.txt +new file mode 100644 +index 0000000..78d1f0e +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/99plan.txt +@@ -0,0 +1,96 @@ ++ ++# Copyright (C) 2005-2009 Junjiro R. Okajima ++# ++# 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 ++ ++Plan ++ ++Restoring some features which was implemented in aufs1. ++They were dropped in aufs2 in order to make source files simpler and ++easier to be reviewed. ++ ++ ++Test Only the Highest One for the Directory Permission (dirperm1 option) ++---------------------------------------------------------------------- ++Let's try case study. ++- aufs has two branches, upper readwrite and lower readonly. ++ /au = /rw + /ro ++- "dirA" exists under /ro, but /rw. and its mode is 0700. ++- user invoked "chmod a+rx /au/dirA" ++- then "dirA" becomes world readable? ++ ++In this case, /ro/dirA is still 0700 since it exists in readonly branch, ++or it may be a natively readonly filesystem. If aufs respects the lower ++branch, it should not respond readdir request from other users. But user ++allowed it by chmod. Should really aufs rejects showing the entries ++under /ro/dirA? ++ ++To be honest, I don't have a best solution for this case. So I ++implemented 'dirperm1' and 'nodirperm1' option in aufs1, and leave it to ++users. ++When dirperm1 is specified, aufs checks only the highest one for the ++directory permission, and shows the entries. Otherwise, as usual, checks ++every dir existing on all branches and rejects the request. ++ ++As a side effect, dirperm1 option improves the performance of aufs ++because the number of permission check is reduced. ++ ++ ++Being Another Aufs's Readonly Branch (robr) ++---------------------------------------------------------------------- ++Aufs1 allows aufs to be another aufs's readonly branch. ++This feature was developed by a user's request. But it may not be used ++currecnly. ++ ++ ++Copy-up on Open (coo=) ++---------------------------------------------------------------------- ++By default the internal copy-up is executed when it is really necessary. ++It is not done when a file is opened for writing, but when write(2) is ++done. Users who have many (over 100) branches want to know and analyse ++when and what file is copied-up. To insert a new upper branch which ++contains such files only may improve the performance of aufs. ++ ++Aufs1 implemented "coo=none | leaf | all" option. ++ ++ ++Refresh the Opened File (refrof) ++---------------------------------------------------------------------- ++This option is implemented in aufs1 but incomplete. ++ ++When user reads from a file, he expects to get its latest filedata ++generally. If the file is removed and a new same named file is created, ++the content he gets is unchanged, ie. the unlinked filedata. ++ ++Let's try case study again. ++- aufs has two branches. ++ /au = /rw + /ro ++- "fileA" exists under /ro, but /rw. ++- user opened "/au/fileA". ++- he or someone else inserts a branch (/new) between /rw and /ro. ++ /au = /rw + /new + /ro ++- the new branch has "fileA". ++- user reads from the opened "fileA" ++- which filedata should aufs return, from /ro or /new? ++ ++Some people says it has to be "from /ro" and it is a semantics of Unix. ++The others say it should be "from /new" because the file is not removed ++and it is equivalent to the case of someone else modifies the file. ++ ++Here again I don't have a best and final answer. I got an idea to ++implement 'refrof' and 'norefrof' option. When 'refrof' (REFResh the ++Opened File) is specified (by default), aufs returns the filedata from ++/new. ++Otherwise from /new. +diff --git a/fs/Kconfig b/fs/Kconfig +index 9f7270f..7795bc6 100644 +--- a/fs/Kconfig ++++ b/fs/Kconfig +@@ -176,6 +176,7 @@ source "fs/romfs/Kconfig" + source "fs/sysv/Kconfig" + source "fs/ufs/Kconfig" + source "fs/exofs/Kconfig" ++source "fs/aufs/Kconfig" + + config NILFS2_FS + tristate "NILFS2 file system support (EXPERIMENTAL)" +diff --git a/fs/Makefile b/fs/Makefile +index af6d047..dba1ce1 100644 +--- a/fs/Makefile ++++ b/fs/Makefile +@@ -124,3 +124,4 @@ obj-$(CONFIG_OCFS2_FS) += ocfs2/ + obj-$(CONFIG_BTRFS_FS) += btrfs/ + obj-$(CONFIG_GFS2_FS) += gfs2/ + obj-$(CONFIG_EXOFS_FS) += exofs/ ++obj-$(CONFIG_AUFS_FS) += aufs/ +diff --git a/fs/aufs/Kconfig b/fs/aufs/Kconfig +new file mode 100644 +index 0000000..1cceb32 +--- /dev/null ++++ b/fs/aufs/Kconfig +@@ -0,0 +1,140 @@ ++config AUFS_FS ++ bool "Aufs (Advanced multi layered unification filesystem) support" ++ depends on EXPERIMENTAL ++ help ++ Aufs is a stackable unification filesystem such as Unionfs, ++ which unifies several directories and provides a merged single ++ directory. ++ In the early days, aufs was entirely re-designed and ++ re-implemented Unionfs Version 1.x series. Introducing many ++ original ideas, approaches and improvements, it becomes totally ++ different from Unionfs while keeping the basic features. ++ ++if AUFS_FS ++choice ++ prompt "Maximum number of branches" ++ default AUFS_BRANCH_MAX_127 ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_127 ++ bool "127" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_511 ++ bool "511" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_1023 ++ bool "1023" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_32767 ++ bool "32767" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++endchoice ++ ++config AUFS_HINOTIFY ++ bool "Use inotify to detect actions on a branch" ++ depends on INOTIFY ++ help ++ If you want to modify files on branches directly, eg. bypassing aufs, ++ and want aufs to detect the changes of them fully, then enable this ++ option and use 'udba=inotify' mount option. ++ It will have a negative impact to the performance. ++ See detail in aufs.5. ++ ++config AUFS_EXPORT ++ bool "NFS-exportable aufs" ++ depends on EXPORTFS = y ++ help ++ If you want to export your mounted aufs via NFS, then enable this ++ option. There are several requirements for this configuration. ++ See detail in aufs.5. ++ ++config AUFS_RDU ++ bool "Readdir in userspace" ++ help ++ If you have millions of files under a single aufs directory, and ++ meet the out of memory, then enable this option and set ++ environment variables for your readdir(3). ++ See detail in aufs.5. ++ ++config AUFS_SHWH ++ bool "Show whiteouts" ++ help ++ If you want to make the whiteouts in aufs visible, then enable ++ this option and specify 'shwh' mount option. Although it may ++ sounds like philosophy or something, but in technically it ++ simply shows the name of whiteout with keeping its behaviour. ++ ++config AUFS_BR_RAMFS ++ bool "Ramfs (initramfs/rootfs) as an aufs branch" ++ help ++ If you want to use ramfs as an aufs branch fs, then enable this ++ option. Generally tmpfs is recommended. ++ Aufs prohibited them to be a branch fs by default, because ++ initramfs becomes unusable after switch_root or something ++ generally. If you sets initramfs as an aufs branch and boot your ++ system by switch_root, you will meet a problem easily since the ++ files in initramfs may be inaccessible. ++ Unless you are going to use ramfs as an aufs branch fs without ++ switch_root or something, leave it N. ++ ++config AUFS_BR_FUSE ++ bool "Fuse fs as an aufs branch" ++ depends on FUSE_FS ++ select AUFS_POLL ++ help ++ If you want to use fuse-based userspace filesystem as an aufs ++ branch fs, then enable this option. ++ It implements the internal poll(2) operation which is ++ implemented by fuse only (curretnly). ++ ++config AUFS_DEBUG ++ bool "Debug aufs" ++ help ++ Enable this to compile aufs internal debug code. ++ It will have a negative impact to the performance. ++ ++config AUFS_MAGIC_SYSRQ ++ bool ++ depends on AUFS_DEBUG && MAGIC_SYSRQ ++ default y ++ help ++ Automatic configuration for internal use. ++ When aufs supports Magic SysRq, enabled automatically. ++ ++config AUFS_BDEV_LOOP ++ bool ++ depends on BLK_DEV_LOOP ++ default y ++ help ++ Automatic configuration for internal use. ++ Convert =[ym] into =y. ++ ++config AUFS_INO_T_64 ++ bool ++ depends on AUFS_EXPORT ++ depends on 64BIT && !(ALPHA || S390) ++ default y ++ help ++ Automatic configuration for internal use. ++ /* typedef unsigned long/int __kernel_ino_t */ ++ /* alpha and s390x are int */ ++ ++config AUFS_POLL ++ bool ++ help ++ Automatic configuration for internal use. ++endif +diff --git a/fs/aufs/Makefile b/fs/aufs/Makefile +new file mode 100644 +index 0000000..feb30fa +--- /dev/null ++++ b/fs/aufs/Makefile +@@ -0,0 +1,23 @@ ++ ++include ${srctree}/${src}/magic.mk ++ ++obj-$(CONFIG_AUFS_FS) += aufs.o ++aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \ ++ wkq.o vfsub.o dcsub.o \ ++ cpup.o whout.o plink.o wbr_policy.o \ ++ dinfo.o dentry.o \ ++ finfo.o file.o f_op.o \ ++ dir.o vdir.o \ ++ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \ ++ ioctl.o ++ ++# all are boolean ++aufs-$(CONFIG_SYSFS) += sysfs.o ++aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o ++aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o ++aufs-$(CONFIG_AUFS_HINOTIFY) += hinotify.o ++aufs-$(CONFIG_AUFS_EXPORT) += export.o ++aufs-$(CONFIG_AUFS_POLL) += poll.o ++aufs-$(CONFIG_AUFS_RDU) += rdu.o ++aufs-$(CONFIG_AUFS_DEBUG) += debug.o ++aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o +diff --git a/fs/aufs/aufs.h b/fs/aufs/aufs.h +new file mode 100644 +index 0000000..96307bb +--- /dev/null ++++ b/fs/aufs/aufs.h +@@ -0,0 +1,51 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * all header files ++ */ ++ ++#ifndef __AUFS_H__ ++#define __AUFS_H__ ++ ++#ifdef __KERNEL__ ++ ++#include "debug.h" ++ ++#include "branch.h" ++#include "cpup.h" ++#include "dcsub.h" ++#include "dbgaufs.h" ++#include "dentry.h" ++#include "dir.h" ++#include "file.h" ++#include "fstype.h" ++#include "inode.h" ++#include "loop.h" ++#include "module.h" ++#include "opts.h" ++#include "rwsem.h" ++#include "spl.h" ++#include "super.h" ++#include "sysaufs.h" ++#include "vfsub.h" ++#include "whout.h" ++#include "wkq.h" ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_H__ */ +diff --git a/fs/aufs/branch.c b/fs/aufs/branch.c +new file mode 100644 +index 0000000..aeedaf4 +--- /dev/null ++++ b/fs/aufs/branch.c +@@ -0,0 +1,974 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * branch management ++ */ ++ ++#include ++#include "aufs.h" ++ ++/* ++ * free a single branch ++ */ ++static void au_br_do_free(struct au_branch *br) ++{ ++ int i; ++ struct au_wbr *wbr; ++ ++ if (br->br_xino.xi_file) ++ fput(br->br_xino.xi_file); ++ mutex_destroy(&br->br_xino.xi_nondir_mtx); ++ ++ AuDebugOn(atomic_read(&br->br_count)); ++ ++ wbr = br->br_wbr; ++ if (wbr) { ++ for (i = 0; i < AuBrWh_Last; i++) ++ dput(wbr->wbr_wh[i]); ++ AuDebugOn(atomic_read(&wbr->wbr_wh_running)); ++ AuRwDestroy(&wbr->wbr_wh_rwsem); ++ } ++ ++ /* some filesystems acquire extra lock */ ++ lockdep_off(); ++ mntput(br->br_mnt); ++ lockdep_on(); ++ ++ kfree(wbr); ++ kfree(br); ++} ++ ++/* ++ * frees all branches ++ */ ++void au_br_free(struct au_sbinfo *sbinfo) ++{ ++ aufs_bindex_t bmax; ++ struct au_branch **br; ++ ++ AuRwMustWriteLock(&sbinfo->si_rwsem); ++ ++ bmax = sbinfo->si_bend + 1; ++ br = sbinfo->si_branch; ++ while (bmax--) ++ au_br_do_free(*br++); ++} ++ ++/* ++ * find the index of a branch which is specified by @br_id. ++ */ ++int au_br_index(struct super_block *sb, aufs_bindex_t br_id) ++{ ++ aufs_bindex_t bindex, bend; ++ ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) ++ if (au_sbr_id(sb, bindex) == br_id) ++ return bindex; ++ return -1; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * add a branch ++ */ ++ ++static int test_overlap(struct super_block *sb, struct dentry *h_d1, ++ struct dentry *h_d2) ++{ ++ if (unlikely(h_d1 == h_d2)) ++ return 1; ++ return !!au_test_subdir(h_d1, h_d2) ++ || !!au_test_subdir(h_d2, h_d1) ++ || au_test_loopback_overlap(sb, h_d1, h_d2) ++ || au_test_loopback_overlap(sb, h_d2, h_d1); ++} ++ ++/* ++ * returns a newly allocated branch. @new_nbranch is a number of branches ++ * after adding a branch. ++ */ ++static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch, ++ int perm) ++{ ++ struct au_branch *add_branch; ++ struct dentry *root; ++ ++ root = sb->s_root; ++ add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS); ++ if (unlikely(!add_branch)) ++ goto out; ++ ++ add_branch->br_wbr = NULL; ++ if (au_br_writable(perm)) { ++ /* may be freed separately at changing the branch permission */ ++ add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr), ++ GFP_NOFS); ++ if (unlikely(!add_branch->br_wbr)) ++ goto out_br; ++ } ++ ++ if (unlikely(au_sbr_realloc(au_sbi(sb), new_nbranch) ++ || au_di_realloc(au_di(root), new_nbranch) ++ || au_ii_realloc(au_ii(root->d_inode), new_nbranch))) ++ goto out_wbr; ++ return add_branch; /* success */ ++ ++ out_wbr: ++ kfree(add_branch->br_wbr); ++ out_br: ++ kfree(add_branch); ++ out: ++ return ERR_PTR(-ENOMEM); ++} ++ ++/* ++ * test if the branch permission is legal or not. ++ */ ++static int test_br(struct inode *inode, int brperm, char *path) ++{ ++ int err; ++ ++ err = 0; ++ if (unlikely(au_br_writable(brperm) && IS_RDONLY(inode))) { ++ AuErr("write permission for readonly mount or inode, %s\n", ++ path); ++ err = -EINVAL; ++ } ++ ++ return err; ++} ++ ++/* ++ * returns: ++ * 0: success, the caller will add it ++ * plus: success, it is already unified, the caller should ignore it ++ * minus: error ++ */ ++static int test_add(struct super_block *sb, struct au_opt_add *add, int remount) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct dentry *root; ++ struct inode *inode, *h_inode; ++ ++ root = sb->s_root; ++ bend = au_sbend(sb); ++ if (unlikely(bend >= 0 ++ && au_find_dbindex(root, add->path.dentry) >= 0)) { ++ err = 1; ++ if (!remount) { ++ err = -EINVAL; ++ AuErr("%s duplicated\n", add->pathname); ++ } ++ goto out; ++ } ++ ++ err = -ENOSPC; /* -E2BIG; */ ++ if (unlikely(AUFS_BRANCH_MAX <= add->bindex ++ || AUFS_BRANCH_MAX - 1 <= bend)) { ++ AuErr("number of branches exceeded %s\n", add->pathname); ++ goto out; ++ } ++ ++ err = -EDOM; ++ if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) { ++ AuErr("bad index %d\n", add->bindex); ++ goto out; ++ } ++ ++ inode = add->path.dentry->d_inode; ++ err = -ENOENT; ++ if (unlikely(!inode->i_nlink)) { ++ AuErr("no existence %s\n", add->pathname); ++ goto out; ++ } ++ ++ err = -EINVAL; ++ if (unlikely(inode->i_sb == sb)) { ++ AuErr("%s must be outside\n", add->pathname); ++ goto out; ++ } ++ ++ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) { ++ AuErr("unsupported filesystem, %s (%s)\n", ++ add->pathname, au_sbtype(inode->i_sb)); ++ goto out; ++ } ++ ++ err = test_br(add->path.dentry->d_inode, add->perm, add->pathname); ++ if (unlikely(err)) ++ goto out; ++ ++ if (bend < 0) ++ return 0; /* success */ ++ ++ err = -EINVAL; ++ for (bindex = 0; bindex <= bend; bindex++) ++ if (unlikely(test_overlap(sb, add->path.dentry, ++ au_h_dptr(root, bindex)))) { ++ AuErr("%s is overlapped\n", add->pathname); ++ goto out; ++ } ++ ++ err = 0; ++ if (au_opt_test(au_mntflags(sb), WARN_PERM)) { ++ h_inode = au_h_dptr(root, 0)->d_inode; ++ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO) ++ || h_inode->i_uid != inode->i_uid ++ || h_inode->i_gid != inode->i_gid) ++ AuWarn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n", ++ add->pathname, ++ inode->i_uid, inode->i_gid, ++ (inode->i_mode & S_IALLUGO), ++ h_inode->i_uid, h_inode->i_gid, ++ (h_inode->i_mode & S_IALLUGO)); ++ } ++ ++ out: ++ return err; ++} ++ ++/* ++ * initialize or clean the whiteouts for an adding branch ++ */ ++static int au_br_init_wh(struct super_block *sb, struct au_branch *br, ++ int new_perm, struct dentry *h_root) ++{ ++ int err, old_perm; ++ aufs_bindex_t bindex; ++ struct mutex *h_mtx; ++ struct au_wbr *wbr; ++ struct au_hinode *hdir; ++ ++ wbr = br->br_wbr; ++ old_perm = br->br_perm; ++ br->br_perm = new_perm; ++ hdir = NULL; ++ h_mtx = NULL; ++ bindex = au_br_index(sb, br->br_id); ++ if (0 <= bindex) { ++ hdir = au_hi(sb->s_root->d_inode, bindex); ++ au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT); ++ } else { ++ h_mtx = &h_root->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_PARENT); ++ } ++ if (!wbr) ++ err = au_wh_init(h_root, br, sb); ++ else { ++ wbr_wh_write_lock(wbr); ++ err = au_wh_init(h_root, br, sb); ++ wbr_wh_write_unlock(wbr); ++ } ++ if (hdir) ++ au_hin_imtx_unlock(hdir); ++ else ++ mutex_unlock(h_mtx); ++ br->br_perm = old_perm; ++ ++ if (!err && wbr && !au_br_writable(new_perm)) { ++ kfree(wbr); ++ br->br_wbr = NULL; ++ } ++ ++ return err; ++} ++ ++static int au_wbr_init(struct au_branch *br, struct super_block *sb, ++ int perm, struct path *path) ++{ ++ int err; ++ struct au_wbr *wbr; ++ ++ wbr = br->br_wbr; ++ au_rw_init(&wbr->wbr_wh_rwsem); ++ memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh)); ++ atomic_set(&wbr->wbr_wh_running, 0); ++ wbr->wbr_bytes = 0; ++ ++ err = au_br_init_wh(sb, br, perm, path->dentry); ++ ++ return err; ++} ++ ++/* intialize a new branch */ ++static int au_br_init(struct au_branch *br, struct super_block *sb, ++ struct au_opt_add *add) ++{ ++ int err; ++ ++ err = 0; ++ memset(&br->br_xino, 0, sizeof(br->br_xino)); ++ mutex_init(&br->br_xino.xi_nondir_mtx); ++ br->br_perm = add->perm; ++ br->br_mnt = add->path.mnt; /* set first, mntget() later */ ++ atomic_set(&br->br_count, 0); ++ br->br_xino_upper = AUFS_XINO_TRUNC_INIT; ++ atomic_set(&br->br_xino_running, 0); ++ br->br_id = au_new_br_id(sb); ++ ++ if (au_br_writable(add->perm)) { ++ err = au_wbr_init(br, sb, add->perm, &add->path); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ if (au_opt_test(au_mntflags(sb), XINO)) { ++ err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino, ++ au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1); ++ if (unlikely(err)) { ++ AuDebugOn(br->br_xino.xi_file); ++ goto out; ++ } ++ } ++ ++ sysaufs_br_init(br); ++ mntget(add->path.mnt); ++ ++ out: ++ return err; ++} ++ ++static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex, ++ struct au_branch *br, aufs_bindex_t bend, ++ aufs_bindex_t amount) ++{ ++ struct au_branch **brp; ++ ++ AuRwMustWriteLock(&sbinfo->si_rwsem); ++ ++ brp = sbinfo->si_branch + bindex; ++ memmove(brp + 1, brp, sizeof(*brp) * amount); ++ *brp = br; ++ sbinfo->si_bend++; ++ if (unlikely(bend < 0)) ++ sbinfo->si_bend = 0; ++} ++ ++static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex, ++ aufs_bindex_t bend, aufs_bindex_t amount) ++{ ++ struct au_hdentry *hdp; ++ ++ AuRwMustWriteLock(&dinfo->di_rwsem); ++ ++ hdp = dinfo->di_hdentry + bindex; ++ memmove(hdp + 1, hdp, sizeof(*hdp) * amount); ++ au_h_dentry_init(hdp); ++ dinfo->di_bend++; ++ if (unlikely(bend < 0)) ++ dinfo->di_bstart = 0; ++} ++ ++static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex, ++ aufs_bindex_t bend, aufs_bindex_t amount) ++{ ++ struct au_hinode *hip; ++ ++ AuRwMustWriteLock(&iinfo->ii_rwsem); ++ ++ hip = iinfo->ii_hinode + bindex; ++ memmove(hip + 1, hip, sizeof(*hip) * amount); ++ hip->hi_inode = NULL; ++ au_hin_init(hip, NULL); ++ iinfo->ii_bend++; ++ if (unlikely(bend < 0)) ++ iinfo->ii_bstart = 0; ++} ++ ++static void au_br_do_add(struct super_block *sb, struct dentry *h_dentry, ++ struct au_branch *br, aufs_bindex_t bindex) ++{ ++ struct dentry *root; ++ struct inode *root_inode; ++ aufs_bindex_t bend, amount; ++ ++ root = sb->s_root; ++ root_inode = root->d_inode; ++ au_plink_block_maintain(sb); ++ bend = au_sbend(sb); ++ amount = bend + 1 - bindex; ++ au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount); ++ au_br_do_add_hdp(au_di(root), bindex, bend, amount); ++ au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount); ++ au_set_h_dptr(root, bindex, dget(h_dentry)); ++ au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode), ++ /*flags*/0); ++} ++ ++int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount) ++{ ++ int err; ++ unsigned long long maxb; ++ aufs_bindex_t bend, add_bindex; ++ struct dentry *root, *h_dentry; ++ struct inode *root_inode; ++ struct au_branch *add_branch; ++ ++ root = sb->s_root; ++ root_inode = root->d_inode; ++ IMustLock(root_inode); ++ err = test_add(sb, add, remount); ++ if (unlikely(err < 0)) ++ goto out; ++ if (err) { ++ err = 0; ++ goto out; /* success */ ++ } ++ ++ bend = au_sbend(sb); ++ add_branch = au_br_alloc(sb, bend + 2, add->perm); ++ err = PTR_ERR(add_branch); ++ if (IS_ERR(add_branch)) ++ goto out; ++ ++ err = au_br_init(add_branch, sb, add); ++ if (unlikely(err)) { ++ au_br_do_free(add_branch); ++ goto out; ++ } ++ ++ add_bindex = add->bindex; ++ h_dentry = add->path.dentry; ++ if (!remount) ++ au_br_do_add(sb, h_dentry, add_branch, add_bindex); ++ else { ++ sysaufs_brs_del(sb, add_bindex); ++ au_br_do_add(sb, h_dentry, add_branch, add_bindex); ++ sysaufs_brs_add(sb, add_bindex); ++ } ++ ++ if (!add_bindex) ++ au_cpup_attr_all(root_inode, /*force*/1); ++ else ++ au_add_nlink(root_inode, h_dentry->d_inode); ++ maxb = h_dentry->d_sb->s_maxbytes; ++ if (sb->s_maxbytes < maxb) ++ sb->s_maxbytes = maxb; ++ ++ /* ++ * this test/set prevents aufs from handling unnecesary inotify events ++ * of xino files, in a case of re-adding a writable branch which was ++ * once detached from aufs. ++ */ ++ if (au_xino_brid(sb) < 0 ++ && au_br_writable(add_branch->br_perm) ++ && !au_test_fs_bad_xino(h_dentry->d_sb) ++ && add_branch->br_xino.xi_file ++ && add_branch->br_xino.xi_file->f_dentry->d_parent == h_dentry) ++ au_xino_brid_set(sb, add_branch->br_id); ++ ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * delete a branch ++ */ ++ ++/* to show the line number, do not make it inlined function */ ++#define AuVerbose(do_info, fmt, args...) do { \ ++ if (do_info) \ ++ AuInfo(fmt, ##args); \ ++} while (0) ++ ++/* ++ * test if the branch is deletable or not. ++ */ ++static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex, ++ unsigned int sigen) ++{ ++ int err, i, j, ndentry; ++ aufs_bindex_t bstart, bend; ++ unsigned char verbose; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry *d; ++ struct inode *inode; ++ ++ err = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_dcsub_pages(&dpages, root, NULL, NULL); ++ if (unlikely(err)) ++ goto out_dpages; ++ ++ verbose = !!au_opt_test(au_mntflags(root->d_sb), VERBOSE); ++ for (i = 0; !err && i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ ndentry = dpage->ndentry; ++ for (j = 0; !err && j < ndentry; j++) { ++ d = dpage->dentries[j]; ++ AuDebugOn(!atomic_read(&d->d_count)); ++ inode = d->d_inode; ++ if (au_digen(d) == sigen && au_iigen(inode) == sigen) ++ di_read_lock_child(d, AuLock_IR); ++ else { ++ di_write_lock_child(d); ++ err = au_reval_dpath(d, sigen); ++ if (!err) ++ di_downgrade_lock(d, AuLock_IR); ++ else { ++ di_write_unlock(d); ++ break; ++ } ++ } ++ ++ bstart = au_dbstart(d); ++ bend = au_dbend(d); ++ if (bstart <= bindex ++ && bindex <= bend ++ && au_h_dptr(d, bindex) ++ && (!S_ISDIR(inode->i_mode) || bstart == bend)) { ++ err = -EBUSY; ++ AuVerbose(verbose, "busy %.*s\n", AuDLNPair(d)); ++ } ++ di_read_unlock(d, AuLock_IR); ++ } ++ } ++ ++ out_dpages: ++ au_dpages_free(&dpages); ++ out: ++ return err; ++} ++ ++static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex, ++ unsigned int sigen) ++{ ++ int err; ++ struct inode *i; ++ aufs_bindex_t bstart, bend; ++ unsigned char verbose; ++ ++ err = 0; ++ verbose = !!au_opt_test(au_mntflags(sb), VERBOSE); ++ list_for_each_entry(i, &sb->s_inodes, i_sb_list) { ++ AuDebugOn(!atomic_read(&i->i_count)); ++ if (!list_empty(&i->i_dentry)) ++ continue; ++ ++ if (au_iigen(i) == sigen) ++ ii_read_lock_child(i); ++ else { ++ ii_write_lock_child(i); ++ err = au_refresh_hinode_self(i, /*do_attr*/1); ++ if (!err) ++ ii_downgrade_lock(i); ++ else { ++ ii_write_unlock(i); ++ break; ++ } ++ } ++ ++ bstart = au_ibstart(i); ++ bend = au_ibend(i); ++ if (bstart <= bindex ++ && bindex <= bend ++ && au_h_iptr(i, bindex) ++ && (!S_ISDIR(i->i_mode) || bstart == bend)) { ++ err = -EBUSY; ++ AuVerbose(verbose, "busy i%lu\n", i->i_ino); ++ ii_read_unlock(i); ++ break; ++ } ++ ii_read_unlock(i); ++ } ++ ++ return err; ++} ++ ++static int test_children_busy(struct dentry *root, aufs_bindex_t bindex) ++{ ++ int err; ++ unsigned int sigen; ++ ++ sigen = au_sigen(root->d_sb); ++ DiMustNoWaiters(root); ++ IiMustNoWaiters(root->d_inode); ++ di_write_unlock(root); ++ err = test_dentry_busy(root, bindex, sigen); ++ if (!err) ++ err = test_inode_busy(root->d_sb, bindex, sigen); ++ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */ ++ ++ return err; ++} ++ ++static void au_br_do_del_brp(struct au_sbinfo *sbinfo, ++ const aufs_bindex_t bindex, ++ const aufs_bindex_t bend) ++{ ++ struct au_branch **brp, **p; ++ ++ AuRwMustWriteLock(&sbinfo->si_rwsem); ++ ++ brp = sbinfo->si_branch + bindex; ++ if (bindex < bend) ++ memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex)); ++ sbinfo->si_branch[0 + bend] = NULL; ++ sbinfo->si_bend--; ++ ++ p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, GFP_NOFS); ++ if (p) ++ sbinfo->si_branch = p; ++} ++ ++static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex, ++ const aufs_bindex_t bend) ++{ ++ struct au_hdentry *hdp, *p; ++ ++ AuRwMustWriteLock(&dinfo->di_rwsem); ++ ++ hdp = dinfo->di_hdentry + bindex; ++ if (bindex < bend) ++ memmove(hdp, hdp + 1, sizeof(*hdp) * (bend - bindex)); ++ dinfo->di_hdentry[0 + bend].hd_dentry = NULL; ++ dinfo->di_bend--; ++ ++ p = krealloc(dinfo->di_hdentry, sizeof(*p) * bend, GFP_NOFS); ++ if (p) ++ dinfo->di_hdentry = p; ++} ++ ++static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex, ++ const aufs_bindex_t bend) ++{ ++ struct au_hinode *hip, *p; ++ ++ AuRwMustWriteLock(&iinfo->ii_rwsem); ++ ++ hip = iinfo->ii_hinode + bindex; ++ if (bindex < bend) ++ memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex)); ++ iinfo->ii_hinode[0 + bend].hi_inode = NULL; ++ au_hin_init(iinfo->ii_hinode + bend, NULL); ++ iinfo->ii_bend--; ++ ++ p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, GFP_NOFS); ++ if (p) ++ iinfo->ii_hinode = p; ++} ++ ++static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex, ++ struct au_branch *br) ++{ ++ aufs_bindex_t bend; ++ struct au_sbinfo *sbinfo; ++ struct dentry *root; ++ struct inode *inode; ++ ++ SiMustWriteLock(sb); ++ ++ root = sb->s_root; ++ inode = root->d_inode; ++ au_plink_block_maintain(sb); ++ sbinfo = au_sbi(sb); ++ bend = sbinfo->si_bend; ++ ++ dput(au_h_dptr(root, bindex)); ++ au_hiput(au_hi(inode, bindex)); ++ au_br_do_free(br); ++ ++ au_br_do_del_brp(sbinfo, bindex, bend); ++ au_br_do_del_hdp(au_di(root), bindex, bend); ++ au_br_do_del_hip(au_ii(inode), bindex, bend); ++} ++ ++int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount) ++{ ++ int err, rerr, i; ++ unsigned int mnt_flags; ++ aufs_bindex_t bindex, bend, br_id; ++ unsigned char do_wh, verbose; ++ struct au_branch *br; ++ struct au_wbr *wbr; ++ ++ err = 0; ++ bindex = au_find_dbindex(sb->s_root, del->h_path.dentry); ++ if (bindex < 0) { ++ if (remount) ++ goto out; /* success */ ++ err = -ENOENT; ++ AuErr("%s no such branch\n", del->pathname); ++ goto out; ++ } ++ AuDbg("bindex b%d\n", bindex); ++ ++ err = -EBUSY; ++ mnt_flags = au_mntflags(sb); ++ verbose = !!au_opt_test(mnt_flags, VERBOSE); ++ bend = au_sbend(sb); ++ if (unlikely(!bend)) { ++ AuVerbose(verbose, "no more branches left\n"); ++ goto out; ++ } ++ br = au_sbr(sb, bindex); ++ i = atomic_read(&br->br_count); ++ if (unlikely(i)) { ++ AuVerbose(verbose, "%d file(s) opened\n", i); ++ goto out; ++ } ++ ++ wbr = br->br_wbr; ++ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph); ++ if (do_wh) { ++ /* instead of WbrWhMustWriteLock(wbr) */ ++ SiMustWriteLock(sb); ++ for (i = 0; i < AuBrWh_Last; i++) { ++ dput(wbr->wbr_wh[i]); ++ wbr->wbr_wh[i] = NULL; ++ } ++ } ++ ++ err = test_children_busy(sb->s_root, bindex); ++ if (unlikely(err)) { ++ if (do_wh) ++ goto out_wh; ++ goto out; ++ } ++ ++ err = 0; ++ br_id = br->br_id; ++ if (!remount) ++ au_br_do_del(sb, bindex, br); ++ else { ++ sysaufs_brs_del(sb, bindex); ++ au_br_do_del(sb, bindex, br); ++ sysaufs_brs_add(sb, bindex); ++ } ++ ++ if (!bindex) ++ au_cpup_attr_all(sb->s_root->d_inode, /*force*/1); ++ else ++ au_sub_nlink(sb->s_root->d_inode, del->h_path.dentry->d_inode); ++ if (au_opt_test(mnt_flags, PLINK)) ++ au_plink_half_refresh(sb, br_id); ++ ++ if (sb->s_maxbytes == del->h_path.dentry->d_sb->s_maxbytes) { ++ bend--; ++ sb->s_maxbytes = 0; ++ for (bindex = 0; bindex <= bend; bindex++) { ++ unsigned long long maxb; ++ ++ maxb = au_sbr_sb(sb, bindex)->s_maxbytes; ++ if (sb->s_maxbytes < maxb) ++ sb->s_maxbytes = maxb; ++ } ++ } ++ ++ if (au_xino_brid(sb) == br->br_id) ++ au_xino_brid_set(sb, -1); ++ goto out; /* success */ ++ ++ out_wh: ++ /* revert */ ++ rerr = au_br_init_wh(sb, br, br->br_perm, del->h_path.dentry); ++ if (rerr) ++ AuWarn("failed re-creating base whiteout, %s. (%d)\n", ++ del->pathname, rerr); ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * change a branch permission ++ */ ++ ++static int do_need_sigen_inc(int a, int b) ++{ ++ return au_br_whable(a) && !au_br_whable(b); ++} ++ ++static int need_sigen_inc(int old, int new) ++{ ++ return do_need_sigen_inc(old, new) ++ || do_need_sigen_inc(new, old); ++} ++ ++static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ int err; ++ unsigned long n, ul, bytes, files; ++ aufs_bindex_t bstart; ++ struct file *file, *hf, **a; ++ const int step_bytes = 1024, /* memory allocation unit */ ++ step_files = step_bytes / sizeof(*a); ++ ++ err = -ENOMEM; ++ n = 0; ++ bytes = step_bytes; ++ files = step_files; ++ a = kmalloc(bytes, GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ /* no need file_list_lock() since sbinfo is locked? defered? */ ++ list_for_each_entry(file, &sb->s_files, f_u.fu_list) { ++ if (special_file(file->f_dentry->d_inode->i_mode)) ++ continue; ++ ++ AuDbg("%.*s\n", AuDLNPair(file->f_dentry)); ++ fi_read_lock(file); ++ if (unlikely(au_test_mmapped(file))) { ++ err = -EBUSY; ++ FiMustNoWaiters(file); ++ fi_read_unlock(file); ++ goto out_free; ++ } ++ ++ bstart = au_fbstart(file); ++ if (!S_ISREG(file->f_dentry->d_inode->i_mode) ++ || !(file->f_mode & FMODE_WRITE) ++ || bstart != bindex) { ++ FiMustNoWaiters(file); ++ fi_read_unlock(file); ++ continue; ++ } ++ ++ hf = au_h_fptr(file, bstart); ++ FiMustNoWaiters(file); ++ fi_read_unlock(file); ++ ++ if (n < files) ++ a[n++] = hf; ++ else { ++ void *p; ++ ++ err = -ENOMEM; ++ bytes += step_bytes; ++ files += step_files; ++ p = krealloc(a, bytes, GFP_NOFS); ++ if (p) { ++ a = p; ++ a[n++] = hf; ++ } else ++ goto out_free; ++ } ++ } ++ ++ err = 0; ++ for (ul = 0; ul < n; ul++) { ++ /* todo: already flushed? */ ++ /* cf. fs/super.c:mark_files_ro() */ ++ hf = a[ul]; ++ hf->f_mode &= ~FMODE_WRITE; ++ if (!file_check_writeable(hf)) { ++ file_release_write(hf); ++ mnt_drop_write(hf->f_vfsmnt); ++ } ++ } ++ ++ out_free: ++ kfree(a); ++ out: ++ return err; ++} ++ ++int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount, ++ int *do_update) ++{ ++ int err, rerr; ++ aufs_bindex_t bindex; ++ struct path path; ++ struct dentry *root; ++ struct au_branch *br; ++ ++ root = sb->s_root; ++ au_plink_block_maintain(sb); ++ bindex = au_find_dbindex(root, mod->h_root); ++ if (bindex < 0) { ++ if (remount) ++ return 0; /* success */ ++ err = -ENOENT; ++ AuErr("%s no such branch\n", mod->path); ++ goto out; ++ } ++ AuDbg("bindex b%d\n", bindex); ++ ++ err = test_br(mod->h_root->d_inode, mod->perm, mod->path); ++ if (unlikely(err)) ++ goto out; ++ ++ br = au_sbr(sb, bindex); ++ if (br->br_perm == mod->perm) ++ return 0; /* success */ ++ ++ if (au_br_writable(br->br_perm)) { ++ /* remove whiteout base */ ++ err = au_br_init_wh(sb, br, mod->perm, mod->h_root); ++ if (unlikely(err)) ++ goto out; ++ ++ if (!au_br_writable(mod->perm)) { ++ /* rw --> ro, file might be mmapped */ ++ DiMustNoWaiters(root); ++ IiMustNoWaiters(root->d_inode); ++ di_write_unlock(root); ++ err = au_br_mod_files_ro(sb, bindex); ++ /* aufs_write_lock() calls ..._child() */ ++ di_write_lock_child(root); ++ ++ if (unlikely(err)) { ++ rerr = -ENOMEM; ++ br->br_wbr = kmalloc(sizeof(*br->br_wbr), ++ GFP_NOFS); ++ if (br->br_wbr) { ++ path.mnt = br->br_mnt; ++ path.dentry = mod->h_root; ++ rerr = au_wbr_init(br, sb, br->br_perm, ++ &path); ++ } ++ if (unlikely(rerr)) { ++ AuIOErr("nested error %d (%d)\n", ++ rerr, err); ++ br->br_perm = mod->perm; ++ } ++ } ++ } ++ } else if (au_br_writable(mod->perm)) { ++ /* ro --> rw */ ++ err = -ENOMEM; ++ br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS); ++ if (br->br_wbr) { ++ path.mnt = br->br_mnt; ++ path.dentry = mod->h_root; ++ err = au_wbr_init(br, sb, mod->perm, &path); ++ if (unlikely(err)) { ++ kfree(br->br_wbr); ++ br->br_wbr = NULL; ++ } ++ } ++ } ++ ++ if (!err) { ++ *do_update |= need_sigen_inc(br->br_perm, mod->perm); ++ br->br_perm = mod->perm; ++ } ++ ++ out: ++ return err; ++} +diff --git a/fs/aufs/branch.h b/fs/aufs/branch.h +new file mode 100644 +index 0000000..1a7219c +--- /dev/null ++++ b/fs/aufs/branch.h +@@ -0,0 +1,219 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * branch filesystems and xino for them ++ */ ++ ++#ifndef __AUFS_BRANCH_H__ ++#define __AUFS_BRANCH_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++#include "rwsem.h" ++#include "super.h" ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* a xino file */ ++struct au_xino_file { ++ struct file *xi_file; ++ struct mutex xi_nondir_mtx; ++ ++ /* todo: make xino files an array to support huge inode number */ ++ ++#ifdef CONFIG_DEBUG_FS ++ struct dentry *xi_dbgaufs; ++#endif ++}; ++ ++/* members for writable branch only */ ++enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last}; ++struct au_wbr { ++ struct au_rwsem wbr_wh_rwsem; ++ struct dentry *wbr_wh[AuBrWh_Last]; ++ atomic_t wbr_wh_running; ++#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */ ++#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */ ++#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */ ++ ++ /* mfs mode */ ++ unsigned long long wbr_bytes; ++}; ++ ++/* protected by superblock rwsem */ ++struct au_branch { ++ struct au_xino_file br_xino; ++ ++ aufs_bindex_t br_id; ++ ++ int br_perm; ++ struct vfsmount *br_mnt; ++ atomic_t br_count; ++ ++ struct au_wbr *br_wbr; ++ ++ /* xino truncation */ ++ blkcnt_t br_xino_upper; /* watermark in blocks */ ++ atomic_t br_xino_running; ++ ++#ifdef CONFIG_SYSFS ++ /* an entry under sysfs per mount-point */ ++ char br_name[8]; ++ struct attribute br_attr; ++#endif ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* branch permission and attribute */ ++enum { ++ AuBrPerm_RW, /* writable, linkable wh */ ++ AuBrPerm_RO, /* readonly, no wh */ ++ AuBrPerm_RR, /* natively readonly, no wh */ ++ ++ AuBrPerm_RWNoLinkWH, /* un-linkable whiteouts */ ++ ++ AuBrPerm_ROWH, /* whiteout-able */ ++ AuBrPerm_RRWH, /* whiteout-able */ ++ ++ AuBrPerm_Last ++}; ++ ++static inline int au_br_writable(int brperm) ++{ ++ return brperm == AuBrPerm_RW || brperm == AuBrPerm_RWNoLinkWH; ++} ++ ++static inline int au_br_whable(int brperm) ++{ ++ return brperm == AuBrPerm_RW ++ || brperm == AuBrPerm_ROWH ++ || brperm == AuBrPerm_RRWH; ++} ++ ++static inline int au_br_rdonly(struct au_branch *br) ++{ ++ return ((br->br_mnt->mnt_sb->s_flags & MS_RDONLY) ++ || !au_br_writable(br->br_perm)) ++ ? -EROFS : 0; ++} ++ ++static inline int au_br_hinotifyable(int brperm __maybe_unused) ++{ ++#ifdef CONFIG_AUFS_HINOTIFY ++ return brperm != AuBrPerm_RR && brperm != AuBrPerm_RRWH; ++#else ++ return 0; ++#endif ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* branch.c */ ++struct au_sbinfo; ++void au_br_free(struct au_sbinfo *sinfo); ++int au_br_index(struct super_block *sb, aufs_bindex_t br_id); ++struct au_opt_add; ++int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount); ++struct au_opt_del; ++int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount); ++struct au_opt_mod; ++int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount, ++ int *do_update); ++ ++/* xino.c */ ++static const loff_t au_loff_max = LLONG_MAX; ++ ++int au_xib_trunc(struct super_block *sb); ++ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size, ++ loff_t *pos); ++ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size, ++ loff_t *pos); ++struct file *au_xino_create2(struct file *base_file, struct file *copy_src); ++struct file *au_xino_create(struct super_block *sb, char *fname, int silent); ++ino_t au_xino_new_ino(struct super_block *sb); ++int au_xino_write0(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t ino); ++int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t ino); ++int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t *ino); ++int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino, ++ struct file *base_file, int do_test); ++int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex); ++ ++struct au_opt_xino; ++int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount); ++void au_xino_clr(struct super_block *sb); ++struct file *au_xino_def(struct super_block *sb); ++int au_xino_path(struct seq_file *seq, struct file *file); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* Superblock to branch */ ++static inline ++aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_sbr(sb, bindex)->br_id; ++} ++ ++static inline ++struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_sbr(sb, bindex)->br_mnt; ++} ++ ++static inline ++struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_sbr_mnt(sb, bindex)->mnt_sb; ++} ++ ++static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ atomic_dec_return(&au_sbr(sb, bindex)->br_count); ++} ++ ++static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_sbr(sb, bindex)->br_perm; ++} ++ ++static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_br_whable(au_sbr_perm(sb, bindex)); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * wbr_wh_read_lock, wbr_wh_write_lock ++ * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock ++ */ ++AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem); ++ ++#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem) ++#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem) ++#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem) ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_BRANCH_H__ */ +diff --git a/fs/aufs/cpup.c b/fs/aufs/cpup.c +new file mode 100644 +index 0000000..7f70e2f +--- /dev/null ++++ b/fs/aufs/cpup.c +@@ -0,0 +1,1048 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * copy-up functions, see wbr_policy.c for copy-down ++ */ ++ ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++void au_cpup_attr_flags(struct inode *dst, struct inode *src) ++{ ++ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE ++ | S_NOATIME | S_NOCMTIME; ++ ++ dst->i_flags |= src->i_flags & ~mask; ++ if (au_test_fs_notime(dst->i_sb)) ++ dst->i_flags |= S_NOATIME | S_NOCMTIME; ++} ++ ++void au_cpup_attr_timesizes(struct inode *inode) ++{ ++ struct inode *h_inode; ++ ++ h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ fsstack_copy_attr_times(inode, h_inode); ++ vfsub_copy_inode_size(inode, h_inode); ++} ++ ++void au_cpup_attr_nlink(struct inode *inode, int force) ++{ ++ struct inode *h_inode; ++ struct super_block *sb; ++ aufs_bindex_t bindex, bend; ++ ++ sb = inode->i_sb; ++ bindex = au_ibstart(inode); ++ h_inode = au_h_iptr(inode, bindex); ++ if (!force ++ && !S_ISDIR(h_inode->i_mode) ++ && au_opt_test(au_mntflags(sb), PLINK) ++ && au_plink_test(inode)) ++ return; ++ ++ inode->i_nlink = h_inode->i_nlink; ++ ++ /* ++ * fewer nlink makes find(1) noisy, but larger nlink doesn't. ++ * it may includes whplink directory. ++ */ ++ if (S_ISDIR(h_inode->i_mode)) { ++ bend = au_ibend(inode); ++ for (bindex++; bindex <= bend; bindex++) { ++ h_inode = au_h_iptr(inode, bindex); ++ if (h_inode) ++ au_add_nlink(inode, h_inode); ++ } ++ } ++} ++ ++void au_cpup_attr_changeable(struct inode *inode) ++{ ++ struct inode *h_inode; ++ ++ h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ inode->i_mode = h_inode->i_mode; ++ inode->i_uid = h_inode->i_uid; ++ inode->i_gid = h_inode->i_gid; ++ au_cpup_attr_timesizes(inode); ++ au_cpup_attr_flags(inode, h_inode); ++} ++ ++void au_cpup_igen(struct inode *inode, struct inode *h_inode) ++{ ++ struct au_iinfo *iinfo = au_ii(inode); ++ ++ IiMustWriteLock(inode); ++ ++ iinfo->ii_higen = h_inode->i_generation; ++ iinfo->ii_hsb1 = h_inode->i_sb; ++} ++ ++void au_cpup_attr_all(struct inode *inode, int force) ++{ ++ struct inode *h_inode; ++ ++ h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ au_cpup_attr_changeable(inode); ++ if (inode->i_nlink > 0) ++ au_cpup_attr_nlink(inode, force); ++ inode->i_rdev = h_inode->i_rdev; ++ inode->i_blkbits = h_inode->i_blkbits; ++ au_cpup_igen(inode, h_inode); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */ ++ ++/* keep the timestamps of the parent dir when cpup */ ++void au_dtime_store(struct au_dtime *dt, struct dentry *dentry, ++ struct path *h_path) ++{ ++ struct inode *h_inode; ++ ++ dt->dt_dentry = dentry; ++ dt->dt_h_path = *h_path; ++ h_inode = h_path->dentry->d_inode; ++ dt->dt_atime = h_inode->i_atime; ++ dt->dt_mtime = h_inode->i_mtime; ++ /* smp_mb(); */ ++} ++ ++void au_dtime_revert(struct au_dtime *dt) ++{ ++ struct iattr attr; ++ int err; ++ ++ attr.ia_atime = dt->dt_atime; ++ attr.ia_mtime = dt->dt_mtime; ++ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET ++ | ATTR_ATIME | ATTR_ATIME_SET; ++ ++ err = vfsub_notify_change(&dt->dt_h_path, &attr); ++ if (unlikely(err)) ++ AuWarn("restoring timestamps failed(%d). ignored\n", err); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static noinline_for_stack ++int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src) ++{ ++ int err, sbits; ++ struct iattr ia; ++ struct path h_path; ++ struct inode *h_isrc, *h_idst; ++ ++ h_path.dentry = au_h_dptr(dst, bindex); ++ h_idst = h_path.dentry->d_inode; ++ h_path.mnt = au_sbr_mnt(dst->d_sb, bindex); ++ h_isrc = h_src->d_inode; ++ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID ++ | ATTR_ATIME | ATTR_MTIME ++ | ATTR_ATIME_SET | ATTR_MTIME_SET; ++ ia.ia_uid = h_isrc->i_uid; ++ ia.ia_gid = h_isrc->i_gid; ++ ia.ia_atime = h_isrc->i_atime; ++ ia.ia_mtime = h_isrc->i_mtime; ++ if (h_idst->i_mode != h_isrc->i_mode ++ && !S_ISLNK(h_idst->i_mode)) { ++ ia.ia_valid |= ATTR_MODE; ++ ia.ia_mode = h_isrc->i_mode; ++ } ++ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID)); ++ au_cpup_attr_flags(h_idst, h_isrc); ++ err = vfsub_notify_change(&h_path, &ia); ++ ++ /* is this nfs only? */ ++ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) { ++ ia.ia_valid = ATTR_FORCE | ATTR_MODE; ++ ia.ia_mode = h_isrc->i_mode; ++ err = vfsub_notify_change(&h_path, &ia); ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_do_copy_file(struct file *dst, struct file *src, loff_t len, ++ char *buf, unsigned long blksize) ++{ ++ int err; ++ size_t sz, rbytes, wbytes; ++ unsigned char all_zero; ++ char *p, *zp; ++ struct mutex *h_mtx; ++ /* reduce stack usage */ ++ struct iattr *ia; ++ ++ zp = page_address(ZERO_PAGE(0)); ++ if (unlikely(!zp)) ++ return -ENOMEM; /* possible? */ ++ ++ err = 0; ++ all_zero = 0; ++ while (len) { ++ AuDbg("len %lld\n", len); ++ sz = blksize; ++ if (len < blksize) ++ sz = len; ++ ++ rbytes = 0; ++ /* todo: signal_pending? */ ++ while (!rbytes || err == -EAGAIN || err == -EINTR) { ++ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos); ++ err = rbytes; ++ } ++ if (unlikely(err < 0)) ++ break; ++ ++ all_zero = 0; ++ if (len >= rbytes && rbytes == blksize) ++ all_zero = !memcmp(buf, zp, rbytes); ++ if (!all_zero) { ++ wbytes = rbytes; ++ p = buf; ++ while (wbytes) { ++ size_t b; ++ ++ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos); ++ err = b; ++ /* todo: signal_pending? */ ++ if (unlikely(err == -EAGAIN || err == -EINTR)) ++ continue; ++ if (unlikely(err < 0)) ++ break; ++ wbytes -= b; ++ p += b; ++ } ++ } else { ++ loff_t res; ++ ++ AuLabel(hole); ++ res = vfsub_llseek(dst, rbytes, SEEK_CUR); ++ err = res; ++ if (unlikely(res < 0)) ++ break; ++ } ++ len -= rbytes; ++ err = 0; ++ } ++ ++ /* the last block may be a hole */ ++ if (!err && all_zero) { ++ AuLabel(last hole); ++ ++ err = 1; ++ if (au_test_nfs(dst->f_dentry->d_sb)) { ++ /* nfs requires this step to make last hole */ ++ /* is this only nfs? */ ++ do { ++ /* todo: signal_pending? */ ++ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos); ++ } while (err == -EAGAIN || err == -EINTR); ++ if (err == 1) ++ dst->f_pos--; ++ } ++ ++ if (err == 1) { ++ ia = (void *)buf; ++ ia->ia_size = dst->f_pos; ++ ia->ia_valid = ATTR_SIZE | ATTR_FILE; ++ ia->ia_file = dst; ++ h_mtx = &dst->f_dentry->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2); ++ err = vfsub_notify_change(&dst->f_path, ia); ++ mutex_unlock(h_mtx); ++ } ++ } ++ ++ return err; ++} ++ ++int au_copy_file(struct file *dst, struct file *src, loff_t len) ++{ ++ int err; ++ unsigned long blksize; ++ unsigned char do_kfree; ++ char *buf; ++ ++ err = -ENOMEM; ++ blksize = dst->f_dentry->d_sb->s_blocksize; ++ if (!blksize || PAGE_SIZE < blksize) ++ blksize = PAGE_SIZE; ++ AuDbg("blksize %lu\n", blksize); ++ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *)); ++ if (do_kfree) ++ buf = kmalloc(blksize, GFP_NOFS); ++ else ++ buf = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!buf)) ++ goto out; ++ ++ if (len > (1 << 22)) ++ AuDbg("copying a large file %lld\n", (long long)len); ++ ++ src->f_pos = 0; ++ dst->f_pos = 0; ++ err = au_do_copy_file(dst, src, len, buf, blksize); ++ if (do_kfree) ++ kfree(buf); ++ else ++ free_page((unsigned long)buf); ++ ++ out: ++ return err; ++} ++ ++/* ++ * to support a sparse file which is opened with O_APPEND, ++ * we need to close the file. ++ */ ++static int au_cp_regular(struct dentry *dentry, aufs_bindex_t bdst, ++ aufs_bindex_t bsrc, loff_t len) ++{ ++ int err, i; ++ enum { SRC, DST }; ++ struct { ++ aufs_bindex_t bindex; ++ unsigned int flags; ++ struct dentry *dentry; ++ struct file *file; ++ void *label, *label_file; ++ } *f, file[] = { ++ { ++ .bindex = bsrc, ++ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE, ++ .file = NULL, ++ .label = &&out, ++ .label_file = &&out_src ++ }, ++ { ++ .bindex = bdst, ++ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE, ++ .file = NULL, ++ .label = &&out_src, ++ .label_file = &&out_dst ++ } ++ }; ++ struct super_block *sb; ++ ++ /* bsrc branch can be ro/rw. */ ++ sb = dentry->d_sb; ++ f = file; ++ for (i = 0; i < 2; i++, f++) { ++ f->dentry = au_h_dptr(dentry, f->bindex); ++ f->file = au_h_open(dentry, f->bindex, f->flags, /*file*/NULL); ++ err = PTR_ERR(f->file); ++ if (IS_ERR(f->file)) ++ goto *f->label; ++ err = -EINVAL; ++ if (unlikely(!f->file->f_op)) ++ goto *f->label_file; ++ } ++ ++ /* try stopping to update while we copyup */ ++ IMustLock(file[SRC].dentry->d_inode); ++ err = au_copy_file(file[DST].file, file[SRC].file, len); ++ ++ out_dst: ++ fput(file[DST].file); ++ au_sbr_put(sb, file[DST].bindex); ++ out_src: ++ fput(file[SRC].file); ++ au_sbr_put(sb, file[SRC].bindex); ++ out: ++ return err; ++} ++ ++static int au_do_cpup_regular(struct dentry *dentry, aufs_bindex_t bdst, ++ aufs_bindex_t bsrc, loff_t len, ++ struct inode *h_dir, struct path *h_path) ++{ ++ int err, rerr; ++ loff_t l; ++ ++ err = 0; ++ l = i_size_read(au_h_iptr(dentry->d_inode, bsrc)); ++ if (len == -1 || l < len) ++ len = l; ++ if (len) ++ err = au_cp_regular(dentry, bdst, bsrc, len); ++ if (!err) ++ goto out; /* success */ ++ ++ rerr = vfsub_unlink(h_dir, h_path, /*force*/0); ++ if (rerr) { ++ AuIOErr("failed unlinking cpup-ed %.*s(%d, %d)\n", ++ AuDLNPair(h_path->dentry), err, rerr); ++ err = -EIO; ++ } ++ ++ out: ++ return err; ++} ++ ++static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src, ++ struct inode *h_dir) ++{ ++ int err, symlen; ++ mm_segment_t old_fs; ++ char *sym; ++ ++ err = -ENOSYS; ++ if (unlikely(!h_src->d_inode->i_op->readlink)) ++ goto out; ++ ++ err = -ENOMEM; ++ sym = __getname(); ++ if (unlikely(!sym)) ++ goto out; ++ ++ old_fs = get_fs(); ++ set_fs(KERNEL_DS); ++ symlen = h_src->d_inode->i_op->readlink(h_src, (char __user *)sym, ++ PATH_MAX); ++ err = symlen; ++ set_fs(old_fs); ++ ++ if (symlen > 0) { ++ sym[symlen] = 0; ++ err = vfsub_symlink(h_dir, h_path, sym); ++ } ++ __putname(sym); ++ ++ out: ++ return err; ++} ++ ++/* return with the lower dst inode is locked */ ++static noinline_for_stack ++int cpup_entry(struct dentry *dentry, aufs_bindex_t bdst, ++ aufs_bindex_t bsrc, loff_t len, unsigned int flags, ++ struct dentry *dst_parent) ++{ ++ int err; ++ umode_t mode; ++ unsigned int mnt_flags; ++ unsigned char isdir; ++ const unsigned char do_dt = !!au_ftest_cpup(flags, DTIME); ++ struct au_dtime dt; ++ struct path h_path; ++ struct dentry *h_src, *h_dst, *h_parent; ++ struct inode *h_inode, *h_dir; ++ struct super_block *sb; ++ ++ /* bsrc branch can be ro/rw. */ ++ h_src = au_h_dptr(dentry, bsrc); ++ h_inode = h_src->d_inode; ++ AuDebugOn(h_inode != au_h_iptr(dentry->d_inode, bsrc)); ++ ++ /* try stopping to be referenced while we are creating */ ++ h_dst = au_h_dptr(dentry, bdst); ++ h_parent = h_dst->d_parent; /* dir inode is locked */ ++ h_dir = h_parent->d_inode; ++ IMustLock(h_dir); ++ AuDebugOn(h_parent != h_dst->d_parent); ++ ++ sb = dentry->d_sb; ++ h_path.mnt = au_sbr_mnt(sb, bdst); ++ if (do_dt) { ++ h_path.dentry = h_parent; ++ au_dtime_store(&dt, dst_parent, &h_path); ++ } ++ h_path.dentry = h_dst; ++ ++ isdir = 0; ++ mode = h_inode->i_mode; ++ switch (mode & S_IFMT) { ++ case S_IFREG: ++ /* try stopping to update while we are referencing */ ++ IMustLock(h_inode); ++ err = vfsub_create(h_dir, &h_path, mode | S_IWUSR); ++ if (!err) ++ err = au_do_cpup_regular ++ (dentry, bdst, bsrc, len, ++ au_h_iptr(dst_parent->d_inode, bdst), &h_path); ++ break; ++ case S_IFDIR: ++ isdir = 1; ++ err = vfsub_mkdir(h_dir, &h_path, mode); ++ if (!err) { ++ /* ++ * strange behaviour from the users view, ++ * particularry setattr case ++ */ ++ if (au_ibstart(dst_parent->d_inode) == bdst) ++ au_cpup_attr_nlink(dst_parent->d_inode, ++ /*force*/1); ++ au_cpup_attr_nlink(dentry->d_inode, /*force*/1); ++ } ++ break; ++ case S_IFLNK: ++ err = au_do_cpup_symlink(&h_path, h_src, h_dir); ++ break; ++ case S_IFCHR: ++ case S_IFBLK: ++ AuDebugOn(!capable(CAP_MKNOD)); ++ /*FALLTHROUGH*/ ++ case S_IFIFO: ++ case S_IFSOCK: ++ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev); ++ break; ++ default: ++ AuIOErr("Unknown inode type 0%o\n", mode); ++ err = -EIO; ++ } ++ ++ mnt_flags = au_mntflags(sb); ++ if (!au_opt_test(mnt_flags, UDBA_NONE) ++ && !isdir ++ && au_opt_test(mnt_flags, XINO) ++ && h_inode->i_nlink == 1 ++ /* todo: unnecessary? */ ++ /* && dentry->d_inode->i_nlink == 1 */ ++ && bdst < bsrc ++ && !au_ftest_cpup(flags, KEEPLINO)) ++ au_xino_write(sb, bsrc, h_inode->i_ino, /*ino*/0); ++ /* ignore this error */ ++ ++ if (do_dt) ++ au_dtime_revert(&dt); ++ return err; ++} ++ ++/* ++ * copyup the @dentry from @bsrc to @bdst. ++ * the caller must set the both of lower dentries. ++ * @len is for truncating when it is -1 copyup the entire file. ++ * in link/rename cases, @dst_parent may be different from the real one. ++ */ ++static int au_cpup_single(struct dentry *dentry, aufs_bindex_t bdst, ++ aufs_bindex_t bsrc, loff_t len, unsigned int flags, ++ struct dentry *dst_parent) ++{ ++ int err, rerr; ++ aufs_bindex_t old_ibstart; ++ unsigned char isdir, plink; ++ struct au_dtime dt; ++ struct path h_path; ++ struct dentry *h_src, *h_dst, *h_parent; ++ struct inode *dst_inode, *h_dir, *inode; ++ struct super_block *sb; ++ ++ AuDebugOn(bsrc <= bdst); ++ ++ sb = dentry->d_sb; ++ h_path.mnt = au_sbr_mnt(sb, bdst); ++ h_dst = au_h_dptr(dentry, bdst); ++ h_parent = h_dst->d_parent; /* dir inode is locked */ ++ h_dir = h_parent->d_inode; ++ IMustLock(h_dir); ++ ++ h_src = au_h_dptr(dentry, bsrc); ++ inode = dentry->d_inode; ++ ++ if (!dst_parent) ++ dst_parent = dget_parent(dentry); ++ else ++ dget(dst_parent); ++ ++ plink = !!au_opt_test(au_mntflags(sb), PLINK); ++ dst_inode = au_h_iptr(inode, bdst); ++ if (dst_inode) { ++ if (unlikely(!plink)) { ++ err = -EIO; ++ AuIOErr("i%lu exists on a upper branch " ++ "but plink is disabled\n", inode->i_ino); ++ goto out; ++ } ++ ++ if (dst_inode->i_nlink) { ++ const int do_dt = au_ftest_cpup(flags, DTIME); ++ ++ h_src = au_plink_lkup(inode, bdst); ++ err = PTR_ERR(h_src); ++ if (IS_ERR(h_src)) ++ goto out; ++ if (unlikely(!h_src->d_inode)) { ++ err = -EIO; ++ AuIOErr("i%lu exists on a upper branch " ++ "but plink is broken\n", inode->i_ino); ++ dput(h_src); ++ goto out; ++ } ++ ++ if (do_dt) { ++ h_path.dentry = h_parent; ++ au_dtime_store(&dt, dst_parent, &h_path); ++ } ++ h_path.dentry = h_dst; ++ err = vfsub_link(h_src, h_dir, &h_path); ++ if (do_dt) ++ au_dtime_revert(&dt); ++ dput(h_src); ++ goto out; ++ } else ++ /* todo: cpup_wh_file? */ ++ /* udba work */ ++ au_update_brange(inode, 1); ++ } ++ ++ old_ibstart = au_ibstart(inode); ++ err = cpup_entry(dentry, bdst, bsrc, len, flags, dst_parent); ++ if (unlikely(err)) ++ goto out; ++ dst_inode = h_dst->d_inode; ++ mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2); ++ ++ err = cpup_iattr(dentry, bdst, h_src); ++ isdir = S_ISDIR(dst_inode->i_mode); ++ if (!err) { ++ if (bdst < old_ibstart) ++ au_set_ibstart(inode, bdst); ++ au_set_h_iptr(inode, bdst, au_igrab(dst_inode), ++ au_hi_flags(inode, isdir)); ++ mutex_unlock(&dst_inode->i_mutex); ++ if (!isdir ++ && h_src->d_inode->i_nlink > 1 ++ && plink) ++ au_plink_append(inode, bdst, h_dst); ++ goto out; /* success */ ++ } ++ ++ /* revert */ ++ h_path.dentry = h_parent; ++ mutex_unlock(&dst_inode->i_mutex); ++ au_dtime_store(&dt, dst_parent, &h_path); ++ h_path.dentry = h_dst; ++ if (!isdir) ++ rerr = vfsub_unlink(h_dir, &h_path, /*force*/0); ++ else ++ rerr = vfsub_rmdir(h_dir, &h_path); ++ au_dtime_revert(&dt); ++ if (rerr) { ++ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr); ++ err = -EIO; ++ } ++ ++ out: ++ dput(dst_parent); ++ return err; ++} ++ ++struct au_cpup_single_args { ++ int *errp; ++ struct dentry *dentry; ++ aufs_bindex_t bdst, bsrc; ++ loff_t len; ++ unsigned int flags; ++ struct dentry *dst_parent; ++}; ++ ++static void au_call_cpup_single(void *args) ++{ ++ struct au_cpup_single_args *a = args; ++ *a->errp = au_cpup_single(a->dentry, a->bdst, a->bsrc, a->len, ++ a->flags, a->dst_parent); ++} ++ ++int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst, ++ aufs_bindex_t bsrc, loff_t len, unsigned int flags, ++ struct dentry *dst_parent) ++{ ++ int err, wkq_err; ++ umode_t mode; ++ struct dentry *h_dentry; ++ ++ h_dentry = au_h_dptr(dentry, bsrc); ++ mode = h_dentry->d_inode->i_mode & S_IFMT; ++ if ((mode != S_IFCHR && mode != S_IFBLK) ++ || capable(CAP_MKNOD)) ++ err = au_cpup_single(dentry, bdst, bsrc, len, flags, ++ dst_parent); ++ else { ++ struct au_cpup_single_args args = { ++ .errp = &err, ++ .dentry = dentry, ++ .bdst = bdst, ++ .bsrc = bsrc, ++ .len = len, ++ .flags = flags, ++ .dst_parent = dst_parent ++ }; ++ wkq_err = au_wkq_wait(au_call_cpup_single, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ return err; ++} ++ ++/* ++ * copyup the @dentry from the first active lower branch to @bdst, ++ * using au_cpup_single(). ++ */ ++static int au_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, ++ unsigned int flags) ++{ ++ int err; ++ aufs_bindex_t bsrc, bend; ++ ++ bend = au_dbend(dentry); ++ for (bsrc = bdst + 1; bsrc <= bend; bsrc++) ++ if (au_h_dptr(dentry, bsrc)) ++ break; ++ ++ err = au_lkup_neg(dentry, bdst); ++ if (!err) { ++ err = au_cpup_single(dentry, bdst, bsrc, len, flags, NULL); ++ if (!err) ++ return 0; /* success */ ++ ++ /* revert */ ++ au_set_h_dptr(dentry, bdst, NULL); ++ au_set_dbstart(dentry, bsrc); ++ } ++ ++ return err; ++} ++ ++struct au_cpup_simple_args { ++ int *errp; ++ struct dentry *dentry; ++ aufs_bindex_t bdst; ++ loff_t len; ++ unsigned int flags; ++}; ++ ++static void au_call_cpup_simple(void *args) ++{ ++ struct au_cpup_simple_args *a = args; ++ *a->errp = au_cpup_simple(a->dentry, a->bdst, a->len, a->flags); ++} ++ ++int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, ++ unsigned int flags) ++{ ++ int err, wkq_err; ++ unsigned char do_sio; ++ struct dentry *parent; ++ struct inode *h_dir; ++ ++ parent = dget_parent(dentry); ++ h_dir = au_h_iptr(parent->d_inode, bdst); ++ do_sio = !!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE); ++ if (!do_sio) { ++ /* ++ * testing CAP_MKNOD is for generic fs, ++ * but CAP_FSETID is for xfs only, currently. ++ */ ++ umode_t mode = dentry->d_inode->i_mode; ++ do_sio = (((mode & (S_IFCHR | S_IFBLK)) ++ && !capable(CAP_MKNOD)) ++ || ((mode & (S_ISUID | S_ISGID)) ++ && !capable(CAP_FSETID))); ++ } ++ if (!do_sio) ++ err = au_cpup_simple(dentry, bdst, len, flags); ++ else { ++ struct au_cpup_simple_args args = { ++ .errp = &err, ++ .dentry = dentry, ++ .bdst = bdst, ++ .len = len, ++ .flags = flags ++ }; ++ wkq_err = au_wkq_wait(au_call_cpup_simple, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ dput(parent); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * copyup the deleted file for writing. ++ */ ++static int au_do_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, ++ struct dentry *wh_dentry, struct file *file, ++ loff_t len) ++{ ++ int err; ++ aufs_bindex_t bstart; ++ struct au_dinfo *dinfo; ++ struct dentry *h_d_dst, *h_d_start; ++ ++ dinfo = au_di(dentry); ++ AuRwMustWriteLock(&dinfo->di_rwsem); ++ ++ bstart = dinfo->di_bstart; ++ h_d_dst = dinfo->di_hdentry[0 + bdst].hd_dentry; ++ dinfo->di_bstart = bdst; ++ dinfo->di_hdentry[0 + bdst].hd_dentry = wh_dentry; ++ h_d_start = dinfo->di_hdentry[0 + bstart].hd_dentry; ++ if (file) ++ dinfo->di_hdentry[0 + bstart].hd_dentry ++ = au_h_fptr(file, au_fbstart(file))->f_dentry; ++ err = au_cpup_single(dentry, bdst, bstart, len, !AuCpup_DTIME, ++ /*h_parent*/NULL); ++ if (!err && file) { ++ err = au_reopen_nondir(file); ++ dinfo->di_hdentry[0 + bstart].hd_dentry = h_d_start; ++ } ++ dinfo->di_hdentry[0 + bdst].hd_dentry = h_d_dst; ++ dinfo->di_bstart = bstart; ++ ++ return err; ++} ++ ++static int au_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, ++ struct file *file) ++{ ++ int err; ++ struct au_dtime dt; ++ struct dentry *parent, *h_parent, *wh_dentry; ++ struct au_branch *br; ++ struct path h_path; ++ ++ br = au_sbr(dentry->d_sb, bdst); ++ parent = dget_parent(dentry); ++ h_parent = au_h_dptr(parent, bdst); ++ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out; ++ ++ h_path.dentry = h_parent; ++ h_path.mnt = br->br_mnt; ++ au_dtime_store(&dt, parent, &h_path); ++ err = au_do_cpup_wh(dentry, bdst, wh_dentry, file, len); ++ if (unlikely(err)) ++ goto out_wh; ++ ++ dget(wh_dentry); ++ h_path.dentry = wh_dentry; ++ err = vfsub_unlink(h_parent->d_inode, &h_path, /*force*/0); ++ if (unlikely(err)) { ++ AuIOErr("failed remove copied-up tmp file %.*s(%d)\n", ++ AuDLNPair(wh_dentry), err); ++ err = -EIO; ++ } ++ au_dtime_revert(&dt); ++ au_set_hi_wh(dentry->d_inode, bdst, wh_dentry); ++ ++ out_wh: ++ dput(wh_dentry); ++ out: ++ dput(parent); ++ return err; ++} ++ ++struct au_cpup_wh_args { ++ int *errp; ++ struct dentry *dentry; ++ aufs_bindex_t bdst; ++ loff_t len; ++ struct file *file; ++}; ++ ++static void au_call_cpup_wh(void *args) ++{ ++ struct au_cpup_wh_args *a = args; ++ *a->errp = au_cpup_wh(a->dentry, a->bdst, a->len, a->file); ++} ++ ++int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, ++ struct file *file) ++{ ++ int err, wkq_err; ++ struct dentry *parent, *h_orph, *h_parent, *h_dentry; ++ struct inode *dir, *h_dir, *h_tmpdir, *h_inode; ++ struct au_wbr *wbr; ++ ++ parent = dget_parent(dentry); ++ dir = parent->d_inode; ++ h_orph = NULL; ++ h_parent = NULL; ++ h_dir = au_igrab(au_h_iptr(dir, bdst)); ++ h_tmpdir = h_dir; ++ if (!h_dir->i_nlink) { ++ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr; ++ h_orph = wbr->wbr_orph; ++ ++ h_parent = dget(au_h_dptr(parent, bdst)); ++ au_set_h_dptr(parent, bdst, NULL); ++ au_set_h_dptr(parent, bdst, dget(h_orph)); ++ h_tmpdir = h_orph->d_inode; ++ au_set_h_iptr(dir, bdst, NULL, 0); ++ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0); ++ ++ /* this temporary unlock is safe */ ++ if (file) ++ h_dentry = au_h_fptr(file, au_fbstart(file))->f_dentry; ++ else ++ h_dentry = au_h_dptr(dentry, au_dbstart(dentry)); ++ h_inode = h_dentry->d_inode; ++ IMustLock(h_inode); ++ mutex_unlock(&h_inode->i_mutex); ++ mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3); ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ } ++ ++ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)) ++ err = au_cpup_wh(dentry, bdst, len, file); ++ else { ++ struct au_cpup_wh_args args = { ++ .errp = &err, ++ .dentry = dentry, ++ .bdst = bdst, ++ .len = len, ++ .file = file ++ }; ++ wkq_err = au_wkq_wait(au_call_cpup_wh, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ if (h_orph) { ++ mutex_unlock(&h_tmpdir->i_mutex); ++ au_set_h_iptr(dir, bdst, NULL, 0); ++ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0); ++ au_set_h_dptr(parent, bdst, NULL); ++ au_set_h_dptr(parent, bdst, h_parent); ++ } ++ iput(h_dir); ++ dput(parent); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * generic routine for both of copy-up and copy-down. ++ */ ++/* cf. revalidate function in file.c */ ++int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, ++ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, ++ struct dentry *h_parent, void *arg), ++ void *arg) ++{ ++ int err; ++ struct au_pin pin; ++ struct dentry *d, *parent, *h_parent, *real_parent; ++ ++ err = 0; ++ parent = dget_parent(dentry); ++ if (IS_ROOT(parent)) ++ goto out; ++ ++ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2, ++ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE); ++ ++ /* do not use au_dpage */ ++ real_parent = parent; ++ while (1) { ++ dput(parent); ++ parent = dget_parent(dentry); ++ h_parent = au_h_dptr(parent, bdst); ++ if (h_parent) ++ goto out; /* success */ ++ ++ /* find top dir which is necessary to cpup */ ++ do { ++ d = parent; ++ dput(parent); ++ parent = dget_parent(d); ++ di_read_lock_parent3(parent, !AuLock_IR); ++ h_parent = au_h_dptr(parent, bdst); ++ di_read_unlock(parent, !AuLock_IR); ++ } while (!h_parent); ++ ++ if (d != real_parent) ++ di_write_lock_child3(d); ++ ++ /* somebody else might create while we were sleeping */ ++ if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) { ++ if (au_h_dptr(d, bdst)) ++ au_update_dbstart(d); ++ ++ au_pin_set_dentry(&pin, d); ++ err = au_do_pin(&pin); ++ if (!err) { ++ err = cp(d, bdst, h_parent, arg); ++ au_unpin(&pin); ++ } ++ } ++ ++ if (d != real_parent) ++ di_write_unlock(d); ++ if (unlikely(err)) ++ break; ++ } ++ ++ out: ++ dput(parent); ++ return err; ++} ++ ++static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst, ++ struct dentry *h_parent __maybe_unused , ++ void *arg __maybe_unused) ++{ ++ return au_sio_cpup_simple(dentry, bdst, -1, AuCpup_DTIME); ++} ++ ++int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) ++{ ++ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL); ++} ++ ++int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) ++{ ++ int err; ++ struct dentry *parent; ++ struct inode *dir; ++ ++ parent = dget_parent(dentry); ++ dir = parent->d_inode; ++ err = 0; ++ if (au_h_iptr(dir, bdst)) ++ goto out; ++ ++ di_read_unlock(parent, AuLock_IR); ++ di_write_lock_parent(parent); ++ /* someone else might change our inode while we were sleeping */ ++ if (!au_h_iptr(dir, bdst)) ++ err = au_cpup_dirs(dentry, bdst); ++ di_downgrade_lock(parent, AuLock_IR); ++ ++ out: ++ dput(parent); ++ return err; ++} +diff --git a/fs/aufs/cpup.h b/fs/aufs/cpup.h +new file mode 100644 +index 0000000..29e2508 +--- /dev/null ++++ b/fs/aufs/cpup.h +@@ -0,0 +1,81 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * copy-up/down functions ++ */ ++ ++#ifndef __AUFS_CPUP_H__ ++#define __AUFS_CPUP_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++ ++struct inode; ++struct file; ++ ++void au_cpup_attr_flags(struct inode *dst, struct inode *src); ++void au_cpup_attr_timesizes(struct inode *inode); ++void au_cpup_attr_nlink(struct inode *inode, int force); ++void au_cpup_attr_changeable(struct inode *inode); ++void au_cpup_igen(struct inode *inode, struct inode *h_inode); ++void au_cpup_attr_all(struct inode *inode, int force); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* cpup flags */ ++#define AuCpup_DTIME 1 /* do dtime_store/revert */ ++#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino, ++ for link(2) */ ++#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name) ++#define au_fset_cpup(flags, name) { (flags) |= AuCpup_##name; } ++#define au_fclr_cpup(flags, name) { (flags) &= ~AuCpup_##name; } ++ ++int au_copy_file(struct file *dst, struct file *src, loff_t len); ++int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst, ++ aufs_bindex_t bsrc, loff_t len, unsigned int flags, ++ struct dentry *dst_parent); ++int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, ++ unsigned int flags); ++int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, ++ struct file *file); ++ ++int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, ++ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, ++ struct dentry *h_parent, void *arg), ++ void *arg); ++int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst); ++int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* keep timestamps when copyup */ ++struct au_dtime { ++ struct dentry *dt_dentry; ++ struct path dt_h_path; ++ struct timespec dt_atime, dt_mtime; ++}; ++void au_dtime_store(struct au_dtime *dt, struct dentry *dentry, ++ struct path *h_path); ++void au_dtime_revert(struct au_dtime *dt); ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_CPUP_H__ */ +diff --git a/fs/aufs/dbgaufs.c b/fs/aufs/dbgaufs.c +new file mode 100644 +index 0000000..9573b70 +--- /dev/null ++++ b/fs/aufs/dbgaufs.c +@@ -0,0 +1,331 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * debugfs interface ++ */ ++ ++#include ++#include "aufs.h" ++ ++#ifndef CONFIG_SYSFS ++#error DEBUG_FS depends upon SYSFS ++#endif ++ ++static struct dentry *dbgaufs; ++static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH; ++ ++/* 20 is max digits length of ulong 64 */ ++struct dbgaufs_arg { ++ int n; ++ char a[20 * 4]; ++}; ++ ++/* ++ * common function for all XINO files ++ */ ++static int dbgaufs_xi_release(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ kfree(file->private_data); ++ return 0; ++} ++ ++static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt) ++{ ++ int err; ++ struct kstat st; ++ struct dbgaufs_arg *p; ++ ++ err = -ENOMEM; ++ p = kmalloc(sizeof(*p), GFP_NOFS); ++ if (unlikely(!p)) ++ goto out; ++ ++ err = 0; ++ p->n = 0; ++ file->private_data = p; ++ if (!xf) ++ goto out; ++ ++ err = vfs_getattr(xf->f_vfsmnt, xf->f_dentry, &st); ++ if (!err) { ++ if (do_fcnt) ++ p->n = snprintf ++ (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n", ++ (long)file_count(xf), st.blocks, st.blksize, ++ (long long)st.size); ++ else ++ p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n", ++ st.blocks, st.blksize, ++ (long long)st.size); ++ AuDebugOn(p->n >= sizeof(p->a)); ++ } else { ++ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err); ++ err = 0; ++ } ++ ++ out: ++ return err; ++ ++} ++ ++static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct dbgaufs_arg *p; ++ ++ p = file->private_data; ++ return simple_read_from_buffer(buf, count, ppos, p->a, p->n); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int dbgaufs_xib_open(struct inode *inode, struct file *file) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ ++ sbinfo = inode->i_private; ++ sb = sbinfo->si_sb; ++ si_noflush_read_lock(sb); ++ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0); ++ si_read_unlock(sb); ++ return err; ++} ++ ++static const struct file_operations dbgaufs_xib_fop = { ++ .open = dbgaufs_xib_open, ++ .release = dbgaufs_xi_release, ++ .read = dbgaufs_xi_read ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define DbgaufsXi_PREFIX "xi" ++ ++static int dbgaufs_xino_open(struct inode *inode, struct file *file) ++{ ++ int err; ++ long l; ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ struct file *xf; ++ struct qstr *name; ++ ++ err = -ENOENT; ++ xf = NULL; ++ name = &file->f_dentry->d_name; ++ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX) ++ || memcmp(name->name, DbgaufsXi_PREFIX, ++ sizeof(DbgaufsXi_PREFIX) - 1))) ++ goto out; ++ err = strict_strtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l); ++ if (unlikely(err)) ++ goto out; ++ ++ sbinfo = inode->i_private; ++ sb = sbinfo->si_sb; ++ si_noflush_read_lock(sb); ++ if (l <= au_sbend(sb)) { ++ xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file; ++ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1); ++ } else ++ err = -ENOENT; ++ si_read_unlock(sb); ++ ++ out: ++ return err; ++} ++ ++static const struct file_operations dbgaufs_xino_fop = { ++ .open = dbgaufs_xino_open, ++ .release = dbgaufs_xi_release, ++ .read = dbgaufs_xi_read ++}; ++ ++void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ aufs_bindex_t bend; ++ struct au_branch *br; ++ struct au_xino_file *xi; ++ ++ if (!au_sbi(sb)->si_dbgaufs) ++ return; ++ ++ bend = au_sbend(sb); ++ for (; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ xi = &br->br_xino; ++ if (xi->xi_dbgaufs) { ++ debugfs_remove(xi->xi_dbgaufs); ++ xi->xi_dbgaufs = NULL; ++ } ++ } ++} ++ ++void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ struct au_sbinfo *sbinfo; ++ struct dentry *parent; ++ struct au_branch *br; ++ struct au_xino_file *xi; ++ aufs_bindex_t bend; ++ char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */ ++ ++ sbinfo = au_sbi(sb); ++ parent = sbinfo->si_dbgaufs; ++ if (!parent) ++ return; ++ ++ bend = au_sbend(sb); ++ for (; bindex <= bend; bindex++) { ++ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex); ++ br = au_sbr(sb, bindex); ++ xi = &br->br_xino; ++ AuDebugOn(xi->xi_dbgaufs); ++ xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent, ++ sbinfo, &dbgaufs_xino_fop); ++ /* ignore an error */ ++ if (unlikely(!xi->xi_dbgaufs)) ++ AuWarn1("failed %s under debugfs\n", name); ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_EXPORT ++static int dbgaufs_xigen_open(struct inode *inode, struct file *file) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ ++ sbinfo = inode->i_private; ++ sb = sbinfo->si_sb; ++ si_noflush_read_lock(sb); ++ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0); ++ si_read_unlock(sb); ++ return err; ++} ++ ++static const struct file_operations dbgaufs_xigen_fop = { ++ .open = dbgaufs_xigen_open, ++ .release = dbgaufs_xi_release, ++ .read = dbgaufs_xi_read ++}; ++ ++static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo) ++{ ++ int err; ++ ++ /* ++ * This function is a dynamic '__init' fucntion actually, ++ * so the tiny check for si_rwsem is unnecessary. ++ */ ++ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ ++ ++ err = -EIO; ++ sbinfo->si_dbgaufs_xigen = debugfs_create_file ++ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo, ++ &dbgaufs_xigen_fop); ++ if (sbinfo->si_dbgaufs_xigen) ++ err = 0; ++ ++ return err; ++} ++#else ++static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo) ++{ ++ return 0; ++} ++#endif /* CONFIG_AUFS_EXPORT */ ++ ++/* ---------------------------------------------------------------------- */ ++ ++void dbgaufs_si_fin(struct au_sbinfo *sbinfo) ++{ ++ /* ++ * This function is a dynamic '__init' fucntion actually, ++ * so the tiny check for si_rwsem is unnecessary. ++ */ ++ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ ++ ++ debugfs_remove_recursive(sbinfo->si_dbgaufs); ++ sbinfo->si_dbgaufs = NULL; ++ kobject_put(&sbinfo->si_kobj); ++} ++ ++int dbgaufs_si_init(struct au_sbinfo *sbinfo) ++{ ++ int err; ++ char name[SysaufsSiNameLen]; ++ ++ /* ++ * This function is a dynamic '__init' fucntion actually, ++ * so the tiny check for si_rwsem is unnecessary. ++ */ ++ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ ++ ++ err = -ENOENT; ++ if (!dbgaufs) { ++ AuErr1("/debug/aufs is uninitialized\n"); ++ goto out; ++ } ++ ++ err = -EIO; ++ sysaufs_name(sbinfo, name); ++ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs); ++ if (unlikely(!sbinfo->si_dbgaufs)) ++ goto out; ++ kobject_get(&sbinfo->si_kobj); ++ ++ sbinfo->si_dbgaufs_xib = debugfs_create_file ++ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo, ++ &dbgaufs_xib_fop); ++ if (unlikely(!sbinfo->si_dbgaufs_xib)) ++ goto out_dir; ++ ++ err = dbgaufs_xigen_init(sbinfo); ++ if (!err) ++ goto out; /* success */ ++ ++ out_dir: ++ dbgaufs_si_fin(sbinfo); ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void dbgaufs_fin(void) ++{ ++ debugfs_remove(dbgaufs); ++} ++ ++int __init dbgaufs_init(void) ++{ ++ int err; ++ ++ err = -EIO; ++ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL); ++ if (dbgaufs) ++ err = 0; ++ return err; ++} +diff --git a/fs/aufs/dbgaufs.h b/fs/aufs/dbgaufs.h +new file mode 100644 +index 0000000..67a7964 +--- /dev/null ++++ b/fs/aufs/dbgaufs.h +@@ -0,0 +1,79 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * debugfs interface ++ */ ++ ++#ifndef __DBGAUFS_H__ ++#define __DBGAUFS_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++ ++struct super_block; ++struct au_sbinfo; ++ ++#ifdef CONFIG_DEBUG_FS ++/* dbgaufs.c */ ++void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex); ++void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex); ++void dbgaufs_si_fin(struct au_sbinfo *sbinfo); ++int dbgaufs_si_init(struct au_sbinfo *sbinfo); ++void dbgaufs_fin(void); ++int __init dbgaufs_init(void); ++ ++#else ++ ++static inline ++void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ /* empty */ ++} ++ ++static inline ++void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ /* empty */ ++} ++ ++static inline ++void dbgaufs_si_fin(struct au_sbinfo *sbinfo) ++{ ++ /* empty */ ++} ++ ++static inline ++int dbgaufs_si_init(struct au_sbinfo *sbinfo) ++{ ++ return 0; ++} ++ ++#define dbgaufs_fin() do {} while (0) ++ ++static inline ++int __init dbgaufs_init(void) ++{ ++ return 0; ++} ++#endif /* CONFIG_DEBUG_FS */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __DBGAUFS_H__ */ +diff --git a/fs/aufs/dcsub.c b/fs/aufs/dcsub.c +new file mode 100644 +index 0000000..43a8cb4 +--- /dev/null ++++ b/fs/aufs/dcsub.c +@@ -0,0 +1,223 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * sub-routines for dentry cache ++ */ ++ ++#include "aufs.h" ++ ++static void au_dpage_free(struct au_dpage *dpage) ++{ ++ int i; ++ struct dentry **p; ++ ++ p = dpage->dentries; ++ for (i = 0; i < dpage->ndentry; i++) ++ dput(*p++); ++ free_page((unsigned long)dpage->dentries); ++} ++ ++int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp) ++{ ++ int err; ++ void *p; ++ ++ err = -ENOMEM; ++ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp); ++ if (unlikely(!dpages->dpages)) ++ goto out; ++ ++ p = (void *)__get_free_page(gfp); ++ if (unlikely(!p)) ++ goto out_dpages; ++ ++ dpages->dpages[0].ndentry = 0; ++ dpages->dpages[0].dentries = p; ++ dpages->ndpage = 1; ++ return 0; /* success */ ++ ++ out_dpages: ++ kfree(dpages->dpages); ++ out: ++ return err; ++} ++ ++void au_dpages_free(struct au_dcsub_pages *dpages) ++{ ++ int i; ++ struct au_dpage *p; ++ ++ p = dpages->dpages; ++ for (i = 0; i < dpages->ndpage; i++) ++ au_dpage_free(p++); ++ kfree(dpages->dpages); ++} ++ ++static int au_dpages_append(struct au_dcsub_pages *dpages, ++ struct dentry *dentry, gfp_t gfp) ++{ ++ int err, sz; ++ struct au_dpage *dpage; ++ void *p; ++ ++ dpage = dpages->dpages + dpages->ndpage - 1; ++ sz = PAGE_SIZE / sizeof(dentry); ++ if (unlikely(dpage->ndentry >= sz)) { ++ AuLabel(new dpage); ++ err = -ENOMEM; ++ sz = dpages->ndpage * sizeof(*dpages->dpages); ++ p = au_kzrealloc(dpages->dpages, sz, ++ sz + sizeof(*dpages->dpages), gfp); ++ if (unlikely(!p)) ++ goto out; ++ ++ dpages->dpages = p; ++ dpage = dpages->dpages + dpages->ndpage; ++ p = (void *)__get_free_page(gfp); ++ if (unlikely(!p)) ++ goto out; ++ ++ dpage->ndentry = 0; ++ dpage->dentries = p; ++ dpages->ndpage++; ++ } ++ ++ dpage->dentries[dpage->ndentry++] = dget(dentry); ++ return 0; /* success */ ++ ++ out: ++ return err; ++} ++ ++int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root, ++ au_dpages_test test, void *arg) ++{ ++ int err; ++ struct dentry *this_parent = root; ++ struct list_head *next; ++ struct super_block *sb = root->d_sb; ++ ++ err = 0; ++ spin_lock(&dcache_lock); ++ repeat: ++ next = this_parent->d_subdirs.next; ++ resume: ++ if (this_parent->d_sb == sb ++ && !IS_ROOT(this_parent) ++ && atomic_read(&this_parent->d_count) ++ && this_parent->d_inode ++ && (!test || test(this_parent, arg))) { ++ err = au_dpages_append(dpages, this_parent, GFP_ATOMIC); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ while (next != &this_parent->d_subdirs) { ++ struct list_head *tmp = next; ++ struct dentry *dentry = list_entry(tmp, struct dentry, ++ d_u.d_child); ++ next = tmp->next; ++ if (/*d_unhashed(dentry) || */!dentry->d_inode) ++ continue; ++ if (!list_empty(&dentry->d_subdirs)) { ++ this_parent = dentry; ++ goto repeat; ++ } ++ if (dentry->d_sb == sb ++ && atomic_read(&dentry->d_count) ++ && (!test || test(dentry, arg))) { ++ err = au_dpages_append(dpages, dentry, GFP_ATOMIC); ++ if (unlikely(err)) ++ goto out; ++ } ++ } ++ ++ if (this_parent != root) { ++ next = this_parent->d_u.d_child.next; ++ this_parent = this_parent->d_parent; /* dcache_lock is locked */ ++ goto resume; ++ } ++ out: ++ spin_unlock(&dcache_lock); ++ return err; ++} ++ ++int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry, ++ int do_include, au_dpages_test test, void *arg) ++{ ++ int err; ++ ++ err = 0; ++ spin_lock(&dcache_lock); ++ if (do_include && (!test || test(dentry, arg))) { ++ err = au_dpages_append(dpages, dentry, GFP_ATOMIC); ++ if (unlikely(err)) ++ goto out; ++ } ++ while (!IS_ROOT(dentry)) { ++ dentry = dentry->d_parent; /* dcache_lock is locked */ ++ if (!test || test(dentry, arg)) { ++ err = au_dpages_append(dpages, dentry, GFP_ATOMIC); ++ if (unlikely(err)) ++ break; ++ } ++ } ++ ++ out: ++ spin_unlock(&dcache_lock); ++ ++ return err; ++} ++ ++struct dentry *au_test_subdir(struct dentry *d1, struct dentry *d2) ++{ ++ struct dentry *trap, **dentries; ++ int err, i, j; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ ++ trap = ERR_PTR(-ENOMEM); ++ err = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_dcsub_pages_rev(&dpages, d1, /*do_include*/1, NULL, NULL); ++ if (unlikely(err)) ++ goto out_dpages; ++ ++ trap = d1; ++ for (i = 0; !err && i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ dentries = dpage->dentries; ++ for (j = 0; !err && j < dpage->ndentry; j++) { ++ struct dentry *d; ++ ++ d = dentries[j]; ++ err = (d == d2); ++ if (!err) ++ trap = d; ++ } ++ } ++ if (!err) ++ trap = NULL; ++ ++ out_dpages: ++ au_dpages_free(&dpages); ++ out: ++ return trap; ++} +diff --git a/fs/aufs/dcsub.h b/fs/aufs/dcsub.h +new file mode 100644 +index 0000000..bb934b4 +--- /dev/null ++++ b/fs/aufs/dcsub.h +@@ -0,0 +1,54 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * sub-routines for dentry cache ++ */ ++ ++#ifndef __AUFS_DCSUB_H__ ++#define __AUFS_DCSUB_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++ ++struct dentry; ++ ++struct au_dpage { ++ int ndentry; ++ struct dentry **dentries; ++}; ++ ++struct au_dcsub_pages { ++ int ndpage; ++ struct au_dpage *dpages; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp); ++void au_dpages_free(struct au_dcsub_pages *dpages); ++typedef int (*au_dpages_test)(struct dentry *dentry, void *arg); ++int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root, ++ au_dpages_test test, void *arg); ++int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry, ++ int do_include, au_dpages_test test, void *arg); ++struct dentry *au_test_subdir(struct dentry *d1, struct dentry *d2); ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_DCSUB_H__ */ +diff --git a/fs/aufs/debug.c b/fs/aufs/debug.c +new file mode 100644 +index 0000000..32bdb72 +--- /dev/null ++++ b/fs/aufs/debug.c +@@ -0,0 +1,431 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * debug print functions ++ */ ++ ++#include ++#include ++#include "aufs.h" ++ ++int aufs_debug; ++MODULE_PARM_DESC(debug, "debug print"); ++module_param_named(debug, aufs_debug, int, S_IRUGO | S_IWUSR | S_IWGRP); ++ ++char *au_plevel = KERN_DEBUG; ++#define dpri(fmt, arg...) do { \ ++ if (au_debug_test()) \ ++ printk("%s" fmt, au_plevel, ##arg); \ ++} while (0) ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_dpri_whlist(struct au_nhash *whlist) ++{ ++ unsigned long ul, n; ++ struct hlist_head *head; ++ struct au_vdir_wh *tpos; ++ struct hlist_node *pos; ++ ++ n = whlist->nh_num; ++ head = whlist->nh_head; ++ for (ul = 0; ul < n; ul++) { ++ hlist_for_each_entry(tpos, pos, head, wh_hash) ++ dpri("b%d, %.*s, %d\n", ++ tpos->wh_bindex, ++ tpos->wh_str.len, tpos->wh_str.name, ++ tpos->wh_str.len); ++ head++; ++ } ++} ++ ++void au_dpri_vdir(struct au_vdir *vdir) ++{ ++ unsigned long ul; ++ union au_vdir_deblk_p p; ++ unsigned char *o; ++ ++ if (!vdir || IS_ERR(vdir)) { ++ dpri("err %ld\n", PTR_ERR(vdir)); ++ return; ++ } ++ ++ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n", ++ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk, ++ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version); ++ for (ul = 0; ul < vdir->vd_nblk; ul++) { ++ p.deblk = vdir->vd_deblk[ul]; ++ o = p.deblk; ++ dpri("[%lu]: %p\n", ul, o); ++ } ++} ++ ++static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, ++ struct dentry *wh) ++{ ++ char *n = NULL; ++ int l = 0; ++ ++ if (!inode || IS_ERR(inode)) { ++ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode)); ++ return -1; ++ } ++ ++ /* the type of i_blocks depends upon CONFIG_LSF */ ++ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long) ++ && sizeof(inode->i_blocks) != sizeof(u64)); ++ if (wh) { ++ n = (void *)wh->d_name.name; ++ l = wh->d_name.len; ++ } ++ ++ dpri("i%d: i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu," ++ " ct %lld, np %lu, st 0x%lx, f 0x%x, g %x%s%.*s\n", ++ bindex, ++ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??", ++ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode, ++ i_size_read(inode), (unsigned long long)inode->i_blocks, ++ (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff, ++ inode->i_mapping ? inode->i_mapping->nrpages : 0, ++ inode->i_state, inode->i_flags, inode->i_generation, ++ l ? ", wh " : "", l, n); ++ return 0; ++} ++ ++void au_dpri_inode(struct inode *inode) ++{ ++ struct au_iinfo *iinfo; ++ aufs_bindex_t bindex; ++ int err; ++ ++ err = do_pri_inode(-1, inode, NULL); ++ if (err || !au_test_aufs(inode->i_sb)) ++ return; ++ ++ iinfo = au_ii(inode); ++ if (!iinfo) ++ return; ++ dpri("i-1: bstart %d, bend %d, gen %d\n", ++ iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode)); ++ if (iinfo->ii_bstart < 0) ++ return; ++ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) ++ do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, ++ iinfo->ii_hinode[0 + bindex].hi_whdentry); ++} ++ ++static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry) ++{ ++ struct dentry *wh = NULL; ++ ++ if (!dentry || IS_ERR(dentry)) { ++ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry)); ++ return -1; ++ } ++ /* do not call dget_parent() here */ ++ dpri("d%d: %.*s?/%.*s, %s, cnt %d, flags 0x%x\n", ++ bindex, ++ AuDLNPair(dentry->d_parent), AuDLNPair(dentry), ++ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??", ++ atomic_read(&dentry->d_count), dentry->d_flags); ++ if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) { ++ struct au_iinfo *iinfo = au_ii(dentry->d_inode); ++ if (iinfo) ++ wh = iinfo->ii_hinode[0 + bindex].hi_whdentry; ++ } ++ do_pri_inode(bindex, dentry->d_inode, wh); ++ return 0; ++} ++ ++void au_dpri_dentry(struct dentry *dentry) ++{ ++ struct au_dinfo *dinfo; ++ aufs_bindex_t bindex; ++ int err; ++ ++ err = do_pri_dentry(-1, dentry); ++ if (err || !au_test_aufs(dentry->d_sb)) ++ return; ++ ++ dinfo = au_di(dentry); ++ if (!dinfo) ++ return; ++ dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d\n", ++ dinfo->di_bstart, dinfo->di_bend, ++ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry)); ++ if (dinfo->di_bstart < 0) ++ return; ++ for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++) ++ do_pri_dentry(bindex, dinfo->di_hdentry[0 + bindex].hd_dentry); ++} ++ ++static int do_pri_file(aufs_bindex_t bindex, struct file *file) ++{ ++ char a[32]; ++ ++ if (!file || IS_ERR(file)) { ++ dpri("f%d: err %ld\n", bindex, PTR_ERR(file)); ++ return -1; ++ } ++ a[0] = 0; ++ if (bindex < 0 ++ && file->f_dentry ++ && au_test_aufs(file->f_dentry->d_sb) ++ && au_fi(file)) ++ snprintf(a, sizeof(a), ", mmapped %d", au_test_mmapped(file)); ++ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, pos %llu%s\n", ++ bindex, file->f_mode, file->f_flags, (long)file_count(file), ++ file->f_pos, a); ++ if (file->f_dentry) ++ do_pri_dentry(bindex, file->f_dentry); ++ return 0; ++} ++ ++void au_dpri_file(struct file *file) ++{ ++ struct au_finfo *finfo; ++ aufs_bindex_t bindex; ++ int err; ++ ++ err = do_pri_file(-1, file); ++ if (err || !file->f_dentry || !au_test_aufs(file->f_dentry->d_sb)) ++ return; ++ ++ finfo = au_fi(file); ++ if (!finfo) ++ return; ++ if (finfo->fi_bstart < 0) ++ return; ++ for (bindex = finfo->fi_bstart; bindex <= finfo->fi_bend; bindex++) { ++ struct au_hfile *hf; ++ ++ hf = finfo->fi_hfile + bindex; ++ do_pri_file(bindex, hf ? hf->hf_file : NULL); ++ } ++} ++ ++static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br) ++{ ++ struct vfsmount *mnt; ++ struct super_block *sb; ++ ++ if (!br || IS_ERR(br)) ++ goto out; ++ mnt = br->br_mnt; ++ if (!mnt || IS_ERR(mnt)) ++ goto out; ++ sb = mnt->mnt_sb; ++ if (!sb || IS_ERR(sb)) ++ goto out; ++ ++ dpri("s%d: {perm 0x%x, cnt %d, wbr %p}, " ++ "%s, dev 0x%02x%02x, flags 0x%lx, cnt(BIAS) %d, active %d, " ++ "xino %d\n", ++ bindex, br->br_perm, atomic_read(&br->br_count), br->br_wbr, ++ au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev), ++ sb->s_flags, sb->s_count - S_BIAS, ++ atomic_read(&sb->s_active), !!br->br_xino.xi_file); ++ return 0; ++ ++ out: ++ dpri("s%d: err %ld\n", bindex, PTR_ERR(br)); ++ return -1; ++} ++ ++void au_dpri_sb(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ aufs_bindex_t bindex; ++ int err; ++ /* to reuduce stack size */ ++ struct { ++ struct vfsmount mnt; ++ struct au_branch fake; ++ } *a; ++ ++ /* this function can be called from magic sysrq */ ++ a = kzalloc(sizeof(*a), GFP_ATOMIC); ++ if (unlikely(!a)) { ++ dpri("no memory\n"); ++ return; ++ } ++ ++ a->mnt.mnt_sb = sb; ++ a->fake.br_perm = 0; ++ a->fake.br_mnt = &a->mnt; ++ a->fake.br_xino.xi_file = NULL; ++ atomic_set(&a->fake.br_count, 0); ++ smp_mb(); /* atomic_set */ ++ err = do_pri_br(-1, &a->fake); ++ kfree(a); ++ dpri("dev 0x%x\n", sb->s_dev); ++ if (err || !au_test_aufs(sb)) ++ return; ++ ++ sbinfo = au_sbi(sb); ++ if (!sbinfo) ++ return; ++ dpri("nw %d, gen %u, kobj %d\n", ++ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation, ++ atomic_read(&sbinfo->si_kobj.kref.refcount)); ++ for (bindex = 0; bindex <= sbinfo->si_bend; bindex++) ++ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_dbg_sleep_jiffy(int jiffy) ++{ ++ while (jiffy) ++ jiffy = schedule_timeout_uninterruptible(jiffy); ++} ++ ++void au_dbg_iattr(struct iattr *ia) ++{ ++#define AuBit(name) if (ia->ia_valid & ATTR_ ## name) \ ++ dpri(#name "\n") ++ AuBit(MODE); ++ AuBit(UID); ++ AuBit(GID); ++ AuBit(SIZE); ++ AuBit(ATIME); ++ AuBit(MTIME); ++ AuBit(CTIME); ++ AuBit(ATIME_SET); ++ AuBit(MTIME_SET); ++ AuBit(FORCE); ++ AuBit(ATTR_FLAG); ++ AuBit(KILL_SUID); ++ AuBit(KILL_SGID); ++ AuBit(FILE); ++ AuBit(KILL_PRIV); ++ AuBit(OPEN); ++ AuBit(TIMES_SET); ++#undef AuBit ++ dpri("ia_file %p\n", ia->ia_file); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen) ++{ ++ struct dentry *parent; ++ ++ parent = dget_parent(dentry); ++ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode) ++ || IS_ROOT(dentry) ++ || au_digen(parent) != sigen); ++ dput(parent); ++} ++ ++void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen) ++{ ++ struct dentry *parent; ++ ++ parent = dget_parent(dentry); ++ AuDebugOn(S_ISDIR(dentry->d_inode->i_mode) ++ || au_digen(parent) != sigen); ++ dput(parent); ++} ++ ++void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen) ++{ ++ int err, i, j; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry **dentries; ++ ++ err = au_dpages_init(&dpages, GFP_NOFS); ++ AuDebugOn(err); ++ err = au_dcsub_pages_rev(&dpages, parent, /*do_include*/1, NULL, NULL); ++ AuDebugOn(err); ++ for (i = dpages.ndpage - 1; !err && i >= 0; i--) { ++ dpage = dpages.dpages + i; ++ dentries = dpage->dentries; ++ for (j = dpage->ndentry - 1; !err && j >= 0; j--) ++ AuDebugOn(au_digen(dentries[j]) != sigen); ++ } ++ au_dpages_free(&dpages); ++} ++ ++void au_dbg_verify_hf(struct au_finfo *finfo) ++{ ++ struct au_hfile *hf; ++ aufs_bindex_t bend, bindex; ++ ++ if (finfo->fi_bstart >= 0) { ++ bend = finfo->fi_bend; ++ for (bindex = finfo->fi_bstart; bindex <= bend; bindex++) { ++ hf = finfo->fi_hfile + bindex; ++ AuDebugOn(hf->hf_file || hf->hf_br); ++ } ++ } ++} ++ ++void au_dbg_verify_kthread(void) ++{ ++ if (au_test_wkq(current)) { ++ au_dbg_blocked(); ++ BUG(); ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_debug_sbinfo_init(struct au_sbinfo *sbinfo __maybe_unused) ++{ ++#ifdef AuForceNoPlink ++ au_opt_clr(sbinfo->si_mntflags, PLINK); ++#endif ++#ifdef AuForceNoXino ++ au_opt_clr(sbinfo->si_mntflags, XINO); ++#endif ++#ifdef AuForceNoRefrof ++ au_opt_clr(sbinfo->si_mntflags, REFROF); ++#endif ++#ifdef AuForceHinotify ++ au_opt_set_udba(sbinfo->si_mntflags, UDBA_HINOTIFY); ++#endif ++#ifdef AuForceRd0 ++ sbinfo->si_rdblk = 0; ++ sbinfo->si_rdhash = 0; ++#endif ++} ++ ++int __init au_debug_init(void) ++{ ++ aufs_bindex_t bindex; ++ struct au_vdir_destr destr; ++ ++ bindex = -1; ++ AuDebugOn(bindex >= 0); ++ ++ destr.len = -1; ++ AuDebugOn(destr.len < NAME_MAX); ++ ++#ifdef CONFIG_4KSTACKS ++ AuWarn("CONFIG_4KSTACKS is defined.\n"); ++#endif ++ ++#ifdef AuForceNoBrs ++ sysaufs_brs = 0; ++#endif ++ ++ return 0; ++} +diff --git a/fs/aufs/debug.h b/fs/aufs/debug.h +new file mode 100644 +index 0000000..dab15f7 +--- /dev/null ++++ b/fs/aufs/debug.h +@@ -0,0 +1,260 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * debug print functions ++ */ ++ ++#ifndef __AUFS_DEBUG_H__ ++#define __AUFS_DEBUG_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++/* #include */ ++/* #include */ ++/* #include */ ++#include ++/* #include */ ++/* #include */ ++#include ++#include ++ ++#ifdef CONFIG_AUFS_DEBUG ++#define AuDebugOn(a) BUG_ON(a) ++ ++/* module parameter */ ++extern int aufs_debug; ++static inline void au_debug(int n) ++{ ++ aufs_debug = n; ++ smp_mb(); ++} ++ ++static inline int au_debug_test(void) ++{ ++ return aufs_debug; ++} ++#else ++#define AuDebugOn(a) do {} while (0) ++#define au_debug() do {} while (0) ++static inline int au_debug_test(void) ++{ ++ return 0; ++} ++#endif /* CONFIG_AUFS_DEBUG */ ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* debug print */ ++ ++#define AuDpri(lvl, fmt, arg...) \ ++ printk(lvl AUFS_NAME " %s:%d:%s[%d]: " fmt, \ ++ __func__, __LINE__, current->comm, current->pid, ##arg) ++#define AuDbg(fmt, arg...) do { \ ++ if (au_debug_test()) \ ++ AuDpri(KERN_DEBUG, "DEBUG: " fmt, ##arg); \ ++} while (0) ++#define AuLabel(l) AuDbg(#l "\n") ++#define AuInfo(fmt, arg...) AuDpri(KERN_INFO, fmt, ##arg) ++#define AuWarn(fmt, arg...) AuDpri(KERN_WARNING, fmt, ##arg) ++#define AuErr(fmt, arg...) AuDpri(KERN_ERR, fmt, ##arg) ++#define AuIOErr(fmt, arg...) AuErr("I/O Error, " fmt, ##arg) ++#define AuWarn1(fmt, arg...) do { \ ++ static unsigned char _c; \ ++ if (!_c++) \ ++ AuWarn(fmt, ##arg); \ ++} while (0) ++ ++#define AuErr1(fmt, arg...) do { \ ++ static unsigned char _c; \ ++ if (!_c++) \ ++ AuErr(fmt, ##arg); \ ++} while (0) ++ ++#define AuIOErr1(fmt, arg...) do { \ ++ static unsigned char _c; \ ++ if (!_c++) \ ++ AuIOErr(fmt, ##arg); \ ++} while (0) ++ ++#define AuUnsupportMsg "This operation is not supported." \ ++ " Please report this application to aufs-users ML." ++#define AuUnsupport(fmt, args...) do { \ ++ AuErr(AuUnsupportMsg "\n" fmt, ##args); \ ++ dump_stack(); \ ++} while (0) ++ ++#define AuTraceErr(e) do { \ ++ if (unlikely((e) < 0)) \ ++ AuDbg("err %d\n", (int)(e)); \ ++} while (0) ++ ++#define AuTraceErrPtr(p) do { \ ++ if (IS_ERR(p)) \ ++ AuDbg("err %ld\n", PTR_ERR(p)); \ ++} while (0) ++ ++/* dirty macros for debug print, use with "%.*s" and caution */ ++#define AuLNPair(qstr) (qstr)->len, (qstr)->name ++#define AuDLNPair(d) AuLNPair(&(d)->d_name) ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_sbinfo; ++struct au_finfo; ++struct dentry; ++#ifdef CONFIG_AUFS_DEBUG ++extern char *au_plevel; ++struct au_nhash; ++void au_dpri_whlist(struct au_nhash *whlist); ++struct au_vdir; ++void au_dpri_vdir(struct au_vdir *vdir); ++struct inode; ++void au_dpri_inode(struct inode *inode); ++void au_dpri_dentry(struct dentry *dentry); ++struct file; ++void au_dpri_file(struct file *filp); ++struct super_block; ++void au_dpri_sb(struct super_block *sb); ++ ++void au_dbg_sleep_jiffy(int jiffy); ++struct iattr; ++void au_dbg_iattr(struct iattr *ia); ++ ++void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen); ++void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen); ++void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen); ++void au_dbg_verify_hf(struct au_finfo *finfo); ++void au_dbg_verify_kthread(void); ++ ++int __init au_debug_init(void); ++void au_debug_sbinfo_init(struct au_sbinfo *sbinfo); ++#define AuDbgWhlist(w) do { \ ++ AuDbg(#w "\n"); \ ++ au_dpri_whlist(w); \ ++} while (0) ++ ++#define AuDbgVdir(v) do { \ ++ AuDbg(#v "\n"); \ ++ au_dpri_vdir(v); \ ++} while (0) ++ ++#define AuDbgInode(i) do { \ ++ AuDbg(#i "\n"); \ ++ au_dpri_inode(i); \ ++} while (0) ++ ++#define AuDbgDentry(d) do { \ ++ AuDbg(#d "\n"); \ ++ au_dpri_dentry(d); \ ++} while (0) ++ ++#define AuDbgFile(f) do { \ ++ AuDbg(#f "\n"); \ ++ au_dpri_file(f); \ ++} while (0) ++ ++#define AuDbgSb(sb) do { \ ++ AuDbg(#sb "\n"); \ ++ au_dpri_sb(sb); \ ++} while (0) ++ ++#define AuDbgSleep(sec) do { \ ++ AuDbg("sleep %d sec\n", sec); \ ++ ssleep(sec); \ ++} while (0) ++ ++#define AuDbgSleepJiffy(jiffy) do { \ ++ AuDbg("sleep %d jiffies\n", jiffy); \ ++ au_dbg_sleep_jiffy(jiffy); \ ++} while (0) ++ ++#define AuDbgIAttr(ia) do { \ ++ AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \ ++ au_dbg_iattr(ia); \ ++} while (0) ++#else ++static inline void au_dbg_verify_dir_parent(struct dentry *dentry, ++ unsigned int sigen) ++{ ++ /* empty */ ++} ++static inline void au_dbg_verify_nondir_parent(struct dentry *dentry, ++ unsigned int sigen) ++{ ++ /* empty */ ++} ++static inline void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen) ++{ ++ /* empty */ ++} ++static inline void au_dbg_verify_hf(struct au_finfo *finfo) ++{ ++ /* empty */ ++} ++static inline void au_dbg_verify_kthread(void) ++{ ++ /* empty */ ++} ++ ++static inline int au_debug_init(void) ++{ ++ return 0; ++} ++static inline void au_debug_sbinfo_init(struct au_sbinfo *sbinfo) ++{ ++ /* empty */ ++} ++#define AuDbgWhlist(w) do {} while (0) ++#define AuDbgVdir(v) do {} while (0) ++#define AuDbgInode(i) do {} while (0) ++#define AuDbgDentry(d) do {} while (0) ++#define AuDbgFile(f) do {} while (0) ++#define AuDbgSb(sb) do {} while (0) ++#define AuDbgSleep(sec) do {} while (0) ++#define AuDbgSleepJiffy(jiffy) do {} while (0) ++#define AuDbgIAttr(ia) do {} while (0) ++#endif /* CONFIG_AUFS_DEBUG */ ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_MAGIC_SYSRQ ++int __init au_sysrq_init(void); ++void au_sysrq_fin(void); ++ ++#ifdef CONFIG_HW_CONSOLE ++#define au_dbg_blocked() do { \ ++ WARN_ON(1); \ ++ handle_sysrq('w', vc_cons[fg_console].d->vc_tty); \ ++} while (0) ++#else ++#define au_dbg_blocked() do {} while (0) ++#endif ++ ++#else ++static inline int au_sysrq_init(void) ++{ ++ return 0; ++} ++#define au_sysrq_fin() do {} while (0) ++#define au_dbg_blocked() do {} while (0) ++#endif /* CONFIG_AUFS_MAGIC_SYSRQ */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_DEBUG_H__ */ +diff --git a/fs/aufs/dentry.c b/fs/aufs/dentry.c +new file mode 100644 +index 0000000..a428d9c +--- /dev/null ++++ b/fs/aufs/dentry.c +@@ -0,0 +1,880 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * lookup and dentry operations ++ */ ++ ++#include ++#include "aufs.h" ++ ++static void au_h_nd(struct nameidata *h_nd, struct nameidata *nd) ++{ ++ if (nd) { ++ *h_nd = *nd; ++ ++ /* ++ * gave up supporting LOOKUP_CREATE/OPEN for lower fs, ++ * due to whiteout and branch permission. ++ */ ++ h_nd->flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE ++ | LOOKUP_FOLLOW); ++ /* unnecessary? */ ++ h_nd->intent.open.file = NULL; ++ } else ++ memset(h_nd, 0, sizeof(*h_nd)); ++} ++ ++struct au_lkup_one_args { ++ struct dentry **errp; ++ struct qstr *name; ++ struct dentry *h_parent; ++ struct au_branch *br; ++ struct nameidata *nd; ++}; ++ ++struct dentry *au_lkup_one(struct qstr *name, struct dentry *h_parent, ++ struct au_branch *br, struct nameidata *nd) ++{ ++ struct dentry *h_dentry; ++ int err; ++ struct nameidata h_nd; ++ ++ if (au_test_fs_null_nd(h_parent->d_sb)) ++ return vfsub_lookup_one_len(name->name, h_parent, name->len); ++ ++ au_h_nd(&h_nd, nd); ++ h_nd.path.dentry = h_parent; ++ h_nd.path.mnt = br->br_mnt; ++ ++ err = __lookup_one_len(name->name, &h_nd.last, NULL, name->len); ++ h_dentry = ERR_PTR(err); ++ if (!err) { ++ path_get(&h_nd.path); ++ h_dentry = vfsub_lookup_hash(&h_nd); ++ path_put(&h_nd.path); ++ } ++ ++ return h_dentry; ++} ++ ++static void au_call_lkup_one(void *args) ++{ ++ struct au_lkup_one_args *a = args; ++ *a->errp = au_lkup_one(a->name, a->h_parent, a->br, a->nd); ++} ++ ++#define AuLkup_ALLOW_NEG 1 ++#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name) ++#define au_fset_lkup(flags, name) { (flags) |= AuLkup_##name; } ++#define au_fclr_lkup(flags, name) { (flags) &= ~AuLkup_##name; } ++ ++struct au_do_lookup_args { ++ unsigned int flags; ++ mode_t type; ++ struct nameidata *nd; ++}; ++ ++/* ++ * returns positive/negative dentry, NULL or an error. ++ * NULL means whiteout-ed or not-found. ++ */ ++static struct dentry* ++au_do_lookup(struct dentry *h_parent, struct dentry *dentry, ++ aufs_bindex_t bindex, struct qstr *wh_name, ++ struct au_do_lookup_args *args) ++{ ++ struct dentry *h_dentry; ++ struct inode *h_inode, *inode; ++ struct qstr *name; ++ struct au_branch *br; ++ int wh_found, opq; ++ unsigned char wh_able; ++ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG); ++ ++ name = &dentry->d_name; ++ wh_found = 0; ++ br = au_sbr(dentry->d_sb, bindex); ++ wh_able = !!au_br_whable(br->br_perm); ++ if (wh_able) ++ wh_found = au_wh_test(h_parent, wh_name, br, /*try_sio*/0); ++ h_dentry = ERR_PTR(wh_found); ++ if (!wh_found) ++ goto real_lookup; ++ if (unlikely(wh_found < 0)) ++ goto out; ++ ++ /* We found a whiteout */ ++ /* au_set_dbend(dentry, bindex); */ ++ au_set_dbwh(dentry, bindex); ++ if (!allow_neg) ++ return NULL; /* success */ ++ ++ real_lookup: ++ h_dentry = au_lkup_one(name, h_parent, br, args->nd); ++ if (IS_ERR(h_dentry)) ++ goto out; ++ ++ h_inode = h_dentry->d_inode; ++ if (!h_inode) { ++ if (!allow_neg) ++ goto out_neg; ++ } else if (wh_found ++ || (args->type && args->type != (h_inode->i_mode & S_IFMT))) ++ goto out_neg; ++ ++ if (au_dbend(dentry) <= bindex) ++ au_set_dbend(dentry, bindex); ++ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry)) ++ au_set_dbstart(dentry, bindex); ++ au_set_h_dptr(dentry, bindex, h_dentry); ++ ++ inode = dentry->d_inode; ++ if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able ++ || (inode && !S_ISDIR(inode->i_mode))) ++ goto out; /* success */ ++ ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ opq = au_diropq_test(h_dentry, br); ++ mutex_unlock(&h_inode->i_mutex); ++ if (opq > 0) ++ au_set_dbdiropq(dentry, bindex); ++ else if (unlikely(opq < 0)) { ++ au_set_h_dptr(dentry, bindex, NULL); ++ h_dentry = ERR_PTR(opq); ++ } ++ goto out; ++ ++ out_neg: ++ dput(h_dentry); ++ h_dentry = NULL; ++ out: ++ return h_dentry; ++} ++ ++static int au_test_shwh(struct super_block *sb, const struct qstr *name) ++{ ++ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH) ++ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))) ++ return -EPERM; ++ return 0; ++} ++ ++/* ++ * returns the number of lower positive dentries, ++ * otherwise an error. ++ * can be called at unlinking with @type is zero. ++ */ ++int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type, ++ struct nameidata *nd) ++{ ++ int npositive, err; ++ aufs_bindex_t bindex, btail, bdiropq; ++ unsigned char isdir; ++ struct qstr whname; ++ struct au_do_lookup_args args = { ++ .flags = 0, ++ .type = type, ++ .nd = nd ++ }; ++ const struct qstr *name = &dentry->d_name; ++ struct dentry *parent; ++ struct inode *inode; ++ ++ parent = dget_parent(dentry); ++ err = au_test_shwh(dentry->d_sb, name); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_wh_name_alloc(&whname, name); ++ if (unlikely(err)) ++ goto out; ++ ++ inode = dentry->d_inode; ++ isdir = !!(inode && S_ISDIR(inode->i_mode)); ++ if (!type) ++ au_fset_lkup(args.flags, ALLOW_NEG); ++ ++ npositive = 0; ++ btail = au_dbtaildir(parent); ++ for (bindex = bstart; bindex <= btail; bindex++) { ++ struct dentry *h_parent, *h_dentry; ++ struct inode *h_inode, *h_dir; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry) { ++ if (h_dentry->d_inode) ++ npositive++; ++ if (type != S_IFDIR) ++ break; ++ continue; ++ } ++ h_parent = au_h_dptr(parent, bindex); ++ if (!h_parent) ++ continue; ++ h_dir = h_parent->d_inode; ++ if (!h_dir || !S_ISDIR(h_dir->i_mode)) ++ continue; ++ ++ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); ++ h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname, ++ &args); ++ mutex_unlock(&h_dir->i_mutex); ++ err = PTR_ERR(h_dentry); ++ if (IS_ERR(h_dentry)) ++ goto out_wh; ++ au_fclr_lkup(args.flags, ALLOW_NEG); ++ ++ if (au_dbwh(dentry) >= 0) ++ break; ++ if (!h_dentry) ++ continue; ++ h_inode = h_dentry->d_inode; ++ if (!h_inode) ++ continue; ++ npositive++; ++ if (!args.type) ++ args.type = h_inode->i_mode & S_IFMT; ++ if (args.type != S_IFDIR) ++ break; ++ else if (isdir) { ++ /* the type of lower may be different */ ++ bdiropq = au_dbdiropq(dentry); ++ if (bdiropq >= 0 && bdiropq <= bindex) ++ break; ++ } ++ } ++ ++ if (npositive) { ++ AuLabel(positive); ++ au_update_dbstart(dentry); ++ } ++ err = npositive; ++ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE) ++ && au_dbstart(dentry) < 0)) ++ /* both of real entry and whiteout found */ ++ err = -EIO; ++ ++ out_wh: ++ kfree(whname.name); ++ out: ++ dput(parent); ++ return err; ++} ++ ++struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent, ++ struct au_branch *br) ++{ ++ struct dentry *dentry; ++ int wkq_err; ++ ++ if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC)) ++ dentry = au_lkup_one(name, parent, br, /*nd*/NULL); ++ else { ++ struct au_lkup_one_args args = { ++ .errp = &dentry, ++ .name = name, ++ .h_parent = parent, ++ .br = br, ++ .nd = NULL ++ }; ++ ++ wkq_err = au_wkq_wait(au_call_lkup_one, &args); ++ if (unlikely(wkq_err)) ++ dentry = ERR_PTR(wkq_err); ++ } ++ ++ return dentry; ++} ++ ++/* ++ * lookup @dentry on @bindex which should be negative. ++ */ ++int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ int err; ++ struct dentry *parent, *h_parent, *h_dentry; ++ struct qstr *name; ++ ++ name = &dentry->d_name; ++ parent = dget_parent(dentry); ++ h_parent = au_h_dptr(parent, bindex); ++ h_dentry = au_sio_lkup_one(name, h_parent, ++ au_sbr(dentry->d_sb, bindex)); ++ err = PTR_ERR(h_dentry); ++ if (IS_ERR(h_dentry)) ++ goto out; ++ if (unlikely(h_dentry->d_inode)) { ++ err = -EIO; ++ AuIOErr("b%d %.*s should be negative.\n", ++ bindex, AuDLNPair(h_dentry)); ++ dput(h_dentry); ++ goto out; ++ } ++ ++ if (bindex < au_dbstart(dentry)) ++ au_set_dbstart(dentry, bindex); ++ if (au_dbend(dentry) < bindex) ++ au_set_dbend(dentry, bindex); ++ au_set_h_dptr(dentry, bindex, h_dentry); ++ err = 0; ++ ++ out: ++ dput(parent); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* subset of struct inode */ ++struct au_iattr { ++ unsigned long i_ino; ++ /* unsigned int i_nlink; */ ++ uid_t i_uid; ++ gid_t i_gid; ++ u64 i_version; ++/* ++ loff_t i_size; ++ blkcnt_t i_blocks; ++*/ ++ umode_t i_mode; ++}; ++ ++static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode) ++{ ++ ia->i_ino = h_inode->i_ino; ++ /* ia->i_nlink = h_inode->i_nlink; */ ++ ia->i_uid = h_inode->i_uid; ++ ia->i_gid = h_inode->i_gid; ++ ia->i_version = h_inode->i_version; ++/* ++ ia->i_size = h_inode->i_size; ++ ia->i_blocks = h_inode->i_blocks; ++*/ ++ ia->i_mode = (h_inode->i_mode & S_IFMT); ++} ++ ++static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode) ++{ ++ return ia->i_ino != h_inode->i_ino ++ /* || ia->i_nlink != h_inode->i_nlink */ ++ || ia->i_uid != h_inode->i_uid ++ || ia->i_gid != h_inode->i_gid ++ || ia->i_version != h_inode->i_version ++/* ++ || ia->i_size != h_inode->i_size ++ || ia->i_blocks != h_inode->i_blocks ++*/ ++ || ia->i_mode != (h_inode->i_mode & S_IFMT); ++} ++ ++static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent, ++ struct au_branch *br) ++{ ++ int err; ++ struct au_iattr ia; ++ struct inode *h_inode; ++ struct dentry *h_d; ++ struct super_block *h_sb; ++ ++ err = 0; ++ memset(&ia, -1, sizeof(ia)); ++ h_sb = h_dentry->d_sb; ++ h_inode = h_dentry->d_inode; ++ if (h_inode) ++ au_iattr_save(&ia, h_inode); ++ else if (au_test_nfs(h_sb) || au_test_fuse(h_sb)) ++ /* nfs d_revalidate may return 0 for negative dentry */ ++ /* fuse d_revalidate always return 0 for negative dentry */ ++ goto out; ++ ++ /* main purpose is namei.c:cached_lookup() and d_revalidate */ ++ h_d = au_lkup_one(&h_dentry->d_name, h_parent, br, /*nd*/NULL); ++ err = PTR_ERR(h_d); ++ if (IS_ERR(h_d)) ++ goto out; ++ ++ err = 0; ++ if (unlikely(h_d != h_dentry ++ || h_d->d_inode != h_inode ++ || (h_inode && au_iattr_test(&ia, h_inode)))) ++ err = au_busy_or_stale(); ++ dput(h_d); ++ ++ out: ++ AuTraceErr(err); ++ return err; ++} ++ ++int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir, ++ struct dentry *h_parent, struct au_branch *br) ++{ ++ int err; ++ ++ err = 0; ++ if (udba == AuOpt_UDBA_REVAL) { ++ IMustLock(h_dir); ++ err = (h_dentry->d_parent->d_inode != h_dir); ++ } else if (udba == AuOpt_UDBA_HINOTIFY) ++ err = au_h_verify_dentry(h_dentry, h_parent, br); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void au_do_refresh_hdentry(struct au_hdentry *p, struct au_dinfo *dinfo, ++ struct dentry *parent) ++{ ++ struct dentry *h_d, *h_dp; ++ struct au_hdentry tmp, *q; ++ struct super_block *sb; ++ aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq; ++ ++ AuRwMustWriteLock(&dinfo->di_rwsem); ++ ++ bend = dinfo->di_bend; ++ bwh = dinfo->di_bwh; ++ bdiropq = dinfo->di_bdiropq; ++ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) { ++ h_d = p->hd_dentry; ++ if (!h_d) ++ continue; ++ ++ h_dp = dget_parent(h_d); ++ if (h_dp == au_h_dptr(parent, bindex)) { ++ dput(h_dp); ++ continue; ++ } ++ ++ new_bindex = au_find_dbindex(parent, h_dp); ++ dput(h_dp); ++ if (dinfo->di_bwh == bindex) ++ bwh = new_bindex; ++ if (dinfo->di_bdiropq == bindex) ++ bdiropq = new_bindex; ++ if (new_bindex < 0) { ++ au_hdput(p); ++ p->hd_dentry = NULL; ++ continue; ++ } ++ ++ /* swap two lower dentries, and loop again */ ++ q = dinfo->di_hdentry + new_bindex; ++ tmp = *q; ++ *q = *p; ++ *p = tmp; ++ if (tmp.hd_dentry) { ++ bindex--; ++ p--; ++ } ++ } ++ ++ sb = parent->d_sb; ++ dinfo->di_bwh = -1; ++ if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh)) ++ dinfo->di_bwh = bwh; ++ ++ dinfo->di_bdiropq = -1; ++ if (bdiropq >= 0 ++ && bdiropq <= au_sbend(sb) ++ && au_sbr_whable(sb, bdiropq)) ++ dinfo->di_bdiropq = bdiropq; ++ ++ bend = au_dbend(parent); ++ p = dinfo->di_hdentry; ++ for (bindex = 0; bindex <= bend; bindex++, p++) ++ if (p->hd_dentry) { ++ dinfo->di_bstart = bindex; ++ break; ++ } ++ ++ p = dinfo->di_hdentry + bend; ++ for (bindex = bend; bindex >= 0; bindex--, p--) ++ if (p->hd_dentry) { ++ dinfo->di_bend = bindex; ++ break; ++ } ++} ++ ++/* ++ * returns the number of found lower positive dentries, ++ * otherwise an error. ++ */ ++int au_refresh_hdentry(struct dentry *dentry, mode_t type) ++{ ++ int npositive, err; ++ unsigned int sigen; ++ aufs_bindex_t bstart; ++ struct au_dinfo *dinfo; ++ struct super_block *sb; ++ struct dentry *parent; ++ ++ DiMustWriteLock(dentry); ++ ++ sb = dentry->d_sb; ++ AuDebugOn(IS_ROOT(dentry)); ++ sigen = au_sigen(sb); ++ parent = dget_parent(dentry); ++ AuDebugOn(au_digen(parent) != sigen ++ || au_iigen(parent->d_inode) != sigen); ++ ++ dinfo = au_di(dentry); ++ err = au_di_realloc(dinfo, au_sbend(sb) + 1); ++ npositive = err; ++ if (unlikely(err)) ++ goto out; ++ au_do_refresh_hdentry(dinfo->di_hdentry + dinfo->di_bstart, dinfo, ++ parent); ++ ++ npositive = 0; ++ bstart = au_dbstart(parent); ++ if (type != S_IFDIR && dinfo->di_bstart == bstart) ++ goto out_dgen; /* success */ ++ ++ npositive = au_lkup_dentry(dentry, bstart, type, /*nd*/NULL); ++ if (npositive < 0) ++ goto out; ++ if (dinfo->di_bwh >= 0 && dinfo->di_bwh <= dinfo->di_bstart) ++ d_drop(dentry); ++ ++ out_dgen: ++ au_update_digen(dentry); ++ out: ++ dput(parent); ++ AuTraceErr(npositive); ++ return npositive; ++} ++ ++static noinline_for_stack ++int au_do_h_d_reval(struct dentry *h_dentry, struct nameidata *nd, ++ struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ int err, valid; ++ int (*reval)(struct dentry *, struct nameidata *); ++ ++ err = 0; ++ reval = NULL; ++ if (h_dentry->d_op) ++ reval = h_dentry->d_op->d_revalidate; ++ if (!reval) ++ goto out; ++ ++ AuDbg("b%d\n", bindex); ++ if (au_test_fs_null_nd(h_dentry->d_sb)) ++ /* it may return tri-state */ ++ valid = reval(h_dentry, NULL); ++ else { ++ struct nameidata h_nd; ++ int locked; ++ struct dentry *parent; ++ ++ au_h_nd(&h_nd, nd); ++ parent = nd->path.dentry; ++ locked = (nd && nd->path.dentry != dentry); ++ if (locked) ++ di_read_lock_parent(parent, AuLock_IR); ++ BUG_ON(bindex > au_dbend(parent)); ++ h_nd.path.dentry = au_h_dptr(parent, bindex); ++ BUG_ON(!h_nd.path.dentry); ++ h_nd.path.mnt = au_sbr(parent->d_sb, bindex)->br_mnt; ++ path_get(&h_nd.path); ++ valid = reval(h_dentry, &h_nd); ++ path_put(&h_nd.path); ++ if (locked) ++ di_read_unlock(parent, AuLock_IR); ++ } ++ ++ if (unlikely(valid < 0)) ++ err = valid; ++ else if (!valid) ++ err = -EINVAL; ++ ++ out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* todo: remove this */ ++static int h_d_revalidate(struct dentry *dentry, struct inode *inode, ++ struct nameidata *nd, int do_udba) ++{ ++ int err; ++ umode_t mode, h_mode; ++ aufs_bindex_t bindex, btail, bstart, ibs, ibe; ++ unsigned char plus, unhashed, is_root, h_plus; ++ struct inode *first, *h_inode, *h_cached_inode; ++ struct dentry *h_dentry; ++ struct qstr *name, *h_name; ++ ++ err = 0; ++ plus = 0; ++ mode = 0; ++ first = NULL; ++ ibs = -1; ++ ibe = -1; ++ unhashed = !!d_unhashed(dentry); ++ is_root = !!IS_ROOT(dentry); ++ name = &dentry->d_name; ++ ++ /* ++ * Theoretically, REVAL test should be unnecessary in case of INOTIFY. ++ * But inotify doesn't fire some necessary events, ++ * IN_ATTRIB for atime/nlink/pageio ++ * IN_DELETE for NFS dentry ++ * Let's do REVAL test too. ++ */ ++ if (do_udba && inode) { ++ mode = (inode->i_mode & S_IFMT); ++ plus = (inode->i_nlink > 0); ++ first = au_h_iptr(inode, au_ibstart(inode)); ++ ibs = au_ibstart(inode); ++ ibe = au_ibend(inode); ++ } ++ ++ bstart = au_dbstart(dentry); ++ btail = bstart; ++ if (inode && S_ISDIR(inode->i_mode)) ++ btail = au_dbtaildir(dentry); ++ for (bindex = bstart; bindex <= btail; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ ++ AuDbg("b%d, %.*s\n", bindex, AuDLNPair(h_dentry)); ++ h_name = &h_dentry->d_name; ++ if (unlikely(do_udba ++ && !is_root ++ && (unhashed != !!d_unhashed(h_dentry) ++ || name->len != h_name->len ++ || memcmp(name->name, h_name->name, name->len)) ++ )) { ++ AuDbg("unhash 0x%x 0x%x, %.*s %.*s\n", ++ unhashed, d_unhashed(h_dentry), ++ AuDLNPair(dentry), AuDLNPair(h_dentry)); ++ goto err; ++ } ++ ++ err = au_do_h_d_reval(h_dentry, nd, dentry, bindex); ++ if (unlikely(err)) ++ /* do not goto err, to keep the errno */ ++ break; ++ ++ /* todo: plink too? */ ++ if (!do_udba) ++ continue; ++ ++ /* UDBA tests */ ++ h_inode = h_dentry->d_inode; ++ if (unlikely(!!inode != !!h_inode)) ++ goto err; ++ ++ h_plus = plus; ++ h_mode = mode; ++ h_cached_inode = h_inode; ++ if (h_inode) { ++ h_mode = (h_inode->i_mode & S_IFMT); ++ h_plus = (h_inode->i_nlink > 0); ++ } ++ if (inode && ibs <= bindex && bindex <= ibe) ++ h_cached_inode = au_h_iptr(inode, bindex); ++ ++ if (unlikely(plus != h_plus ++ || mode != h_mode ++ || h_cached_inode != h_inode)) ++ goto err; ++ continue; ++ ++ err: ++ err = -EINVAL; ++ break; ++ } ++ ++ return err; ++} ++ ++static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen) ++{ ++ int err; ++ struct dentry *parent; ++ struct inode *inode; ++ ++ inode = dentry->d_inode; ++ if (au_digen(dentry) == sigen && au_iigen(inode) == sigen) ++ return 0; ++ ++ parent = dget_parent(dentry); ++ di_read_lock_parent(parent, AuLock_IR); ++ AuDebugOn(au_digen(parent) != sigen ++ || au_iigen(parent->d_inode) != sigen); ++ au_dbg_verify_gen(parent, sigen); ++ ++ /* returns a number of positive dentries */ ++ err = au_refresh_hdentry(dentry, inode->i_mode & S_IFMT); ++ if (err >= 0) ++ err = au_refresh_hinode(inode, dentry); ++ ++ di_read_unlock(parent, AuLock_IR); ++ dput(parent); ++ return err; ++} ++ ++int au_reval_dpath(struct dentry *dentry, unsigned int sigen) ++{ ++ int err; ++ struct dentry *d, *parent; ++ struct inode *inode; ++ ++ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS)) ++ return simple_reval_dpath(dentry, sigen); ++ ++ /* slow loop, keep it simple and stupid */ ++ /* cf: au_cpup_dirs() */ ++ err = 0; ++ parent = NULL; ++ while (au_digen(dentry) != sigen ++ || au_iigen(dentry->d_inode) != sigen) { ++ d = dentry; ++ while (1) { ++ dput(parent); ++ parent = dget_parent(d); ++ if (au_digen(parent) == sigen ++ && au_iigen(parent->d_inode) == sigen) ++ break; ++ d = parent; ++ } ++ ++ inode = d->d_inode; ++ if (d != dentry) ++ di_write_lock_child(d); ++ ++ /* someone might update our dentry while we were sleeping */ ++ if (au_digen(d) != sigen || au_iigen(d->d_inode) != sigen) { ++ di_read_lock_parent(parent, AuLock_IR); ++ /* returns a number of positive dentries */ ++ err = au_refresh_hdentry(d, inode->i_mode & S_IFMT); ++ if (err >= 0) ++ err = au_refresh_hinode(inode, d); ++ di_read_unlock(parent, AuLock_IR); ++ } ++ ++ if (d != dentry) ++ di_write_unlock(d); ++ dput(parent); ++ if (unlikely(err)) ++ break; ++ } ++ ++ return err; ++} ++ ++/* ++ * if valid returns 1, otherwise 0. ++ */ ++static int aufs_d_revalidate(struct dentry *dentry, struct nameidata *nd) ++{ ++ int valid, err; ++ unsigned int sigen; ++ unsigned char do_udba; ++ struct super_block *sb; ++ struct inode *inode; ++ ++ err = -EINVAL; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW); ++ sigen = au_sigen(sb); ++ if (au_digen(dentry) != sigen) { ++ AuDebugOn(IS_ROOT(dentry)); ++ if (inode) ++ err = au_reval_dpath(dentry, sigen); ++ if (unlikely(err)) ++ goto out_dgrade; ++ AuDebugOn(au_digen(dentry) != sigen); ++ } ++ if (inode && au_iigen(inode) != sigen) { ++ AuDebugOn(IS_ROOT(dentry)); ++ err = au_refresh_hinode(inode, dentry); ++ if (unlikely(err)) ++ goto out_dgrade; ++ AuDebugOn(au_iigen(inode) != sigen); ++ } ++ di_downgrade_lock(dentry, AuLock_IR); ++ ++ AuDebugOn(au_digen(dentry) != sigen); ++ AuDebugOn(inode && au_iigen(inode) != sigen); ++ err = -EINVAL; ++ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE); ++ if (do_udba && inode) { ++ aufs_bindex_t bstart = au_ibstart(inode); ++ ++ if (bstart >= 0 ++ && au_test_higen(inode, au_h_iptr(inode, bstart))) ++ goto out; ++ } ++ ++ err = h_d_revalidate(dentry, inode, nd, do_udba); ++ if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) ++ /* both of real entry and whiteout found */ ++ err = -EIO; ++ goto out; ++ ++ out_dgrade: ++ di_downgrade_lock(dentry, AuLock_IR); ++ out: ++ au_store_oflag(nd, inode); ++ aufs_read_unlock(dentry, AuLock_IR); ++ AuTraceErr(err); ++ valid = !err; ++ if (!valid) ++ AuDbg("%.*s invalid\n", AuDLNPair(dentry)); ++ return valid; ++} ++ ++static void aufs_d_release(struct dentry *dentry) ++{ ++ struct au_dinfo *dinfo; ++ aufs_bindex_t bend, bindex; ++ ++ dinfo = dentry->d_fsdata; ++ if (!dinfo) ++ return; ++ ++ /* dentry may not be revalidated */ ++ bindex = dinfo->di_bstart; ++ if (bindex >= 0) { ++ struct au_hdentry *p; ++ ++ bend = dinfo->di_bend; ++ p = dinfo->di_hdentry + bindex; ++ while (bindex++ <= bend) { ++ if (p->hd_dentry) ++ au_hdput(p); ++ p++; ++ } ++ } ++ kfree(dinfo->di_hdentry); ++ AuRwDestroy(&dinfo->di_rwsem); ++ au_cache_free_dinfo(dinfo); ++ au_hin_di_reinit(dentry); ++} ++ ++struct dentry_operations aufs_dop = { ++ .d_revalidate = aufs_d_revalidate, ++ .d_release = aufs_d_release ++}; +diff --git a/fs/aufs/dentry.h b/fs/aufs/dentry.h +new file mode 100644 +index 0000000..b1f9a6e +--- /dev/null ++++ b/fs/aufs/dentry.h +@@ -0,0 +1,231 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * lookup and dentry operations ++ */ ++ ++#ifndef __AUFS_DENTRY_H__ ++#define __AUFS_DENTRY_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include "rwsem.h" ++ ++/* make a single member structure for future use */ ++/* todo: remove this structure */ ++struct au_hdentry { ++ struct dentry *hd_dentry; ++}; ++ ++struct au_dinfo { ++ atomic_t di_generation; ++ ++ struct au_rwsem di_rwsem; ++ aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq; ++ struct au_hdentry *di_hdentry; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* dentry.c */ ++extern struct dentry_operations aufs_dop; ++struct au_branch; ++struct dentry *au_lkup_one(struct qstr *name, struct dentry *h_parent, ++ struct au_branch *br, struct nameidata *nd); ++struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent, ++ struct au_branch *br); ++int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir, ++ struct dentry *h_parent, struct au_branch *br); ++ ++int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type, ++ struct nameidata *nd); ++int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex); ++int au_refresh_hdentry(struct dentry *dentry, mode_t type); ++int au_reval_dpath(struct dentry *dentry, unsigned int sigen); ++ ++/* dinfo.c */ ++int au_alloc_dinfo(struct dentry *dentry); ++int au_di_realloc(struct au_dinfo *dinfo, int nbr); ++ ++void di_read_lock(struct dentry *d, int flags, unsigned int lsc); ++void di_read_unlock(struct dentry *d, int flags); ++void di_downgrade_lock(struct dentry *d, int flags); ++void di_write_lock(struct dentry *d, unsigned int lsc); ++void di_write_unlock(struct dentry *d); ++void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir); ++void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir); ++void di_write_unlock2(struct dentry *d1, struct dentry *d2); ++ ++struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex); ++aufs_bindex_t au_dbtail(struct dentry *dentry); ++aufs_bindex_t au_dbtaildir(struct dentry *dentry); ++ ++void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_dentry); ++void au_update_digen(struct dentry *dentry); ++void au_update_dbrange(struct dentry *dentry, int do_put_zero); ++void au_update_dbstart(struct dentry *dentry); ++void au_update_dbend(struct dentry *dentry); ++int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct au_dinfo *au_di(struct dentry *dentry) ++{ ++ return dentry->d_fsdata; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* lock subclass for dinfo */ ++enum { ++ AuLsc_DI_CHILD, /* child first */ ++ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hinotify */ ++ AuLsc_DI_CHILD3, /* copyup dirs */ ++ AuLsc_DI_PARENT, ++ AuLsc_DI_PARENT2, ++ AuLsc_DI_PARENT3 ++}; ++ ++/* ++ * di_read_lock_child, di_write_lock_child, ++ * di_read_lock_child2, di_write_lock_child2, ++ * di_read_lock_child3, di_write_lock_child3, ++ * di_read_lock_parent, di_write_lock_parent, ++ * di_read_lock_parent2, di_write_lock_parent2, ++ * di_read_lock_parent3, di_write_lock_parent3, ++ */ ++#define AuReadLockFunc(name, lsc) \ ++static inline void di_read_lock_##name(struct dentry *d, int flags) \ ++{ di_read_lock(d, flags, AuLsc_DI_##lsc); } ++ ++#define AuWriteLockFunc(name, lsc) \ ++static inline void di_write_lock_##name(struct dentry *d) \ ++{ di_write_lock(d, AuLsc_DI_##lsc); } ++ ++#define AuRWLockFuncs(name, lsc) \ ++ AuReadLockFunc(name, lsc) \ ++ AuWriteLockFunc(name, lsc) ++ ++AuRWLockFuncs(child, CHILD); ++AuRWLockFuncs(child2, CHILD2); ++AuRWLockFuncs(child3, CHILD3); ++AuRWLockFuncs(parent, PARENT); ++AuRWLockFuncs(parent2, PARENT2); ++AuRWLockFuncs(parent3, PARENT3); ++ ++#undef AuReadLockFunc ++#undef AuWriteLockFunc ++#undef AuRWLockFuncs ++ ++#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem) ++#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem) ++#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem) ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* todo: memory barrier? */ ++static inline unsigned int au_digen(struct dentry *d) ++{ ++ return atomic_read(&au_di(d)->di_generation); ++} ++ ++static inline void au_h_dentry_init(struct au_hdentry *hdentry) ++{ ++ hdentry->hd_dentry = NULL; ++} ++ ++static inline void au_hdput(struct au_hdentry *hd) ++{ ++ dput(hd->hd_dentry); ++} ++ ++static inline aufs_bindex_t au_dbstart(struct dentry *dentry) ++{ ++ DiMustAnyLock(dentry); ++ return au_di(dentry)->di_bstart; ++} ++ ++static inline aufs_bindex_t au_dbend(struct dentry *dentry) ++{ ++ DiMustAnyLock(dentry); ++ return au_di(dentry)->di_bend; ++} ++ ++static inline aufs_bindex_t au_dbwh(struct dentry *dentry) ++{ ++ DiMustAnyLock(dentry); ++ return au_di(dentry)->di_bwh; ++} ++ ++static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry) ++{ ++ DiMustAnyLock(dentry); ++ return au_di(dentry)->di_bdiropq; ++} ++ ++/* todo: hard/soft set? */ ++static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ DiMustWriteLock(dentry); ++ au_di(dentry)->di_bstart = bindex; ++} ++ ++static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ DiMustWriteLock(dentry); ++ au_di(dentry)->di_bend = bindex; ++} ++ ++static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ DiMustWriteLock(dentry); ++ /* dbwh can be outside of bstart - bend range */ ++ au_di(dentry)->di_bwh = bindex; ++} ++ ++static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ DiMustWriteLock(dentry); ++ au_di(dentry)->di_bdiropq = bindex; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_HINOTIFY ++static inline void au_digen_dec(struct dentry *d) ++{ ++ atomic_dec_return(&au_di(d)->di_generation); ++} ++ ++static inline void au_hin_di_reinit(struct dentry *dentry) ++{ ++ dentry->d_fsdata = NULL; ++} ++#else ++static inline void au_hin_di_reinit(struct dentry *dentry __maybe_unused) ++{ ++ /* empty */ ++} ++#endif /* CONFIG_AUFS_HINOTIFY */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_DENTRY_H__ */ +diff --git a/fs/aufs/dinfo.c b/fs/aufs/dinfo.c +new file mode 100644 +index 0000000..0010c99 +--- /dev/null ++++ b/fs/aufs/dinfo.c +@@ -0,0 +1,367 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * dentry private data ++ */ ++ ++#include "aufs.h" ++ ++int au_alloc_dinfo(struct dentry *dentry) ++{ ++ struct au_dinfo *dinfo; ++ struct super_block *sb; ++ int nbr; ++ ++ dinfo = au_cache_alloc_dinfo(); ++ if (unlikely(!dinfo)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ nbr = au_sbend(sb) + 1; ++ if (nbr <= 0) ++ nbr = 1; ++ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS); ++ if (unlikely(!dinfo->di_hdentry)) ++ goto out_dinfo; ++ ++ atomic_set(&dinfo->di_generation, au_sigen(sb)); ++ /* smp_mb(); */ /* atomic_set */ ++ au_rw_init_wlock_nested(&dinfo->di_rwsem, AuLsc_DI_CHILD); ++ dinfo->di_bstart = -1; ++ dinfo->di_bend = -1; ++ dinfo->di_bwh = -1; ++ dinfo->di_bdiropq = -1; ++ ++ dentry->d_fsdata = dinfo; ++ dentry->d_op = &aufs_dop; ++ return 0; /* success */ ++ ++ out_dinfo: ++ au_cache_free_dinfo(dinfo); ++ out: ++ return -ENOMEM; ++} ++ ++int au_di_realloc(struct au_dinfo *dinfo, int nbr) ++{ ++ int err, sz; ++ struct au_hdentry *hdp; ++ ++ AuRwMustWriteLock(&dinfo->di_rwsem); ++ ++ err = -ENOMEM; ++ sz = sizeof(*hdp) * (dinfo->di_bend + 1); ++ if (!sz) ++ sz = sizeof(*hdp); ++ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS); ++ if (hdp) { ++ dinfo->di_hdentry = hdp; ++ err = 0; ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void do_ii_write_lock(struct inode *inode, unsigned int lsc) ++{ ++ switch (lsc) { ++ case AuLsc_DI_CHILD: ++ ii_write_lock_child(inode); ++ break; ++ case AuLsc_DI_CHILD2: ++ ii_write_lock_child2(inode); ++ break; ++ case AuLsc_DI_CHILD3: ++ ii_write_lock_child3(inode); ++ break; ++ case AuLsc_DI_PARENT: ++ ii_write_lock_parent(inode); ++ break; ++ case AuLsc_DI_PARENT2: ++ ii_write_lock_parent2(inode); ++ break; ++ case AuLsc_DI_PARENT3: ++ ii_write_lock_parent3(inode); ++ break; ++ default: ++ BUG(); ++ } ++} ++ ++static void do_ii_read_lock(struct inode *inode, unsigned int lsc) ++{ ++ switch (lsc) { ++ case AuLsc_DI_CHILD: ++ ii_read_lock_child(inode); ++ break; ++ case AuLsc_DI_CHILD2: ++ ii_read_lock_child2(inode); ++ break; ++ case AuLsc_DI_CHILD3: ++ ii_read_lock_child3(inode); ++ break; ++ case AuLsc_DI_PARENT: ++ ii_read_lock_parent(inode); ++ break; ++ case AuLsc_DI_PARENT2: ++ ii_read_lock_parent2(inode); ++ break; ++ case AuLsc_DI_PARENT3: ++ ii_read_lock_parent3(inode); ++ break; ++ default: ++ BUG(); ++ } ++} ++ ++void di_read_lock(struct dentry *d, int flags, unsigned int lsc) ++{ ++ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc); ++ if (d->d_inode) { ++ if (au_ftest_lock(flags, IW)) ++ do_ii_write_lock(d->d_inode, lsc); ++ else if (au_ftest_lock(flags, IR)) ++ do_ii_read_lock(d->d_inode, lsc); ++ } ++} ++ ++void di_read_unlock(struct dentry *d, int flags) ++{ ++ if (d->d_inode) { ++ if (au_ftest_lock(flags, IW)) ++ ii_write_unlock(d->d_inode); ++ else if (au_ftest_lock(flags, IR)) ++ ii_read_unlock(d->d_inode); ++ } ++ au_rw_read_unlock(&au_di(d)->di_rwsem); ++} ++ ++void di_downgrade_lock(struct dentry *d, int flags) ++{ ++ if (d->d_inode && au_ftest_lock(flags, IR)) ++ ii_downgrade_lock(d->d_inode); ++ au_rw_dgrade_lock(&au_di(d)->di_rwsem); ++} ++ ++void di_write_lock(struct dentry *d, unsigned int lsc) ++{ ++ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc); ++ if (d->d_inode) ++ do_ii_write_lock(d->d_inode, lsc); ++} ++ ++void di_write_unlock(struct dentry *d) ++{ ++ if (d->d_inode) ++ ii_write_unlock(d->d_inode); ++ au_rw_write_unlock(&au_di(d)->di_rwsem); ++} ++ ++void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir) ++{ ++ AuDebugOn(d1 == d2 ++ || d1->d_inode == d2->d_inode ++ || d1->d_sb != d2->d_sb); ++ ++ if (isdir && au_test_subdir(d1, d2)) { ++ di_write_lock_child(d1); ++ di_write_lock_child2(d2); ++ } else { ++ /* there should be no races */ ++ di_write_lock_child(d2); ++ di_write_lock_child2(d1); ++ } ++} ++ ++void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir) ++{ ++ AuDebugOn(d1 == d2 ++ || d1->d_inode == d2->d_inode ++ || d1->d_sb != d2->d_sb); ++ ++ if (isdir && au_test_subdir(d1, d2)) { ++ di_write_lock_parent(d1); ++ di_write_lock_parent2(d2); ++ } else { ++ /* there should be no races */ ++ di_write_lock_parent(d2); ++ di_write_lock_parent2(d1); ++ } ++} ++ ++void di_write_unlock2(struct dentry *d1, struct dentry *d2) ++{ ++ di_write_unlock(d1); ++ if (d1->d_inode == d2->d_inode) ++ au_rw_write_unlock(&au_di(d2)->di_rwsem); ++ else ++ di_write_unlock(d2); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ struct dentry *d; ++ ++ DiMustAnyLock(dentry); ++ ++ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry)) ++ return NULL; ++ AuDebugOn(bindex < 0); ++ d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry; ++ AuDebugOn(d && (atomic_read(&d->d_count) <= 0)); ++ return d; ++} ++ ++aufs_bindex_t au_dbtail(struct dentry *dentry) ++{ ++ aufs_bindex_t bend, bwh; ++ ++ bend = au_dbend(dentry); ++ if (0 <= bend) { ++ bwh = au_dbwh(dentry); ++ if (!bwh) ++ return bwh; ++ if (0 < bwh && bwh < bend) ++ return bwh - 1; ++ } ++ return bend; ++} ++ ++aufs_bindex_t au_dbtaildir(struct dentry *dentry) ++{ ++ aufs_bindex_t bend, bopq; ++ ++ bend = au_dbtail(dentry); ++ if (0 <= bend) { ++ bopq = au_dbdiropq(dentry); ++ if (0 <= bopq && bopq < bend) ++ bend = bopq; ++ } ++ return bend; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_dentry) ++{ ++ struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex; ++ ++ DiMustWriteLock(dentry); ++ ++ if (hd->hd_dentry) ++ au_hdput(hd); ++ hd->hd_dentry = h_dentry; ++} ++ ++void au_update_digen(struct dentry *dentry) ++{ ++ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb)); ++ /* smp_mb(); */ /* atomic_set */ ++} ++ ++void au_update_dbrange(struct dentry *dentry, int do_put_zero) ++{ ++ struct au_dinfo *dinfo; ++ struct dentry *h_d; ++ ++ DiMustWriteLock(dentry); ++ ++ dinfo = au_di(dentry); ++ if (!dinfo || dinfo->di_bstart < 0) ++ return; ++ ++ if (do_put_zero) { ++ aufs_bindex_t bindex, bend; ++ ++ bend = dinfo->di_bend; ++ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) { ++ h_d = dinfo->di_hdentry[0 + bindex].hd_dentry; ++ if (h_d && !h_d->d_inode) ++ au_set_h_dptr(dentry, bindex, NULL); ++ } ++ } ++ ++ dinfo->di_bstart = -1; ++ while (++dinfo->di_bstart <= dinfo->di_bend) ++ if (dinfo->di_hdentry[0 + dinfo->di_bstart].hd_dentry) ++ break; ++ if (dinfo->di_bstart > dinfo->di_bend) { ++ dinfo->di_bstart = -1; ++ dinfo->di_bend = -1; ++ return; ++ } ++ ++ dinfo->di_bend++; ++ while (0 <= --dinfo->di_bend) ++ if (dinfo->di_hdentry[0 + dinfo->di_bend].hd_dentry) ++ break; ++ AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0); ++} ++ ++void au_update_dbstart(struct dentry *dentry) ++{ ++ aufs_bindex_t bindex, bend; ++ struct dentry *h_dentry; ++ ++ bend = au_dbend(dentry); ++ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ if (h_dentry->d_inode) { ++ au_set_dbstart(dentry, bindex); ++ return; ++ } ++ au_set_h_dptr(dentry, bindex, NULL); ++ } ++} ++ ++void au_update_dbend(struct dentry *dentry) ++{ ++ aufs_bindex_t bindex, bstart; ++ struct dentry *h_dentry; ++ ++ bstart = au_dbstart(dentry); ++ for (bindex = au_dbend(dentry); bindex <= bstart; bindex--) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ if (h_dentry->d_inode) { ++ au_set_dbend(dentry, bindex); ++ return; ++ } ++ au_set_h_dptr(dentry, bindex, NULL); ++ } ++} ++ ++int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry) ++{ ++ aufs_bindex_t bindex, bend; ++ ++ bend = au_dbend(dentry); ++ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) ++ if (au_h_dptr(dentry, bindex) == h_dentry) ++ return bindex; ++ return -1; ++} +diff --git a/fs/aufs/dir.c b/fs/aufs/dir.c +new file mode 100644 +index 0000000..df37ffd +--- /dev/null ++++ b/fs/aufs/dir.c +@@ -0,0 +1,591 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * directory operations ++ */ ++ ++#include ++#include ++#include "aufs.h" ++ ++void au_add_nlink(struct inode *dir, struct inode *h_dir) ++{ ++ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); ++ ++ dir->i_nlink += h_dir->i_nlink - 2; ++ if (h_dir->i_nlink < 2) ++ dir->i_nlink += 2; ++} ++ ++void au_sub_nlink(struct inode *dir, struct inode *h_dir) ++{ ++ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); ++ ++ dir->i_nlink -= h_dir->i_nlink - 2; ++ if (h_dir->i_nlink < 2) ++ dir->i_nlink -= 2; ++} ++ ++loff_t au_dir_size(struct file *file, struct dentry *dentry) ++{ ++ loff_t sz; ++ aufs_bindex_t bindex, bend; ++ struct file *h_file; ++ struct dentry *h_dentry; ++ ++ sz = 0; ++ if (file) { ++ AuDebugOn(!file->f_dentry); ++ AuDebugOn(!file->f_dentry->d_inode); ++ AuDebugOn(!S_ISDIR(file->f_dentry->d_inode->i_mode)); ++ ++ bend = au_fbend(file); ++ for (bindex = au_fbstart(file); ++ bindex <= bend && sz < KMALLOC_MAX_SIZE; ++ bindex++) { ++ h_file = au_h_fptr(file, bindex); ++ if (h_file ++ && h_file->f_dentry ++ && h_file->f_dentry->d_inode) ++ sz += i_size_read(h_file->f_dentry->d_inode); ++ } ++ } else { ++ AuDebugOn(!dentry); ++ AuDebugOn(!dentry->d_inode); ++ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode)); ++ ++ bend = au_dbtaildir(dentry); ++ for (bindex = au_dbstart(dentry); ++ bindex <= bend && sz < KMALLOC_MAX_SIZE; ++ bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry && h_dentry->d_inode) ++ sz += i_size_read(h_dentry->d_inode); ++ } ++ } ++ if (sz < KMALLOC_MAX_SIZE) ++ sz = roundup_pow_of_two(sz); ++ if (sz > KMALLOC_MAX_SIZE) ++ sz = KMALLOC_MAX_SIZE; ++ else if (sz < NAME_MAX) { ++ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX); ++ sz = AUFS_RDBLK_DEF; ++ } ++ return sz; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int reopen_dir(struct file *file) ++{ ++ int err; ++ unsigned int flags; ++ aufs_bindex_t bindex, btail, bstart; ++ struct dentry *dentry, *h_dentry; ++ struct file *h_file; ++ ++ /* open all lower dirs */ ++ dentry = file->f_dentry; ++ bstart = au_dbstart(dentry); ++ for (bindex = au_fbstart(file); bindex < bstart; bindex++) ++ au_set_h_fptr(file, bindex, NULL); ++ au_set_fbstart(file, bstart); ++ ++ btail = au_dbtaildir(dentry); ++ for (bindex = au_fbend(file); btail < bindex; bindex--) ++ au_set_h_fptr(file, bindex, NULL); ++ au_set_fbend(file, btail); ++ ++ flags = file->f_flags; ++ for (bindex = bstart; bindex <= btail; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ h_file = au_h_fptr(file, bindex); ++ if (h_file) ++ continue; ++ ++ h_file = au_h_open(dentry, bindex, flags, file); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; /* close all? */ ++ au_set_h_fptr(file, bindex, h_file); ++ } ++ au_update_figen(file); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ err = 0; ++ ++ out: ++ return err; ++} ++ ++static int do_open_dir(struct file *file, int flags) ++{ ++ int err; ++ aufs_bindex_t bindex, btail; ++ struct dentry *dentry, *h_dentry; ++ struct file *h_file; ++ ++ FiMustWriteLock(file); ++ ++ err = 0; ++ dentry = file->f_dentry; ++ au_set_fvdir_cache(file, NULL); ++ au_fi(file)->fi_maintain_plink = 0; ++ file->f_version = dentry->d_inode->i_version; ++ bindex = au_dbstart(dentry); ++ au_set_fbstart(file, bindex); ++ btail = au_dbtaildir(dentry); ++ au_set_fbend(file, btail); ++ for (; !err && bindex <= btail; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ ++ h_file = au_h_open(dentry, bindex, flags, file); ++ if (IS_ERR(h_file)) { ++ err = PTR_ERR(h_file); ++ break; ++ } ++ au_set_h_fptr(file, bindex, h_file); ++ } ++ au_update_figen(file); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ if (!err) ++ return 0; /* success */ ++ ++ /* close all */ ++ for (bindex = au_fbstart(file); bindex <= btail; bindex++) ++ au_set_h_fptr(file, bindex, NULL); ++ au_set_fbstart(file, -1); ++ au_set_fbend(file, -1); ++ return err; ++} ++ ++static int aufs_open_dir(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ return au_do_open(file, do_open_dir); ++} ++ ++static int aufs_release_dir(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ struct au_vdir *vdir_cache; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ ++ sb = file->f_dentry->d_sb; ++ si_noflush_read_lock(sb); ++ fi_write_lock(file); ++ vdir_cache = au_fvdir_cache(file); ++ if (vdir_cache) ++ au_vdir_free(vdir_cache); ++ if (au_fi(file)->fi_maintain_plink) { ++ sbinfo = au_sbi(sb); ++ /* clear the flag without write-lock */ ++ sbinfo->au_si_status &= ~AuSi_MAINTAIN_PLINK; ++ smp_mb(); ++ wake_up_all(&sbinfo->si_plink_wq); ++ } ++ fi_write_unlock(file); ++ au_finfo_fin(file); ++ si_read_unlock(sb); ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct inode *inode; ++ struct super_block *sb; ++ ++ err = 0; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ IMustLock(inode); ++ bend = au_dbend(dentry); ++ for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) { ++ struct path h_path; ++ struct inode *h_inode; ++ ++ if (au_test_ro(sb, bindex, inode)) ++ continue; ++ h_path.dentry = au_h_dptr(dentry, bindex); ++ if (!h_path.dentry) ++ continue; ++ h_inode = h_path.dentry->d_inode; ++ if (!h_inode) ++ continue; ++ ++ /* no mnt_want_write() */ ++ /* cf. fs/nsfd/vfs.c and fs/nfsd/nfs4recover.c */ ++ /* todo: inotiry fired? */ ++ h_path.mnt = au_sbr_mnt(sb, bindex); ++ mutex_lock(&h_inode->i_mutex); ++ err = filemap_fdatawrite(h_inode->i_mapping); ++ AuDebugOn(!h_inode->i_fop); ++ if (!err && h_inode->i_fop->fsync) ++ err = h_inode->i_fop->fsync(NULL, h_path.dentry, ++ datasync); ++ if (!err) ++ err = filemap_fdatawrite(h_inode->i_mapping); ++ if (!err) ++ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/ ++ mutex_unlock(&h_inode->i_mutex); ++ } ++ ++ return err; ++} ++ ++static int au_do_fsync_dir(struct file *file, int datasync) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct file *h_file; ++ struct super_block *sb; ++ struct inode *inode; ++ struct mutex *h_mtx; ++ ++ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ sb = file->f_dentry->d_sb; ++ inode = file->f_dentry->d_inode; ++ bend = au_fbend(file); ++ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) { ++ h_file = au_h_fptr(file, bindex); ++ if (!h_file || au_test_ro(sb, bindex, inode)) ++ continue; ++ ++ err = vfs_fsync(h_file, h_file->f_dentry, datasync); ++ if (!err) { ++ h_mtx = &h_file->f_dentry->d_inode->i_mutex; ++ mutex_lock(h_mtx); ++ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); ++ /*ignore*/ ++ mutex_unlock(h_mtx); ++ } ++ } ++ ++ out: ++ return err; ++} ++ ++/* ++ * @file may be NULL ++ */ ++static int aufs_fsync_dir(struct file *file, struct dentry *dentry, ++ int datasync) ++{ ++ int err; ++ struct super_block *sb; ++ ++ IMustLock(dentry->d_inode); ++ ++ err = 0; ++ sb = dentry->d_sb; ++ si_noflush_read_lock(sb); ++ if (file) ++ err = au_do_fsync_dir(file, datasync); ++ else { ++ di_write_lock_child(dentry); ++ err = au_do_fsync_dir_no_file(dentry, datasync); ++ } ++ au_cpup_attr_timesizes(dentry->d_inode); ++ di_write_unlock(dentry); ++ if (file) ++ fi_write_unlock(file); ++ ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int aufs_readdir(struct file *file, void *dirent, filldir_t filldir) ++{ ++ int err; ++ struct dentry *dentry; ++ struct inode *inode; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ inode = dentry->d_inode; ++ IMustLock(inode); ++ ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ err = au_vdir_init(file); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ if (!au_test_nfsd(current)) { ++ err = au_vdir_fill_de(file, dirent, filldir); ++ fsstack_copy_attr_atime(inode, ++ au_h_iptr(inode, au_ibstart(inode))); ++ } else { ++ /* ++ * nfsd filldir may call lookup_one_len(), vfs_getattr(), ++ * encode_fh() and others. ++ */ ++ struct inode *h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ ++ di_read_unlock(dentry, AuLock_IR); ++ si_read_unlock(sb); ++ lockdep_off(); ++ err = au_vdir_fill_de(file, dirent, filldir); ++ lockdep_on(); ++ fsstack_copy_attr_atime(inode, h_inode); ++ fi_write_unlock(file); ++ ++ AuTraceErr(err); ++ return err; ++ } ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define AuTestEmpty_WHONLY 1 ++#define AuTestEmpty_CALLED (1 << 1) ++#define AuTestEmpty_SHWH (1 << 2) ++#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name) ++#define au_fset_testempty(flags, name) { (flags) |= AuTestEmpty_##name; } ++#define au_fclr_testempty(flags, name) { (flags) &= ~AuTestEmpty_##name; } ++ ++#ifndef CONFIG_AUFS_SHWH ++#undef AuTestEmpty_SHWH ++#define AuTestEmpty_SHWH 0 ++#endif ++ ++struct test_empty_arg { ++ struct au_nhash *whlist; ++ unsigned int flags; ++ int err; ++ aufs_bindex_t bindex; ++}; ++ ++static int test_empty_cb(void *__arg, const char *__name, int namelen, ++ loff_t offset __maybe_unused, u64 ino, ++ unsigned int d_type) ++{ ++ struct test_empty_arg *arg = __arg; ++ char *name = (void *)__name; ++ ++ arg->err = 0; ++ au_fset_testempty(arg->flags, CALLED); ++ /* smp_mb(); */ ++ if (name[0] == '.' ++ && (namelen == 1 || (name[1] == '.' && namelen == 2))) ++ goto out; /* success */ ++ ++ if (namelen <= AUFS_WH_PFX_LEN ++ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { ++ if (au_ftest_testempty(arg->flags, WHONLY) ++ && !au_nhash_test_known_wh(arg->whlist, name, namelen)) ++ arg->err = -ENOTEMPTY; ++ goto out; ++ } ++ ++ name += AUFS_WH_PFX_LEN; ++ namelen -= AUFS_WH_PFX_LEN; ++ if (!au_nhash_test_known_wh(arg->whlist, name, namelen)) ++ arg->err = au_nhash_append_wh ++ (arg->whlist, name, namelen, ino, d_type, arg->bindex, ++ au_ftest_testempty(arg->flags, SHWH)); ++ ++ out: ++ /* smp_mb(); */ ++ AuTraceErr(arg->err); ++ return arg->err; ++} ++ ++static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg) ++{ ++ int err; ++ struct file *h_file; ++ ++ h_file = au_h_open(dentry, arg->bindex, ++ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE, ++ /*file*/NULL); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; ++ ++ err = 0; ++ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE) ++ && !h_file->f_dentry->d_inode->i_nlink) ++ goto out_put; ++ ++ do { ++ arg->err = 0; ++ au_fclr_testempty(arg->flags, CALLED); ++ /* smp_mb(); */ ++ err = vfsub_readdir(h_file, test_empty_cb, arg); ++ if (err >= 0) ++ err = arg->err; ++ } while (!err && au_ftest_testempty(arg->flags, CALLED)); ++ ++ out_put: ++ fput(h_file); ++ au_sbr_put(dentry->d_sb, arg->bindex); ++ out: ++ return err; ++} ++ ++struct do_test_empty_args { ++ int *errp; ++ struct dentry *dentry; ++ struct test_empty_arg *arg; ++}; ++ ++static void call_do_test_empty(void *args) ++{ ++ struct do_test_empty_args *a = args; ++ *a->errp = do_test_empty(a->dentry, a->arg); ++} ++ ++static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg) ++{ ++ int err, wkq_err; ++ struct dentry *h_dentry; ++ struct inode *h_inode; ++ ++ h_dentry = au_h_dptr(dentry, arg->bindex); ++ h_inode = h_dentry->d_inode; ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ); ++ mutex_unlock(&h_inode->i_mutex); ++ if (!err) ++ err = do_test_empty(dentry, arg); ++ else { ++ struct do_test_empty_args args = { ++ .errp = &err, ++ .dentry = dentry, ++ .arg = arg ++ }; ++ unsigned int flags = arg->flags; ++ ++ wkq_err = au_wkq_wait(call_do_test_empty, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ arg->flags = flags; ++ } ++ ++ return err; ++} ++ ++int au_test_empty_lower(struct dentry *dentry) ++{ ++ int err; ++ unsigned int rdhash; ++ aufs_bindex_t bindex, bstart, btail; ++ struct au_nhash whlist; ++ struct test_empty_arg arg; ++ ++ SiMustAnyLock(dentry->d_sb); ++ ++ rdhash = au_sbi(dentry->d_sb)->si_rdhash; ++ if (!rdhash) ++ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry)); ++ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ ++ arg.flags = 0; ++ arg.whlist = &whlist; ++ bstart = au_dbstart(dentry); ++ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)) ++ au_fset_testempty(arg.flags, SHWH); ++ arg.bindex = bstart; ++ err = do_test_empty(dentry, &arg); ++ if (unlikely(err)) ++ goto out_whlist; ++ ++ au_fset_testempty(arg.flags, WHONLY); ++ btail = au_dbtaildir(dentry); ++ for (bindex = bstart + 1; !err && bindex <= btail; bindex++) { ++ struct dentry *h_dentry; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry && h_dentry->d_inode) { ++ arg.bindex = bindex; ++ err = do_test_empty(dentry, &arg); ++ } ++ } ++ ++ out_whlist: ++ au_nhash_wh_free(&whlist); ++ out: ++ return err; ++} ++ ++int au_test_empty(struct dentry *dentry, struct au_nhash *whlist) ++{ ++ int err; ++ struct test_empty_arg arg; ++ aufs_bindex_t bindex, btail; ++ ++ err = 0; ++ arg.whlist = whlist; ++ arg.flags = AuTestEmpty_WHONLY; ++ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)) ++ au_fset_testempty(arg.flags, SHWH); ++ btail = au_dbtaildir(dentry); ++ for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) { ++ struct dentry *h_dentry; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry && h_dentry->d_inode) { ++ arg.bindex = bindex; ++ err = sio_test_empty(dentry, &arg); ++ } ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++const struct file_operations aufs_dir_fop = { ++ .read = generic_read_dir, ++ .readdir = aufs_readdir, ++ .unlocked_ioctl = aufs_ioctl_dir, ++ .open = aufs_open_dir, ++ .release = aufs_release_dir, ++ .flush = aufs_flush, ++ .fsync = aufs_fsync_dir ++}; +diff --git a/fs/aufs/dir.h b/fs/aufs/dir.h +new file mode 100644 +index 0000000..d90c63f +--- /dev/null ++++ b/fs/aufs/dir.h +@@ -0,0 +1,127 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * directory operations ++ */ ++ ++#ifndef __AUFS_DIR_H__ ++#define __AUFS_DIR_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* need to be faster and smaller */ ++ ++struct au_nhash { ++ unsigned int nh_num; ++ struct hlist_head *nh_head; ++}; ++ ++struct au_vdir_destr { ++ unsigned char len; ++ unsigned char name[0]; ++} __packed; ++ ++struct au_vdir_dehstr { ++ struct hlist_node hash; ++ struct au_vdir_destr *str; ++}; ++ ++struct au_vdir_de { ++ ino_t de_ino; ++ unsigned char de_type; ++ /* caution: packed */ ++ struct au_vdir_destr de_str; ++} __packed; ++ ++struct au_vdir_wh { ++ struct hlist_node wh_hash; ++#ifdef CONFIG_AUFS_SHWH ++ ino_t wh_ino; ++ aufs_bindex_t wh_bindex; ++ unsigned char wh_type; ++#else ++ aufs_bindex_t wh_bindex; ++#endif ++ /* caution: packed */ ++ struct au_vdir_destr wh_str; ++} __packed; ++ ++union au_vdir_deblk_p { ++ unsigned char *deblk; ++ struct au_vdir_de *de; ++}; ++ ++struct au_vdir { ++ unsigned char **vd_deblk; ++ unsigned long vd_nblk; ++ struct { ++ unsigned long ul; ++ union au_vdir_deblk_p p; ++ } vd_last; ++ ++ unsigned long vd_version; ++ unsigned int vd_deblk_sz; ++ unsigned long vd_jiffy; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* dir.c */ ++extern const struct file_operations aufs_dir_fop; ++void au_add_nlink(struct inode *dir, struct inode *h_dir); ++void au_sub_nlink(struct inode *dir, struct inode *h_dir); ++loff_t au_dir_size(struct file *file, struct dentry *dentry); ++int au_test_empty_lower(struct dentry *dentry); ++int au_test_empty(struct dentry *dentry, struct au_nhash *whlist); ++ ++/* vdir.c */ ++unsigned int au_rdhash_est(loff_t sz); ++int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp); ++void au_nhash_wh_free(struct au_nhash *whlist); ++int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt, ++ int limit); ++int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen); ++int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino, ++ unsigned int d_type, aufs_bindex_t bindex, ++ unsigned char shwh); ++void au_vdir_free(struct au_vdir *vdir); ++int au_vdir_init(struct file *file); ++int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir); ++ ++/* ioctl.c */ ++long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg); ++ ++#ifdef CONFIG_AUFS_RDU ++/* rdu.c */ ++long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg); ++#else ++static inline long au_rdu_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ return -EINVAL; ++} ++#endif ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_DIR_H__ */ +diff --git a/fs/aufs/export.c b/fs/aufs/export.c +new file mode 100644 +index 0000000..861f61b +--- /dev/null ++++ b/fs/aufs/export.c +@@ -0,0 +1,745 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * export via nfs ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++union conv { ++#ifdef CONFIG_AUFS_INO_T_64 ++ __u32 a[2]; ++#else ++ __u32 a[1]; ++#endif ++ ino_t ino; ++}; ++ ++static ino_t decode_ino(__u32 *a) ++{ ++ union conv u; ++ ++ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a)); ++ u.a[0] = a[0]; ++#ifdef CONFIG_AUFS_INO_T_64 ++ u.a[1] = a[1]; ++#endif ++ return u.ino; ++} ++ ++static void encode_ino(__u32 *a, ino_t ino) ++{ ++ union conv u; ++ ++ u.ino = ino; ++ a[0] = u.a[0]; ++#ifdef CONFIG_AUFS_INO_T_64 ++ a[1] = u.a[1]; ++#endif ++} ++ ++/* NFS file handle */ ++enum { ++ Fh_br_id, ++ Fh_sigen, ++#ifdef CONFIG_AUFS_INO_T_64 ++ /* support 64bit inode number */ ++ Fh_ino1, ++ Fh_ino2, ++ Fh_dir_ino1, ++ Fh_dir_ino2, ++#else ++ Fh_ino1, ++ Fh_dir_ino1, ++#endif ++ Fh_igen, ++ Fh_h_type, ++ Fh_tail, ++ ++ Fh_ino = Fh_ino1, ++ Fh_dir_ino = Fh_dir_ino1 ++}; ++ ++static int au_test_anon(struct dentry *dentry) ++{ ++ return !!(dentry->d_flags & DCACHE_DISCONNECTED); ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* inode generation external table */ ++ ++int au_xigen_inc(struct inode *inode) ++{ ++ int err; ++ loff_t pos; ++ ssize_t sz; ++ __u32 igen; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ ++ err = 0; ++ sb = inode->i_sb; ++ sbinfo = au_sbi(sb); ++ /* ++ * temporary workaround for escaping from SiMustAnyLock() in ++ * au_mntflags(), since this function is called from au_iinfo_fin(). ++ */ ++ if (unlikely(!au_opt_test(sbinfo->si_mntflags, XINO))) ++ goto out; ++ ++ pos = inode->i_ino; ++ pos *= sizeof(igen); ++ igen = inode->i_generation + 1; ++ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen, ++ sizeof(igen), &pos); ++ if (sz == sizeof(igen)) ++ goto out; /* success */ ++ ++ err = sz; ++ if (unlikely(sz >= 0)) { ++ err = -EIO; ++ AuIOErr("xigen error (%zd)\n", sz); ++ } ++ ++ out: ++ return err; ++} ++ ++int au_xigen_new(struct inode *inode) ++{ ++ int err; ++ loff_t pos; ++ ssize_t sz; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ ++ err = 0; ++ /* todo: dirty, at mount time */ ++ if (inode->i_ino == AUFS_ROOT_INO) ++ goto out; ++ sb = inode->i_sb; ++ SiMustAnyLock(sb); ++ if (unlikely(!au_opt_test(au_mntflags(sb), XINO))) ++ goto out; ++ ++ err = -EFBIG; ++ pos = inode->i_ino; ++ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) { ++ AuIOErr1("too large i%lld\n", pos); ++ goto out; ++ } ++ pos *= sizeof(inode->i_generation); ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ file = sbinfo->si_xigen; ++ BUG_ON(!file); ++ ++ if (i_size_read(file->f_dentry->d_inode) ++ < pos + sizeof(inode->i_generation)) { ++ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next); ++ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation, ++ sizeof(inode->i_generation), &pos); ++ } else ++ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation, ++ sizeof(inode->i_generation), &pos); ++ if (sz == sizeof(inode->i_generation)) ++ goto out; /* success */ ++ ++ err = sz; ++ if (unlikely(sz >= 0)) { ++ err = -EIO; ++ AuIOErr("xigen error (%zd)\n", sz); ++ } ++ ++ out: ++ return err; ++} ++ ++int au_xigen_set(struct super_block *sb, struct file *base) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ file = au_xino_create2(base, sbinfo->si_xigen); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ err = 0; ++ if (sbinfo->si_xigen) ++ fput(sbinfo->si_xigen); ++ sbinfo->si_xigen = file; ++ ++ out: ++ return err; ++} ++ ++void au_xigen_clr(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ if (sbinfo->si_xigen) { ++ fput(sbinfo->si_xigen); ++ sbinfo->si_xigen = NULL; ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino, ++ ino_t dir_ino) ++{ ++ struct dentry *dentry, *d; ++ struct inode *inode; ++ unsigned int sigen; ++ ++ dentry = NULL; ++ inode = ilookup(sb, ino); ++ if (!inode) ++ goto out; ++ ++ dentry = ERR_PTR(-ESTALE); ++ sigen = au_sigen(sb); ++ if (unlikely(is_bad_inode(inode) ++ || IS_DEADDIR(inode) ++ || sigen != au_iigen(inode))) ++ goto out_iput; ++ ++ dentry = NULL; ++ if (!dir_ino || S_ISDIR(inode->i_mode)) ++ dentry = d_find_alias(inode); ++ else { ++ spin_lock(&dcache_lock); ++ list_for_each_entry(d, &inode->i_dentry, d_alias) ++ if (!au_test_anon(d) ++ && d->d_parent->d_inode->i_ino == dir_ino) { ++ dentry = dget_locked(d); ++ break; ++ } ++ spin_unlock(&dcache_lock); ++ } ++ if (unlikely(dentry && sigen != au_digen(dentry))) { ++ dput(dentry); ++ dentry = ERR_PTR(-ESTALE); ++ } ++ ++ out_iput: ++ iput(inode); ++ out: ++ return dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* todo: dirty? */ ++/* if exportfs_decode_fh() passed vfsmount*, we could be happy */ ++static struct vfsmount *au_mnt_get(struct super_block *sb) ++{ ++ struct mnt_namespace *ns; ++ struct vfsmount *pos, *mnt; ++ ++ spin_lock(&vfsmount_lock); ++ /* no get/put ?? */ ++ AuDebugOn(!current->nsproxy); ++ ns = current->nsproxy->mnt_ns; ++ AuDebugOn(!ns); ++ mnt = NULL; ++ /* the order (reverse) will not be a problem */ ++ list_for_each_entry(pos, &ns->list, mnt_list) ++ if (pos->mnt_sb == sb) { ++ mnt = mntget(pos); ++ break; ++ } ++ spin_unlock(&vfsmount_lock); ++ AuDebugOn(!mnt); ++ ++ return mnt; ++} ++ ++struct au_nfsd_si_lock { ++ const unsigned int sigen; ++ const aufs_bindex_t br_id; ++ unsigned char force_lock; ++}; ++ ++static aufs_bindex_t si_nfsd_read_lock(struct super_block *sb, ++ struct au_nfsd_si_lock *nsi_lock) ++{ ++ aufs_bindex_t bindex; ++ ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ /* branch id may be wrapped around */ ++ bindex = au_br_index(sb, nsi_lock->br_id); ++ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb)) ++ goto out; /* success */ ++ ++ if (!nsi_lock->force_lock) ++ si_read_unlock(sb); ++ bindex = -1; ++ ++ out: ++ return bindex; ++} ++ ++struct find_name_by_ino { ++ int called, found; ++ ino_t ino; ++ char *name; ++ int namelen; ++}; ++ ++static int ++find_name_by_ino(void *arg, const char *name, int namelen, loff_t offset, ++ u64 ino, unsigned int d_type) ++{ ++ struct find_name_by_ino *a = arg; ++ ++ a->called++; ++ if (a->ino != ino) ++ return 0; ++ ++ memcpy(a->name, name, namelen); ++ a->namelen = namelen; ++ a->found = 1; ++ return 1; ++} ++ ++static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino, ++ struct au_nfsd_si_lock *nsi_lock) ++{ ++ struct dentry *dentry, *parent; ++ struct file *file; ++ struct inode *dir; ++ struct find_name_by_ino arg; ++ int err; ++ ++ parent = path->dentry; ++ if (nsi_lock) ++ si_read_unlock(parent->d_sb); ++ path_get(path); ++ file = dentry_open(parent, path->mnt, au_dir_roflags, current_cred()); ++ dentry = (void *)file; ++ if (IS_ERR(file)) ++ goto out; ++ ++ dentry = ERR_PTR(-ENOMEM); ++ arg.name = __getname(); ++ if (unlikely(!arg.name)) ++ goto out_file; ++ arg.ino = ino; ++ arg.found = 0; ++ do { ++ arg.called = 0; ++ /* smp_mb(); */ ++ err = vfsub_readdir(file, find_name_by_ino, &arg); ++ } while (!err && !arg.found && arg.called); ++ dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out_name; ++ dentry = ERR_PTR(-ENOENT); ++ if (!arg.found) ++ goto out_name; ++ ++ /* do not call au_lkup_one() */ ++ dir = parent->d_inode; ++ mutex_lock(&dir->i_mutex); ++ dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen); ++ mutex_unlock(&dir->i_mutex); ++ AuTraceErrPtr(dentry); ++ if (IS_ERR(dentry)) ++ goto out_name; ++ AuDebugOn(au_test_anon(dentry)); ++ if (unlikely(!dentry->d_inode)) { ++ dput(dentry); ++ dentry = ERR_PTR(-ENOENT); ++ } ++ ++ out_name: ++ __putname(arg.name); ++ out_file: ++ fput(file); ++ out: ++ if (unlikely(nsi_lock ++ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0)) ++ if (!IS_ERR(dentry)) { ++ dput(dentry); ++ dentry = ERR_PTR(-ESTALE); ++ } ++ AuTraceErrPtr(dentry); ++ return dentry; ++} ++ ++static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino, ++ ino_t dir_ino, ++ struct au_nfsd_si_lock *nsi_lock) ++{ ++ struct dentry *dentry; ++ struct path path; ++ ++ if (dir_ino != AUFS_ROOT_INO) { ++ path.dentry = decode_by_ino(sb, dir_ino, 0); ++ dentry = path.dentry; ++ if (!path.dentry || IS_ERR(path.dentry)) ++ goto out; ++ AuDebugOn(au_test_anon(path.dentry)); ++ } else ++ path.dentry = dget(sb->s_root); ++ ++ path.mnt = au_mnt_get(sb); ++ dentry = au_lkup_by_ino(&path, ino, nsi_lock); ++ path_put(&path); ++ ++ out: ++ AuTraceErrPtr(dentry); ++ return dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int h_acceptable(void *expv, struct dentry *dentry) ++{ ++ return 1; ++} ++ ++static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath, ++ char *buf, int len, struct super_block *sb) ++{ ++ char *p; ++ int n; ++ struct path path; ++ ++ p = d_path(h_rootpath, buf, len); ++ if (IS_ERR(p)) ++ goto out; ++ n = strlen(p); ++ ++ path.mnt = h_rootpath->mnt; ++ path.dentry = h_parent; ++ p = d_path(&path, buf, len); ++ if (IS_ERR(p)) ++ goto out; ++ if (n != 1) ++ p += n; ++ ++ path.mnt = au_mnt_get(sb); ++ path.dentry = sb->s_root; ++ p = d_path(&path, buf, len - strlen(p)); ++ mntput(path.mnt); ++ if (IS_ERR(p)) ++ goto out; ++ if (n != 1) ++ p[strlen(p)] = '/'; ++ ++ out: ++ AuTraceErrPtr(p); ++ return p; ++} ++ ++static ++struct dentry *decode_by_path(struct super_block *sb, aufs_bindex_t bindex, ++ ino_t ino, __u32 *fh, int fh_len, ++ struct au_nfsd_si_lock *nsi_lock) ++{ ++ struct dentry *dentry, *h_parent, *root; ++ struct super_block *h_sb; ++ char *pathname, *p; ++ struct vfsmount *h_mnt; ++ struct au_branch *br; ++ int err; ++ struct path path; ++ ++ br = au_sbr(sb, bindex); ++ /* au_br_get(br); */ ++ h_mnt = br->br_mnt; ++ h_sb = h_mnt->mnt_sb; ++ /* todo: call lower fh_to_dentry()? fh_to_parent()? */ ++ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail), ++ fh_len - Fh_tail, fh[Fh_h_type], ++ h_acceptable, /*context*/NULL); ++ dentry = h_parent; ++ if (unlikely(!h_parent || IS_ERR(h_parent))) { ++ AuWarn1("%s decode_fh failed, %ld\n", ++ au_sbtype(h_sb), PTR_ERR(h_parent)); ++ goto out; ++ } ++ dentry = NULL; ++ if (unlikely(au_test_anon(h_parent))) { ++ AuWarn1("%s decode_fh returned a disconnected dentry\n", ++ au_sbtype(h_sb)); ++ goto out_h_parent; ++ } ++ ++ dentry = ERR_PTR(-ENOMEM); ++ pathname = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!pathname)) ++ goto out_h_parent; ++ ++ root = sb->s_root; ++ path.mnt = h_mnt; ++ di_read_lock_parent(root, !AuLock_IR); ++ path.dentry = au_h_dptr(root, bindex); ++ di_read_unlock(root, !AuLock_IR); ++ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb); ++ dentry = (void *)p; ++ if (IS_ERR(p)) ++ goto out_pathname; ++ ++ si_read_unlock(sb); ++ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path); ++ dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out_relock; ++ ++ dentry = ERR_PTR(-ENOENT); ++ AuDebugOn(au_test_anon(path.dentry)); ++ if (unlikely(!path.dentry->d_inode)) ++ goto out_path; ++ ++ if (ino != path.dentry->d_inode->i_ino) ++ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL); ++ else ++ dentry = dget(path.dentry); ++ ++ out_path: ++ path_put(&path); ++ out_relock: ++ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0)) ++ if (!IS_ERR(dentry)) { ++ dput(dentry); ++ dentry = ERR_PTR(-ESTALE); ++ } ++ out_pathname: ++ free_page((unsigned long)pathname); ++ out_h_parent: ++ dput(h_parent); ++ out: ++ /* au_br_put(br); */ ++ AuTraceErrPtr(dentry); ++ return dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct dentry * ++aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, ++ int fh_type) ++{ ++ struct dentry *dentry; ++ __u32 *fh = fid->raw; ++ ino_t ino, dir_ino; ++ aufs_bindex_t bindex; ++ struct au_nfsd_si_lock nsi_lock = { ++ .sigen = fh[Fh_sigen], ++ .br_id = fh[Fh_br_id], ++ .force_lock = 0 ++ }; ++ ++ AuDebugOn(fh_len < Fh_tail); ++ ++ dentry = ERR_PTR(-ESTALE); ++ /* branch id may be wrapped around */ ++ bindex = si_nfsd_read_lock(sb, &nsi_lock); ++ if (unlikely(bindex < 0)) ++ goto out; ++ nsi_lock.force_lock = 1; ++ ++ /* is this inode still cached? */ ++ ino = decode_ino(fh + Fh_ino); ++ AuDebugOn(ino == AUFS_ROOT_INO); ++ dir_ino = decode_ino(fh + Fh_dir_ino); ++ dentry = decode_by_ino(sb, ino, dir_ino); ++ if (IS_ERR(dentry)) ++ goto out_unlock; ++ if (dentry) ++ goto accept; ++ ++ /* is the parent dir cached? */ ++ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock); ++ if (IS_ERR(dentry)) ++ goto out_unlock; ++ if (dentry) ++ goto accept; ++ ++ /* lookup path */ ++ dentry = decode_by_path(sb, bindex, ino, fh, fh_len, &nsi_lock); ++ if (IS_ERR(dentry)) ++ goto out_unlock; ++ if (unlikely(!dentry)) ++ /* todo?: make it ESTALE */ ++ goto out_unlock; ++ ++ accept: ++ if (dentry->d_inode->i_generation == fh[Fh_igen]) ++ goto out_unlock; /* success */ ++ ++ dput(dentry); ++ dentry = ERR_PTR(-ESTALE); ++ out_unlock: ++ si_read_unlock(sb); ++ out: ++ AuTraceErrPtr(dentry); ++ return dentry; ++} ++ ++#if 0 /* reserved for future use */ ++/* support subtreecheck option */ ++static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid, ++ int fh_len, int fh_type) ++{ ++ struct dentry *parent; ++ __u32 *fh = fid->raw; ++ ino_t dir_ino; ++ ++ dir_ino = decode_ino(fh + Fh_dir_ino); ++ parent = decode_by_ino(sb, dir_ino, 0); ++ if (IS_ERR(parent)) ++ goto out; ++ if (!parent) ++ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]), ++ dir_ino, fh, fh_len); ++ ++ out: ++ AuTraceErrPtr(parent); ++ return parent; ++} ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int aufs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len, ++ int connectable) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ struct super_block *sb, *h_sb; ++ struct inode *inode; ++ struct dentry *parent, *h_parent; ++ struct au_branch *br; ++ ++ AuDebugOn(au_test_anon(dentry)); ++ ++ parent = NULL; ++ err = -ENOSPC; ++ if (unlikely(*max_len <= Fh_tail)) { ++ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len); ++ goto out; ++ } ++ ++ err = FILEID_ROOT; ++ if (IS_ROOT(dentry)) { ++ AuDebugOn(dentry->d_inode->i_ino != AUFS_ROOT_INO); ++ goto out; ++ } ++ ++ err = -EIO; ++ h_parent = NULL; ++ sb = dentry->d_sb; ++ aufs_read_lock(dentry, AuLock_FLUSH | AuLock_IR); ++ parent = dget_parent(dentry); ++ di_read_lock_parent(parent, !AuLock_IR); ++ inode = dentry->d_inode; ++ AuDebugOn(!inode); ++#ifdef CONFIG_AUFS_DEBUG ++ if (unlikely(!au_opt_test(au_mntflags(sb), XINO))) ++ AuWarn1("NFS-exporting requires xino\n"); ++#endif ++ ++ bend = au_dbtaildir(parent); ++ for (bindex = au_dbstart(parent); bindex <= bend; bindex++) { ++ h_parent = au_h_dptr(parent, bindex); ++ if (h_parent) { ++ dget(h_parent); ++ break; ++ } ++ } ++ if (unlikely(!h_parent)) ++ goto out_unlock; ++ ++ err = -EPERM; ++ br = au_sbr(sb, bindex); ++ h_sb = br->br_mnt->mnt_sb; ++ if (unlikely(!h_sb->s_export_op)) { ++ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb)); ++ goto out_dput; ++ } ++ ++ fh[Fh_br_id] = br->br_id; ++ fh[Fh_sigen] = au_sigen(sb); ++ encode_ino(fh + Fh_ino, inode->i_ino); ++ encode_ino(fh + Fh_dir_ino, parent->d_inode->i_ino); ++ fh[Fh_igen] = inode->i_generation; ++ ++ *max_len -= Fh_tail; ++ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail), ++ max_len, ++ /*connectable or subtreecheck*/0); ++ err = fh[Fh_h_type]; ++ *max_len += Fh_tail; ++ /* todo: macros? */ ++ if (err != 255) ++ err = 99; ++ else ++ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb)); ++ ++ out_dput: ++ dput(h_parent); ++ out_unlock: ++ di_read_unlock(parent, !AuLock_IR); ++ dput(parent); ++ aufs_read_unlock(dentry, AuLock_IR); ++ out: ++ if (unlikely(err < 0)) ++ err = 255; ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct export_operations aufs_export_op = { ++ .fh_to_dentry = aufs_fh_to_dentry, ++ /* .fh_to_parent = aufs_fh_to_parent, */ ++ .encode_fh = aufs_encode_fh ++}; ++ ++void au_export_init(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ __u32 u; ++ ++ sb->s_export_op = &aufs_export_op; ++ sbinfo = au_sbi(sb); ++ sbinfo->si_xigen = NULL; ++ get_random_bytes(&u, sizeof(u)); ++ BUILD_BUG_ON(sizeof(u) != sizeof(int)); ++ atomic_set(&sbinfo->si_xigen_next, u); ++} +diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c +new file mode 100644 +index 0000000..b1cc10d +--- /dev/null ++++ b/fs/aufs/f_op.c +@@ -0,0 +1,802 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * file and vm operations ++ */ ++ ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++/* common function to regular file and dir */ ++int aufs_flush(struct file *file, fl_owner_t id) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ struct dentry *dentry; ++ struct file *h_file; ++ ++ dentry = file->f_dentry; ++ si_noflush_read_lock(dentry->d_sb); ++ fi_read_lock(file); ++ di_read_lock_child(dentry, AuLock_IW); ++ ++ err = 0; ++ bend = au_fbend(file); ++ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) { ++ h_file = au_h_fptr(file, bindex); ++ if (!h_file || !h_file->f_op || !h_file->f_op->flush) ++ continue; ++ ++ err = h_file->f_op->flush(h_file, id); ++ if (!err) ++ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); ++ /*ignore*/ ++ } ++ au_cpup_attr_timesizes(dentry->d_inode); ++ ++ di_read_unlock(dentry, AuLock_IW); ++ fi_read_unlock(file); ++ si_read_unlock(dentry->d_sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int do_open_nondir(struct file *file, int flags) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ struct file *h_file; ++ struct dentry *dentry; ++ struct au_finfo *finfo; ++ ++ FiMustWriteLock(file); ++ ++ err = 0; ++ dentry = file->f_dentry; ++ finfo = au_fi(file); ++ finfo->fi_h_vm_ops = NULL; ++ finfo->fi_vm_ops = NULL; ++ bindex = au_dbstart(dentry); ++ /* O_TRUNC is processed already */ ++ BUG_ON(au_test_ro(dentry->d_sb, bindex, dentry->d_inode) ++ && (flags & O_TRUNC)); ++ ++ h_file = au_h_open(dentry, bindex, flags, file); ++ if (IS_ERR(h_file)) ++ err = PTR_ERR(h_file); ++ else { ++ au_set_fbstart(file, bindex); ++ au_set_fbend(file, bindex); ++ au_set_h_fptr(file, bindex, h_file); ++ au_update_figen(file); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ } ++ return err; ++} ++ ++static int aufs_open_nondir(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ return au_do_open(file, do_open_nondir); ++} ++ ++static int aufs_release_nondir(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ struct super_block *sb = file->f_dentry->d_sb; ++ ++ si_noflush_read_lock(sb); ++ kfree(au_fi(file)->fi_vm_ops); ++ au_finfo_fin(file); ++ si_read_unlock(sb); ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static ssize_t aufs_read(struct file *file, char __user *buf, size_t count, ++ loff_t *ppos) ++{ ++ ssize_t err; ++ struct dentry *dentry; ++ struct file *h_file; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ err = vfsub_read_u(h_file, buf, count, ppos); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode); ++ ++ di_read_unlock(dentry, AuLock_IR); ++ fi_read_unlock(file); ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++static ssize_t aufs_write(struct file *file, const char __user *ubuf, ++ size_t count, loff_t *ppos) ++{ ++ ssize_t err; ++ aufs_bindex_t bstart; ++ struct au_pin pin; ++ struct dentry *dentry; ++ struct inode *inode; ++ struct super_block *sb; ++ struct file *h_file; ++ char __user *buf = (char __user *)ubuf; ++ ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ mutex_lock(&inode->i_mutex); ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ bstart = au_fbstart(file); ++ h_file = au_h_fptr(file, bstart); ++ au_unpin(&pin); ++ err = vfsub_write_u(h_file, buf, count, ppos); ++ au_cpup_attr_timesizes(inode); ++ inode->i_mode = h_file->f_dentry->d_inode->i_mode; ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ out: ++ si_read_unlock(sb); ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++ ++static ssize_t aufs_aio_read(struct kiocb *kio, const struct iovec *iov, ++ unsigned long nv, loff_t pos) ++{ ++ ssize_t err; ++ struct file *file, *h_file; ++ struct dentry *dentry; ++ struct super_block *sb; ++ ++ file = kio->ki_filp; ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ err = -ENOSYS; ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ if (h_file->f_op && h_file->f_op->aio_read) { ++ err = security_file_permission(h_file, MAY_READ); ++ if (unlikely(err)) ++ goto out_unlock; ++ if (!is_sync_kiocb(kio)) { ++ get_file(h_file); ++ fput(file); ++ } ++ kio->ki_filp = h_file; ++ err = h_file->f_op->aio_read(kio, iov, nv, pos); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ fsstack_copy_attr_atime(dentry->d_inode, ++ h_file->f_dentry->d_inode); ++ } else ++ /* currently there is no such fs */ ++ WARN_ON_ONCE(h_file->f_op && h_file->f_op->read); ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_read_unlock(file); ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++static ssize_t aufs_aio_write(struct kiocb *kio, const struct iovec *iov, ++ unsigned long nv, loff_t pos) ++{ ++ ssize_t err; ++ aufs_bindex_t bstart; ++ struct au_pin pin; ++ struct dentry *dentry; ++ struct inode *inode; ++ struct super_block *sb; ++ struct file *file, *h_file; ++ ++ file = kio->ki_filp; ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ mutex_lock(&inode->i_mutex); ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ err = -ENOSYS; ++ bstart = au_fbstart(file); ++ h_file = au_h_fptr(file, bstart); ++ au_unpin(&pin); ++ if (h_file->f_op && h_file->f_op->aio_write) { ++ err = security_file_permission(h_file, MAY_WRITE); ++ if (unlikely(err)) ++ goto out_unlock; ++ if (!is_sync_kiocb(kio)) { ++ get_file(h_file); ++ fput(file); ++ } ++ kio->ki_filp = h_file; ++ err = h_file->f_op->aio_write(kio, iov, nv, pos); ++ au_cpup_attr_timesizes(inode); ++ inode->i_mode = h_file->f_dentry->d_inode->i_mode; ++ } else ++ /* currently there is no such fs */ ++ WARN_ON_ONCE(h_file->f_op && h_file->f_op->write); ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ out: ++ si_read_unlock(sb); ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++ ++static ssize_t aufs_splice_read(struct file *file, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags) ++{ ++ ssize_t err; ++ struct file *h_file; ++ struct dentry *dentry; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ err = -EINVAL; ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ if (au_test_loopback_kthread()) { ++ file->f_mapping = h_file->f_mapping; ++ smp_mb(); /* unnecessary? */ ++ } ++ err = vfsub_splice_to(h_file, ppos, pipe, len, flags); ++ /* todo: necessasry? */ ++ /* file->f_ra = h_file->f_ra; */ ++ fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode); ++ ++ di_read_unlock(dentry, AuLock_IR); ++ fi_read_unlock(file); ++ ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++static ssize_t ++aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos, ++ size_t len, unsigned int flags) ++{ ++ ssize_t err; ++ struct au_pin pin; ++ struct dentry *dentry; ++ struct inode *inode; ++ struct super_block *sb; ++ struct file *h_file; ++ ++ dentry = file->f_dentry; ++ inode = dentry->d_inode; ++ mutex_lock(&inode->i_mutex); ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ au_unpin(&pin); ++ err = vfsub_splice_from(pipe, h_file, ppos, len, flags); ++ au_cpup_attr_timesizes(inode); ++ inode->i_mode = h_file->f_dentry->d_inode->i_mode; ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ out: ++ si_read_unlock(sb); ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct file *au_safe_file(struct vm_area_struct *vma) ++{ ++ struct file *file; ++ ++ file = vma->vm_file; ++ if (file->private_data && au_test_aufs(file->f_dentry->d_sb)) ++ return file; ++ return NULL; ++} ++ ++static void au_reset_file(struct vm_area_struct *vma, struct file *file) ++{ ++ vma->vm_file = file; ++ /* smp_mb(); */ /* flush vm_file */ ++} ++ ++static int aufs_fault(struct vm_area_struct *vma, struct vm_fault *vmf) ++{ ++ int err; ++ static DECLARE_WAIT_QUEUE_HEAD(wq); ++ struct file *file, *h_file; ++ struct au_finfo *finfo; ++ ++ /* todo: non-robr mode, user vm_file as it is? */ ++ wait_event(wq, (file = au_safe_file(vma))); ++ ++ /* do not revalidate, no si lock */ ++ finfo = au_fi(file); ++ h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file; ++ AuDebugOn(!h_file || !finfo->fi_h_vm_ops); ++ ++ fi_write_lock(file); ++ vma->vm_file = h_file; ++ err = finfo->fi_h_vm_ops->fault(vma, vmf); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ au_reset_file(vma, file); ++ fi_write_unlock(file); ++#if 0 /* def CONFIG_SMP */ ++ /* wake_up_nr(&wq, online_cpu - 1); */ ++ wake_up_all(&wq); ++#else ++ wake_up(&wq); ++#endif ++ ++ return err; ++} ++ ++static int aufs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) ++{ ++ int err; ++ static DECLARE_WAIT_QUEUE_HEAD(wq); ++ struct file *file, *h_file; ++ struct au_finfo *finfo; ++ ++ wait_event(wq, (file = au_safe_file(vma))); ++ ++ finfo = au_fi(file); ++ h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file; ++ AuDebugOn(!h_file || !finfo->fi_h_vm_ops); ++ ++ fi_write_lock(file); ++ vma->vm_file = h_file; ++ err = finfo->fi_h_vm_ops->page_mkwrite(vma, vmf); ++ au_reset_file(vma, file); ++ fi_write_unlock(file); ++ wake_up(&wq); ++ ++ return err; ++} ++ ++static void aufs_vm_close(struct vm_area_struct *vma) ++{ ++ static DECLARE_WAIT_QUEUE_HEAD(wq); ++ struct file *file, *h_file; ++ struct au_finfo *finfo; ++ ++ wait_event(wq, (file = au_safe_file(vma))); ++ ++ finfo = au_fi(file); ++ h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file; ++ AuDebugOn(!h_file || !finfo->fi_h_vm_ops); ++ ++ fi_write_lock(file); ++ vma->vm_file = h_file; ++ finfo->fi_h_vm_ops->close(vma); ++ au_reset_file(vma, file); ++ fi_write_unlock(file); ++ wake_up(&wq); ++} ++ ++static struct vm_operations_struct aufs_vm_ops = { ++ /* .close and .page_mkwrite are not set by default */ ++ .fault = aufs_fault, ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct vm_operations_struct *au_vm_ops(struct file *h_file, ++ struct vm_area_struct *vma) ++{ ++ struct vm_operations_struct *vm_ops; ++ int err; ++ ++ vm_ops = ERR_PTR(-ENODEV); ++ if (!h_file->f_op || !h_file->f_op->mmap) ++ goto out; ++ ++ err = h_file->f_op->mmap(h_file, vma); ++ vm_ops = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ ++ vm_ops = vma->vm_ops; ++ err = do_munmap(current->mm, vma->vm_start, ++ vma->vm_end - vma->vm_start); ++ if (unlikely(err)) { ++ AuIOErr("failed internal unmapping %.*s, %d\n", ++ AuDLNPair(h_file->f_dentry), err); ++ vm_ops = ERR_PTR(-EIO); ++ } ++ ++ out: ++ return vm_ops; ++} ++ ++static int au_custom_vm_ops(struct au_finfo *finfo, struct vm_area_struct *vma) ++{ ++ int err; ++ struct vm_operations_struct *h_ops; ++ ++ AuRwMustAnyLock(&finfo->fi_rwsem); ++ ++ err = 0; ++ h_ops = finfo->fi_h_vm_ops; ++ AuDebugOn(!h_ops); ++ if ((!h_ops->page_mkwrite && !h_ops->close) ++ || finfo->fi_vm_ops) ++ goto out; ++ ++ err = -ENOMEM; ++ finfo->fi_vm_ops = kmemdup(&aufs_vm_ops, sizeof(aufs_vm_ops), GFP_NOFS); ++ if (unlikely(!finfo->fi_vm_ops)) ++ goto out; ++ ++ err = 0; ++ if (h_ops->page_mkwrite) ++ finfo->fi_vm_ops->page_mkwrite = aufs_page_mkwrite; ++ if (h_ops->close) ++ finfo->fi_vm_ops->close = aufs_vm_close; ++ ++ vma->vm_ops = finfo->fi_vm_ops; ++ ++ out: ++ return err; ++} ++ ++static int aufs_mmap(struct file *file, struct vm_area_struct *vma) ++{ ++ int err; ++ unsigned char wlock, mmapped; ++ struct dentry *dentry; ++ struct super_block *sb; ++ struct file *h_file; ++ struct vm_operations_struct *vm_ops; ++ ++ dentry = file->f_dentry; ++ wlock = !!(file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED); ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ mmapped = !!au_test_mmapped(file); ++ if (wlock) { ++ struct au_pin pin; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ au_unpin(&pin); ++ } else ++ di_downgrade_lock(dentry, AuLock_IR); ++ ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ if (!mmapped && au_test_fs_bad_mapping(h_file->f_dentry->d_sb)) { ++ /* ++ * by this assignment, f_mapping will differs from aufs inode ++ * i_mapping. ++ * if someone else mixes the use of f_dentry->d_inode and ++ * f_mapping->host, then a problem may arise. ++ */ ++ file->f_mapping = h_file->f_mapping; ++ } ++ ++ vm_ops = NULL; ++ if (!mmapped) { ++ vm_ops = au_vm_ops(h_file, vma); ++ err = PTR_ERR(vm_ops); ++ if (IS_ERR(vm_ops)) ++ goto out_unlock; ++ } ++ ++ /* ++ * unnecessary to handle MAP_DENYWRITE and deny_write_access()? ++ * currently MAP_DENYWRITE from userspace is ignored, but elf loader ++ * sets it. when FMODE_EXEC is set (by open_exec() or sys_uselib()), ++ * both of the aufs file and the lower file is deny_write_access()-ed. ++ * finally I hope we can skip handlling MAP_DENYWRITE here. ++ */ ++ err = generic_file_mmap(file, vma); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ vma->vm_ops = &aufs_vm_ops; ++ /* test again */ ++ if (!au_test_mmapped(file)) ++ au_fi(file)->fi_h_vm_ops = vm_ops; ++ ++ err = au_custom_vm_ops(au_fi(file), vma); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ vfsub_file_accessed(h_file); ++ fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode); ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int aufs_fsync_nondir(struct file *file, struct dentry *dentry, ++ int datasync) ++{ ++ int err; ++ struct au_pin pin; ++ struct inode *inode; ++ struct file *h_file; ++ struct super_block *sb; ++ ++ inode = dentry->d_inode; ++ IMustLock(file->f_mapping->host); ++ if (inode != file->f_mapping->host) { ++ mutex_unlock(&file->f_mapping->host->i_mutex); ++ mutex_lock(&inode->i_mutex); ++ } ++ IMustLock(inode); ++ ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ err = 0; /* -EBADF; */ /* posix? */ ++ if (unlikely(!(file->f_mode & FMODE_WRITE))) ++ goto out; ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ au_unpin(&pin); ++ ++ err = -EINVAL; ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ if (h_file->f_op && h_file->f_op->fsync) { ++ struct dentry *h_d; ++ struct mutex *h_mtx; ++ ++ /* ++ * no filemap_fdatawrite() since aufs file has no its own ++ * mapping, but dir. ++ */ ++ h_d = h_file->f_dentry; ++ h_mtx = &h_d->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ err = h_file->f_op->fsync(h_file, h_d, datasync); ++ if (!err) ++ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); ++ /*ignore*/ ++ au_cpup_attr_timesizes(inode); ++ mutex_unlock(h_mtx); ++ } ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ out: ++ si_read_unlock(sb); ++ if (inode != file->f_mapping->host) { ++ mutex_unlock(&inode->i_mutex); ++ mutex_lock(&file->f_mapping->host->i_mutex); ++ } ++ return err; ++} ++ ++/* no one supports this operation, currently */ ++#if 0 ++static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync) ++{ ++ int err; ++ struct au_pin pin; ++ struct dentry *dentry; ++ struct inode *inode; ++ struct file *file, *h_file; ++ struct super_block *sb; ++ ++ file = kio->ki_filp; ++ dentry = file->f_dentry; ++ inode = dentry->d_inode; ++ mutex_lock(&inode->i_mutex); ++ ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ err = 0; /* -EBADF; */ /* posix? */ ++ if (unlikely(!(file->f_mode & FMODE_WRITE))) ++ goto out; ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ au_unpin(&pin); ++ ++ err = -ENOSYS; ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ if (h_file->f_op && h_file->f_op->aio_fsync) { ++ struct dentry *h_d; ++ struct mutex *h_mtx; ++ ++ h_d = h_file->f_dentry; ++ h_mtx = &h_d->d_inode->i_mutex; ++ if (!is_sync_kiocb(kio)) { ++ get_file(h_file); ++ fput(file); ++ } ++ kio->ki_filp = h_file; ++ err = h_file->f_op->aio_fsync(kio, datasync); ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ if (!err) ++ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); ++ /*ignore*/ ++ au_cpup_attr_timesizes(inode); ++ mutex_unlock(h_mtx); ++ } ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ out: ++ si_read_unlock(sb); ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++#endif ++ ++static int aufs_fasync(int fd, struct file *file, int flag) ++{ ++ int err; ++ struct file *h_file; ++ struct dentry *dentry; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ if (h_file->f_op && h_file->f_op->fasync) ++ err = h_file->f_op->fasync(fd, h_file, flag); ++ ++ di_read_unlock(dentry, AuLock_IR); ++ fi_read_unlock(file); ++ ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* no one supports this operation, currently */ ++#if 0 ++static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset, ++ size_t len, loff_t *pos , int more) ++{ ++} ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ ++const struct file_operations aufs_file_fop = { ++ /* ++ * while generic_file_llseek/_unlocked() don't use BKL, ++ * don't use it since it operates file->f_mapping->host. ++ * in aufs, it may be a real file and may confuse users by UDBA. ++ */ ++ /* .llseek = generic_file_llseek, */ ++ ++ .read = aufs_read, ++ .write = aufs_write, ++ .aio_read = aufs_aio_read, ++ .aio_write = aufs_aio_write, ++#ifdef CONFIG_AUFS_POLL ++ .poll = aufs_poll, ++#endif ++ .mmap = aufs_mmap, ++ .open = aufs_open_nondir, ++ .flush = aufs_flush, ++ .release = aufs_release_nondir, ++ .fsync = aufs_fsync_nondir, ++ /* .aio_fsync = aufs_aio_fsync_nondir, */ ++ .fasync = aufs_fasync, ++ /* .sendpage = aufs_sendpage, */ ++ .splice_write = aufs_splice_write, ++ .splice_read = aufs_splice_read, ++#if 0 ++ .aio_splice_write = aufs_aio_splice_write, ++ .aio_splice_read = aufs_aio_splice_read ++#endif ++}; +diff --git a/fs/aufs/file.c b/fs/aufs/file.c +new file mode 100644 +index 0000000..081856b +--- /dev/null ++++ b/fs/aufs/file.c +@@ -0,0 +1,578 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * handling file/dir, and address_space operation ++ */ ++ ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++/* ++ * a dirty trick for handling deny_write_access(). ++ * because FMODE_EXEC flag is not passed to f_op->open(), ++ * set it to file->private_data temporary. ++ */ ++void au_store_oflag(struct nameidata *nd, struct inode *inode) ++{ ++ if (nd ++ /* && !(nd->flags & LOOKUP_CONTINUE) */ ++ && (nd->flags & LOOKUP_OPEN) ++ && (nd->intent.open.flags & vfsub_fmode_to_uint(FMODE_EXEC)) ++ && inode ++ && S_ISREG(inode->i_mode)) { ++ /* suppress a warning in lp64 */ ++ unsigned long flags = nd->intent.open.flags; ++ nd->intent.open.file->private_data = (void *)flags; ++ /* smp_mb(); */ ++ } ++} ++ ++/* drop flags for writing */ ++unsigned int au_file_roflags(unsigned int flags) ++{ ++ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC); ++ flags |= O_RDONLY | O_NOATIME; ++ return flags; ++} ++ ++/* common functions to regular file and dir */ ++struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, ++ struct file *file) ++{ ++ struct file *h_file; ++ struct dentry *h_dentry; ++ struct inode *h_inode; ++ struct super_block *sb; ++ struct au_branch *br; ++ int err; ++ ++ /* a race condition can happen between open and unlink/rmdir */ ++ h_file = ERR_PTR(-ENOENT); ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (au_test_nfsd(current) && !h_dentry) ++ goto out; ++ h_inode = h_dentry->d_inode; ++ if (au_test_nfsd(current) && !h_inode) ++ goto out; ++ if (unlikely((!d_unhashed(dentry) && d_unhashed(h_dentry)) ++ || !h_inode)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ br = au_sbr(sb, bindex); ++ h_file = ERR_PTR(-EACCES); ++ if (file && (file->f_mode & FMODE_EXEC) ++ && (br->br_mnt->mnt_flags & MNT_NOEXEC)) ++ goto out; ++ ++ /* drop flags for writing */ ++ if (au_test_ro(sb, bindex, dentry->d_inode)) ++ flags = au_file_roflags(flags); ++ flags &= ~O_CREAT; ++ atomic_inc(&br->br_count); ++ h_file = dentry_open(dget(h_dentry), mntget(br->br_mnt), flags, ++ current_cred()); ++ if (IS_ERR(h_file)) ++ goto out_br; ++ ++ if (file && (file->f_mode & FMODE_EXEC)) { ++ h_file->f_mode |= FMODE_EXEC; ++ err = deny_write_access(h_file); ++ if (unlikely(err)) { ++ fput(h_file); ++ h_file = ERR_PTR(err); ++ goto out_br; ++ } ++ } ++ fsnotify_open(h_dentry); ++ goto out; /* success */ ++ ++ out_br: ++ atomic_dec(&br->br_count); ++ out: ++ return h_file; ++} ++ ++int au_do_open(struct file *file, int (*open)(struct file *file, int flags)) ++{ ++ int err; ++ struct dentry *dentry; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_finfo_init(file); ++ if (unlikely(err)) ++ goto out; ++ ++ di_read_lock_child(dentry, AuLock_IR); ++ err = open(file, file->f_flags); ++ di_read_unlock(dentry, AuLock_IR); ++ ++ fi_write_unlock(file); ++ if (unlikely(err)) ++ au_finfo_fin(file); ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++int au_reopen_nondir(struct file *file) ++{ ++ int err; ++ aufs_bindex_t bstart, bindex, bend; ++ struct dentry *dentry; ++ struct file *h_file, *h_file_tmp; ++ ++ dentry = file->f_dentry; ++ bstart = au_dbstart(dentry); ++ h_file_tmp = NULL; ++ if (au_fbstart(file) == bstart) { ++ h_file = au_h_fptr(file, bstart); ++ if (file->f_mode == h_file->f_mode) ++ return 0; /* success */ ++ h_file_tmp = h_file; ++ get_file(h_file_tmp); ++ au_set_h_fptr(file, bstart, NULL); ++ } ++ AuDebugOn(au_fbstart(file) < bstart ++ || au_fi(file)->fi_hfile[0 + bstart].hf_file); ++ ++ h_file = au_h_open(dentry, bstart, file->f_flags & ~O_TRUNC, file); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; /* todo: close all? */ ++ ++ err = 0; ++ au_set_fbstart(file, bstart); ++ au_set_h_fptr(file, bstart, h_file); ++ au_update_figen(file); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ ++ /* close lower files */ ++ bend = au_fbend(file); ++ for (bindex = bstart + 1; bindex <= bend; bindex++) ++ au_set_h_fptr(file, bindex, NULL); ++ au_set_fbend(file, bstart); ++ ++ out: ++ if (h_file_tmp) ++ fput(h_file_tmp); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_reopen_wh(struct file *file, aufs_bindex_t btgt, ++ struct dentry *hi_wh) ++{ ++ int err; ++ aufs_bindex_t bstart; ++ struct au_dinfo *dinfo; ++ struct dentry *h_dentry; ++ ++ dinfo = au_di(file->f_dentry); ++ AuRwMustWriteLock(&dinfo->di_rwsem); ++ ++ bstart = dinfo->di_bstart; ++ dinfo->di_bstart = btgt; ++ h_dentry = dinfo->di_hdentry[0 + btgt].hd_dentry; ++ dinfo->di_hdentry[0 + btgt].hd_dentry = hi_wh; ++ err = au_reopen_nondir(file); ++ dinfo->di_hdentry[0 + btgt].hd_dentry = h_dentry; ++ dinfo->di_bstart = bstart; ++ ++ return err; ++} ++ ++static int au_ready_to_write_wh(struct file *file, loff_t len, ++ aufs_bindex_t bcpup) ++{ ++ int err; ++ struct inode *inode; ++ struct dentry *dentry, *hi_wh; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ inode = dentry->d_inode; ++ hi_wh = au_hi_wh(inode, bcpup); ++ if (!hi_wh) ++ err = au_sio_cpup_wh(dentry, bcpup, len, file); ++ else ++ /* already copied-up after unlink */ ++ err = au_reopen_wh(file, bcpup, hi_wh); ++ ++ sb = dentry->d_sb; ++ if (!err && inode->i_nlink > 1 && au_opt_test(au_mntflags(sb), PLINK)) ++ au_plink_append(inode, bcpup, au_h_dptr(dentry, bcpup)); ++ ++ return err; ++} ++ ++/* ++ * prepare the @file for writing. ++ */ ++int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin) ++{ ++ int err; ++ aufs_bindex_t bstart, bcpup; ++ struct dentry *dentry, *parent, *h_dentry; ++ struct inode *h_inode, *inode; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ bstart = au_fbstart(file); ++ inode = dentry->d_inode; ++ err = au_test_ro(sb, bstart, inode); ++ if (!err && (au_h_fptr(file, bstart)->f_mode & FMODE_WRITE)) { ++ err = au_pin(pin, dentry, bstart, AuOpt_UDBA_NONE, /*flags*/0); ++ goto out; ++ } ++ ++ /* need to cpup */ ++ parent = dget_parent(dentry); ++ di_write_lock_parent(parent); ++ err = AuWbrCopyup(au_sbi(sb), dentry); ++ bcpup = err; ++ if (unlikely(err < 0)) ++ goto out_dgrade; ++ err = 0; ++ ++ if (!au_h_dptr(parent, bcpup)) { ++ err = au_cpup_dirs(dentry, bcpup); ++ if (unlikely(err)) ++ goto out_dgrade; ++ } ++ ++ err = au_pin(pin, dentry, bcpup, AuOpt_UDBA_NONE, ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (unlikely(err)) ++ goto out_dgrade; ++ ++ h_dentry = au_h_fptr(file, bstart)->f_dentry; ++ h_inode = h_dentry->d_inode; ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ if (d_unhashed(dentry) /* || d_unhashed(h_dentry) */ ++ /* || !h_inode->i_nlink */) { ++ err = au_ready_to_write_wh(file, len, bcpup); ++ di_downgrade_lock(parent, AuLock_IR); ++ } else { ++ di_downgrade_lock(parent, AuLock_IR); ++ if (!au_h_dptr(dentry, bcpup)) ++ err = au_sio_cpup_simple(dentry, bcpup, len, ++ AuCpup_DTIME); ++ if (!err) ++ err = au_reopen_nondir(file); ++ } ++ mutex_unlock(&h_inode->i_mutex); ++ ++ if (!err) { ++ au_pin_set_parent_lflag(pin, /*lflag*/0); ++ goto out_dput; /* success */ ++ } ++ au_unpin(pin); ++ goto out_unlock; ++ ++ out_dgrade: ++ di_downgrade_lock(parent, AuLock_IR); ++ out_unlock: ++ di_read_unlock(parent, AuLock_IR); ++ out_dput: ++ dput(parent); ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_file_refresh_by_inode(struct file *file, int *need_reopen) ++{ ++ int err; ++ aufs_bindex_t bstart; ++ struct au_pin pin; ++ struct au_finfo *finfo; ++ struct dentry *dentry, *parent, *hi_wh; ++ struct inode *inode; ++ struct super_block *sb; ++ ++ FiMustWriteLock(file); ++ ++ err = 0; ++ finfo = au_fi(file); ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ bstart = au_ibstart(inode); ++ if (bstart == finfo->fi_bstart) ++ goto out; ++ ++ parent = dget_parent(dentry); ++ if (au_test_ro(sb, bstart, inode)) { ++ di_read_lock_parent(parent, !AuLock_IR); ++ err = AuWbrCopyup(au_sbi(sb), dentry); ++ bstart = err; ++ di_read_unlock(parent, !AuLock_IR); ++ if (unlikely(err < 0)) ++ goto out_parent; ++ err = 0; ++ } ++ ++ di_read_lock_parent(parent, AuLock_IR); ++ hi_wh = au_hi_wh(inode, bstart); ++ if (au_opt_test(au_mntflags(sb), PLINK) ++ && au_plink_test(inode) ++ && !d_unhashed(dentry)) { ++ err = au_test_and_cpup_dirs(dentry, bstart); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ /* always superio. */ ++ err = au_pin(&pin, dentry, bstart, AuOpt_UDBA_NONE, ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (!err) ++ err = au_sio_cpup_simple(dentry, bstart, -1, ++ AuCpup_DTIME); ++ au_unpin(&pin); ++ } else if (hi_wh) { ++ /* already copied-up after unlink */ ++ err = au_reopen_wh(file, bstart, hi_wh); ++ *need_reopen = 0; ++ } ++ ++ out_unlock: ++ di_read_unlock(parent, AuLock_IR); ++ out_parent: ++ dput(parent); ++ out: ++ return err; ++} ++ ++static void au_do_refresh_file(struct file *file) ++{ ++ aufs_bindex_t bindex, bend, new_bindex, brid; ++ struct au_hfile *p, tmp, *q; ++ struct au_finfo *finfo; ++ struct super_block *sb; ++ ++ FiMustWriteLock(file); ++ ++ sb = file->f_dentry->d_sb; ++ finfo = au_fi(file); ++ p = finfo->fi_hfile + finfo->fi_bstart; ++ brid = p->hf_br->br_id; ++ bend = finfo->fi_bend; ++ for (bindex = finfo->fi_bstart; bindex <= bend; bindex++, p++) { ++ if (!p->hf_file) ++ continue; ++ ++ new_bindex = au_br_index(sb, p->hf_br->br_id); ++ if (new_bindex == bindex) ++ continue; ++ if (new_bindex < 0) { ++ au_set_h_fptr(file, bindex, NULL); ++ continue; ++ } ++ ++ /* swap two lower inode, and loop again */ ++ q = finfo->fi_hfile + new_bindex; ++ tmp = *q; ++ *q = *p; ++ *p = tmp; ++ if (tmp.hf_file) { ++ bindex--; ++ p--; ++ } ++ } ++ ++ p = finfo->fi_hfile; ++ if (!au_test_mmapped(file) && !d_unhashed(file->f_dentry)) { ++ bend = au_sbend(sb); ++ for (finfo->fi_bstart = 0; finfo->fi_bstart <= bend; ++ finfo->fi_bstart++, p++) ++ if (p->hf_file) { ++ if (p->hf_file->f_dentry ++ && p->hf_file->f_dentry->d_inode) ++ break; ++ else ++ au_hfput(p, file); ++ } ++ } else { ++ bend = au_br_index(sb, brid); ++ for (finfo->fi_bstart = 0; finfo->fi_bstart < bend; ++ finfo->fi_bstart++, p++) ++ if (p->hf_file) ++ au_hfput(p, file); ++ bend = au_sbend(sb); ++ } ++ ++ p = finfo->fi_hfile + bend; ++ for (finfo->fi_bend = bend; finfo->fi_bend >= finfo->fi_bstart; ++ finfo->fi_bend--, p--) ++ if (p->hf_file) { ++ if (p->hf_file->f_dentry ++ && p->hf_file->f_dentry->d_inode) ++ break; ++ else ++ au_hfput(p, file); ++ } ++ AuDebugOn(finfo->fi_bend < finfo->fi_bstart); ++} ++ ++/* ++ * after branch manipulating, refresh the file. ++ */ ++static int refresh_file(struct file *file, int (*reopen)(struct file *file)) ++{ ++ int err, need_reopen; ++ struct dentry *dentry; ++ aufs_bindex_t bend, bindex; ++ ++ dentry = file->f_dentry; ++ err = au_fi_realloc(au_fi(file), au_sbend(dentry->d_sb) + 1); ++ if (unlikely(err)) ++ goto out; ++ au_do_refresh_file(file); ++ ++ err = 0; ++ need_reopen = 1; ++ if (!au_test_mmapped(file)) ++ err = au_file_refresh_by_inode(file, &need_reopen); ++ if (!err && need_reopen && !d_unhashed(dentry)) ++ err = reopen(file); ++ if (!err) { ++ au_update_figen(file); ++ return 0; /* success */ ++ } ++ ++ /* error, close all lower files */ ++ bend = au_fbend(file); ++ for (bindex = au_fbstart(file); bindex <= bend; bindex++) ++ au_set_h_fptr(file, bindex, NULL); ++ ++ out: ++ return err; ++} ++ ++/* common function to regular file and dir */ ++int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file), ++ int wlock) ++{ ++ int err; ++ unsigned int sigen, figen; ++ aufs_bindex_t bstart; ++ unsigned char pseudo_link; ++ struct dentry *dentry; ++ ++ err = 0; ++ dentry = file->f_dentry; ++ sigen = au_sigen(dentry->d_sb); ++ fi_write_lock(file); ++ figen = au_figen(file); ++ di_write_lock_child(dentry); ++ bstart = au_dbstart(dentry); ++ pseudo_link = (bstart != au_ibstart(dentry->d_inode)); ++ if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) { ++ if (!wlock) { ++ di_downgrade_lock(dentry, AuLock_IR); ++ fi_downgrade_lock(file); ++ } ++ goto out; /* success */ ++ } ++ ++ AuDbg("sigen %d, figen %d\n", sigen, figen); ++ if (sigen != au_digen(dentry) ++ || sigen != au_iigen(dentry->d_inode)) { ++ err = au_reval_dpath(dentry, sigen); ++ if (unlikely(err < 0)) ++ goto out; ++ AuDebugOn(au_digen(dentry) != sigen ++ || au_iigen(dentry->d_inode) != sigen); ++ } ++ ++ err = refresh_file(file, reopen); ++ if (!err) { ++ if (!wlock) { ++ di_downgrade_lock(dentry, AuLock_IR); ++ fi_downgrade_lock(file); ++ } ++ } else { ++ di_write_unlock(dentry); ++ fi_write_unlock(file); ++ } ++ ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* cf. aufs_nopage() */ ++/* for madvise(2) */ ++static int aufs_readpage(struct file *file __maybe_unused, struct page *page) ++{ ++ unlock_page(page); ++ return 0; ++} ++ ++/* they will never be called. */ ++#ifdef CONFIG_AUFS_DEBUG ++static int aufs_write_begin(struct file *file, struct address_space *mapping, ++ loff_t pos, unsigned len, unsigned flags, ++ struct page **pagep, void **fsdata) ++{ AuUnsupport(); return 0; } ++static int aufs_write_end(struct file *file, struct address_space *mapping, ++ loff_t pos, unsigned len, unsigned copied, ++ struct page *page, void *fsdata) ++{ AuUnsupport(); return 0; } ++static int aufs_writepage(struct page *page, struct writeback_control *wbc) ++{ AuUnsupport(); return 0; } ++static void aufs_sync_page(struct page *page) ++{ AuUnsupport(); } ++ ++static int aufs_set_page_dirty(struct page *page) ++{ AuUnsupport(); return 0; } ++static void aufs_invalidatepage(struct page *page, unsigned long offset) ++{ AuUnsupport(); } ++static int aufs_releasepage(struct page *page, gfp_t gfp) ++{ AuUnsupport(); return 0; } ++static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb, ++ const struct iovec *iov, loff_t offset, ++ unsigned long nr_segs) ++{ AuUnsupport(); return 0; } ++#endif /* CONFIG_AUFS_DEBUG */ ++ ++struct address_space_operations aufs_aop = { ++ .readpage = aufs_readpage, ++#ifdef CONFIG_AUFS_DEBUG ++ .writepage = aufs_writepage, ++ .sync_page = aufs_sync_page, ++ .set_page_dirty = aufs_set_page_dirty, ++ .write_begin = aufs_write_begin, ++ .write_end = aufs_write_end, ++ .invalidatepage = aufs_invalidatepage, ++ .releasepage = aufs_releasepage, ++ .direct_IO = aufs_direct_IO, ++#endif /* CONFIG_AUFS_DEBUG */ ++}; +diff --git a/fs/aufs/file.h b/fs/aufs/file.h +new file mode 100644 +index 0000000..ceeeb38 +--- /dev/null ++++ b/fs/aufs/file.h +@@ -0,0 +1,175 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * file operations ++ */ ++ ++#ifndef __AUFS_FILE_H__ ++#define __AUFS_FILE_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++#include "rwsem.h" ++ ++struct au_branch; ++struct au_hfile { ++ struct file *hf_file; ++ struct au_branch *hf_br; ++}; ++ ++struct au_vdir; ++struct au_finfo { ++ atomic_t fi_generation; ++ ++ struct au_rwsem fi_rwsem; ++ struct au_hfile *fi_hfile; ++ aufs_bindex_t fi_bstart, fi_bend; ++ ++ union { ++ /* non-dir only */ ++ struct { ++ struct vm_operations_struct *fi_h_vm_ops; ++ struct vm_operations_struct *fi_vm_ops; ++ }; ++ ++ /* dir only */ ++ struct { ++ struct au_vdir *fi_vdir_cache; ++ int fi_maintain_plink; ++ }; ++ }; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* file.c */ ++extern struct address_space_operations aufs_aop; ++void au_store_oflag(struct nameidata *nd, struct inode *inode); ++unsigned int au_file_roflags(unsigned int flags); ++struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, ++ struct file *file); ++int au_do_open(struct file *file, int (*open)(struct file *file, int flags)); ++int au_reopen_nondir(struct file *file); ++struct au_pin; ++int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin); ++int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file), ++ int wlock); ++ ++/* poll.c */ ++#ifdef CONFIG_AUFS_POLL ++unsigned int aufs_poll(struct file *file, poll_table *wait); ++#endif ++ ++/* f_op.c */ ++extern const struct file_operations aufs_file_fop; ++int aufs_flush(struct file *file, fl_owner_t id); ++ ++/* finfo.c */ ++void au_hfput(struct au_hfile *hf, struct file *file); ++void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, ++ struct file *h_file); ++ ++void au_update_figen(struct file *file); ++ ++void au_finfo_fin(struct file *file); ++int au_finfo_init(struct file *file); ++int au_fi_realloc(struct au_finfo *finfo, int nbr); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct au_finfo *au_fi(struct file *file) ++{ ++ return file->private_data; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * fi_read_lock, fi_write_lock, ++ * fi_read_unlock, fi_write_unlock, fi_downgrade_lock ++ */ ++AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem); ++ ++#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem) ++#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem) ++#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem) ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* todo: hard/soft set? */ ++static inline aufs_bindex_t au_fbstart(struct file *file) ++{ ++ FiMustAnyLock(file); ++ return au_fi(file)->fi_bstart; ++} ++ ++static inline aufs_bindex_t au_fbend(struct file *file) ++{ ++ FiMustAnyLock(file); ++ return au_fi(file)->fi_bend; ++} ++ ++static inline struct au_vdir *au_fvdir_cache(struct file *file) ++{ ++ FiMustAnyLock(file); ++ return au_fi(file)->fi_vdir_cache; ++} ++ ++static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex) ++{ ++ FiMustWriteLock(file); ++ au_fi(file)->fi_bstart = bindex; ++} ++ ++static inline void au_set_fbend(struct file *file, aufs_bindex_t bindex) ++{ ++ FiMustWriteLock(file); ++ au_fi(file)->fi_bend = bindex; ++} ++ ++static inline void au_set_fvdir_cache(struct file *file, ++ struct au_vdir *vdir_cache) ++{ ++ FiMustWriteLock(file); ++ au_fi(file)->fi_vdir_cache = vdir_cache; ++} ++ ++static inline struct file *au_h_fptr(struct file *file, aufs_bindex_t bindex) ++{ ++ FiMustAnyLock(file); ++ return au_fi(file)->fi_hfile[0 + bindex].hf_file; ++} ++ ++/* todo: memory barrier? */ ++static inline unsigned int au_figen(struct file *f) ++{ ++ return atomic_read(&au_fi(f)->fi_generation); ++} ++ ++static inline int au_test_mmapped(struct file *f) ++{ ++ /* FiMustAnyLock(f); */ ++ return !!(au_fi(f)->fi_h_vm_ops); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_FILE_H__ */ +diff --git a/fs/aufs/finfo.c b/fs/aufs/finfo.c +new file mode 100644 +index 0000000..16e5c67 +--- /dev/null ++++ b/fs/aufs/finfo.c +@@ -0,0 +1,133 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * file private data ++ */ ++ ++#include ++#include "aufs.h" ++ ++void au_hfput(struct au_hfile *hf, struct file *file) ++{ ++ if (file->f_mode & FMODE_EXEC) ++ allow_write_access(hf->hf_file); ++ fput(hf->hf_file); ++ hf->hf_file = NULL; ++ atomic_dec_return(&hf->hf_br->br_count); ++ hf->hf_br = NULL; ++} ++ ++void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val) ++{ ++ struct au_finfo *finfo = au_fi(file); ++ struct au_hfile *hf; ++ ++ hf = finfo->fi_hfile + bindex; ++ if (hf->hf_file) ++ au_hfput(hf, file); ++ if (val) { ++ hf->hf_file = val; ++ hf->hf_br = au_sbr(file->f_dentry->d_sb, bindex); ++ } ++} ++ ++void au_update_figen(struct file *file) ++{ ++ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_dentry)); ++ /* smp_mb(); */ /* atomic_set */ ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_finfo_fin(struct file *file) ++{ ++ struct au_finfo *finfo; ++ aufs_bindex_t bindex, bend; ++ ++ fi_write_lock(file); ++ bend = au_fbend(file); ++ bindex = au_fbstart(file); ++ if (bindex >= 0) ++ /* ++ * calls fput() instead of filp_close(), ++ * since no dnotify or lock for the lower file. ++ */ ++ for (; bindex <= bend; bindex++) ++ au_set_h_fptr(file, bindex, NULL); ++ ++ finfo = au_fi(file); ++ au_dbg_verify_hf(finfo); ++ kfree(finfo->fi_hfile); ++ fi_write_unlock(file); ++ AuRwDestroy(&finfo->fi_rwsem); ++ au_cache_free_finfo(finfo); ++} ++ ++int au_finfo_init(struct file *file) ++{ ++ struct au_finfo *finfo; ++ struct dentry *dentry; ++ unsigned long ul; ++ ++ dentry = file->f_dentry; ++ finfo = au_cache_alloc_finfo(); ++ if (unlikely(!finfo)) ++ goto out; ++ ++ finfo->fi_hfile = kcalloc(au_sbend(dentry->d_sb) + 1, ++ sizeof(*finfo->fi_hfile), GFP_NOFS); ++ if (unlikely(!finfo->fi_hfile)) ++ goto out_finfo; ++ ++ au_rw_init_wlock(&finfo->fi_rwsem); ++ finfo->fi_bstart = -1; ++ finfo->fi_bend = -1; ++ atomic_set(&finfo->fi_generation, au_digen(dentry)); ++ /* smp_mb(); */ /* atomic_set */ ++ ++ /* cf. au_store_oflag() */ ++ /* suppress a warning in lp64 */ ++ ul = (unsigned long)file->private_data; ++ file->f_mode |= (vfsub_uint_to_fmode(ul) & FMODE_EXEC); ++ file->private_data = finfo; ++ return 0; /* success */ ++ ++ out_finfo: ++ au_cache_free_finfo(finfo); ++ out: ++ return -ENOMEM; ++} ++ ++int au_fi_realloc(struct au_finfo *finfo, int nbr) ++{ ++ int err, sz; ++ struct au_hfile *hfp; ++ ++ err = -ENOMEM; ++ sz = sizeof(*hfp) * (finfo->fi_bend + 1); ++ if (!sz) ++ sz = sizeof(*hfp); ++ hfp = au_kzrealloc(finfo->fi_hfile, sz, sizeof(*hfp) * nbr, GFP_NOFS); ++ if (hfp) { ++ finfo->fi_hfile = hfp; ++ err = 0; ++ } ++ ++ return err; ++} +diff --git a/fs/aufs/fstype.h b/fs/aufs/fstype.h +new file mode 100644 +index 0000000..be664a0 +--- /dev/null ++++ b/fs/aufs/fstype.h +@@ -0,0 +1,474 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * judging filesystem type ++ */ ++ ++#ifndef __AUFS_FSTYPE_H__ ++#define __AUFS_FSTYPE_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static inline int au_test_aufs(struct super_block *sb) ++{ ++ return sb->s_magic == AUFS_SUPER_MAGIC; ++} ++ ++static inline const char *au_sbtype(struct super_block *sb) ++{ ++ return sb->s_type->name; ++} ++ ++static inline int au_test_iso9660(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE) ++ return sb->s_magic == ROMFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_romfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE) ++ return sb->s_magic == ISOFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_cramfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE) ++ return sb->s_magic == CRAMFS_MAGIC; ++#endif ++ return 0; ++} ++ ++static inline int au_test_nfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE) ++ return sb->s_magic == NFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_fuse(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE) ++ return sb->s_magic == FUSE_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_xfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE) ++ return sb->s_magic == XFS_SB_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_tmpfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_TMPFS ++ return sb->s_magic == TMPFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE) ++ return !strcmp(au_sbtype(sb), "ecryptfs"); ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_smbfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_SMB_FS) || defined(CONFIG_SMB_FS_MODULE) ++ return sb->s_magic == SMB_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ocfs2(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE) ++ return sb->s_magic == OCFS2_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_OCFS2_FS_O2CB) || defined(CONFIG_OCFS2_FS_O2CB_MODULE) ++ return sb->s_magic == DLMFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_coda(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_CODA_FS) || defined(CONFIG_CODA_FS_MODULE) ++ return sb->s_magic == CODA_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_v9fs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_9P_FS) || defined(CONFIG_9P_FS_MODULE) ++ return sb->s_magic == V9FS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ext4(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_EXT4DEV_FS) || defined(CONFIG_EXT4DEV_FS_MODULE) ++ return sb->s_magic == EXT4_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_sysv(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_SYSV_FS) || defined(CONFIG_SYSV_FS_MODULE) ++ return !strcmp(au_sbtype(sb), "sysv"); ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ramfs(struct super_block *sb) ++{ ++ return sb->s_magic == RAMFS_MAGIC; ++} ++ ++static inline int au_test_ubifs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE) ++ return sb->s_magic == UBIFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_procfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_PROC_FS ++ return sb->s_magic == PROC_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_sysfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_SYSFS ++ return sb->s_magic == SYSFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_configfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE) ++ return sb->s_magic == CONFIGFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_minix(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE) ++ return sb->s_magic == MINIX3_SUPER_MAGIC ++ || sb->s_magic == MINIX2_SUPER_MAGIC ++ || sb->s_magic == MINIX2_SUPER_MAGIC2 ++ || sb->s_magic == MINIX_SUPER_MAGIC ++ || sb->s_magic == MINIX_SUPER_MAGIC2; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_cifs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_CIFS_FS) || defined(CONFIGCIFS_FS_MODULE) ++ return sb->s_magic == CIFS_MAGIC_NUMBER; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_fat(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE) ++ return sb->s_magic == MSDOS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_msdos(struct super_block *sb) ++{ ++ return au_test_fat(sb); ++} ++ ++static inline int au_test_vfat(struct super_block *sb) ++{ ++ return au_test_fat(sb); ++} ++ ++static inline int au_test_securityfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_SECURITYFS ++ return sb->s_magic == SECURITYFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_squashfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE) ++ return sb->s_magic == SQUASHFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_btrfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE) ++ return sb->s_magic == BTRFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_xenfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE) ++ return sb->s_magic == XENFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_debugfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_DEBUG_FS ++ return sb->s_magic == DEBUGFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* ++ * they can't be an aufs branch. ++ */ ++static inline int au_test_fs_unsuppoted(struct super_block *sb) ++{ ++ return ++#ifndef CONFIG_AUFS_BR_RAMFS ++ au_test_ramfs(sb) || ++#endif ++ au_test_procfs(sb) ++ || au_test_sysfs(sb) ++ || au_test_configfs(sb) ++ || au_test_debugfs(sb) ++ || au_test_securityfs(sb) ++ || au_test_xenfs(sb) ++ /* || !strcmp(au_sbtype(sb), "unionfs") */ ++ || au_test_aufs(sb); /* will be supported in next version */ ++} ++ ++/* ++ * If the filesystem supports NFS-export, then it has to support NULL as ++ * a nameidata parameter for ->create(), ->lookup() and ->d_revalidate(). ++ * We can apply this principle when we handle a lower filesystem. ++ */ ++static inline int au_test_fs_null_nd(struct super_block *sb) ++{ ++ return !!sb->s_export_op; ++} ++ ++static inline int au_test_fs_remote(struct super_block *sb) ++{ ++ return !au_test_tmpfs(sb) ++#ifdef CONFIG_AUFS_BR_RAMFS ++ && !au_test_ramfs(sb) ++#endif ++ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * Note: these functions (below) are created after reading ->getattr() in all ++ * filesystems under linux/fs. it means we have to do so in every update... ++ */ ++ ++/* ++ * some filesystems require getattr to refresh the inode attributes before ++ * referencing. ++ * in most cases, we can rely on the inode attribute in NFS (or every remote fs) ++ * and leave the work for d_revalidate() ++ */ ++static inline int au_test_fs_refresh_iattr(struct super_block *sb) ++{ ++ return au_test_nfs(sb) ++ || au_test_fuse(sb) ++ /* || au_test_smbfs(sb) */ /* untested */ ++ /* || au_test_ocfs2(sb) */ /* untested */ ++ /* || au_test_btrfs(sb) */ /* untested */ ++ /* || au_test_coda(sb) */ /* untested */ ++ /* || au_test_v9fs(sb) */ /* untested */ ++ ; ++} ++ ++/* ++ * filesystems which don't maintain i_size or i_blocks. ++ */ ++static inline int au_test_fs_bad_iattr_size(struct super_block *sb) ++{ ++ return au_test_xfs(sb) ++ /* || au_test_ext4(sb) */ /* untested */ ++ /* || au_test_ocfs2(sb) */ /* untested */ ++ /* || au_test_ocfs2_dlmfs(sb) */ /* untested */ ++ /* || au_test_sysv(sb) */ /* untested */ ++ /* || au_test_ubifs(sb) */ /* untested */ ++ /* || au_test_minix(sb) */ /* untested */ ++ ; ++} ++ ++/* ++ * filesystems which don't store the correct value in some of their inode ++ * attributes. ++ */ ++static inline int au_test_fs_bad_iattr(struct super_block *sb) ++{ ++ return au_test_fs_bad_iattr_size(sb) ++ /* || au_test_cifs(sb) */ /* untested */ ++ || au_test_fat(sb) ++ || au_test_msdos(sb) ++ || au_test_vfat(sb); ++} ++ ++/* they don't check i_nlink in link(2) */ ++static inline int au_test_fs_no_limit_nlink(struct super_block *sb) ++{ ++ return au_test_tmpfs(sb) ++#ifdef CONFIG_AUFS_BR_RAMFS ++ || au_test_ramfs(sb) ++#endif ++ || au_test_ubifs(sb); ++} ++ ++/* ++ * filesystems which sets S_NOATIME and S_NOCMTIME. ++ */ ++static inline int au_test_fs_notime(struct super_block *sb) ++{ ++ return au_test_nfs(sb) ++ || au_test_fuse(sb) ++ || au_test_ubifs(sb) ++ /* || au_test_cifs(sb) */ /* untested */ ++ ; ++} ++ ++/* ++ * filesystems which requires replacing i_mapping. ++ */ ++static inline int au_test_fs_bad_mapping(struct super_block *sb) ++{ ++ return au_test_fuse(sb) ++ || au_test_ubifs(sb); ++} ++ ++/* temporary support for i#1 in cramfs */ ++static inline int au_test_fs_unique_ino(struct inode *inode) ++{ ++ if (au_test_cramfs(inode->i_sb)) ++ return inode->i_ino != 1; ++ return 1; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * the filesystem where the xino files placed must support i/o after unlink and ++ * maintain i_size and i_blocks. ++ */ ++static inline int au_test_fs_bad_xino(struct super_block *sb) ++{ ++ return au_test_fs_remote(sb) ++ || au_test_fs_bad_iattr_size(sb) ++#ifdef CONFIG_AUFS_BR_RAMFS ++ || !(au_test_ramfs(sb) || au_test_fs_null_nd(sb)) ++#else ++ || !au_test_fs_null_nd(sb) /* to keep xino code simple */ ++#endif ++ /* don't want unnecessary work for xino */ ++ || au_test_aufs(sb) ++ || au_test_ecryptfs(sb); ++} ++ ++static inline int au_test_fs_trunc_xino(struct super_block *sb) ++{ ++ return au_test_tmpfs(sb) ++ || au_test_ramfs(sb); ++} ++ ++/* ++ * test if the @sb is real-readonly. ++ */ ++static inline int au_test_fs_rr(struct super_block *sb) ++{ ++ return au_test_squashfs(sb) ++ || au_test_iso9660(sb) ++ || au_test_cramfs(sb) ++ || au_test_romfs(sb); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_FSTYPE_H__ */ +diff --git a/fs/aufs/hinotify.c b/fs/aufs/hinotify.c +new file mode 100644 +index 0000000..66b761f +--- /dev/null ++++ b/fs/aufs/hinotify.c +@@ -0,0 +1,755 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * inotify for the lower directories ++ */ ++ ++#include "aufs.h" ++ ++static const __u32 AuHinMask = (IN_MOVE | IN_DELETE | IN_CREATE); ++static struct inotify_handle *au_hin_handle; ++ ++AuCacheFuncs(hinotify, HINOTIFY); ++ ++int au_hin_alloc(struct au_hinode *hinode, struct inode *inode, ++ struct inode *h_inode) ++{ ++ int err; ++ struct au_hinotify *hin; ++ s32 wd; ++ ++ err = -ENOMEM; ++ hin = au_cache_alloc_hinotify(); ++ if (hin) { ++ AuDebugOn(hinode->hi_notify); ++ hinode->hi_notify = hin; ++ hin->hin_aufs_inode = inode; ++ ++ inotify_init_watch(&hin->hin_watch); ++ wd = inotify_add_watch(au_hin_handle, &hin->hin_watch, h_inode, ++ AuHinMask); ++ if (wd >= 0) ++ return 0; /* success */ ++ ++ err = wd; ++ put_inotify_watch(&hin->hin_watch); ++ au_cache_free_hinotify(hin); ++ hinode->hi_notify = NULL; ++ } ++ ++ return err; ++} ++ ++void au_hin_free(struct au_hinode *hinode) ++{ ++ int err; ++ struct au_hinotify *hin; ++ ++ hin = hinode->hi_notify; ++ if (hin) { ++ err = 0; ++ if (atomic_read(&hin->hin_watch.count)) ++ err = inotify_rm_watch(au_hin_handle, &hin->hin_watch); ++ if (unlikely(err)) ++ /* it means the watch is already removed */ ++ AuWarn("failed inotify_rm_watch() %d\n", err); ++ au_cache_free_hinotify(hin); ++ hinode->hi_notify = NULL; ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_hin_ctl(struct au_hinode *hinode, int do_set) ++{ ++ struct inode *h_inode; ++ struct inotify_watch *watch; ++ ++ if (!hinode->hi_notify) ++ return; ++ ++ h_inode = hinode->hi_inode; ++ IMustLock(h_inode); ++ ++ /* todo: try inotify_find_update_watch()? */ ++ watch = &hinode->hi_notify->hin_watch; ++ mutex_lock(&h_inode->inotify_mutex); ++ /* mutex_lock(&watch->ih->mutex); */ ++ if (do_set) { ++ AuDebugOn(watch->mask & AuHinMask); ++ watch->mask |= AuHinMask; ++ } else { ++ AuDebugOn(!(watch->mask & AuHinMask)); ++ watch->mask &= ~AuHinMask; ++ } ++ /* mutex_unlock(&watch->ih->mutex); */ ++ mutex_unlock(&h_inode->inotify_mutex); ++} ++ ++void au_reset_hinotify(struct inode *inode, unsigned int flags) ++{ ++ aufs_bindex_t bindex, bend; ++ struct inode *hi; ++ struct dentry *iwhdentry; ++ ++ bend = au_ibend(inode); ++ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) { ++ hi = au_h_iptr(inode, bindex); ++ if (!hi) ++ continue; ++ ++ /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */ ++ iwhdentry = au_hi_wh(inode, bindex); ++ if (iwhdentry) ++ dget(iwhdentry); ++ au_igrab(hi); ++ au_set_h_iptr(inode, bindex, NULL, 0); ++ au_set_h_iptr(inode, bindex, au_igrab(hi), ++ flags & ~AuHi_XINO); ++ iput(hi); ++ dput(iwhdentry); ++ /* mutex_unlock(&hi->i_mutex); */ ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int hin_xino(struct inode *inode, struct inode *h_inode) ++{ ++ int err; ++ aufs_bindex_t bindex, bend, bfound, bstart; ++ struct inode *h_i; ++ ++ err = 0; ++ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { ++ AuWarn("branch root dir was changed\n"); ++ goto out; ++ } ++ ++ bfound = -1; ++ bend = au_ibend(inode); ++ bstart = au_ibstart(inode); ++#if 0 /* reserved for future use */ ++ if (bindex == bend) { ++ /* keep this ino in rename case */ ++ goto out; ++ } ++#endif ++ for (bindex = bstart; bindex <= bend; bindex++) { ++ if (au_h_iptr(inode, bindex) == h_inode) { ++ bfound = bindex; ++ break; ++ } ++ } ++ if (bfound < 0) ++ goto out; ++ ++ for (bindex = bstart; bindex <= bend; bindex++) { ++ h_i = au_h_iptr(inode, bindex); ++ if (!h_i) ++ continue; ++ ++ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0); ++ /* ignore this error */ ++ /* bad action? */ ++ } ++ ++ /* children inode number will be broken */ ++ ++ out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int hin_gen_tree(struct dentry *dentry) ++{ ++ int err, i, j, ndentry; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry **dentries; ++ ++ err = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_dcsub_pages(&dpages, dentry, NULL, NULL); ++ if (unlikely(err)) ++ goto out_dpages; ++ ++ for (i = 0; i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ dentries = dpage->dentries; ++ ndentry = dpage->ndentry; ++ for (j = 0; j < ndentry; j++) { ++ struct dentry *d; ++ ++ d = dentries[j]; ++ if (IS_ROOT(d)) ++ continue; ++ ++ d_drop(d); ++ au_digen_dec(d); ++ if (d->d_inode) ++ /* todo: reset children xino? ++ cached children only? */ ++ au_iigen_dec(d->d_inode); ++ } ++ } ++ ++ out_dpages: ++ au_dpages_free(&dpages); ++ ++ /* discard children */ ++ dentry_unhash(dentry); ++ dput(dentry); ++ out: ++ return err; ++} ++ ++/* ++ * return 0 if processed. ++ */ ++static int hin_gen_by_inode(char *name, unsigned int nlen, struct inode *inode, ++ const unsigned int isdir) ++{ ++ int err; ++ struct dentry *d; ++ struct qstr *dname; ++ ++ err = 1; ++ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { ++ AuWarn("branch root dir was changed\n"); ++ err = 0; ++ goto out; ++ } ++ ++ if (!isdir) { ++ AuDebugOn(!name); ++ au_iigen_dec(inode); ++ spin_lock(&dcache_lock); ++ list_for_each_entry(d, &inode->i_dentry, d_alias) { ++ dname = &d->d_name; ++ if (dname->len != nlen ++ && memcmp(dname->name, name, nlen)) ++ continue; ++ err = 0; ++ spin_lock(&d->d_lock); ++ __d_drop(d); ++ au_digen_dec(d); ++ spin_unlock(&d->d_lock); ++ break; ++ } ++ spin_unlock(&dcache_lock); ++ } else { ++ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIRS); ++ d = d_find_alias(inode); ++ if (!d) { ++ au_iigen_dec(inode); ++ goto out; ++ } ++ ++ dname = &d->d_name; ++ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) ++ err = hin_gen_tree(d); ++ dput(d); ++ } ++ ++ out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int hin_gen_by_name(struct dentry *dentry, const unsigned int isdir) ++{ ++ int err; ++ struct inode *inode; ++ ++ inode = dentry->d_inode; ++ if (IS_ROOT(dentry) ++ /* || (inode && inode->i_ino == AUFS_ROOT_INO) */ ++ ) { ++ AuWarn("branch root dir was changed\n"); ++ return 0; ++ } ++ ++ err = 0; ++ if (!isdir) { ++ d_drop(dentry); ++ au_digen_dec(dentry); ++ if (inode) ++ au_iigen_dec(inode); ++ } else { ++ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS); ++ if (inode) ++ err = hin_gen_tree(dentry); ++ } ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* hinotify job flags */ ++#define AuHinJob_XINO0 1 ++#define AuHinJob_GEN (1 << 1) ++#define AuHinJob_DIRENT (1 << 2) ++#define AuHinJob_ISDIR (1 << 3) ++#define AuHinJob_TRYXINO0 (1 << 4) ++#define AuHinJob_MNTPNT (1 << 5) ++#define au_ftest_hinjob(flags, name) ((flags) & AuHinJob_##name) ++#define au_fset_hinjob(flags, name) { (flags) |= AuHinJob_##name; } ++#define au_fclr_hinjob(flags, name) { (flags) &= ~AuHinJob_##name; } ++ ++struct hin_job_args { ++ unsigned int flags; ++ struct inode *inode, *h_inode, *dir, *h_dir; ++ struct dentry *dentry; ++ char *h_name; ++ int h_nlen; ++}; ++ ++static int hin_job(struct hin_job_args *a) ++{ ++ const unsigned int isdir = au_ftest_hinjob(a->flags, ISDIR); ++ ++ /* reset xino */ ++ if (au_ftest_hinjob(a->flags, XINO0) && a->inode) ++ hin_xino(a->inode, a->h_inode); /* ignore this error */ ++ ++ if (au_ftest_hinjob(a->flags, TRYXINO0) ++ && a->inode ++ && a->h_inode) { ++ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ if (!a->h_inode->i_nlink) ++ hin_xino(a->inode, a->h_inode); /* ignore this error */ ++ mutex_unlock(&a->h_inode->i_mutex); ++ } ++ ++ /* make the generation obsolete */ ++ if (au_ftest_hinjob(a->flags, GEN)) { ++ int err = -1; ++ if (a->inode) ++ err = hin_gen_by_inode(a->h_name, a->h_nlen, a->inode, ++ isdir); ++ if (err && a->dentry) ++ hin_gen_by_name(a->dentry, isdir); ++ /* ignore this error */ ++ } ++ ++ /* make dir entries obsolete */ ++ if (au_ftest_hinjob(a->flags, DIRENT) && a->inode) { ++ struct au_vdir *vdir; ++ ++ vdir = au_ivdir(a->inode); ++ if (vdir) ++ vdir->vd_jiffy = 0; ++ /* IMustLock(a->inode); */ ++ /* a->inode->i_version++; */ ++ } ++ ++ /* can do nothing but warn */ ++ if (au_ftest_hinjob(a->flags, MNTPNT) ++ && a->dentry ++ && d_mountpoint(a->dentry)) ++ AuWarn("mount-point %.*s is removed or renamed\n", ++ AuDLNPair(a->dentry)); ++ ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static char *in_name(u32 mask) ++{ ++#ifdef CONFIG_AUFS_DEBUG ++#define test_ret(flag) if (mask & flag) \ ++ return #flag; ++ test_ret(IN_ACCESS); ++ test_ret(IN_MODIFY); ++ test_ret(IN_ATTRIB); ++ test_ret(IN_CLOSE_WRITE); ++ test_ret(IN_CLOSE_NOWRITE); ++ test_ret(IN_OPEN); ++ test_ret(IN_MOVED_FROM); ++ test_ret(IN_MOVED_TO); ++ test_ret(IN_CREATE); ++ test_ret(IN_DELETE); ++ test_ret(IN_DELETE_SELF); ++ test_ret(IN_MOVE_SELF); ++ test_ret(IN_UNMOUNT); ++ test_ret(IN_Q_OVERFLOW); ++ test_ret(IN_IGNORED); ++ return ""; ++#undef test_ret ++#else ++ return "??"; ++#endif ++} ++ ++static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen, ++ struct inode *dir) ++{ ++ struct dentry *dentry, *d, *parent; ++ struct qstr *dname; ++ ++ parent = d_find_alias(dir); ++ if (!parent) ++ return NULL; ++ ++ dentry = NULL; ++ spin_lock(&dcache_lock); ++ list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) { ++ /* AuDbg("%.*s\n", AuDLNPair(d)); */ ++ dname = &d->d_name; ++ if (dname->len != nlen || memcmp(dname->name, name, nlen)) ++ continue; ++ if (!atomic_read(&d->d_count) || !d->d_fsdata) { ++ spin_lock(&d->d_lock); ++ __d_drop(d); ++ spin_unlock(&d->d_lock); ++ continue; ++ } ++ ++ dentry = dget(d); ++ break; ++ } ++ spin_unlock(&dcache_lock); ++ dput(parent); ++ ++ if (dentry) ++ di_write_lock_child(dentry); ++ ++ return dentry; ++} ++ ++static struct inode *lookup_wlock_by_ino(struct super_block *sb, ++ aufs_bindex_t bindex, ino_t h_ino) ++{ ++ struct inode *inode; ++ ino_t ino; ++ int err; ++ ++ inode = NULL; ++ err = au_xino_read(sb, bindex, h_ino, &ino); ++ if (!err && ino) ++ inode = ilookup(sb, ino); ++ if (!inode) ++ goto out; ++ ++ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { ++ AuWarn("wrong root branch\n"); ++ iput(inode); ++ inode = NULL; ++ goto out; ++ } ++ ++ ii_write_lock_child(inode); ++ ++ out: ++ return inode; ++} ++ ++enum { CHILD, PARENT }; ++struct postproc_args { ++ struct inode *h_dir, *dir, *h_child_inode; ++ u32 mask; ++ unsigned int flags[2]; ++ unsigned int h_child_nlen; ++ char h_child_name[]; ++}; ++ ++static void postproc(void *_args) ++{ ++ struct postproc_args *a = _args; ++ struct super_block *sb; ++ aufs_bindex_t bindex, bend, bfound; ++ unsigned char xino, try_iput; ++ int err; ++ struct inode *inode; ++ ino_t h_ino; ++ struct hin_job_args args; ++ struct dentry *dentry; ++ struct au_sbinfo *sbinfo; ++ ++ AuDebugOn(!_args); ++ AuDebugOn(!a->h_dir); ++ AuDebugOn(!a->dir); ++ AuDebugOn(!a->mask); ++ AuDbg("mask 0x%x %s, i%lu, hi%lu, hci%lu\n", ++ a->mask, in_name(a->mask), a->dir->i_ino, a->h_dir->i_ino, ++ a->h_child_inode ? a->h_child_inode->i_ino : 0); ++ ++ inode = NULL; ++ dentry = NULL; ++ /* ++ * do not lock a->dir->i_mutex here ++ * because of d_revalidate() may cause a deadlock. ++ */ ++ sb = a->dir->i_sb; ++ AuDebugOn(!sb); ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!sbinfo); ++ /* big aufs lock */ ++ si_noflush_write_lock(sb); ++ ++ ii_read_lock_parent(a->dir); ++ bfound = -1; ++ bend = au_ibend(a->dir); ++ for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++) ++ if (au_h_iptr(a->dir, bindex) == a->h_dir) { ++ bfound = bindex; ++ break; ++ } ++ ii_read_unlock(a->dir); ++ if (unlikely(bfound < 0)) ++ goto out; ++ ++ xino = !!au_opt_test(au_mntflags(sb), XINO); ++ h_ino = 0; ++ if (a->h_child_inode) ++ h_ino = a->h_child_inode->i_ino; ++ ++ if (a->h_child_nlen ++ && (au_ftest_hinjob(a->flags[CHILD], GEN) ++ || au_ftest_hinjob(a->flags[CHILD], MNTPNT))) ++ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen, ++ a->dir); ++ try_iput = 0; ++ if (dentry) ++ inode = dentry->d_inode; ++ if (xino && !inode && h_ino ++ && (au_ftest_hinjob(a->flags[CHILD], XINO0) ++ || au_ftest_hinjob(a->flags[CHILD], TRYXINO0) ++ || au_ftest_hinjob(a->flags[CHILD], GEN))) { ++ inode = lookup_wlock_by_ino(sb, bfound, h_ino); ++ try_iput = 1; ++ } ++ ++ args.flags = a->flags[CHILD]; ++ args.dentry = dentry; ++ args.inode = inode; ++ args.h_inode = a->h_child_inode; ++ args.dir = a->dir; ++ args.h_dir = a->h_dir; ++ args.h_name = a->h_child_name; ++ args.h_nlen = a->h_child_nlen; ++ err = hin_job(&args); ++ if (dentry) { ++ if (dentry->d_fsdata) ++ di_write_unlock(dentry); ++ dput(dentry); ++ } ++ if (inode && try_iput) { ++ ii_write_unlock(inode); ++ iput(inode); ++ } ++ ++ ii_write_lock_parent(a->dir); ++ args.flags = a->flags[PARENT]; ++ args.dentry = NULL; ++ args.inode = a->dir; ++ args.h_inode = a->h_dir; ++ args.dir = NULL; ++ args.h_dir = NULL; ++ args.h_name = NULL; ++ args.h_nlen = 0; ++ err = hin_job(&args); ++ ii_write_unlock(a->dir); ++ ++ out: ++ au_nwt_done(&sbinfo->si_nowait); ++ si_write_unlock(sb); ++ ++ iput(a->h_child_inode); ++ iput(a->h_dir); ++ iput(a->dir); ++ kfree(a); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void aufs_inotify(struct inotify_watch *watch, u32 wd __maybe_unused, ++ u32 mask, u32 cookie __maybe_unused, ++ const char *h_child_name, struct inode *h_child_inode) ++{ ++ struct au_hinotify *hinotify; ++ struct postproc_args *args; ++ int len, wkq_err; ++ unsigned char isdir, isroot, wh; ++ char *p; ++ struct inode *dir; ++ unsigned int flags[2]; ++ ++ /* if IN_UNMOUNT happens, there must be another bug */ ++ AuDebugOn(mask & IN_UNMOUNT); ++ if (mask & (IN_IGNORED | IN_UNMOUNT)) { ++ put_inotify_watch(watch); ++ return; ++ } ++#ifdef AuDbgHinotify ++ au_debug(1); ++ if (1 || !h_child_name || strcmp(h_child_name, AUFS_XINO_FNAME)) { ++ AuDbg("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s," ++ " hi%lu\n", ++ watch->inode->i_ino, wd, mask, in_name(mask), cookie, ++ h_child_name ? h_child_name : "", ++ h_child_inode ? h_child_inode->i_ino : 0); ++ WARN_ON(1); ++ } ++ au_debug(0); ++#endif ++ ++ hinotify = container_of(watch, struct au_hinotify, hin_watch); ++ AuDebugOn(!hinotify || !hinotify->hin_aufs_inode); ++ dir = igrab(hinotify->hin_aufs_inode); ++ if (!dir) ++ return; ++ ++ isroot = (dir->i_ino == AUFS_ROOT_INO); ++ len = 0; ++ wh = 0; ++ if (h_child_name) { ++ len = strlen(h_child_name); ++ if (!memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { ++ h_child_name += AUFS_WH_PFX_LEN; ++ len -= AUFS_WH_PFX_LEN; ++ wh = 1; ++ } ++ } ++ ++ isdir = 0; ++ if (h_child_inode) ++ isdir = !!S_ISDIR(h_child_inode->i_mode); ++ flags[PARENT] = AuHinJob_ISDIR; ++ flags[CHILD] = 0; ++ if (isdir) ++ flags[CHILD] = AuHinJob_ISDIR; ++ switch (mask & IN_ALL_EVENTS) { ++ case IN_MOVED_FROM: ++ case IN_MOVED_TO: ++ AuDebugOn(!h_child_name || !h_child_inode); ++ au_fset_hinjob(flags[CHILD], GEN); ++ au_fset_hinjob(flags[CHILD], XINO0); ++ au_fset_hinjob(flags[CHILD], MNTPNT); ++ au_fset_hinjob(flags[PARENT], DIRENT); ++ break; ++ ++ case IN_CREATE: ++ AuDebugOn(!h_child_name || !h_child_inode); ++ au_fset_hinjob(flags[PARENT], DIRENT); ++ au_fset_hinjob(flags[CHILD], GEN); ++ break; ++ ++ case IN_DELETE: ++ /* ++ * aufs never be able to get this child inode. ++ * revalidation should be in d_revalidate() ++ * by checking i_nlink, i_generation or d_unhashed(). ++ */ ++ AuDebugOn(!h_child_name); ++ au_fset_hinjob(flags[PARENT], DIRENT); ++ au_fset_hinjob(flags[CHILD], GEN); ++ au_fset_hinjob(flags[CHILD], TRYXINO0); ++ au_fset_hinjob(flags[CHILD], MNTPNT); ++ break; ++ ++ default: ++ AuDebugOn(1); ++ } ++ ++ if (wh) ++ h_child_inode = NULL; ++ ++ /* iput() and kfree() will be called in postproc() */ ++ /* ++ * inotify_mutex is already acquired and kmalloc/prune_icache may lock ++ * iprune_mutex. strange. ++ */ ++ lockdep_off(); ++ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS); ++ lockdep_on(); ++ if (unlikely(!args)) { ++ AuErr1("no memory\n"); ++ iput(dir); ++ return; ++ } ++ args->flags[PARENT] = flags[PARENT]; ++ args->flags[CHILD] = flags[CHILD]; ++ args->mask = mask; ++ args->dir = dir; ++ args->h_dir = igrab(watch->inode); ++ if (h_child_inode) ++ h_child_inode = igrab(h_child_inode); /* can be NULL */ ++ args->h_child_inode = h_child_inode; ++ args->h_child_nlen = len; ++ if (len) { ++ p = (void *)args; ++ p += sizeof(*args); ++ memcpy(p, h_child_name, len + 1); ++ } ++ ++ lockdep_off(); ++ wkq_err = au_wkq_nowait(postproc, args, dir->i_sb); ++ lockdep_on(); ++ if (unlikely(wkq_err)) ++ AuErr("wkq %d\n", wkq_err); ++} ++ ++static void aufs_inotify_destroy(struct inotify_watch *watch __maybe_unused) ++{ ++ return; ++} ++ ++static struct inotify_operations aufs_inotify_ops = { ++ .handle_event = aufs_inotify, ++ .destroy_watch = aufs_inotify_destroy ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void au_hin_destroy_cache(void) ++{ ++ kmem_cache_destroy(au_cachep[AuCache_HINOTIFY]); ++ au_cachep[AuCache_HINOTIFY] = NULL; ++} ++ ++int __init au_hinotify_init(void) ++{ ++ int err; ++ ++ err = -ENOMEM; ++ au_cachep[AuCache_HINOTIFY] = AuCache(au_hinotify); ++ if (au_cachep[AuCache_HINOTIFY]) { ++ err = 0; ++ au_hin_handle = inotify_init(&aufs_inotify_ops); ++ if (IS_ERR(au_hin_handle)) { ++ err = PTR_ERR(au_hin_handle); ++ au_hin_destroy_cache(); ++ } ++ } ++ AuTraceErr(err); ++ return err; ++} ++ ++void au_hinotify_fin(void) ++{ ++ inotify_destroy(au_hin_handle); ++ if (au_cachep[AuCache_HINOTIFY]) ++ au_hin_destroy_cache(); ++} +diff --git a/fs/aufs/i_op.c b/fs/aufs/i_op.c +new file mode 100644 +index 0000000..0dc51de +--- /dev/null ++++ b/fs/aufs/i_op.c +@@ -0,0 +1,884 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * inode operations (except add/del/rename) ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++static int h_permission(struct inode *h_inode, int mask, ++ struct vfsmount *h_mnt, int brperm) ++{ ++ int err; ++ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND)); ++ ++ err = -EACCES; ++ if ((write_mask && IS_IMMUTABLE(h_inode)) ++ || ((mask & MAY_EXEC) ++ && S_ISREG(h_inode->i_mode) ++ && ((h_mnt->mnt_flags & MNT_NOEXEC) ++ || !(h_inode->i_mode & S_IXUGO)))) ++ goto out; ++ ++ /* ++ * - skip the lower fs test in the case of write to ro branch. ++ * - nfs dir permission write check is optimized, but a policy for ++ * link/rename requires a real check. ++ */ ++ if ((write_mask && !au_br_writable(brperm)) ++ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode) ++ && write_mask && !(mask & MAY_READ)) ++ || !h_inode->i_op->permission) { ++ /* AuLabel(generic_permission); */ ++ err = generic_permission(h_inode, mask, NULL); ++ } else { ++ /* AuLabel(h_inode->permission); */ ++ err = h_inode->i_op->permission(h_inode, mask); ++ AuTraceErr(err); ++ } ++ ++ if (!err) ++ err = devcgroup_inode_permission(h_inode, mask); ++ if (!err) ++ err = security_inode_permission ++ (h_inode, mask & (MAY_READ | MAY_WRITE | MAY_EXEC ++ | MAY_APPEND)); ++ ++ out: ++ return err; ++} ++ ++static int aufs_permission(struct inode *inode, int mask) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ const unsigned char isdir = !!S_ISDIR(inode->i_mode); ++ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND)); ++ struct inode *h_inode; ++ struct super_block *sb; ++ struct au_branch *br; ++ ++ sb = inode->i_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ ii_read_lock_child(inode); ++ ++ if (!isdir || write_mask) { ++ err = au_busy_or_stale(); ++ h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ if (unlikely(!h_inode ++ || (h_inode->i_mode & S_IFMT) ++ != (inode->i_mode & S_IFMT))) ++ goto out; ++ ++ err = 0; ++ bindex = au_ibstart(inode); ++ br = au_sbr(sb, bindex); ++ err = h_permission(h_inode, mask, br->br_mnt, br->br_perm); ++ if (write_mask && !err) { ++ /* test whether the upper writable branch exists */ ++ err = -EROFS; ++ for (; bindex >= 0; bindex--) ++ if (!au_br_rdonly(au_sbr(sb, bindex))) { ++ err = 0; ++ break; ++ } ++ } ++ goto out; ++ } ++ ++ /* non-write to dir */ ++ err = 0; ++ bend = au_ibend(inode); ++ for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) { ++ h_inode = au_h_iptr(inode, bindex); ++ if (h_inode) { ++ err = au_busy_or_stale(); ++ if (unlikely(!S_ISDIR(h_inode->i_mode))) ++ break; ++ ++ br = au_sbr(sb, bindex); ++ err = h_permission(h_inode, mask, br->br_mnt, ++ br->br_perm); ++ } ++ } ++ ++ out: ++ ii_read_unlock(inode); ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry, ++ struct nameidata *nd) ++{ ++ struct dentry *ret, *parent; ++ struct inode *inode, *h_inode; ++ struct mutex *mtx; ++ struct super_block *sb; ++ int err, npositive; ++ aufs_bindex_t bstart; ++ ++ /* temporary workaround for a bug in NFSD readdir */ ++ if (!au_test_nfsd(current)) ++ IMustLock(dir); ++ else ++ WARN_ONCE(!mutex_is_locked(&dir->i_mutex), ++ "a known problem of NFSD readdir since 2.6.28\n"); ++ ++ sb = dir->i_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_alloc_dinfo(dentry); ++ ret = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ ++ parent = dentry->d_parent; /* dir inode is locked */ ++ di_read_lock_parent(parent, AuLock_IR); ++ npositive = au_lkup_dentry(dentry, au_dbstart(parent), /*type*/0, nd); ++ di_read_unlock(parent, AuLock_IR); ++ err = npositive; ++ ret = ERR_PTR(err); ++ if (unlikely(err < 0)) ++ goto out_unlock; ++ ++ inode = NULL; ++ if (npositive) { ++ bstart = au_dbstart(dentry); ++ h_inode = au_h_dptr(dentry, bstart)->d_inode; ++ if (!S_ISDIR(h_inode->i_mode)) { ++ /* ++ * stop 'race'-ing between hardlinks under different ++ * parents. ++ */ ++ mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx; ++ mutex_lock(mtx); ++ inode = au_new_inode(dentry, /*must_new*/0); ++ mutex_unlock(mtx); ++ } else ++ inode = au_new_inode(dentry, /*must_new*/0); ++ ret = (void *)inode; ++ } ++ if (IS_ERR(inode)) ++ goto out_unlock; ++ ++ ret = d_splice_alias(inode, dentry); ++ if (unlikely(IS_ERR(ret) && inode)) ++ ii_write_unlock(inode); ++ au_store_oflag(nd, inode); ++ ++ out_unlock: ++ di_write_unlock(dentry); ++ out: ++ si_read_unlock(sb); ++ return ret; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent, ++ const unsigned char add_entry, aufs_bindex_t bcpup, ++ aufs_bindex_t bstart) ++{ ++ int err; ++ struct dentry *h_parent; ++ struct inode *h_dir; ++ ++ if (add_entry) { ++ au_update_dbstart(dentry); ++ IMustLock(parent->d_inode); ++ } else ++ di_write_lock_parent(parent); ++ ++ err = 0; ++ if (!au_h_dptr(parent, bcpup)) { ++ if (bstart < bcpup) ++ err = au_cpdown_dirs(dentry, bcpup); ++ else ++ err = au_cpup_dirs(dentry, bcpup); ++ } ++ if (!err && add_entry) { ++ h_parent = au_h_dptr(parent, bcpup); ++ h_dir = h_parent->d_inode; ++ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); ++ err = au_lkup_neg(dentry, bcpup); ++ /* todo: no unlock here */ ++ mutex_unlock(&h_dir->i_mutex); ++ if (bstart < bcpup && au_dbstart(dentry) < 0) { ++ au_set_dbstart(dentry, 0); ++ au_update_dbrange(dentry, /*do_put_zero*/0); ++ } ++ } ++ ++ if (!add_entry) ++ di_write_unlock(parent); ++ if (!err) ++ err = bcpup; /* success */ ++ ++ return err; ++} ++ ++/* ++ * decide the branch and the parent dir where we will create a new entry. ++ * returns new bindex or an error. ++ * copyup the parent dir if needed. ++ */ ++int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, ++ struct au_wr_dir_args *args) ++{ ++ int err; ++ aufs_bindex_t bcpup, bstart, src_bstart; ++ const unsigned char add_entry = !!au_ftest_wrdir(args->flags, ++ ADD_ENTRY); ++ struct super_block *sb; ++ struct dentry *parent; ++ struct au_sbinfo *sbinfo; ++ ++ sb = dentry->d_sb; ++ sbinfo = au_sbi(sb); ++ parent = dget_parent(dentry); ++ bstart = au_dbstart(dentry); ++ bcpup = bstart; ++ if (args->force_btgt < 0) { ++ if (src_dentry) { ++ src_bstart = au_dbstart(src_dentry); ++ if (src_bstart < bstart) ++ bcpup = src_bstart; ++ } else if (add_entry) { ++ err = AuWbrCreate(sbinfo, dentry, ++ au_ftest_wrdir(args->flags, ISDIR)); ++ bcpup = err; ++ } ++ ++ if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) { ++ if (add_entry) ++ err = AuWbrCopyup(sbinfo, dentry); ++ else { ++ if (!IS_ROOT(dentry)) { ++ di_read_lock_parent(parent, !AuLock_IR); ++ err = AuWbrCopyup(sbinfo, dentry); ++ di_read_unlock(parent, !AuLock_IR); ++ } else ++ err = AuWbrCopyup(sbinfo, dentry); ++ } ++ bcpup = err; ++ if (unlikely(err < 0)) ++ goto out; ++ } ++ } else { ++ bcpup = args->force_btgt; ++ AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode)); ++ } ++ AuDbg("bstart %d, bcpup %d\n", bstart, bcpup); ++ if (bstart < bcpup) ++ au_update_dbrange(dentry, /*do_put_zero*/1); ++ ++ err = bcpup; ++ if (bcpup == bstart) ++ goto out; /* success */ ++ ++ /* copyup the new parent into the branch we process */ ++ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart); ++ ++ out: ++ dput(parent); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct dentry *au_pinned_h_parent(struct au_pin *pin) ++{ ++ if (pin && pin->parent) ++ return au_h_dptr(pin->parent, pin->bindex); ++ return NULL; ++} ++ ++void au_unpin(struct au_pin *p) ++{ ++ if (au_ftest_pin(p->flags, MNT_WRITE)) ++ mnt_drop_write(p->h_mnt); ++ if (!p->hdir) ++ return; ++ ++ au_hin_imtx_unlock(p->hdir); ++ if (!au_ftest_pin(p->flags, DI_LOCKED)) ++ di_read_unlock(p->parent, AuLock_IR); ++ iput(p->hdir->hi_inode); ++ dput(p->parent); ++ p->parent = NULL; ++ p->hdir = NULL; ++ p->h_mnt = NULL; ++} ++ ++int au_do_pin(struct au_pin *p) ++{ ++ int err; ++ struct super_block *sb; ++ struct dentry *h_dentry, *h_parent; ++ struct au_branch *br; ++ struct inode *h_dir; ++ ++ err = 0; ++ sb = p->dentry->d_sb; ++ br = au_sbr(sb, p->bindex); ++ if (IS_ROOT(p->dentry)) { ++ if (au_ftest_pin(p->flags, MNT_WRITE)) { ++ p->h_mnt = br->br_mnt; ++ err = mnt_want_write(p->h_mnt); ++ if (unlikely(err)) { ++ au_fclr_pin(p->flags, MNT_WRITE); ++ goto out_err; ++ } ++ } ++ goto out; ++ } ++ ++ h_dentry = NULL; ++ if (p->bindex <= au_dbend(p->dentry)) ++ h_dentry = au_h_dptr(p->dentry, p->bindex); ++ ++ p->parent = dget_parent(p->dentry); ++ if (!au_ftest_pin(p->flags, DI_LOCKED)) ++ di_read_lock(p->parent, AuLock_IR, p->lsc_di); ++ ++ h_dir = NULL; ++ h_parent = au_h_dptr(p->parent, p->bindex); ++ p->hdir = au_hi(p->parent->d_inode, p->bindex); ++ if (p->hdir) ++ h_dir = p->hdir->hi_inode; ++ ++ /* udba case */ ++ if (unlikely(!p->hdir || !h_dir)) { ++ if (!au_ftest_pin(p->flags, DI_LOCKED)) ++ di_read_unlock(p->parent, AuLock_IR); ++ dput(p->parent); ++ p->parent = NULL; ++ goto out_err; ++ } ++ ++ au_igrab(h_dir); ++ au_hin_imtx_lock_nested(p->hdir, p->lsc_hi); ++ ++ if (unlikely(p->hdir->hi_inode != h_parent->d_inode)) { ++ err = -EBUSY; ++ goto out_unpin; ++ } ++ if (h_dentry) { ++ err = au_h_verify(h_dentry, p->udba, h_dir, h_parent, br); ++ if (unlikely(err)) { ++ au_fclr_pin(p->flags, MNT_WRITE); ++ goto out_unpin; ++ } ++ } ++ ++ if (au_ftest_pin(p->flags, MNT_WRITE)) { ++ p->h_mnt = br->br_mnt; ++ err = mnt_want_write(p->h_mnt); ++ if (unlikely(err)) { ++ au_fclr_pin(p->flags, MNT_WRITE); ++ goto out_unpin; ++ } ++ } ++ goto out; /* success */ ++ ++ out_unpin: ++ au_unpin(p); ++ out_err: ++ AuErr("err %d\n", err); ++ err = au_busy_or_stale(); ++ out: ++ return err; ++} ++ ++void au_pin_init(struct au_pin *p, struct dentry *dentry, ++ aufs_bindex_t bindex, int lsc_di, int lsc_hi, ++ unsigned int udba, unsigned char flags) ++{ ++ p->dentry = dentry; ++ p->udba = udba; ++ p->lsc_di = lsc_di; ++ p->lsc_hi = lsc_hi; ++ p->flags = flags; ++ p->bindex = bindex; ++ ++ p->parent = NULL; ++ p->hdir = NULL; ++ p->h_mnt = NULL; ++} ++ ++int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int udba, unsigned char flags) ++{ ++ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2, ++ udba, flags); ++ return au_do_pin(pin); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define AuIcpup_DID_CPUP 1 ++#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name) ++#define au_fset_icpup(flags, name) { (flags) |= AuIcpup_##name; } ++#define au_fclr_icpup(flags, name) { (flags) &= ~AuIcpup_##name; } ++ ++struct au_icpup_args { ++ unsigned char flags; ++ unsigned char pin_flags; ++ aufs_bindex_t btgt; ++ struct au_pin pin; ++ struct path h_path; ++ struct inode *h_inode; ++}; ++ ++static int au_lock_and_icpup(struct dentry *dentry, struct iattr *ia, ++ struct au_icpup_args *a) ++{ ++ int err; ++ unsigned int udba; ++ loff_t sz; ++ aufs_bindex_t bstart; ++ struct dentry *hi_wh, *parent; ++ struct inode *inode; ++ struct au_wr_dir_args wr_dir_args = { ++ .force_btgt = -1, ++ .flags = 0 ++ }; ++ ++ di_write_lock_child(dentry); ++ bstart = au_dbstart(dentry); ++ inode = dentry->d_inode; ++ if (S_ISDIR(inode->i_mode)) ++ au_fset_wrdir(wr_dir_args.flags, ISDIR); ++ /* plink or hi_wh() case */ ++ if (bstart != au_ibstart(inode)) ++ wr_dir_args.force_btgt = au_ibstart(inode); ++ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args); ++ if (unlikely(err < 0)) ++ goto out_dentry; ++ a->btgt = err; ++ if (err != bstart) ++ au_fset_icpup(a->flags, DID_CPUP); ++ ++ err = 0; ++ a->pin_flags = AuPin_MNT_WRITE; ++ parent = NULL; ++ if (!IS_ROOT(dentry)) { ++ au_fset_pin(a->pin_flags, DI_LOCKED); ++ parent = dget_parent(dentry); ++ di_write_lock_parent(parent); ++ } ++ ++ udba = au_opt_udba(dentry->d_sb); ++ if (d_unhashed(dentry) || (ia->ia_valid & ATTR_FILE)) ++ udba = AuOpt_UDBA_NONE; ++ err = au_pin(&a->pin, dentry, a->btgt, udba, a->pin_flags); ++ if (unlikely(err)) { ++ if (parent) { ++ di_write_unlock(parent); ++ dput(parent); ++ } ++ goto out_dentry; ++ } ++ a->h_path.dentry = au_h_dptr(dentry, bstart); ++ a->h_inode = a->h_path.dentry->d_inode; ++ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ sz = -1; ++ if ((ia->ia_valid & ATTR_SIZE) && ia->ia_size < i_size_read(a->h_inode)) ++ sz = ia->ia_size; ++ ++ hi_wh = NULL; ++ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unhashed(dentry)) { ++ hi_wh = au_hi_wh(inode, a->btgt); ++ if (!hi_wh) { ++ err = au_sio_cpup_wh(dentry, a->btgt, sz, /*file*/NULL); ++ if (unlikely(err)) ++ goto out_unlock; ++ hi_wh = au_hi_wh(inode, a->btgt); ++ /* todo: revalidate hi_wh? */ ++ } ++ } ++ ++ if (parent) { ++ au_pin_set_parent_lflag(&a->pin, /*lflag*/0); ++ di_downgrade_lock(parent, AuLock_IR); ++ dput(parent); ++ } ++ if (!au_ftest_icpup(a->flags, DID_CPUP)) ++ goto out; /* success */ ++ ++ if (!d_unhashed(dentry)) { ++ err = au_sio_cpup_simple(dentry, a->btgt, sz, AuCpup_DTIME); ++ if (!err) ++ a->h_path.dentry = au_h_dptr(dentry, a->btgt); ++ } else if (!hi_wh) ++ a->h_path.dentry = au_h_dptr(dentry, a->btgt); ++ else ++ a->h_path.dentry = hi_wh; /* do not dget here */ ++ ++ out_unlock: ++ mutex_unlock(&a->h_inode->i_mutex); ++ a->h_inode = a->h_path.dentry->d_inode; ++ if (!err) { ++ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ goto out; /* success */ ++ } ++ ++ au_unpin(&a->pin); ++ ++ out_dentry: ++ di_write_unlock(dentry); ++ out: ++ return err; ++} ++ ++static int aufs_setattr(struct dentry *dentry, struct iattr *ia) ++{ ++ int err; ++ struct inode *inode; ++ struct super_block *sb; ++ struct file *file; ++ struct au_icpup_args *a; ++ ++ err = -ENOMEM; ++ a = kzalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ inode = dentry->d_inode; ++ IMustLock(inode); ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ file = NULL; ++ if (ia->ia_valid & ATTR_FILE) { ++ /* currently ftruncate(2) only */ ++ file = ia->ia_file; ++ fi_write_lock(file); ++ ia->ia_file = au_h_fptr(file, au_fbstart(file)); ++ } ++ ++ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) ++ ia->ia_valid &= ~ATTR_MODE; ++ ++ err = au_lock_and_icpup(dentry, ia, a); ++ if (unlikely(err < 0)) ++ goto out_si; ++ if (au_ftest_icpup(a->flags, DID_CPUP)) { ++ ia->ia_file = NULL; ++ ia->ia_valid &= ~ATTR_FILE; ++ } ++ ++ a->h_path.mnt = au_sbr_mnt(sb, a->btgt); ++ if (ia->ia_valid & ATTR_SIZE) { ++ struct file *f; ++ ++ if (ia->ia_size < i_size_read(inode)) { ++ /* unmap only */ ++ err = vmtruncate(inode, ia->ia_size); ++ if (unlikely(err)) ++ goto out_unlock; ++ } ++ ++ f = NULL; ++ if (ia->ia_valid & ATTR_FILE) ++ f = ia->ia_file; ++ mutex_unlock(&a->h_inode->i_mutex); ++ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f); ++ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ } else ++ err = vfsub_notify_change(&a->h_path, ia); ++ if (!err) ++ au_cpup_attr_changeable(inode); ++ ++ out_unlock: ++ mutex_unlock(&a->h_inode->i_mutex); ++ au_unpin(&a->pin); ++ di_write_unlock(dentry); ++ out_si: ++ if (file) { ++ fi_write_unlock(file); ++ ia->ia_file = file; ++ ia->ia_valid |= ATTR_FILE; ++ } ++ si_read_unlock(sb); ++ kfree(a); ++ out: ++ return err; ++} ++ ++static int au_getattr_lock_reval(struct dentry *dentry, unsigned int sigen) ++{ ++ int err; ++ struct inode *inode; ++ struct dentry *parent; ++ ++ err = 0; ++ inode = dentry->d_inode; ++ di_write_lock_child(dentry); ++ if (au_digen(dentry) != sigen || au_iigen(inode) != sigen) { ++ parent = dget_parent(dentry); ++ di_read_lock_parent(parent, AuLock_IR); ++ /* returns a number of positive dentries */ ++ err = au_refresh_hdentry(dentry, inode->i_mode & S_IFMT); ++ if (err > 0) ++ err = au_refresh_hinode(inode, dentry); ++ di_read_unlock(parent, AuLock_IR); ++ dput(parent); ++ if (unlikely(!err)) ++ err = -EIO; ++ } ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ di_read_unlock(dentry, AuLock_IR); ++ ++ return err; ++} ++ ++static void au_refresh_iattr(struct inode *inode, struct kstat *st, ++ unsigned int nlink) ++{ ++ inode->i_mode = st->mode; ++ inode->i_uid = st->uid; ++ inode->i_gid = st->gid; ++ inode->i_atime = st->atime; ++ inode->i_mtime = st->mtime; ++ inode->i_ctime = st->ctime; ++ ++ au_cpup_attr_nlink(inode, /*force*/0); ++ if (S_ISDIR(inode->i_mode)) { ++ inode->i_nlink -= nlink; ++ inode->i_nlink += st->nlink; ++ } ++ ++ spin_lock(&inode->i_lock); ++ inode->i_blocks = st->blocks; ++ i_size_write(inode, st->size); ++ spin_unlock(&inode->i_lock); ++} ++ ++static int aufs_getattr(struct vfsmount *mnt __maybe_unused, ++ struct dentry *dentry, struct kstat *st) ++{ ++ int err; ++ unsigned int mnt_flags; ++ aufs_bindex_t bindex; ++ unsigned char udba_none, positive; ++ struct super_block *sb, *h_sb; ++ struct inode *inode; ++ struct vfsmount *h_mnt; ++ struct dentry *h_dentry; ++ ++ err = 0; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ si_read_lock(sb, AuLock_FLUSH); ++ mnt_flags = au_mntflags(sb); ++ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE); ++ ++ /* support fstat(2) */ ++ if (!d_unhashed(dentry) && !udba_none) { ++ unsigned int sigen = au_sigen(sb); ++ if (au_digen(dentry) == sigen && au_iigen(inode) == sigen) ++ di_read_lock_child(dentry, AuLock_IR); ++ else { ++ /* NFSD may skip the revalidation */ ++ if (!au_test_nfsd(current)) ++ AuDebugOn(!IS_ROOT(dentry)); ++ else { ++ err = au_busy_or_stale(); ++ if (unlikely(!IS_ROOT(dentry))) ++ goto out; ++ } ++ err = au_getattr_lock_reval(dentry, sigen); ++ if (unlikely(err)) ++ goto out; ++ } ++ } else ++ di_read_lock_child(dentry, AuLock_IR); ++ ++ bindex = au_ibstart(inode); ++ h_mnt = au_sbr_mnt(sb, bindex); ++ h_sb = h_mnt->mnt_sb; ++ if (!au_test_fs_bad_iattr(h_sb) && udba_none) ++ goto out_fill; /* success */ ++ ++ h_dentry = NULL; ++ if (au_dbstart(dentry) == bindex) ++ h_dentry = dget(au_h_dptr(dentry, bindex)); ++ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) { ++ h_dentry = au_plink_lkup(inode, bindex); ++ if (IS_ERR(h_dentry)) ++ goto out_fill; /* pretending success */ ++ } ++ /* illegally overlapped or something */ ++ if (unlikely(!h_dentry)) ++ goto out_fill; /* pretending success */ ++ ++ positive = !!h_dentry->d_inode; ++ if (positive) ++ err = vfs_getattr(h_mnt, h_dentry, st); ++ dput(h_dentry); ++ if (!err) { ++ if (positive) ++ au_refresh_iattr(inode, st, h_dentry->d_inode->i_nlink); ++ goto out_fill; /* success */ ++ } ++ goto out_unlock; ++ ++ out_fill: ++ generic_fillattr(inode, st); ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int h_readlink(struct dentry *dentry, int bindex, char __user *buf, ++ int bufsiz) ++{ ++ int err; ++ struct super_block *sb; ++ struct dentry *h_dentry; ++ ++ err = -EINVAL; ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (unlikely(/* !h_dentry ++ || !h_dentry->d_inode ++ || !h_dentry->d_inode->i_op ++ || */ !h_dentry->d_inode->i_op->readlink)) ++ goto out; ++ ++ err = security_inode_readlink(h_dentry); ++ if (unlikely(err)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ if (!au_test_ro(sb, bindex, dentry->d_inode)) { ++ vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry); ++ fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode); ++ } ++ err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz); ++ ++ out: ++ return err; ++} ++ ++static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) ++{ ++ int err; ++ ++ aufs_read_lock(dentry, AuLock_IR); ++ err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz); ++ aufs_read_unlock(dentry, AuLock_IR); ++ ++ return err; ++} ++ ++static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd) ++{ ++ int err; ++ char *buf; ++ mm_segment_t old_fs; ++ ++ err = -ENOMEM; ++ buf = __getname(); ++ if (unlikely(!buf)) ++ goto out; ++ ++ aufs_read_lock(dentry, AuLock_IR); ++ old_fs = get_fs(); ++ set_fs(KERNEL_DS); ++ err = h_readlink(dentry, au_dbstart(dentry), (char __user *)buf, ++ PATH_MAX); ++ set_fs(old_fs); ++ aufs_read_unlock(dentry, AuLock_IR); ++ ++ if (err >= 0) { ++ buf[err] = 0; ++ /* will be freed by put_link */ ++ nd_set_link(nd, buf); ++ return NULL; /* success */ ++ } ++ __putname(buf); ++ ++ out: ++ path_put(&nd->path); ++ AuTraceErr(err); ++ return ERR_PTR(err); ++} ++ ++static void aufs_put_link(struct dentry *dentry __maybe_unused, ++ struct nameidata *nd, void *cookie __maybe_unused) ++{ ++ __putname(nd_get_link(nd)); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void aufs_truncate_range(struct inode *inode __maybe_unused, ++ loff_t start __maybe_unused, ++ loff_t end __maybe_unused) ++{ ++ AuUnsupport(); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct inode_operations aufs_symlink_iop = { ++ .permission = aufs_permission, ++ .setattr = aufs_setattr, ++ .getattr = aufs_getattr, ++ .readlink = aufs_readlink, ++ .follow_link = aufs_follow_link, ++ .put_link = aufs_put_link ++}; ++ ++struct inode_operations aufs_dir_iop = { ++ .create = aufs_create, ++ .lookup = aufs_lookup, ++ .link = aufs_link, ++ .unlink = aufs_unlink, ++ .symlink = aufs_symlink, ++ .mkdir = aufs_mkdir, ++ .rmdir = aufs_rmdir, ++ .mknod = aufs_mknod, ++ .rename = aufs_rename, ++ ++ .permission = aufs_permission, ++ .setattr = aufs_setattr, ++ .getattr = aufs_getattr ++}; ++ ++struct inode_operations aufs_iop = { ++ .permission = aufs_permission, ++ .setattr = aufs_setattr, ++ .getattr = aufs_getattr, ++ .truncate_range = aufs_truncate_range ++}; +diff --git a/fs/aufs/i_op_add.c b/fs/aufs/i_op_add.c +new file mode 100644 +index 0000000..39b7a48 +--- /dev/null ++++ b/fs/aufs/i_op_add.c +@@ -0,0 +1,649 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * inode operations (add entry) ++ */ ++ ++#include "aufs.h" ++ ++/* ++ * final procedure of adding a new entry, except link(2). ++ * remove whiteout, instantiate, copyup the parent dir's times and size ++ * and update version. ++ * if it failed, re-create the removed whiteout. ++ */ ++static int epilog(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct dentry *dentry) ++{ ++ int err, rerr; ++ aufs_bindex_t bwh; ++ struct path h_path; ++ struct inode *inode, *h_dir; ++ struct dentry *wh; ++ ++ bwh = -1; ++ if (wh_dentry) { ++ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */ ++ IMustLock(h_dir); ++ AuDebugOn(au_h_iptr(dir, bindex) != h_dir); ++ bwh = au_dbwh(dentry); ++ h_path.dentry = wh_dentry; ++ h_path.mnt = au_sbr_mnt(dir->i_sb, bindex); ++ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, ++ dentry); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ inode = au_new_inode(dentry, /*must_new*/1); ++ if (!IS_ERR(inode)) { ++ d_instantiate(dentry, inode); ++ dir = dentry->d_parent->d_inode; /* dir inode is locked */ ++ IMustLock(dir); ++ if (au_ibstart(dir) == au_dbstart(dentry)) ++ au_cpup_attr_timesizes(dir); ++ dir->i_version++; ++ return 0; /* success */ ++ } ++ ++ err = PTR_ERR(inode); ++ if (!wh_dentry) ++ goto out; ++ ++ /* revert */ ++ /* dir inode is locked */ ++ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent); ++ rerr = PTR_ERR(wh); ++ if (IS_ERR(wh)) { ++ AuIOErr("%.*s reverting whiteout failed(%d, %d)\n", ++ AuDLNPair(dentry), err, rerr); ++ err = -EIO; ++ } else ++ dput(wh); ++ ++ out: ++ return err; ++} ++ ++/* ++ * simple tests for the adding inode operations. ++ * following the checks in vfs, plus the parent-child relationship. ++ */ ++int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent, int isdir) ++{ ++ int err; ++ umode_t h_mode; ++ struct dentry *h_dentry; ++ struct inode *h_inode; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ h_inode = h_dentry->d_inode; ++ if (!dentry->d_inode) { ++ err = -EEXIST; ++ if (unlikely(h_inode)) ++ goto out; ++ } else { ++ /* rename(2) case */ ++ err = -EIO; ++ if (unlikely(!h_inode || !h_inode->i_nlink)) ++ goto out; ++ ++ h_mode = h_inode->i_mode; ++ if (!isdir) { ++ err = -EISDIR; ++ if (unlikely(S_ISDIR(h_mode))) ++ goto out; ++ } else if (unlikely(!S_ISDIR(h_mode))) { ++ err = -ENOTDIR; ++ goto out; ++ } ++ } ++ ++ err = -EIO; ++ /* expected parent dir is locked */ ++ if (unlikely(h_parent != h_dentry->d_parent)) ++ goto out; ++ err = 0; ++ ++ out: ++ return err; ++} ++ ++/* ++ * initial procedure of adding a new entry. ++ * prepare writable branch and the parent dir, lock it, ++ * and lookup whiteout for the new entry. ++ */ ++static struct dentry* ++lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt, ++ struct dentry *src_dentry, struct au_pin *pin, ++ struct au_wr_dir_args *wr_dir_args) ++{ ++ struct dentry *wh_dentry, *h_parent; ++ struct super_block *sb; ++ struct au_branch *br; ++ int err; ++ unsigned int udba; ++ aufs_bindex_t bcpup; ++ ++ err = au_wr_dir(dentry, src_dentry, wr_dir_args); ++ bcpup = err; ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err < 0)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ udba = au_opt_udba(sb); ++ err = au_pin(pin, dentry, bcpup, udba, ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ ++ h_parent = au_pinned_h_parent(pin); ++ if (udba != AuOpt_UDBA_NONE ++ && au_dbstart(dentry) == bcpup) { ++ err = au_may_add(dentry, bcpup, h_parent, ++ au_ftest_wrdir(wr_dir_args->flags, ISDIR)); ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out_unpin; ++ } ++ ++ br = au_sbr(sb, bcpup); ++ if (dt) { ++ struct path tmp = { ++ .dentry = h_parent, ++ .mnt = br->br_mnt ++ }; ++ au_dtime_store(dt, au_pinned_parent(pin), &tmp); ++ } ++ ++ wh_dentry = NULL; ++ if (bcpup != au_dbwh(dentry)) ++ goto out; /* success */ ++ ++ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br); ++ ++ out_unpin: ++ if (IS_ERR(wh_dentry)) ++ au_unpin(pin); ++ out: ++ return wh_dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++enum { Mknod, Symlink, Creat }; ++struct simple_arg { ++ int type; ++ union { ++ struct { ++ int mode; ++ struct nameidata *nd; ++ } c; ++ struct { ++ const char *symname; ++ } s; ++ struct { ++ int mode; ++ dev_t dev; ++ } m; ++ } u; ++}; ++ ++static int add_simple(struct inode *dir, struct dentry *dentry, ++ struct simple_arg *arg) ++{ ++ int err; ++ aufs_bindex_t bstart; ++ unsigned char created; ++ struct au_dtime dt; ++ struct au_pin pin; ++ struct path h_path; ++ struct dentry *wh_dentry, *parent; ++ struct inode *h_dir; ++ struct au_wr_dir_args wr_dir_args = { ++ .force_btgt = -1, ++ .flags = AuWrDir_ADD_ENTRY ++ }; ++ ++ IMustLock(dir); ++ ++ parent = dentry->d_parent; /* dir inode is locked */ ++ aufs_read_lock(dentry, AuLock_DW); ++ di_write_lock_parent(parent); ++ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL, &pin, ++ &wr_dir_args); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out; ++ ++ bstart = au_dbstart(dentry); ++ h_path.dentry = au_h_dptr(dentry, bstart); ++ h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart); ++ h_dir = au_pinned_h_dir(&pin); ++ switch (arg->type) { ++ case Creat: ++ err = vfsub_create(h_dir, &h_path, arg->u.c.mode); ++ break; ++ case Symlink: ++ err = vfsub_symlink(h_dir, &h_path, arg->u.s.symname); ++ break; ++ case Mknod: ++ err = vfsub_mknod(h_dir, &h_path, arg->u.m.mode, arg->u.m.dev); ++ break; ++ default: ++ BUG(); ++ } ++ created = !err; ++ if (!err) ++ err = epilog(dir, bstart, wh_dentry, dentry); ++ ++ /* revert */ ++ if (unlikely(created && err && h_path.dentry->d_inode)) { ++ int rerr; ++ rerr = vfsub_unlink(h_dir, &h_path, /*force*/0); ++ if (rerr) { ++ AuIOErr("%.*s revert failure(%d, %d)\n", ++ AuDLNPair(dentry), err, rerr); ++ err = -EIO; ++ } ++ au_dtime_revert(&dt); ++ d_drop(dentry); ++ } ++ ++ au_unpin(&pin); ++ dput(wh_dentry); ++ ++ out: ++ if (unlikely(err)) { ++ au_update_dbstart(dentry); ++ d_drop(dentry); ++ } ++ di_write_unlock(parent); ++ aufs_read_unlock(dentry, AuLock_DW); ++ return err; ++} ++ ++int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) ++{ ++ struct simple_arg arg = { ++ .type = Mknod, ++ .u.m = { ++ .mode = mode, ++ .dev = dev ++ } ++ }; ++ return add_simple(dir, dentry, &arg); ++} ++ ++int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) ++{ ++ struct simple_arg arg = { ++ .type = Symlink, ++ .u.s.symname = symname ++ }; ++ return add_simple(dir, dentry, &arg); ++} ++ ++int aufs_create(struct inode *dir, struct dentry *dentry, int mode, ++ struct nameidata *nd) ++{ ++ struct simple_arg arg = { ++ .type = Creat, ++ .u.c = { ++ .mode = mode, ++ .nd = nd ++ } ++ }; ++ return add_simple(dir, dentry, &arg); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_link_args { ++ aufs_bindex_t bdst, bsrc; ++ struct au_pin pin; ++ struct path h_path; ++ struct dentry *src_parent, *parent; ++}; ++ ++static int au_cpup_before_link(struct dentry *src_dentry, ++ struct au_link_args *a) ++{ ++ int err; ++ struct dentry *h_src_dentry; ++ struct mutex *h_mtx; ++ ++ di_read_lock_parent(a->src_parent, AuLock_IR); ++ err = au_test_and_cpup_dirs(src_dentry, a->bdst); ++ if (unlikely(err)) ++ goto out; ++ ++ h_src_dentry = au_h_dptr(src_dentry, a->bsrc); ++ h_mtx = &h_src_dentry->d_inode->i_mutex; ++ err = au_pin(&a->pin, src_dentry, a->bdst, ++ au_opt_udba(src_dentry->d_sb), ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (unlikely(err)) ++ goto out; ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ err = au_sio_cpup_simple(src_dentry, a->bdst, -1, ++ AuCpup_DTIME /* | AuCpup_KEEPLINO */); ++ mutex_unlock(h_mtx); ++ au_unpin(&a->pin); ++ ++ out: ++ di_read_unlock(a->src_parent, AuLock_IR); ++ return err; ++} ++ ++static int au_cpup_or_link(struct dentry *src_dentry, struct au_link_args *a) ++{ ++ int err; ++ unsigned char plink; ++ struct inode *h_inode, *inode; ++ struct dentry *h_src_dentry; ++ struct super_block *sb; ++ ++ plink = 0; ++ h_inode = NULL; ++ sb = src_dentry->d_sb; ++ inode = src_dentry->d_inode; ++ if (au_ibstart(inode) <= a->bdst) ++ h_inode = au_h_iptr(inode, a->bdst); ++ if (!h_inode || !h_inode->i_nlink) { ++ /* copyup src_dentry as the name of dentry. */ ++ au_set_dbstart(src_dentry, a->bdst); ++ au_set_h_dptr(src_dentry, a->bdst, dget(a->h_path.dentry)); ++ h_inode = au_h_dptr(src_dentry, a->bsrc)->d_inode; ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ err = au_sio_cpup_single(src_dentry, a->bdst, a->bsrc, -1, ++ AuCpup_KEEPLINO, a->parent); ++ mutex_unlock(&h_inode->i_mutex); ++ au_set_h_dptr(src_dentry, a->bdst, NULL); ++ au_set_dbstart(src_dentry, a->bsrc); ++ } else { ++ /* the inode of src_dentry already exists on a.bdst branch */ ++ h_src_dentry = d_find_alias(h_inode); ++ if (!h_src_dentry && au_plink_test(inode)) { ++ plink = 1; ++ h_src_dentry = au_plink_lkup(inode, a->bdst); ++ err = PTR_ERR(h_src_dentry); ++ if (IS_ERR(h_src_dentry)) ++ goto out; ++ ++ if (unlikely(!h_src_dentry->d_inode)) { ++ dput(h_src_dentry); ++ h_src_dentry = NULL; ++ } ++ ++ } ++ if (h_src_dentry) { ++ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), ++ &a->h_path); ++ dput(h_src_dentry); ++ } else { ++ AuIOErr("no dentry found for hi%lu on b%d\n", ++ h_inode->i_ino, a->bdst); ++ err = -EIO; ++ } ++ } ++ ++ if (!err && !plink) ++ au_plink_append(inode, a->bdst, a->h_path.dentry); ++ ++out: ++ return err; ++} ++ ++int aufs_link(struct dentry *src_dentry, struct inode *dir, ++ struct dentry *dentry) ++{ ++ int err, rerr; ++ struct au_dtime dt; ++ struct au_link_args *a; ++ struct dentry *wh_dentry, *h_src_dentry; ++ struct inode *inode; ++ struct super_block *sb; ++ struct au_wr_dir_args wr_dir_args = { ++ /* .force_btgt = -1, */ ++ .flags = AuWrDir_ADD_ENTRY ++ }; ++ ++ IMustLock(dir); ++ inode = src_dentry->d_inode; ++ IMustLock(inode); ++ ++ err = -ENOENT; ++ if (unlikely(!inode->i_nlink)) ++ goto out; ++ ++ err = -ENOMEM; ++ a = kzalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ a->parent = dentry->d_parent; /* dir inode is locked */ ++ aufs_read_and_write_lock2(dentry, src_dentry, /*AuLock_FLUSH*/0); ++ a->src_parent = dget_parent(src_dentry); ++ wr_dir_args.force_btgt = au_dbstart(src_dentry); ++ ++ di_write_lock_parent(a->parent); ++ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt); ++ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin, ++ &wr_dir_args); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out_unlock; ++ ++ err = 0; ++ sb = dentry->d_sb; ++ a->bdst = au_dbstart(dentry); ++ a->h_path.dentry = au_h_dptr(dentry, a->bdst); ++ a->h_path.mnt = au_sbr_mnt(sb, a->bdst); ++ a->bsrc = au_dbstart(src_dentry); ++ if (au_opt_test(au_mntflags(sb), PLINK)) { ++ if (a->bdst < a->bsrc ++ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) ++ err = au_cpup_or_link(src_dentry, a); ++ else { ++ h_src_dentry = au_h_dptr(src_dentry, a->bdst); ++ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), ++ &a->h_path); ++ } ++ } else { ++ /* ++ * copyup src_dentry to the branch we process, ++ * and then link(2) to it. ++ */ ++ if (a->bdst < a->bsrc ++ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) { ++ au_unpin(&a->pin); ++ di_write_unlock(a->parent); ++ err = au_cpup_before_link(src_dentry, a); ++ di_write_lock_parent(a->parent); ++ if (!err) ++ err = au_pin(&a->pin, dentry, a->bdst, ++ au_opt_udba(sb), ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (unlikely(err)) ++ goto out_wh; ++ } ++ if (!err) { ++ h_src_dentry = au_h_dptr(src_dentry, a->bdst); ++ err = -ENOENT; ++ if (h_src_dentry && h_src_dentry->d_inode) ++ err = vfsub_link(h_src_dentry, ++ au_pinned_h_dir(&a->pin), ++ &a->h_path); ++ } ++ } ++ if (unlikely(err)) ++ goto out_unpin; ++ ++ if (wh_dentry) { ++ a->h_path.dentry = wh_dentry; ++ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path, ++ dentry); ++ if (unlikely(err)) ++ goto out_revert; ++ } ++ ++ dir->i_version++; ++ if (au_ibstart(dir) == au_dbstart(dentry)) ++ au_cpup_attr_timesizes(dir); ++ inc_nlink(inode); ++ inode->i_ctime = dir->i_ctime; ++ if (!d_unhashed(a->h_path.dentry)) ++ d_instantiate(dentry, au_igrab(inode)); ++ else ++ /* some filesystem calls d_drop() */ ++ d_drop(dentry); ++ goto out_unpin; /* success */ ++ ++ out_revert: ++ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path, /*force*/0); ++ if (!rerr) ++ goto out_dt; ++ AuIOErr("%.*s reverting failed(%d, %d)\n", ++ AuDLNPair(dentry), err, rerr); ++ err = -EIO; ++ out_dt: ++ d_drop(dentry); ++ au_dtime_revert(&dt); ++ out_unpin: ++ au_unpin(&a->pin); ++ out_wh: ++ dput(wh_dentry); ++ out_unlock: ++ if (unlikely(err)) { ++ au_update_dbstart(dentry); ++ d_drop(dentry); ++ } ++ di_write_unlock(a->parent); ++ dput(a->src_parent); ++ aufs_read_and_write_unlock2(dentry, src_dentry); ++ kfree(a); ++ out: ++ return err; ++} ++ ++int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ++{ ++ int err, rerr; ++ aufs_bindex_t bindex; ++ unsigned char diropq; ++ struct path h_path; ++ struct dentry *wh_dentry, *parent, *opq_dentry; ++ struct mutex *h_mtx; ++ struct super_block *sb; ++ struct { ++ struct au_pin pin; ++ struct au_dtime dt; ++ } *a; /* reduce the stack usage */ ++ struct au_wr_dir_args wr_dir_args = { ++ .force_btgt = -1, ++ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR ++ }; ++ ++ IMustLock(dir); ++ ++ err = -ENOMEM; ++ a = kmalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ aufs_read_lock(dentry, AuLock_DW); ++ parent = dentry->d_parent; /* dir inode is locked */ ++ di_write_lock_parent(parent); ++ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL, ++ &a->pin, &wr_dir_args); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out_free; ++ ++ sb = dentry->d_sb; ++ bindex = au_dbstart(dentry); ++ h_path.dentry = au_h_dptr(dentry, bindex); ++ h_path.mnt = au_sbr_mnt(sb, bindex); ++ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ /* make the dir opaque */ ++ diropq = 0; ++ h_mtx = &h_path.dentry->d_inode->i_mutex; ++ if (wh_dentry ++ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) { ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ opq_dentry = au_diropq_create(dentry, bindex); ++ mutex_unlock(h_mtx); ++ err = PTR_ERR(opq_dentry); ++ if (IS_ERR(opq_dentry)) ++ goto out_dir; ++ dput(opq_dentry); ++ diropq = 1; ++ } ++ ++ err = epilog(dir, bindex, wh_dentry, dentry); ++ if (!err) { ++ inc_nlink(dir); ++ goto out_unlock; /* success */ ++ } ++ ++ /* revert */ ++ if (diropq) { ++ AuLabel(revert opq); ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ rerr = au_diropq_remove(dentry, bindex); ++ mutex_unlock(h_mtx); ++ if (rerr) { ++ AuIOErr("%.*s reverting diropq failed(%d, %d)\n", ++ AuDLNPair(dentry), err, rerr); ++ err = -EIO; ++ } ++ } ++ ++ out_dir: ++ AuLabel(revert dir); ++ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path); ++ if (rerr) { ++ AuIOErr("%.*s reverting dir failed(%d, %d)\n", ++ AuDLNPair(dentry), err, rerr); ++ err = -EIO; ++ } ++ d_drop(dentry); ++ au_dtime_revert(&a->dt); ++ out_unlock: ++ au_unpin(&a->pin); ++ dput(wh_dentry); ++ out_free: ++ if (unlikely(err)) { ++ au_update_dbstart(dentry); ++ d_drop(dentry); ++ } ++ di_write_unlock(parent); ++ aufs_read_unlock(dentry, AuLock_DW); ++ kfree(a); ++ out: ++ return err; ++} +diff --git a/fs/aufs/i_op_del.c b/fs/aufs/i_op_del.c +new file mode 100644 +index 0000000..c0ee77d +--- /dev/null ++++ b/fs/aufs/i_op_del.c +@@ -0,0 +1,468 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * inode operations (del entry) ++ */ ++ ++#include "aufs.h" ++ ++/* ++ * decide if a new whiteout for @dentry is necessary or not. ++ * when it is necessary, prepare the parent dir for the upper branch whose ++ * branch index is @bcpup for creation. the actual creation of the whiteout will ++ * be done by caller. ++ * return value: ++ * 0: wh is unnecessary ++ * plus: wh is necessary ++ * minus: error ++ */ ++int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup) ++{ ++ int need_wh, err; ++ aufs_bindex_t bstart; ++ struct super_block *sb; ++ ++ sb = dentry->d_sb; ++ bstart = au_dbstart(dentry); ++ if (*bcpup < 0) { ++ *bcpup = bstart; ++ if (au_test_ro(sb, bstart, dentry->d_inode)) { ++ err = AuWbrCopyup(au_sbi(sb), dentry); ++ *bcpup = err; ++ if (unlikely(err < 0)) ++ goto out; ++ } ++ } else ++ AuDebugOn(bstart < *bcpup ++ || au_test_ro(sb, *bcpup, dentry->d_inode)); ++ AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart); ++ ++ if (*bcpup != bstart) { ++ err = au_cpup_dirs(dentry, *bcpup); ++ if (unlikely(err)) ++ goto out; ++ need_wh = 1; ++ } else { ++ aufs_bindex_t old_bend, new_bend, bdiropq = -1; ++ ++ old_bend = au_dbend(dentry); ++ if (isdir) { ++ bdiropq = au_dbdiropq(dentry); ++ au_set_dbdiropq(dentry, -1); ++ } ++ need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0, ++ /*nd*/NULL); ++ err = need_wh; ++ if (isdir) ++ au_set_dbdiropq(dentry, bdiropq); ++ if (unlikely(err < 0)) ++ goto out; ++ new_bend = au_dbend(dentry); ++ if (!need_wh && old_bend != new_bend) { ++ au_set_h_dptr(dentry, new_bend, NULL); ++ au_set_dbend(dentry, old_bend); ++ } ++ } ++ AuDbg("need_wh %d\n", need_wh); ++ err = need_wh; ++ ++ out: ++ return err; ++} ++ ++/* ++ * simple tests for the del-entry operations. ++ * following the checks in vfs, plus the parent-child relationship. ++ */ ++int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent, int isdir) ++{ ++ int err; ++ umode_t h_mode; ++ struct dentry *h_dentry, *h_latest; ++ struct inode *h_inode; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ h_inode = h_dentry->d_inode; ++ if (dentry->d_inode) { ++ err = -ENOENT; ++ if (unlikely(!h_inode || !h_inode->i_nlink)) ++ goto out; ++ ++ h_mode = h_inode->i_mode; ++ if (!isdir) { ++ err = -EISDIR; ++ if (unlikely(S_ISDIR(h_mode))) ++ goto out; ++ } else if (unlikely(!S_ISDIR(h_mode))) { ++ err = -ENOTDIR; ++ goto out; ++ } ++ } else { ++ /* rename(2) case */ ++ err = -EIO; ++ if (unlikely(h_inode)) ++ goto out; ++ } ++ ++ err = -ENOENT; ++ /* expected parent dir is locked */ ++ if (unlikely(h_parent != h_dentry->d_parent)) ++ goto out; ++ err = 0; ++ ++ /* ++ * rmdir a dir may break the consistency on some filesystem. ++ * let's try heavy test. ++ */ ++ err = -EACCES; ++ if (unlikely(au_test_h_perm(h_parent->d_inode, MAY_EXEC | MAY_WRITE))) ++ goto out; ++ ++ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent, ++ au_sbr(dentry->d_sb, bindex)); ++ err = -EIO; ++ if (IS_ERR(h_latest)) ++ goto out; ++ if (h_latest == h_dentry) ++ err = 0; ++ dput(h_latest); ++ ++ out: ++ return err; ++} ++ ++/* ++ * decide the branch where we operate for @dentry. the branch index will be set ++ * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent ++ * dir for reverting. ++ * when a new whiteout is necessary, create it. ++ */ ++static struct dentry* ++lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup, ++ struct au_dtime *dt, struct au_pin *pin) ++{ ++ struct dentry *wh_dentry; ++ struct super_block *sb; ++ struct path h_path; ++ int err, need_wh; ++ unsigned int udba; ++ aufs_bindex_t bcpup; ++ ++ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup); ++ wh_dentry = ERR_PTR(need_wh); ++ if (unlikely(need_wh < 0)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ udba = au_opt_udba(sb); ++ bcpup = *rbcpup; ++ err = au_pin(pin, dentry, bcpup, udba, ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ ++ h_path.dentry = au_pinned_h_parent(pin); ++ if (udba != AuOpt_UDBA_NONE ++ && au_dbstart(dentry) == bcpup) { ++ err = au_may_del(dentry, bcpup, h_path.dentry, isdir); ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out_unpin; ++ } ++ ++ h_path.mnt = au_sbr_mnt(sb, bcpup); ++ au_dtime_store(dt, au_pinned_parent(pin), &h_path); ++ wh_dentry = NULL; ++ if (!need_wh) ++ goto out; /* success, no need to create whiteout */ ++ ++ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry); ++ if (!IS_ERR(wh_dentry)) ++ goto out; /* success */ ++ /* returns with the parent is locked and wh_dentry is dget-ed */ ++ ++ out_unpin: ++ au_unpin(pin); ++ out: ++ return wh_dentry; ++} ++ ++/* ++ * when removing a dir, rename it to a unique temporary whiteout-ed name first ++ * in order to be revertible and save time for removing many child whiteouts ++ * under the dir. ++ * returns 1 when there are too many child whiteout and caller should remove ++ * them asynchronously. returns 0 when the number of children is enough small to ++ * remove now or the branch fs is a remote fs. ++ * otherwise return an error. ++ */ ++static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex, ++ struct au_nhash *whlist, struct inode *dir) ++{ ++ int rmdir_later, err, dirwh; ++ struct dentry *h_dentry; ++ struct super_block *sb; ++ ++ sb = dentry->d_sb; ++ SiMustAnyLock(sb); ++ h_dentry = au_h_dptr(dentry, bindex); ++ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex)); ++ if (unlikely(err)) ++ goto out; ++ ++ /* stop monitoring */ ++ au_hin_free(au_hi(dentry->d_inode, bindex)); ++ ++ if (!au_test_fs_remote(h_dentry->d_sb)) { ++ dirwh = au_sbi(sb)->si_dirwh; ++ rmdir_later = (dirwh <= 1); ++ if (!rmdir_later) ++ rmdir_later = au_nhash_test_longer_wh(whlist, bindex, ++ dirwh); ++ if (rmdir_later) ++ return rmdir_later; ++ } ++ ++ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist); ++ if (unlikely(err)) { ++ AuIOErr("rmdir %.*s, b%d failed, %d. ignored\n", ++ AuDLNPair(h_dentry), bindex, err); ++ err = 0; ++ } ++ ++ out: ++ return err; ++} ++ ++/* ++ * final procedure for deleting a entry. ++ * maintain dentry and iattr. ++ */ ++static void epilog(struct inode *dir, struct dentry *dentry, ++ aufs_bindex_t bindex) ++{ ++ struct inode *inode; ++ ++ inode = dentry->d_inode; ++ d_drop(dentry); ++ inode->i_ctime = dir->i_ctime; ++ ++ if (atomic_read(&dentry->d_count) == 1) { ++ au_set_h_dptr(dentry, au_dbstart(dentry), NULL); ++ au_update_dbstart(dentry); ++ } ++ if (au_ibstart(dir) == bindex) ++ au_cpup_attr_timesizes(dir); ++ dir->i_version++; ++} ++ ++/* ++ * when an error happened, remove the created whiteout and revert everything. ++ */ ++static int do_revert(int err, struct inode *dir, aufs_bindex_t bwh, ++ struct dentry *wh_dentry, struct dentry *dentry, ++ struct au_dtime *dt) ++{ ++ int rerr; ++ struct path h_path = { ++ .dentry = wh_dentry, ++ .mnt = au_sbr_mnt(dir->i_sb, bwh) ++ }; ++ ++ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bwh), &h_path, dentry); ++ if (!rerr) { ++ au_set_dbwh(dentry, bwh); ++ au_dtime_revert(dt); ++ return 0; ++ } ++ ++ AuIOErr("%.*s reverting whiteout failed(%d, %d)\n", ++ AuDLNPair(dentry), err, rerr); ++ return -EIO; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int aufs_unlink(struct inode *dir, struct dentry *dentry) ++{ ++ int err; ++ aufs_bindex_t bwh, bindex, bstart; ++ struct au_dtime dt; ++ struct au_pin pin; ++ struct path h_path; ++ struct inode *inode, *h_dir; ++ struct dentry *parent, *wh_dentry; ++ ++ IMustLock(dir); ++ inode = dentry->d_inode; ++ if (unlikely(!inode)) ++ return -ENOENT; /* possible? */ ++ IMustLock(inode); ++ ++ aufs_read_lock(dentry, AuLock_DW); ++ parent = dentry->d_parent; /* dir inode is locked */ ++ di_write_lock_parent(parent); ++ ++ bstart = au_dbstart(dentry); ++ bwh = au_dbwh(dentry); ++ bindex = -1; ++ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt, &pin); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out; ++ ++ h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart); ++ h_path.dentry = au_h_dptr(dentry, bstart); ++ dget(h_path.dentry); ++ if (bindex == bstart) { ++ h_dir = au_pinned_h_dir(&pin); ++ err = vfsub_unlink(h_dir, &h_path, /*force*/0); ++ } else { ++ /* dir inode is locked */ ++ h_dir = wh_dentry->d_parent->d_inode; ++ IMustLock(h_dir); ++ err = 0; ++ } ++ ++ if (!err) { ++ drop_nlink(inode); ++ epilog(dir, dentry, bindex); ++ ++ /* update target timestamps */ ++ if (bindex == bstart) { ++ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/ ++ inode->i_ctime = h_path.dentry->d_inode->i_ctime; ++ } else ++ /* todo: this timestamp may be reverted later */ ++ inode->i_ctime = h_dir->i_ctime; ++ goto out_unlock; /* success */ ++ } ++ ++ /* revert */ ++ if (wh_dentry) { ++ int rerr; ++ ++ rerr = do_revert(err, dir, bwh, wh_dentry, dentry, &dt); ++ if (rerr) ++ err = rerr; ++ } ++ ++ out_unlock: ++ au_unpin(&pin); ++ dput(wh_dentry); ++ dput(h_path.dentry); ++ out: ++ di_write_unlock(parent); ++ aufs_read_unlock(dentry, AuLock_DW); ++ return err; ++} ++ ++int aufs_rmdir(struct inode *dir, struct dentry *dentry) ++{ ++ int err, rmdir_later; ++ aufs_bindex_t bwh, bindex, bstart; ++ struct au_dtime dt; ++ struct au_pin pin; ++ struct inode *inode; ++ struct dentry *parent, *wh_dentry, *h_dentry; ++ struct au_whtmp_rmdir *args; ++ ++ IMustLock(dir); ++ inode = dentry->d_inode; ++ err = -ENOENT; /* possible? */ ++ if (unlikely(!inode)) ++ goto out; ++ IMustLock(inode); ++ ++ aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH); ++ err = -ENOMEM; ++ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS); ++ if (unlikely(!args)) ++ goto out_unlock; ++ ++ parent = dentry->d_parent; /* dir inode is locked */ ++ di_write_lock_parent(parent); ++ err = au_test_empty(dentry, &args->whlist); ++ if (unlikely(err)) ++ goto out_args; ++ ++ bstart = au_dbstart(dentry); ++ bwh = au_dbwh(dentry); ++ bindex = -1; ++ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &dt, &pin); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out_args; ++ ++ h_dentry = au_h_dptr(dentry, bstart); ++ dget(h_dentry); ++ rmdir_later = 0; ++ if (bindex == bstart) { ++ err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir); ++ if (err > 0) { ++ rmdir_later = err; ++ err = 0; ++ } ++ } else { ++ /* stop monitoring */ ++ au_hin_free(au_hi(inode, bstart)); ++ ++ /* dir inode is locked */ ++ IMustLock(wh_dentry->d_parent->d_inode); ++ err = 0; ++ } ++ ++ if (!err) { ++ clear_nlink(inode); ++ au_set_dbdiropq(dentry, -1); ++ epilog(dir, dentry, bindex); ++ ++ if (rmdir_later) { ++ au_whtmp_kick_rmdir(dir, bstart, h_dentry, args); ++ args = NULL; ++ } ++ ++ goto out_unpin; /* success */ ++ } ++ ++ /* revert */ ++ AuLabel(revert); ++ if (wh_dentry) { ++ int rerr; ++ ++ rerr = do_revert(err, dir, bwh, wh_dentry, dentry, &dt); ++ if (rerr) ++ err = rerr; ++ } ++ ++ out_unpin: ++ au_unpin(&pin); ++ dput(wh_dentry); ++ dput(h_dentry); ++ out_args: ++ di_write_unlock(parent); ++ if (args) ++ au_whtmp_rmdir_free(args); ++ out_unlock: ++ aufs_read_unlock(dentry, AuLock_DW); ++ out: ++ return err; ++} +diff --git a/fs/aufs/i_op_ren.c b/fs/aufs/i_op_ren.c +new file mode 100644 +index 0000000..006148e +--- /dev/null ++++ b/fs/aufs/i_op_ren.c +@@ -0,0 +1,957 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * inode operation (rename entry) ++ * todo: this is crazy monster ++ */ ++ ++#include "aufs.h" ++ ++enum { AuSRC, AuDST, AuSrcDst }; ++enum { AuPARENT, AuCHILD, AuParentChild }; ++ ++#define AuRen_ISDIR 1 ++#define AuRen_ISSAMEDIR (1 << 1) ++#define AuRen_WHSRC (1 << 2) ++#define AuRen_WHDST (1 << 3) ++#define AuRen_MNT_WRITE (1 << 4) ++#define AuRen_DT_DSTDIR (1 << 5) ++#define AuRen_DIROPQ (1 << 6) ++#define AuRen_CPUP (1 << 7) ++#define au_ftest_ren(flags, name) ((flags) & AuRen_##name) ++#define au_fset_ren(flags, name) { (flags) |= AuRen_##name; } ++#define au_fclr_ren(flags, name) { (flags) &= ~AuRen_##name; } ++ ++struct au_ren_args { ++ struct { ++ struct dentry *dentry, *h_dentry, *parent, *h_parent, ++ *wh_dentry; ++ struct inode *dir, *inode; ++ struct au_hinode *hdir; ++ struct au_dtime dt[AuParentChild]; ++ aufs_bindex_t bstart; ++ } sd[AuSrcDst]; ++ ++#define src_dentry sd[AuSRC].dentry ++#define src_dir sd[AuSRC].dir ++#define src_inode sd[AuSRC].inode ++#define src_h_dentry sd[AuSRC].h_dentry ++#define src_parent sd[AuSRC].parent ++#define src_h_parent sd[AuSRC].h_parent ++#define src_wh_dentry sd[AuSRC].wh_dentry ++#define src_hdir sd[AuSRC].hdir ++#define src_h_dir sd[AuSRC].hdir->hi_inode ++#define src_dt sd[AuSRC].dt ++#define src_bstart sd[AuSRC].bstart ++ ++#define dst_dentry sd[AuDST].dentry ++#define dst_dir sd[AuDST].dir ++#define dst_inode sd[AuDST].inode ++#define dst_h_dentry sd[AuDST].h_dentry ++#define dst_parent sd[AuDST].parent ++#define dst_h_parent sd[AuDST].h_parent ++#define dst_wh_dentry sd[AuDST].wh_dentry ++#define dst_hdir sd[AuDST].hdir ++#define dst_h_dir sd[AuDST].hdir->hi_inode ++#define dst_dt sd[AuDST].dt ++#define dst_bstart sd[AuDST].bstart ++ ++ struct dentry *h_trap; ++ struct au_branch *br; ++ struct au_hinode *src_hinode; ++ struct path h_path; ++ struct au_nhash whlist; ++ aufs_bindex_t btgt; ++ ++ unsigned int flags; ++ ++ struct au_whtmp_rmdir *thargs; ++ struct dentry *h_dst; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * functions for reverting. ++ * when an error happened in a single rename systemcall, we should revert ++ * everything as if nothing happend. ++ * we don't need to revert the copied-up/down the parent dir since they are ++ * harmless. ++ */ ++ ++#define RevertFailure(fmt, args...) do { \ ++ AuIOErr("revert failure: " fmt " (%d, %d)\n", \ ++ ##args, err, rerr); \ ++ err = -EIO; \ ++} while (0) ++ ++static void au_ren_rev_diropq(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ ++ au_hin_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD); ++ rerr = au_diropq_remove(a->src_dentry, a->btgt); ++ au_hin_imtx_unlock(a->src_hinode); ++ if (rerr) ++ RevertFailure("remove diropq %.*s", AuDLNPair(a->src_dentry)); ++} ++ ++ ++static void au_ren_rev_rename(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ ++ a->h_path.dentry = au_lkup_one(&a->src_dentry->d_name, a->src_h_parent, ++ a->br, /*nd*/NULL); ++ rerr = PTR_ERR(a->h_path.dentry); ++ if (IS_ERR(a->h_path.dentry)) { ++ RevertFailure("au_lkup_one %.*s", AuDLNPair(a->src_dentry)); ++ return; ++ } ++ ++ rerr = vfsub_rename(a->dst_h_dir, ++ au_h_dptr(a->src_dentry, a->btgt), ++ a->src_h_dir, &a->h_path); ++ d_drop(a->h_path.dentry); ++ dput(a->h_path.dentry); ++ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */ ++ if (rerr) ++ RevertFailure("rename %.*s", AuDLNPair(a->src_dentry)); ++} ++ ++static void au_ren_rev_cpup(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ ++ a->h_path.dentry = a->dst_h_dentry; ++ rerr = vfsub_unlink(a->dst_h_dir, &a->h_path, /*force*/0); ++ au_set_h_dptr(a->src_dentry, a->btgt, NULL); ++ au_set_dbstart(a->src_dentry, a->src_bstart); ++ if (rerr) ++ RevertFailure("unlink %.*s", AuDLNPair(a->dst_h_dentry)); ++} ++ ++ ++static void au_ren_rev_whtmp(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ ++ a->h_path.dentry = au_lkup_one(&a->dst_dentry->d_name, a->dst_h_parent, ++ a->br, /*nd*/NULL); ++ rerr = PTR_ERR(a->h_path.dentry); ++ if (IS_ERR(a->h_path.dentry)) { ++ RevertFailure("lookup %.*s", AuDLNPair(a->dst_dentry)); ++ return; ++ } ++ if (a->h_path.dentry->d_inode) { ++ d_drop(a->h_path.dentry); ++ dput(a->h_path.dentry); ++ return; ++ } ++ ++ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path); ++ d_drop(a->h_path.dentry); ++ dput(a->h_path.dentry); ++ if (!rerr) { ++ au_set_h_dptr(a->dst_dentry, a->btgt, NULL); ++ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst)); ++ } else ++ RevertFailure("rename %.*s", AuDLNPair(a->h_dst)); ++} ++ ++static void au_ren_rev_whsrc(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ ++ a->h_path.dentry = a->src_wh_dentry; ++ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry); ++ if (rerr) ++ RevertFailure("unlink %.*s", AuDLNPair(a->src_wh_dentry)); ++} ++ ++static void au_ren_rev_drop(struct au_ren_args *a) ++{ ++ struct dentry *d, *h_d; ++ int i; ++ aufs_bindex_t bend, bindex; ++ ++ for (i = 0; i < AuSrcDst; i++) { ++ d = a->sd[i].dentry; ++ d_drop(d); ++ bend = au_dbend(d); ++ for (bindex = au_dbstart(d); bindex <= bend; bindex++) { ++ h_d = au_h_dptr(d, bindex); ++ if (h_d) ++ d_drop(h_d); ++ } ++ } ++ ++ au_update_dbstart(a->dst_dentry); ++ if (a->thargs) ++ d_drop(a->h_dst); ++} ++#undef RevertFailure ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * when we have to copyup the renaming entry, do it with the rename-target name ++ * in order to minimize the cost (the later actual rename is unnecessary). ++ * otherwise rename it on the target branch. ++ */ ++static int au_ren_or_cpup(struct au_ren_args *a) ++{ ++ int err; ++ struct dentry *d; ++ ++ d = a->src_dentry; ++ if (au_dbstart(d) == a->btgt) { ++ a->h_path.dentry = a->dst_h_dentry; ++ if (au_ftest_ren(a->flags, DIROPQ) ++ && au_dbdiropq(d) == a->btgt) ++ au_fclr_ren(a->flags, DIROPQ); ++ AuDebugOn(au_dbstart(d) != a->btgt); ++ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt), ++ a->dst_h_dir, &a->h_path); ++ } else { ++ struct mutex *h_mtx = &a->src_h_dentry->d_inode->i_mutex; ++ ++ au_fset_ren(a->flags, CPUP); ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ au_set_dbstart(d, a->btgt); ++ au_set_h_dptr(d, a->btgt, dget(a->dst_h_dentry)); ++ err = au_sio_cpup_single(d, a->btgt, a->src_bstart, -1, ++ !AuCpup_DTIME, a->dst_parent); ++ if (unlikely(err)) { ++ au_set_h_dptr(d, a->btgt, NULL); ++ au_set_dbstart(d, a->src_bstart); ++ } ++ mutex_unlock(h_mtx); ++ } ++ ++ return err; ++} ++ ++/* cf. aufs_rmdir() */ ++static int au_ren_del_whtmp(struct au_ren_args *a) ++{ ++ int err; ++ struct inode *dir; ++ ++ dir = a->dst_dir; ++ SiMustAnyLock(dir->i_sb); ++ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt, ++ au_sbi(dir->i_sb)->si_dirwh) ++ || au_test_fs_remote(a->h_dst->d_sb)) { ++ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist); ++ if (unlikely(err)) ++ AuWarn("failed removing whtmp dir %.*s (%d), " ++ "ignored.\n", AuDLNPair(a->h_dst), err); ++ } else { ++ au_nhash_wh_free(&a->thargs->whlist); ++ a->thargs->whlist = a->whlist; ++ a->whlist.nh_num = 0; ++ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs); ++ dput(a->h_dst); ++ a->thargs = NULL; ++ } ++ ++ return 0; ++} ++ ++/* make it 'opaque' dir. */ ++static int au_ren_diropq(struct au_ren_args *a) ++{ ++ int err; ++ struct dentry *diropq; ++ ++ err = 0; ++ a->src_hinode = au_hi(a->src_inode, a->btgt); ++ au_hin_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD); ++ diropq = au_diropq_create(a->src_dentry, a->btgt); ++ au_hin_imtx_unlock(a->src_hinode); ++ if (IS_ERR(diropq)) ++ err = PTR_ERR(diropq); ++ dput(diropq); ++ ++ return err; ++} ++ ++static int do_rename(struct au_ren_args *a) ++{ ++ int err; ++ struct dentry *d, *h_d; ++ ++ /* prepare workqueue args for asynchronous rmdir */ ++ h_d = a->dst_h_dentry; ++ if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) { ++ err = -ENOMEM; ++ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS); ++ if (unlikely(!a->thargs)) ++ goto out; ++ a->h_dst = dget(h_d); ++ } ++ ++ /* create whiteout for src_dentry */ ++ if (au_ftest_ren(a->flags, WHSRC)) { ++ a->src_wh_dentry ++ = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent); ++ err = PTR_ERR(a->src_wh_dentry); ++ if (IS_ERR(a->src_wh_dentry)) ++ goto out_thargs; ++ } ++ ++ /* lookup whiteout for dentry */ ++ if (au_ftest_ren(a->flags, WHDST)) { ++ h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name, ++ a->br); ++ err = PTR_ERR(h_d); ++ if (IS_ERR(h_d)) ++ goto out_whsrc; ++ if (!h_d->d_inode) ++ dput(h_d); ++ else ++ a->dst_wh_dentry = h_d; ++ } ++ ++ /* rename dentry to tmpwh */ ++ if (a->thargs) { ++ err = au_whtmp_ren(a->dst_h_dentry, a->br); ++ if (unlikely(err)) ++ goto out_whdst; ++ ++ d = a->dst_dentry; ++ au_set_h_dptr(d, a->btgt, NULL); ++ err = au_lkup_neg(d, a->btgt); ++ if (unlikely(err)) ++ goto out_whtmp; ++ a->dst_h_dentry = au_h_dptr(d, a->btgt); ++ } ++ ++ /* cpup src */ ++ if (a->dst_h_dentry->d_inode && a->src_bstart != a->btgt) { ++ struct mutex *h_mtx = &a->src_h_dentry->d_inode->i_mutex; ++ ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ err = au_sio_cpup_simple(a->src_dentry, a->btgt, -1, ++ !AuCpup_DTIME); ++ mutex_unlock(h_mtx); ++ if (unlikely(err)) ++ goto out_whtmp; ++ } ++ ++ /* rename by vfs_rename or cpup */ ++ d = a->dst_dentry; ++ if (au_ftest_ren(a->flags, ISDIR) ++ && (a->dst_wh_dentry ++ || au_dbdiropq(d) == a->btgt ++ /* hide the lower to keep xino */ ++ || a->btgt < au_dbend(d) ++ || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ))) ++ au_fset_ren(a->flags, DIROPQ); ++ err = au_ren_or_cpup(a); ++ if (unlikely(err)) ++ /* leave the copied-up one */ ++ goto out_whtmp; ++ ++ /* make dir opaque */ ++ if (au_ftest_ren(a->flags, DIROPQ)) { ++ err = au_ren_diropq(a); ++ if (unlikely(err)) ++ goto out_rename; ++ } ++ ++ /* update target timestamps */ ++ AuDebugOn(au_dbstart(a->src_dentry) != a->btgt); ++ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt); ++ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/ ++ a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime; ++ ++ /* remove whiteout for dentry */ ++ if (a->dst_wh_dentry) { ++ a->h_path.dentry = a->dst_wh_dentry; ++ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path, ++ a->dst_dentry); ++ if (unlikely(err)) ++ goto out_diropq; ++ } ++ ++ /* remove whtmp */ ++ if (a->thargs) ++ au_ren_del_whtmp(a); /* ignore this error */ ++ ++ err = 0; ++ goto out_success; ++ ++ out_diropq: ++ if (au_ftest_ren(a->flags, DIROPQ)) ++ au_ren_rev_diropq(err, a); ++ out_rename: ++ if (!au_ftest_ren(a->flags, CPUP)) ++ au_ren_rev_rename(err, a); ++ else ++ au_ren_rev_cpup(err, a); ++ out_whtmp: ++ if (a->thargs) ++ au_ren_rev_whtmp(err, a); ++ out_whdst: ++ dput(a->dst_wh_dentry); ++ a->dst_wh_dentry = NULL; ++ out_whsrc: ++ if (a->src_wh_dentry) ++ au_ren_rev_whsrc(err, a); ++ au_ren_rev_drop(a); ++ out_success: ++ dput(a->src_wh_dentry); ++ dput(a->dst_wh_dentry); ++ out_thargs: ++ if (a->thargs) { ++ dput(a->h_dst); ++ au_whtmp_rmdir_free(a->thargs); ++ a->thargs = NULL; ++ } ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * test if @dentry dir can be rename destination or not. ++ * success means, it is a logically empty dir. ++ */ ++static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist) ++{ ++ return au_test_empty(dentry, whlist); ++} ++ ++/* ++ * test if @dentry dir can be rename source or not. ++ * if it can, return 0 and @children is filled. ++ * success means, ++ * - it is a logically empty dir. ++ * - or, it exists on writable branch and has no children including whiteouts ++ * on the lower branch. ++ */ ++static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt) ++{ ++ int err; ++ unsigned int rdhash; ++ aufs_bindex_t bstart; ++ ++ bstart = au_dbstart(dentry); ++ if (bstart != btgt) { ++ struct au_nhash whlist; ++ ++ SiMustAnyLock(dentry->d_sb); ++ rdhash = au_sbi(dentry->d_sb)->si_rdhash; ++ if (!rdhash) ++ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, ++ dentry)); ++ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_test_empty(dentry, &whlist); ++ au_nhash_wh_free(&whlist); ++ goto out; ++ } ++ ++ if (bstart == au_dbtaildir(dentry)) ++ return 0; /* success */ ++ ++ err = au_test_empty_lower(dentry); ++ ++ out: ++ if (err == -ENOTEMPTY) { ++ AuWarn1("renaming dir who has child(ren) on multiple branches," ++ " is not supported\n"); ++ err = -EXDEV; ++ } ++ return err; ++} ++ ++/* side effect: sets whlist and h_dentry */ ++static int au_ren_may_dir(struct au_ren_args *a) ++{ ++ int err; ++ unsigned int rdhash; ++ struct dentry *d; ++ ++ d = a->dst_dentry; ++ SiMustAnyLock(d->d_sb); ++ ++ err = 0; ++ if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) { ++ rdhash = au_sbi(d->d_sb)->si_rdhash; ++ if (!rdhash) ++ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d)); ++ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ ++ au_set_dbstart(d, a->dst_bstart); ++ err = may_rename_dstdir(d, &a->whlist); ++ au_set_dbstart(d, a->btgt); ++ } ++ a->dst_h_dentry = au_h_dptr(d, au_dbstart(d)); ++ if (unlikely(err)) ++ goto out; ++ ++ d = a->src_dentry; ++ a->src_h_dentry = au_h_dptr(d, au_dbstart(d)); ++ if (au_ftest_ren(a->flags, ISDIR)) { ++ err = may_rename_srcdir(d, a->btgt); ++ if (unlikely(err)) { ++ au_nhash_wh_free(&a->whlist); ++ a->whlist.nh_num = 0; ++ } ++ } ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * simple tests for rename. ++ * following the checks in vfs, plus the parent-child relationship. ++ */ ++static int au_may_ren(struct au_ren_args *a) ++{ ++ int err, isdir; ++ struct inode *h_inode; ++ ++ if (a->src_bstart == a->btgt) { ++ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent, ++ au_ftest_ren(a->flags, ISDIR)); ++ if (unlikely(err)) ++ goto out; ++ err = -EINVAL; ++ if (unlikely(a->src_h_dentry == a->h_trap)) ++ goto out; ++ } ++ ++ err = 0; ++ if (a->dst_bstart != a->btgt) ++ goto out; ++ ++ err = -EIO; ++ h_inode = a->dst_h_dentry->d_inode; ++ isdir = !!au_ftest_ren(a->flags, ISDIR); ++ if (!a->dst_dentry->d_inode) { ++ if (unlikely(h_inode)) ++ goto out; ++ err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent, ++ isdir); ++ } else { ++ if (unlikely(!h_inode || !h_inode->i_nlink)) ++ goto out; ++ err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent, ++ isdir); ++ if (unlikely(err)) ++ goto out; ++ err = -ENOTEMPTY; ++ if (unlikely(a->dst_h_dentry == a->h_trap)) ++ goto out; ++ err = 0; ++ } ++ ++ out: ++ if (unlikely(err == -ENOENT || err == -EEXIST)) ++ err = -EIO; ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * locking order ++ * (VFS) ++ * - src_dir and dir by lock_rename() ++ * - inode if exitsts ++ * (aufs) ++ * - lock all ++ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls, ++ * + si_read_lock ++ * + di_write_lock2_child() ++ * + di_write_lock_child() ++ * + ii_write_lock_child() ++ * + di_write_lock_child2() ++ * + ii_write_lock_child2() ++ * + src_parent and parent ++ * + di_write_lock_parent() ++ * + ii_write_lock_parent() ++ * + di_write_lock_parent2() ++ * + ii_write_lock_parent2() ++ * + lower src_dir and dir by vfsub_lock_rename() ++ * + verify the every relationships between child and parent. if any ++ * of them failed, unlock all and return -EBUSY. ++ */ ++static void au_ren_unlock(struct au_ren_args *a) ++{ ++ struct super_block *sb; ++ ++ sb = a->dst_dentry->d_sb; ++ if (au_ftest_ren(a->flags, MNT_WRITE)) ++ mnt_drop_write(a->br->br_mnt); ++ vfsub_unlock_rename(a->src_h_parent, a->src_hdir, ++ a->dst_h_parent, a->dst_hdir); ++} ++ ++static int au_ren_lock(struct au_ren_args *a) ++{ ++ int err; ++ unsigned int udba; ++ ++ err = 0; ++ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt); ++ a->src_hdir = au_hi(a->src_dir, a->btgt); ++ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt); ++ a->dst_hdir = au_hi(a->dst_dir, a->btgt); ++ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir, ++ a->dst_h_parent, a->dst_hdir); ++ udba = au_opt_udba(a->src_dentry->d_sb); ++ if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode ++ || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode)) ++ err = au_busy_or_stale(); ++ if (!err && au_dbstart(a->src_dentry) == a->btgt) ++ err = au_h_verify(a->src_h_dentry, udba, ++ a->src_h_parent->d_inode, a->src_h_parent, ++ a->br); ++ if (!err && au_dbstart(a->dst_dentry) == a->btgt) ++ err = au_h_verify(a->dst_h_dentry, udba, ++ a->dst_h_parent->d_inode, a->dst_h_parent, ++ a->br); ++ if (!err) { ++ err = mnt_want_write(a->br->br_mnt); ++ if (unlikely(err)) ++ goto out_unlock; ++ au_fset_ren(a->flags, MNT_WRITE); ++ goto out; /* success */ ++ } ++ ++ err = au_busy_or_stale(); ++ ++ out_unlock: ++ au_ren_unlock(a); ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void au_ren_refresh_dir(struct au_ren_args *a) ++{ ++ struct inode *dir; ++ ++ dir = a->dst_dir; ++ dir->i_version++; ++ if (au_ftest_ren(a->flags, ISDIR)) { ++ /* is this updating defined in POSIX? */ ++ au_cpup_attr_timesizes(a->src_inode); ++ au_cpup_attr_nlink(dir, /*force*/1); ++ if (a->dst_inode) { ++ clear_nlink(a->dst_inode); ++ au_cpup_attr_timesizes(a->dst_inode); ++ } ++ } ++ if (au_ibstart(dir) == a->btgt) ++ au_cpup_attr_timesizes(dir); ++ ++ if (au_ftest_ren(a->flags, ISSAMEDIR)) ++ return; ++ ++ dir = a->src_dir; ++ dir->i_version++; ++ if (au_ftest_ren(a->flags, ISDIR)) ++ au_cpup_attr_nlink(dir, /*force*/1); ++ if (au_ibstart(dir) == a->btgt) ++ au_cpup_attr_timesizes(dir); ++} ++ ++static void au_ren_refresh(struct au_ren_args *a) ++{ ++ aufs_bindex_t bend, bindex; ++ struct dentry *d, *h_d; ++ struct inode *i, *h_i; ++ struct super_block *sb; ++ ++ d = a->src_dentry; ++ au_set_dbwh(d, -1); ++ bend = au_dbend(d); ++ for (bindex = a->btgt + 1; bindex <= bend; bindex++) { ++ h_d = au_h_dptr(d, bindex); ++ if (h_d) ++ au_set_h_dptr(d, bindex, NULL); ++ } ++ au_set_dbend(d, a->btgt); ++ ++ sb = d->d_sb; ++ i = a->src_inode; ++ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i)) ++ return; /* success */ ++ ++ bend = au_ibend(i); ++ for (bindex = a->btgt + 1; bindex <= bend; bindex++) { ++ h_i = au_h_iptr(i, bindex); ++ if (h_i) { ++ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0); ++ /* ignore this error */ ++ au_set_h_iptr(i, bindex, NULL, 0); ++ } ++ } ++ au_set_ibend(i, a->btgt); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* mainly for link(2) and rename(2) */ ++int au_wbr(struct dentry *dentry, aufs_bindex_t btgt) ++{ ++ aufs_bindex_t bdiropq, bwh; ++ struct dentry *parent; ++ struct au_branch *br; ++ ++ parent = dentry->d_parent; ++ IMustLock(parent->d_inode); /* dir is locked */ ++ ++ bdiropq = au_dbdiropq(parent); ++ bwh = au_dbwh(dentry); ++ br = au_sbr(dentry->d_sb, btgt); ++ if (au_br_rdonly(br) ++ || (0 <= bdiropq && bdiropq < btgt) ++ || (0 <= bwh && bwh < btgt)) ++ btgt = -1; ++ ++ AuDbg("btgt %d\n", btgt); ++ return btgt; ++} ++ ++/* sets src_bstart, dst_bstart and btgt */ ++static int au_ren_wbr(struct au_ren_args *a) ++{ ++ int err; ++ struct au_wr_dir_args wr_dir_args = { ++ /* .force_btgt = -1, */ ++ .flags = AuWrDir_ADD_ENTRY ++ }; ++ ++ a->src_bstart = au_dbstart(a->src_dentry); ++ a->dst_bstart = au_dbstart(a->dst_dentry); ++ if (au_ftest_ren(a->flags, ISDIR)) ++ au_fset_wrdir(wr_dir_args.flags, ISDIR); ++ wr_dir_args.force_btgt = a->src_bstart; ++ if (a->dst_inode && a->dst_bstart < a->src_bstart) ++ wr_dir_args.force_btgt = a->dst_bstart; ++ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt); ++ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args); ++ a->btgt = err; ++ ++ return err; ++} ++ ++static void au_ren_dt(struct au_ren_args *a) ++{ ++ a->h_path.dentry = a->src_h_parent; ++ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path); ++ if (!au_ftest_ren(a->flags, ISSAMEDIR)) { ++ a->h_path.dentry = a->dst_h_parent; ++ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path); ++ } ++ ++ au_fclr_ren(a->flags, DT_DSTDIR); ++ if (!au_ftest_ren(a->flags, ISDIR)) ++ return; ++ ++ a->h_path.dentry = a->src_h_dentry; ++ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path); ++ if (a->dst_h_dentry->d_inode) { ++ au_fset_ren(a->flags, DT_DSTDIR); ++ a->h_path.dentry = a->dst_h_dentry; ++ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path); ++ } ++} ++ ++static void au_ren_rev_dt(int err, struct au_ren_args *a) ++{ ++ struct dentry *h_d; ++ struct mutex *h_mtx; ++ ++ au_dtime_revert(a->src_dt + AuPARENT); ++ if (!au_ftest_ren(a->flags, ISSAMEDIR)) ++ au_dtime_revert(a->dst_dt + AuPARENT); ++ ++ if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) { ++ h_d = a->src_dt[AuCHILD].dt_h_path.dentry; ++ h_mtx = &h_d->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ au_dtime_revert(a->src_dt + AuCHILD); ++ mutex_unlock(h_mtx); ++ ++ if (au_ftest_ren(a->flags, DT_DSTDIR)) { ++ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry; ++ h_mtx = &h_d->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ au_dtime_revert(a->dst_dt + AuCHILD); ++ mutex_unlock(h_mtx); ++ } ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry, ++ struct inode *_dst_dir, struct dentry *_dst_dentry) ++{ ++ int err; ++ /* reduce stack space */ ++ struct au_ren_args *a; ++ ++ IMustLock(_src_dir); ++ IMustLock(_dst_dir); ++ ++ err = -ENOMEM; ++ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE); ++ a = kzalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ a->src_dir = _src_dir; ++ a->src_dentry = _src_dentry; ++ a->src_inode = a->src_dentry->d_inode; ++ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */ ++ a->dst_dir = _dst_dir; ++ a->dst_dentry = _dst_dentry; ++ a->dst_inode = a->dst_dentry->d_inode; ++ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */ ++ if (a->dst_inode) { ++ IMustLock(a->dst_inode); ++ au_igrab(a->dst_inode); ++ } ++ ++ err = -ENOTDIR; ++ if (S_ISDIR(a->src_inode->i_mode)) { ++ au_fset_ren(a->flags, ISDIR); ++ if (unlikely(a->dst_inode && !S_ISDIR(a->dst_inode->i_mode))) ++ goto out_free; ++ aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry, ++ AuLock_DIR | AuLock_FLUSH); ++ } else ++ aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry, ++ AuLock_FLUSH); ++ ++ au_fset_ren(a->flags, ISSAMEDIR); /* temporary */ ++ di_write_lock_parent(a->dst_parent); ++ ++ /* which branch we process */ ++ err = au_ren_wbr(a); ++ if (unlikely(err < 0)) ++ goto out_unlock; ++ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt); ++ a->h_path.mnt = a->br->br_mnt; ++ ++ /* are they available to be renamed */ ++ err = au_ren_may_dir(a); ++ if (unlikely(err)) ++ goto out_children; ++ ++ /* prepare the writable parent dir on the same branch */ ++ if (a->dst_bstart == a->btgt) { ++ au_fset_ren(a->flags, WHDST); ++ } else { ++ err = au_cpup_dirs(a->dst_dentry, a->btgt); ++ if (unlikely(err)) ++ goto out_children; ++ } ++ ++ if (a->src_dir != a->dst_dir) { ++ /* ++ * this temporary unlock is safe, ++ * because both dir->i_mutex are locked. ++ */ ++ di_write_unlock(a->dst_parent); ++ di_write_lock_parent(a->src_parent); ++ err = au_wr_dir_need_wh(a->src_dentry, ++ au_ftest_ren(a->flags, ISDIR), ++ &a->btgt); ++ di_write_unlock(a->src_parent); ++ di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1); ++ au_fclr_ren(a->flags, ISSAMEDIR); ++ } else ++ err = au_wr_dir_need_wh(a->src_dentry, ++ au_ftest_ren(a->flags, ISDIR), ++ &a->btgt); ++ if (unlikely(err < 0)) ++ goto out_children; ++ if (err) ++ au_fset_ren(a->flags, WHSRC); ++ ++ /* lock them all */ ++ err = au_ren_lock(a); ++ if (unlikely(err)) ++ goto out_children; ++ ++ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE)) { ++ err = au_may_ren(a); ++ if (unlikely(err)) ++ goto out_hdir; ++ } ++ ++ /* store timestamps to be revertible */ ++ au_ren_dt(a); ++ ++ /* here we go */ ++ err = do_rename(a); ++ if (unlikely(err)) ++ goto out_dt; ++ ++ /* update dir attributes */ ++ au_ren_refresh_dir(a); ++ ++ /* dput/iput all lower dentries */ ++ au_ren_refresh(a); ++ ++ goto out_hdir; /* success */ ++ ++ out_dt: ++ au_ren_rev_dt(err, a); ++ out_hdir: ++ au_ren_unlock(a); ++ out_children: ++ au_nhash_wh_free(&a->whlist); ++ out_unlock: ++ if (unlikely(err && au_ftest_ren(a->flags, ISDIR))) { ++ au_update_dbstart(a->dst_dentry); ++ d_drop(a->dst_dentry); ++ } ++ if (!err) ++ d_move(a->src_dentry, a->dst_dentry); ++ if (au_ftest_ren(a->flags, ISSAMEDIR)) ++ di_write_unlock(a->dst_parent); ++ else ++ di_write_unlock2(a->src_parent, a->dst_parent); ++ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry); ++ out_free: ++ iput(a->dst_inode); ++ if (a->thargs) ++ au_whtmp_rmdir_free(a->thargs); ++ kfree(a); ++ out: ++ return err; ++} +diff --git a/fs/aufs/iinfo.c b/fs/aufs/iinfo.c +new file mode 100644 +index 0000000..072ddfc +--- /dev/null ++++ b/fs/aufs/iinfo.c +@@ -0,0 +1,283 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * inode private data ++ */ ++ ++#include "aufs.h" ++ ++struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex) ++{ ++ struct inode *h_inode; ++ ++ IiMustAnyLock(inode); ++ ++ h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode; ++ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); ++ return h_inode; ++} ++ ++/* todo: hard/soft set? */ ++void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex) ++{ ++ struct au_iinfo *iinfo = au_ii(inode); ++ struct inode *h_inode; ++ ++ IiMustWriteLock(inode); ++ ++ iinfo->ii_bstart = bindex; ++ h_inode = iinfo->ii_hinode[bindex + 0].hi_inode; ++ if (h_inode) ++ au_cpup_igen(inode, h_inode); ++} ++ ++void au_hiput(struct au_hinode *hinode) ++{ ++ au_hin_free(hinode); ++ dput(hinode->hi_whdentry); ++ iput(hinode->hi_inode); ++} ++ ++unsigned int au_hi_flags(struct inode *inode, int isdir) ++{ ++ unsigned int flags; ++ const unsigned int mnt_flags = au_mntflags(inode->i_sb); ++ ++ flags = 0; ++ if (au_opt_test(mnt_flags, XINO)) ++ au_fset_hi(flags, XINO); ++ if (isdir && au_opt_test(mnt_flags, UDBA_HINOTIFY)) ++ au_fset_hi(flags, HINOTIFY); ++ return flags; ++} ++ ++void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, ++ struct inode *h_inode, unsigned int flags) ++{ ++ struct au_hinode *hinode; ++ struct inode *hi; ++ struct au_iinfo *iinfo = au_ii(inode); ++ ++ IiMustWriteLock(inode); ++ ++ hinode = iinfo->ii_hinode + bindex; ++ hi = hinode->hi_inode; ++ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); ++ AuDebugOn(h_inode && hi); ++ ++ if (hi) ++ au_hiput(hinode); ++ hinode->hi_inode = h_inode; ++ if (h_inode) { ++ int err; ++ struct super_block *sb = inode->i_sb; ++ struct au_branch *br; ++ ++ if (bindex == iinfo->ii_bstart) ++ au_cpup_igen(inode, h_inode); ++ br = au_sbr(sb, bindex); ++ hinode->hi_id = br->br_id; ++ if (au_ftest_hi(flags, XINO)) { ++ err = au_xino_write(sb, bindex, h_inode->i_ino, ++ inode->i_ino); ++ if (unlikely(err)) ++ AuIOErr1("failed au_xino_write() %d\n", err); ++ } ++ ++ if (au_ftest_hi(flags, HINOTIFY) ++ && au_br_hinotifyable(br->br_perm)) { ++ err = au_hin_alloc(hinode, inode, h_inode); ++ if (unlikely(err)) ++ AuIOErr1("au_hin_alloc() %d\n", err); ++ } ++ } ++} ++ ++void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_wh) ++{ ++ struct au_hinode *hinode; ++ ++ IiMustWriteLock(inode); ++ ++ hinode = au_ii(inode)->ii_hinode + bindex; ++ AuDebugOn(hinode->hi_whdentry); ++ hinode->hi_whdentry = h_wh; ++} ++ ++void au_update_iigen(struct inode *inode) ++{ ++ atomic_set(&au_ii(inode)->ii_generation, au_sigen(inode->i_sb)); ++ /* smp_mb(); */ /* atomic_set */ ++} ++ ++/* it may be called at remount time, too */ ++void au_update_brange(struct inode *inode, int do_put_zero) ++{ ++ struct au_iinfo *iinfo; ++ ++ iinfo = au_ii(inode); ++ if (!iinfo || iinfo->ii_bstart < 0) ++ return; ++ ++ IiMustWriteLock(inode); ++ ++ if (do_put_zero) { ++ aufs_bindex_t bindex; ++ ++ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; ++ bindex++) { ++ struct inode *h_i; ++ ++ h_i = iinfo->ii_hinode[0 + bindex].hi_inode; ++ if (h_i && !h_i->i_nlink) ++ au_set_h_iptr(inode, bindex, NULL, 0); ++ } ++ } ++ ++ iinfo->ii_bstart = -1; ++ while (++iinfo->ii_bstart <= iinfo->ii_bend) ++ if (iinfo->ii_hinode[0 + iinfo->ii_bstart].hi_inode) ++ break; ++ if (iinfo->ii_bstart > iinfo->ii_bend) { ++ iinfo->ii_bstart = -1; ++ iinfo->ii_bend = -1; ++ return; ++ } ++ ++ iinfo->ii_bend++; ++ while (0 <= --iinfo->ii_bend) ++ if (iinfo->ii_hinode[0 + iinfo->ii_bend].hi_inode) ++ break; ++ AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend || iinfo->ii_bend < 0); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_iinfo_init(struct inode *inode) ++{ ++ struct au_iinfo *iinfo; ++ struct super_block *sb; ++ int nbr, i; ++ ++ sb = inode->i_sb; ++ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo); ++ nbr = au_sbend(sb) + 1; ++ if (unlikely(nbr <= 0)) ++ nbr = 1; ++ iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS); ++ if (iinfo->ii_hinode) { ++ for (i = 0; i < nbr; i++) ++ iinfo->ii_hinode[i].hi_id = -1; ++ ++ atomic_set(&iinfo->ii_generation, au_sigen(sb)); ++ /* smp_mb(); */ /* atomic_set */ ++ au_rw_init(&iinfo->ii_rwsem); ++ iinfo->ii_bstart = -1; ++ iinfo->ii_bend = -1; ++ iinfo->ii_vdir = NULL; ++ return 0; ++ } ++ return -ENOMEM; ++} ++ ++int au_ii_realloc(struct au_iinfo *iinfo, int nbr) ++{ ++ int err, sz; ++ struct au_hinode *hip; ++ ++ AuRwMustWriteLock(&iinfo->ii_rwsem); ++ ++ err = -ENOMEM; ++ sz = sizeof(*hip) * (iinfo->ii_bend + 1); ++ if (!sz) ++ sz = sizeof(*hip); ++ hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS); ++ if (hip) { ++ iinfo->ii_hinode = hip; ++ err = 0; ++ } ++ ++ return err; ++} ++ ++static int au_iinfo_write0(struct super_block *sb, struct au_hinode *hinode, ++ ino_t ino) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ unsigned char locked; ++ ++ err = 0; ++ locked = !!si_noflush_read_trylock(sb); ++ bindex = au_br_index(sb, hinode->hi_id); ++ if (bindex >= 0) ++ err = au_xino_write0(sb, bindex, hinode->hi_inode->i_ino, ino); ++ /* error action? */ ++ if (locked) ++ si_read_unlock(sb); ++ return err; ++} ++ ++void au_iinfo_fin(struct inode *inode) ++{ ++ ino_t ino; ++ aufs_bindex_t bend; ++ unsigned char unlinked = !inode->i_nlink; ++ struct au_iinfo *iinfo; ++ struct au_hinode *hi; ++ struct super_block *sb; ++ ++ if (unlinked) { ++ int err = au_xigen_inc(inode); ++ if (unlikely(err)) ++ AuWarn1("failed resetting i_generation, %d\n", err); ++ } ++ ++ iinfo = au_ii(inode); ++ /* bad_inode case */ ++ if (!iinfo) ++ return; ++ ++ if (iinfo->ii_vdir) ++ au_vdir_free(iinfo->ii_vdir); ++ ++ if (iinfo->ii_bstart >= 0) { ++ sb = inode->i_sb; ++ ino = 0; ++ if (unlinked) ++ ino = inode->i_ino; ++ hi = iinfo->ii_hinode + iinfo->ii_bstart; ++ bend = iinfo->ii_bend; ++ while (iinfo->ii_bstart++ <= bend) { ++ if (hi->hi_inode) { ++ if (unlinked || !hi->hi_inode->i_nlink) { ++ au_iinfo_write0(sb, hi, ino); ++ /* ignore this error */ ++ ino = 0; ++ } ++ au_hiput(hi); ++ } ++ hi++; ++ } ++ } ++ ++ kfree(iinfo->ii_hinode); ++ AuRwDestroy(&iinfo->ii_rwsem); ++} +diff --git a/fs/aufs/inode.c b/fs/aufs/inode.c +new file mode 100644 +index 0000000..a85c19c +--- /dev/null ++++ b/fs/aufs/inode.c +@@ -0,0 +1,413 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * inode functions ++ */ ++ ++#include "aufs.h" ++ ++struct inode *au_igrab(struct inode *inode) ++{ ++ if (inode) { ++ AuDebugOn(!atomic_read(&inode->i_count)); ++ atomic_inc_return(&inode->i_count); ++ } ++ return inode; ++} ++ ++static void au_refresh_hinode_attr(struct inode *inode, int do_version) ++{ ++ au_cpup_attr_all(inode, /*force*/0); ++ au_update_iigen(inode); ++ if (do_version) ++ inode->i_version++; ++} ++ ++int au_refresh_hinode_self(struct inode *inode, int do_attr) ++{ ++ int err; ++ aufs_bindex_t bindex, new_bindex; ++ unsigned char update; ++ struct inode *first; ++ struct au_hinode *p, *q, tmp; ++ struct super_block *sb; ++ struct au_iinfo *iinfo; ++ ++ IiMustWriteLock(inode); ++ ++ update = 0; ++ sb = inode->i_sb; ++ iinfo = au_ii(inode); ++ err = au_ii_realloc(iinfo, au_sbend(sb) + 1); ++ if (unlikely(err)) ++ goto out; ++ ++ p = iinfo->ii_hinode + iinfo->ii_bstart; ++ first = p->hi_inode; ++ err = 0; ++ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; ++ bindex++, p++) { ++ if (!p->hi_inode) ++ continue; ++ ++ new_bindex = au_br_index(sb, p->hi_id); ++ if (new_bindex == bindex) ++ continue; ++ ++ if (new_bindex < 0) { ++ update++; ++ au_hiput(p); ++ p->hi_inode = NULL; ++ continue; ++ } ++ ++ if (new_bindex < iinfo->ii_bstart) ++ iinfo->ii_bstart = new_bindex; ++ if (iinfo->ii_bend < new_bindex) ++ iinfo->ii_bend = new_bindex; ++ /* swap two lower inode, and loop again */ ++ q = iinfo->ii_hinode + new_bindex; ++ tmp = *q; ++ *q = *p; ++ *p = tmp; ++ if (tmp.hi_inode) { ++ bindex--; ++ p--; ++ } ++ } ++ au_update_brange(inode, /*do_put_zero*/0); ++ if (do_attr) ++ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode)); ++ ++ out: ++ return err; ++} ++ ++int au_refresh_hinode(struct inode *inode, struct dentry *dentry) ++{ ++ int err, update; ++ unsigned int flags; ++ aufs_bindex_t bindex, bend; ++ unsigned char isdir; ++ struct inode *first; ++ struct au_hinode *p; ++ struct au_iinfo *iinfo; ++ ++ err = au_refresh_hinode_self(inode, /*do_attr*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ update = 0; ++ iinfo = au_ii(inode); ++ p = iinfo->ii_hinode + iinfo->ii_bstart; ++ first = p->hi_inode; ++ isdir = S_ISDIR(inode->i_mode); ++ flags = au_hi_flags(inode, isdir); ++ bend = au_dbend(dentry); ++ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) { ++ struct inode *h_i; ++ struct dentry *h_d; ++ ++ h_d = au_h_dptr(dentry, bindex); ++ if (!h_d || !h_d->d_inode) ++ continue; ++ ++ if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) { ++ h_i = au_h_iptr(inode, bindex); ++ if (h_i) { ++ if (h_i == h_d->d_inode) ++ continue; ++ err = -EIO; ++ break; ++ } ++ } ++ if (bindex < iinfo->ii_bstart) ++ iinfo->ii_bstart = bindex; ++ if (iinfo->ii_bend < bindex) ++ iinfo->ii_bend = bindex; ++ au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags); ++ update = 1; ++ } ++ au_update_brange(inode, /*do_put_zero*/0); ++ ++ if (unlikely(err)) ++ goto out; ++ ++ au_refresh_hinode_attr(inode, update && isdir); ++ ++ out: ++ return err; ++} ++ ++static int set_inode(struct inode *inode, struct dentry *dentry) ++{ ++ int err; ++ unsigned int flags; ++ umode_t mode; ++ aufs_bindex_t bindex, bstart, btail; ++ unsigned char isdir; ++ struct dentry *h_dentry; ++ struct inode *h_inode; ++ struct au_iinfo *iinfo; ++ ++ IiMustWriteLock(inode); ++ ++ err = 0; ++ isdir = 0; ++ bstart = au_dbstart(dentry); ++ h_inode = au_h_dptr(dentry, bstart)->d_inode; ++ mode = h_inode->i_mode; ++ switch (mode & S_IFMT) { ++ case S_IFREG: ++ btail = au_dbtail(dentry); ++ inode->i_op = &aufs_iop; ++ inode->i_fop = &aufs_file_fop; ++ inode->i_mapping->a_ops = &aufs_aop; ++ break; ++ case S_IFDIR: ++ isdir = 1; ++ btail = au_dbtaildir(dentry); ++ inode->i_op = &aufs_dir_iop; ++ inode->i_fop = &aufs_dir_fop; ++ break; ++ case S_IFLNK: ++ btail = au_dbtail(dentry); ++ inode->i_op = &aufs_symlink_iop; ++ break; ++ case S_IFBLK: ++ case S_IFCHR: ++ case S_IFIFO: ++ case S_IFSOCK: ++ btail = au_dbtail(dentry); ++ inode->i_op = &aufs_iop; ++ init_special_inode(inode, mode, h_inode->i_rdev); ++ break; ++ default: ++ AuIOErr("Unknown file type 0%o\n", mode); ++ err = -EIO; ++ goto out; ++ } ++ ++ /* do not set inotify for whiteouted dirs (SHWH mode) */ ++ flags = au_hi_flags(inode, isdir); ++ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH) ++ && au_ftest_hi(flags, HINOTIFY) ++ && dentry->d_name.len > AUFS_WH_PFX_LEN ++ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) ++ au_fclr_hi(flags, HINOTIFY); ++ iinfo = au_ii(inode); ++ iinfo->ii_bstart = bstart; ++ iinfo->ii_bend = btail; ++ for (bindex = bstart; bindex <= btail; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry) ++ au_set_h_iptr(inode, bindex, ++ au_igrab(h_dentry->d_inode), flags); ++ } ++ au_cpup_attr_all(inode, /*force*/1); ++ ++ out: ++ return err; ++} ++ ++/* successful returns with iinfo write_locked */ ++static int reval_inode(struct inode *inode, struct dentry *dentry, int *matched) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ struct inode *h_inode, *h_dinode; ++ ++ *matched = 0; ++ ++ /* ++ * before this function, if aufs got any iinfo lock, it must be only ++ * one, the parent dir. ++ * it can happen by UDBA and the obsoleted inode number. ++ */ ++ err = -EIO; ++ if (unlikely(inode->i_ino == parent_ino(dentry))) ++ goto out; ++ ++ err = 0; ++ ii_write_lock_new_child(inode); ++ h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode; ++ bend = au_ibend(inode); ++ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) { ++ h_inode = au_h_iptr(inode, bindex); ++ if (h_inode && h_inode == h_dinode) { ++ *matched = 1; ++ err = 0; ++ if (au_iigen(inode) != au_digen(dentry)) ++ err = au_refresh_hinode(inode, dentry); ++ break; ++ } ++ } ++ ++ if (unlikely(err)) ++ ii_write_unlock(inode); ++ out: ++ return err; ++} ++ ++int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ unsigned int d_type, ino_t *ino) ++{ ++ int err; ++ struct mutex *mtx; ++ const int isdir = (d_type == DT_DIR); ++ ++ /* prevent hardlinks from race condition */ ++ mtx = NULL; ++ if (!isdir) { ++ mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx; ++ mutex_lock(mtx); ++ } ++ err = au_xino_read(sb, bindex, h_ino, ino); ++ if (unlikely(err)) ++ goto out; ++ ++ if (!*ino) { ++ err = -EIO; ++ *ino = au_xino_new_ino(sb); ++ if (unlikely(!*ino)) ++ goto out; ++ err = au_xino_write(sb, bindex, h_ino, *ino); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ out: ++ if (!isdir) ++ mutex_unlock(mtx); ++ return err; ++} ++ ++/* successful returns with iinfo write_locked */ ++/* todo: return with unlocked? */ ++struct inode *au_new_inode(struct dentry *dentry, int must_new) ++{ ++ struct inode *inode; ++ struct dentry *h_dentry; ++ struct super_block *sb; ++ ino_t h_ino, ino; ++ int err, match; ++ aufs_bindex_t bstart; ++ ++ sb = dentry->d_sb; ++ bstart = au_dbstart(dentry); ++ h_dentry = au_h_dptr(dentry, bstart); ++ h_ino = h_dentry->d_inode->i_ino; ++ err = au_xino_read(sb, bstart, h_ino, &ino); ++ inode = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ new_ino: ++ if (!ino) { ++ ino = au_xino_new_ino(sb); ++ if (unlikely(!ino)) { ++ inode = ERR_PTR(-EIO); ++ goto out; ++ } ++ } ++ ++ AuDbg("i%lu\n", (unsigned long)ino); ++ inode = au_iget_locked(sb, ino); ++ err = PTR_ERR(inode); ++ if (IS_ERR(inode)) ++ goto out; ++ ++ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW)); ++ if (inode->i_state & I_NEW) { ++ ii_write_lock_new_child(inode); ++ err = set_inode(inode, dentry); ++ unlock_new_inode(inode); ++ if (!err) ++ goto out; /* success */ ++ ++ iget_failed(inode); ++ ii_write_unlock(inode); ++ goto out_iput; ++ } else if (!must_new) { ++ err = reval_inode(inode, dentry, &match); ++ if (!err) ++ goto out; /* success */ ++ else if (match) ++ goto out_iput; ++ } ++ ++ if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode))) ++ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir," ++ " b%d, %s, %.*s, hi%lu, i%lu.\n", ++ bstart, au_sbtype(h_dentry->d_sb), AuDLNPair(dentry), ++ (unsigned long)h_ino, (unsigned long)ino); ++ ino = 0; ++ err = au_xino_write(sb, bstart, h_ino, /*ino*/0); ++ if (!err) { ++ iput(inode); ++ goto new_ino; ++ } ++ ++ out_iput: ++ iput(inode); ++ inode = ERR_PTR(err); ++ out: ++ return inode; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, ++ struct inode *inode) ++{ ++ int err; ++ ++ err = au_br_rdonly(au_sbr(sb, bindex)); ++ ++ /* pseudo-link after flushed may happen out of bounds */ ++ if (!err ++ && inode ++ && au_ibstart(inode) <= bindex ++ && bindex <= au_ibend(inode)) { ++ /* ++ * permission check is unnecessary since vfsub routine ++ * will be called later ++ */ ++ struct inode *hi = au_h_iptr(inode, bindex); ++ if (hi) ++ err = IS_IMMUTABLE(hi) ? -EROFS : 0; ++ } ++ ++ return err; ++} ++ ++int au_test_h_perm(struct inode *h_inode, int mask) ++{ ++ if (!current_fsuid()) ++ return 0; ++ return inode_permission(h_inode, mask); ++} ++ ++int au_test_h_perm_sio(struct inode *h_inode, int mask) ++{ ++ if (au_test_nfs(h_inode->i_sb) ++ && (mask & MAY_WRITE) ++ && S_ISDIR(h_inode->i_mode)) ++ mask |= MAY_READ; /* force permission check */ ++ return au_test_h_perm(h_inode, mask); ++} +diff --git a/fs/aufs/inode.h b/fs/aufs/inode.h +new file mode 100644 +index 0000000..1c5559b +--- /dev/null ++++ b/fs/aufs/inode.h +@@ -0,0 +1,497 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * inode operations ++ */ ++ ++#ifndef __AUFS_INODE_H__ ++#define __AUFS_INODE_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++#include "rwsem.h" ++ ++struct vfsmount; ++ ++struct au_hinotify { ++#ifdef CONFIG_AUFS_HINOTIFY ++ struct inotify_watch hin_watch; ++ struct inode *hin_aufs_inode; /* no get/put */ ++#endif ++}; ++ ++struct au_hinode { ++ struct inode *hi_inode; ++ aufs_bindex_t hi_id; ++#ifdef CONFIG_AUFS_HINOTIFY ++ struct au_hinotify *hi_notify; ++#endif ++ ++ /* reference to the copied-up whiteout with get/put */ ++ struct dentry *hi_whdentry; ++}; ++ ++struct au_vdir; ++struct au_iinfo { ++ atomic_t ii_generation; ++ struct super_block *ii_hsb1; /* no get/put */ ++ ++ struct au_rwsem ii_rwsem; ++ aufs_bindex_t ii_bstart, ii_bend; ++ __u32 ii_higen; ++ struct au_hinode *ii_hinode; ++ struct au_vdir *ii_vdir; ++}; ++ ++struct au_icntnr { ++ struct au_iinfo iinfo; ++ struct inode vfs_inode; ++}; ++ ++/* au_pin flags */ ++#define AuPin_DI_LOCKED 1 ++#define AuPin_MNT_WRITE (1 << 1) ++#define au_ftest_pin(flags, name) ((flags) & AuPin_##name) ++#define au_fset_pin(flags, name) { (flags) |= AuPin_##name; } ++#define au_fclr_pin(flags, name) { (flags) &= ~AuPin_##name; } ++ ++struct au_pin { ++ /* input */ ++ struct dentry *dentry; ++ unsigned int udba; ++ unsigned char lsc_di, lsc_hi, flags; ++ aufs_bindex_t bindex; ++ ++ /* output */ ++ struct dentry *parent; ++ struct au_hinode *hdir; ++ struct vfsmount *h_mnt; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct au_iinfo *au_ii(struct inode *inode) ++{ ++ struct au_iinfo *iinfo; ++ ++ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo); ++ if (iinfo->ii_hinode) ++ return iinfo; ++ return NULL; /* debugging bad_inode case */ ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* inode.c */ ++struct inode *au_igrab(struct inode *inode); ++int au_refresh_hinode_self(struct inode *inode, int do_attr); ++int au_refresh_hinode(struct inode *inode, struct dentry *dentry); ++int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ unsigned int d_type, ino_t *ino); ++struct inode *au_new_inode(struct dentry *dentry, int must_new); ++int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, ++ struct inode *inode); ++int au_test_h_perm(struct inode *h_inode, int mask); ++int au_test_h_perm_sio(struct inode *h_inode, int mask); ++ ++static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex, ++ ino_t h_ino, unsigned int d_type, ino_t *ino) ++{ ++#ifdef CONFIG_AUFS_SHWH ++ return au_ino(sb, bindex, h_ino, d_type, ino); ++#else ++ return 0; ++#endif ++} ++ ++/* i_op.c */ ++extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop; ++ ++/* au_wr_dir flags */ ++#define AuWrDir_ADD_ENTRY 1 ++#define AuWrDir_ISDIR (1 << 1) ++#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name) ++#define au_fset_wrdir(flags, name) { (flags) |= AuWrDir_##name; } ++#define au_fclr_wrdir(flags, name) { (flags) &= ~AuWrDir_##name; } ++ ++struct au_wr_dir_args { ++ aufs_bindex_t force_btgt; ++ unsigned char flags; ++}; ++int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, ++ struct au_wr_dir_args *args); ++ ++struct dentry *au_pinned_h_parent(struct au_pin *pin); ++void au_pin_init(struct au_pin *pin, struct dentry *dentry, ++ aufs_bindex_t bindex, int lsc_di, int lsc_hi, ++ unsigned int udba, unsigned char flags); ++int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int udba, unsigned char flags) __must_check; ++int au_do_pin(struct au_pin *pin) __must_check; ++void au_unpin(struct au_pin *pin); ++ ++/* i_op_add.c */ ++int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent, int isdir); ++int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev); ++int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname); ++int aufs_create(struct inode *dir, struct dentry *dentry, int mode, ++ struct nameidata *nd); ++int aufs_link(struct dentry *src_dentry, struct inode *dir, ++ struct dentry *dentry); ++int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode); ++ ++/* i_op_del.c */ ++int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup); ++int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent, int isdir); ++int aufs_unlink(struct inode *dir, struct dentry *dentry); ++int aufs_rmdir(struct inode *dir, struct dentry *dentry); ++ ++/* i_op_ren.c */ ++int au_wbr(struct dentry *dentry, aufs_bindex_t btgt); ++int aufs_rename(struct inode *src_dir, struct dentry *src_dentry, ++ struct inode *dir, struct dentry *dentry); ++ ++/* iinfo.c */ ++struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex); ++void au_hiput(struct au_hinode *hinode); ++void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex); ++void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_wh); ++unsigned int au_hi_flags(struct inode *inode, int isdir); ++ ++/* hinode flags */ ++#define AuHi_XINO 1 ++#define AuHi_HINOTIFY (1 << 1) ++#define au_ftest_hi(flags, name) ((flags) & AuHi_##name) ++#define au_fset_hi(flags, name) { (flags) |= AuHi_##name; } ++#define au_fclr_hi(flags, name) { (flags) &= ~AuHi_##name; } ++ ++#ifndef CONFIG_AUFS_HINOTIFY ++#undef AuHi_HINOTIFY ++#define AuHi_HINOTIFY 0 ++#endif ++ ++void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, ++ struct inode *h_inode, unsigned int flags); ++ ++void au_update_iigen(struct inode *inode); ++void au_update_brange(struct inode *inode, int do_put_zero); ++ ++int au_iinfo_init(struct inode *inode); ++void au_iinfo_fin(struct inode *inode); ++int au_ii_realloc(struct au_iinfo *iinfo, int nbr); ++ ++/* plink.c */ ++void au_plink_block_maintain(struct super_block *sb); ++#ifdef CONFIG_AUFS_DEBUG ++void au_plink_list(struct super_block *sb); ++#else ++static inline void au_plink_list(struct super_block *sb) ++{ ++ /* nothing */ ++} ++#endif ++int au_plink_test(struct inode *inode); ++struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex); ++void au_plink_append(struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_dentry); ++void au_plink_put(struct super_block *sb); ++void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id); ++long au_plink_ioctl(struct file *file, unsigned int cmd); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* lock subclass for iinfo */ ++enum { ++ AuLsc_II_CHILD, /* child first */ ++ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hinotify */ ++ AuLsc_II_CHILD3, /* copyup dirs */ ++ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */ ++ AuLsc_II_PARENT2, ++ AuLsc_II_PARENT3, /* copyup dirs */ ++ AuLsc_II_NEW_CHILD ++}; ++ ++/* ++ * ii_read_lock_child, ii_write_lock_child, ++ * ii_read_lock_child2, ii_write_lock_child2, ++ * ii_read_lock_child3, ii_write_lock_child3, ++ * ii_read_lock_parent, ii_write_lock_parent, ++ * ii_read_lock_parent2, ii_write_lock_parent2, ++ * ii_read_lock_parent3, ii_write_lock_parent3, ++ * ii_read_lock_new_child, ii_write_lock_new_child, ++ */ ++#define AuReadLockFunc(name, lsc) \ ++static inline void ii_read_lock_##name(struct inode *i) \ ++{ \ ++ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \ ++} ++ ++#define AuWriteLockFunc(name, lsc) \ ++static inline void ii_write_lock_##name(struct inode *i) \ ++{ \ ++ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \ ++} ++ ++#define AuRWLockFuncs(name, lsc) \ ++ AuReadLockFunc(name, lsc) \ ++ AuWriteLockFunc(name, lsc) ++ ++AuRWLockFuncs(child, CHILD); ++AuRWLockFuncs(child2, CHILD2); ++AuRWLockFuncs(child3, CHILD3); ++AuRWLockFuncs(parent, PARENT); ++AuRWLockFuncs(parent2, PARENT2); ++AuRWLockFuncs(parent3, PARENT3); ++AuRWLockFuncs(new_child, NEW_CHILD); ++ ++#undef AuReadLockFunc ++#undef AuWriteLockFunc ++#undef AuRWLockFuncs ++ ++/* ++ * ii_read_unlock, ii_write_unlock, ii_downgrade_lock ++ */ ++AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem); ++ ++#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem) ++#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem) ++#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem) ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline unsigned int au_iigen(struct inode *inode) ++{ ++ return atomic_read(&au_ii(inode)->ii_generation); ++} ++ ++/* tiny test for inode number */ ++/* tmpfs generation is too rough */ ++static inline int au_test_higen(struct inode *inode, struct inode *h_inode) ++{ ++ struct au_iinfo *iinfo; ++ ++ iinfo = au_ii(inode); ++ AuRwMustAnyLock(&iinfo->ii_rwsem); ++ return !(iinfo->ii_hsb1 == h_inode->i_sb ++ && iinfo->ii_higen == h_inode->i_generation); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline aufs_bindex_t au_ii_br_id(struct inode *inode, ++ aufs_bindex_t bindex) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_hinode[0 + bindex].hi_id; ++} ++ ++static inline aufs_bindex_t au_ibstart(struct inode *inode) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_bstart; ++} ++ ++static inline aufs_bindex_t au_ibend(struct inode *inode) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_bend; ++} ++ ++static inline struct au_vdir *au_ivdir(struct inode *inode) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_vdir; ++} ++ ++static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry; ++} ++ ++static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex) ++{ ++ IiMustWriteLock(inode); ++ au_ii(inode)->ii_bend = bindex; ++} ++ ++static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir) ++{ ++ IiMustWriteLock(inode); ++ au_ii(inode)->ii_vdir = vdir; ++} ++ ++static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_hinode + bindex; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct dentry *au_pinned_parent(struct au_pin *pin) ++{ ++ if (pin) ++ return pin->parent; ++ return NULL; ++} ++ ++static inline struct inode *au_pinned_h_dir(struct au_pin *pin) ++{ ++ if (pin && pin->hdir) ++ return pin->hdir->hi_inode; ++ return NULL; ++} ++ ++static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin) ++{ ++ if (pin) ++ return pin->hdir; ++ return NULL; ++} ++ ++static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry) ++{ ++ if (pin) ++ pin->dentry = dentry; ++} ++ ++static inline void au_pin_set_parent_lflag(struct au_pin *pin, ++ unsigned char lflag) ++{ ++ if (pin) { ++ /* dirty macros require brackets */ ++ if (lflag) { ++ au_fset_pin(pin->flags, DI_LOCKED); ++ } else { ++ au_fclr_pin(pin->flags, DI_LOCKED); ++ } ++ } ++} ++ ++static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent) ++{ ++ if (pin) { ++ dput(pin->parent); ++ pin->parent = dget(parent); ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_HINOTIFY ++/* hinotify.c */ ++int au_hin_alloc(struct au_hinode *hinode, struct inode *inode, ++ struct inode *h_inode); ++void au_hin_free(struct au_hinode *hinode); ++void au_hin_ctl(struct au_hinode *hinode, int do_set); ++void au_reset_hinotify(struct inode *inode, unsigned int flags); ++ ++int __init au_hinotify_init(void); ++void au_hinotify_fin(void); ++ ++static inline ++void au_hin_init(struct au_hinode *hinode, struct au_hinotify *val) ++{ ++ hinode->hi_notify = val; ++} ++ ++static inline void au_iigen_dec(struct inode *inode) ++{ ++ atomic_dec_return(&au_ii(inode)->ii_generation); ++} ++ ++#else ++static inline ++int au_hin_alloc(struct au_hinode *hinode __maybe_unused, ++ struct inode *inode __maybe_unused, ++ struct inode *h_inode __maybe_unused) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static inline void au_hin_free(struct au_hinode *hinode __maybe_unused) ++{ ++ /* nothing */ ++} ++ ++static inline void au_hin_ctl(struct au_hinode *hinode __maybe_unused, ++ int do_set __maybe_unused) ++{ ++ /* nothing */ ++} ++ ++static inline void au_reset_hinotify(struct inode *inode __maybe_unused, ++ unsigned int flags __maybe_unused) ++{ ++ /* nothing */ ++} ++ ++static inline int au_hinotify_init(void) ++{ ++ return 0; ++} ++ ++#define au_hinotify_fin() do {} while (0) ++ ++static inline ++void au_hin_init(struct au_hinode *hinode __maybe_unused, ++ struct au_hinotify *val __maybe_unused) ++{ ++ /* empty */ ++} ++#endif /* CONFIG_AUFS_HINOTIFY */ ++ ++static inline void au_hin_suspend(struct au_hinode *hdir) ++{ ++ au_hin_ctl(hdir, /*do_set*/0); ++} ++ ++static inline void au_hin_resume(struct au_hinode *hdir) ++{ ++ au_hin_ctl(hdir, /*do_set*/1); ++} ++ ++static inline void au_hin_imtx_lock(struct au_hinode *hdir) ++{ ++ mutex_lock(&hdir->hi_inode->i_mutex); ++ au_hin_suspend(hdir); ++} ++ ++static inline void au_hin_imtx_lock_nested(struct au_hinode *hdir, ++ unsigned int sc __maybe_unused) ++{ ++ mutex_lock_nested(&hdir->hi_inode->i_mutex, sc); ++ au_hin_suspend(hdir); ++} ++ ++static inline void au_hin_imtx_unlock(struct au_hinode *hdir) ++{ ++ au_hin_resume(hdir); ++ mutex_unlock(&hdir->hi_inode->i_mutex); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_INODE_H__ */ +diff --git a/fs/aufs/ioctl.c b/fs/aufs/ioctl.c +new file mode 100644 +index 0000000..012361a +--- /dev/null ++++ b/fs/aufs/ioctl.c +@@ -0,0 +1,47 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * ioctl ++ * plink-management and readdir in userspace. ++ */ ++ ++#include "aufs.h" ++ ++long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ long err; ++ ++ switch (cmd) { ++ case AUFS_CTL_PLINK_MAINT: ++ case AUFS_CTL_PLINK_CLEAN: ++ err = au_plink_ioctl(file, cmd); ++ break; ++ ++ case AUFS_CTL_RDU: ++ case AUFS_CTL_RDU_INO: ++ err = au_rdu_ioctl(file, cmd, arg); ++ break; ++ ++ default: ++ err = -EINVAL; ++ } ++ ++ AuTraceErr(err); ++ return err; ++} +diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c +new file mode 100644 +index 0000000..277011f +--- /dev/null ++++ b/fs/aufs/loop.c +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * support for loopback block device as a branch ++ */ ++ ++#include ++#include "aufs.h" ++ ++/* ++ * test if two lower dentries have overlapping branches. ++ */ ++int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_d1, ++ struct dentry *h_d2) ++{ ++ struct inode *h_inode; ++ struct loop_device *l; ++ ++ h_inode = h_d1->d_inode; ++ if (MAJOR(h_inode->i_sb->s_dev) != LOOP_MAJOR) ++ return 0; ++ ++ l = h_inode->i_sb->s_bdev->bd_disk->private_data; ++ h_d1 = l->lo_backing_file->f_dentry; ++ /* h_d1 can be local NFS. in this case aufs cannot detect the loop */ ++ if (unlikely(h_d1->d_sb == sb)) ++ return 1; ++ return !!au_test_subdir(h_d1, h_d2); ++} ++ ++/* true if a kernel thread named 'loop[0-9].*' accesses a file */ ++int au_test_loopback_kthread(void) ++{ ++ const char c = current->comm[4]; ++ ++ return current->mm == NULL ++ && '0' <= c && c <= '9' ++ && strncmp(current->comm, "loop", 4) == 0; ++} +diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h +new file mode 100644 +index 0000000..5a0fd87 +--- /dev/null ++++ b/fs/aufs/loop.h +@@ -0,0 +1,51 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * support for loopback mount as a branch ++ */ ++ ++#ifndef __AUFS_LOOP_H__ ++#define __AUFS_LOOP_H__ ++ ++#ifdef __KERNEL__ ++ ++struct dentry; ++struct super_block; ++ ++#ifdef CONFIG_AUFS_BDEV_LOOP ++/* loop.c */ ++int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_d1, ++ struct dentry *h_d2); ++int au_test_loopback_kthread(void); ++#else ++static inline ++int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_d1, ++ struct dentry *h_d2) ++{ ++ return 0; ++} ++ ++static inline int au_test_loopback_kthread(void) ++{ ++ return 0; ++} ++#endif /* BLK_DEV_LOOP */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_LOOP_H__ */ +diff --git a/fs/aufs/magic.mk b/fs/aufs/magic.mk +new file mode 100644 +index 0000000..83d613c +--- /dev/null ++++ b/fs/aufs/magic.mk +@@ -0,0 +1,52 @@ ++ ++# defined in ${srctree}/fs/fuse/inode.c ++# tristate ++ifdef CONFIG_FUSE_FS ++ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546 ++endif ++ ++# defined in ${srctree}/fs/ocfs2/ocfs2_fs.h ++# tristate ++ifdef CONFIG_OCFS2_FS ++ccflags-y += -DOCFS2_SUPER_MAGIC=0x7461636f ++endif ++ ++# defined in ${srctree}/fs/ocfs2/dlm/userdlm.h ++# tristate ++ifdef CONFIG_OCFS2_FS_O2CB ++ccflags-y += -DDLMFS_MAGIC=0x76a9f425 ++endif ++ ++# defined in ${srctree}/fs/ramfs/inode.c ++# always true ++ccflags-y += -DRAMFS_MAGIC=0x858458f6 ++ ++# defined in ${srctree}/fs/cifs/cifsfs.c ++# tristate ++ifdef CONFIG_CIFS_FS ++ccflags-y += -DCIFS_MAGIC_NUMBER=0xFF534D42 ++endif ++ ++# defined in ${srctree}/fs/xfs/xfs_sb.h ++# tristate ++ifdef CONFIG_XFS_FS ++ccflags-y += -DXFS_SB_MAGIC=0x58465342 ++endif ++ ++# defined in ${srctree}/fs/configfs/mount.c ++# tristate ++ifdef CONFIG_CONFIGFS_FS ++ccflags-y += -DCONFIGFS_MAGIC=0x62656570 ++endif ++ ++# defined in ${srctree}/fs/9p/v9fs.h ++# tristate ++ifdef CONFIG_9P_FS ++ccflags-y += -DV9FS_MAGIC=0x01021997 ++endif ++ ++# defined in ${srctree}/fs/ubifs/ubifs.h ++# tristate ++ifdef CONFIG_UBIFS_FS ++ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905 ++endif +diff --git a/fs/aufs/module.c b/fs/aufs/module.c +new file mode 100644 +index 0000000..dbfb2c4 +--- /dev/null ++++ b/fs/aufs/module.c +@@ -0,0 +1,173 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * module global variables and operations ++ */ ++ ++#include ++#include ++#include "aufs.h" ++ ++void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp) ++{ ++ if (new_sz <= nused) ++ return p; ++ ++ p = krealloc(p, new_sz, gfp); ++ if (p) ++ memset(p + nused, 0, new_sz - nused); ++ return p; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * aufs caches ++ */ ++struct kmem_cache *au_cachep[AuCache_Last]; ++static int __init au_cache_init(void) ++{ ++ au_cachep[AuCache_DINFO] = AuCache(au_dinfo); ++ if (au_cachep[AuCache_DINFO]) ++ au_cachep[AuCache_ICNTNR] = AuCache(au_icntnr); ++ if (au_cachep[AuCache_ICNTNR]) ++ au_cachep[AuCache_FINFO] = AuCache(au_finfo); ++ if (au_cachep[AuCache_FINFO]) ++ au_cachep[AuCache_VDIR] = AuCache(au_vdir); ++ if (au_cachep[AuCache_VDIR]) ++ au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr); ++ if (au_cachep[AuCache_DEHSTR]) ++ return 0; ++ ++ return -ENOMEM; ++} ++ ++static void au_cache_fin(void) ++{ ++ int i; ++ for (i = 0; i < AuCache_Last; i++) ++ if (au_cachep[i]) { ++ kmem_cache_destroy(au_cachep[i]); ++ au_cachep[i] = NULL; ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_dir_roflags; ++ ++/* ++ * functions for module interface. ++ */ ++MODULE_LICENSE("GPL"); ++/* MODULE_LICENSE("GPL v2"); */ ++MODULE_AUTHOR("Junjiro R. Okajima "); ++MODULE_DESCRIPTION(AUFS_NAME ++ " -- Advanced multi layered unification filesystem"); ++MODULE_VERSION(AUFS_VERSION); ++ ++/* it should be 'byte', but param_set_byte() prints it by "%c" */ ++short aufs_nwkq = AUFS_NWKQ_DEF; ++MODULE_PARM_DESC(nwkq, "the number of workqueue thread, " AUFS_WKQ_NAME); ++module_param_named(nwkq, aufs_nwkq, short, S_IRUGO); ++ ++/* this module parameter has no meaning when SYSFS is disabled */ ++int sysaufs_brs = 1; ++MODULE_PARM_DESC(brs, "use /fs/aufs/si_*/brN"); ++module_param_named(brs, sysaufs_brs, int, S_IRUGO); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */ ++ ++int au_seq_path(struct seq_file *seq, struct path *path) ++{ ++ return seq_path(seq, path, au_esc_chars); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int __init aufs_init(void) ++{ ++ int err, i; ++ char *p; ++ ++ p = au_esc_chars; ++ for (i = 1; i <= ' '; i++) ++ *p++ = i; ++ *p++ = '\\'; ++ *p++ = '\x7f'; ++ *p = 0; ++ ++ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE); ++ ++ sysaufs_brs_init(); ++ au_debug_init(); ++ ++ err = -EINVAL; ++ if (unlikely(aufs_nwkq <= 0)) ++ goto out; ++ ++ err = sysaufs_init(); ++ if (unlikely(err)) ++ goto out; ++ err = au_wkq_init(); ++ if (unlikely(err)) ++ goto out_sysaufs; ++ err = au_hinotify_init(); ++ if (unlikely(err)) ++ goto out_wkq; ++ err = au_sysrq_init(); ++ if (unlikely(err)) ++ goto out_hin; ++ err = au_cache_init(); ++ if (unlikely(err)) ++ goto out_sysrq; ++ err = register_filesystem(&aufs_fs_type); ++ if (unlikely(err)) ++ goto out_cache; ++ pr_info(AUFS_NAME " " AUFS_VERSION "\n"); ++ goto out; /* success */ ++ ++ out_cache: ++ au_cache_fin(); ++ out_sysrq: ++ au_sysrq_fin(); ++ out_hin: ++ au_hinotify_fin(); ++ out_wkq: ++ au_wkq_fin(); ++ out_sysaufs: ++ sysaufs_fin(); ++ out: ++ return err; ++} ++ ++static void __exit aufs_exit(void) ++{ ++ unregister_filesystem(&aufs_fs_type); ++ au_cache_fin(); ++ au_sysrq_fin(); ++ au_hinotify_fin(); ++ au_wkq_fin(); ++ sysaufs_fin(); ++} ++ ++module_init(aufs_init); ++module_exit(aufs_exit); +diff --git a/fs/aufs/module.h b/fs/aufs/module.h +new file mode 100644 +index 0000000..cea7bc7 +--- /dev/null ++++ b/fs/aufs/module.h +@@ -0,0 +1,78 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * module initialization and module-global ++ */ ++ ++#ifndef __AUFS_MODULE_H__ ++#define __AUFS_MODULE_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++ ++struct path; ++struct seq_file; ++ ++/* module parameters */ ++extern short aufs_nwkq; ++extern int sysaufs_brs; ++ ++/* ---------------------------------------------------------------------- */ ++ ++extern int au_dir_roflags; ++ ++void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp); ++int au_seq_path(struct seq_file *seq, struct path *path); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* kmem cache */ ++enum { ++ AuCache_DINFO, ++ AuCache_ICNTNR, ++ AuCache_FINFO, ++ AuCache_VDIR, ++ AuCache_DEHSTR, ++#ifdef CONFIG_AUFS_HINOTIFY ++ AuCache_HINOTIFY, ++#endif ++ AuCache_Last ++}; ++ ++#define AuCache(type) KMEM_CACHE(type, SLAB_RECLAIM_ACCOUNT) ++ ++extern struct kmem_cache *au_cachep[]; ++ ++#define AuCacheFuncs(name, index) \ ++static inline void *au_cache_alloc_##name(void) \ ++{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \ ++static inline void au_cache_free_##name(void *p) \ ++{ kmem_cache_free(au_cachep[AuCache_##index], p); } ++ ++AuCacheFuncs(dinfo, DINFO); ++AuCacheFuncs(icntnr, ICNTNR); ++AuCacheFuncs(finfo, FINFO); ++AuCacheFuncs(vdir, VDIR); ++AuCacheFuncs(dehstr, DEHSTR); ++ ++/* ---------------------------------------------------------------------- */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_MODULE_H__ */ +diff --git a/fs/aufs/opts.c b/fs/aufs/opts.c +new file mode 100644 +index 0000000..70f8be9 +--- /dev/null ++++ b/fs/aufs/opts.c +@@ -0,0 +1,1543 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * mount options/flags ++ */ ++ ++#include ++#include ++#include /* a distribution requires */ ++#include ++#include "aufs.h" ++ ++/* ---------------------------------------------------------------------- */ ++ ++enum { ++ Opt_br, ++ Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend, ++ Opt_idel, Opt_imod, Opt_ireorder, ++ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir, ++ Opt_rdblk_def, Opt_rdhash_def, ++ Opt_xino, Opt_zxino, Opt_noxino, ++ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino, ++ Opt_trunc_xino_path, Opt_itrunc_xino, ++ Opt_trunc_xib, Opt_notrunc_xib, ++ Opt_shwh, Opt_noshwh, ++ Opt_plink, Opt_noplink, Opt_list_plink, ++ Opt_udba, ++ /* Opt_lock, Opt_unlock, */ ++ Opt_cmd, Opt_cmd_args, ++ Opt_diropq_a, Opt_diropq_w, ++ Opt_warn_perm, Opt_nowarn_perm, ++ Opt_wbr_copyup, Opt_wbr_create, ++ Opt_refrof, Opt_norefrof, ++ Opt_verbose, Opt_noverbose, ++ Opt_sum, Opt_nosum, Opt_wsum, ++ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err ++}; ++ ++static match_table_t options = { ++ {Opt_br, "br=%s"}, ++ {Opt_br, "br:%s"}, ++ ++ {Opt_add, "add=%d:%s"}, ++ {Opt_add, "add:%d:%s"}, ++ {Opt_add, "ins=%d:%s"}, ++ {Opt_add, "ins:%d:%s"}, ++ {Opt_append, "append=%s"}, ++ {Opt_append, "append:%s"}, ++ {Opt_prepend, "prepend=%s"}, ++ {Opt_prepend, "prepend:%s"}, ++ ++ {Opt_del, "del=%s"}, ++ {Opt_del, "del:%s"}, ++ /* {Opt_idel, "idel:%d"}, */ ++ {Opt_mod, "mod=%s"}, ++ {Opt_mod, "mod:%s"}, ++ /* {Opt_imod, "imod:%d:%s"}, */ ++ ++ {Opt_dirwh, "dirwh=%d"}, ++ ++ {Opt_xino, "xino=%s"}, ++ {Opt_noxino, "noxino"}, ++ {Opt_trunc_xino, "trunc_xino"}, ++ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"}, ++ {Opt_notrunc_xino, "notrunc_xino"}, ++ {Opt_trunc_xino_path, "trunc_xino=%s"}, ++ {Opt_itrunc_xino, "itrunc_xino=%d"}, ++ /* {Opt_zxino, "zxino=%s"}, */ ++ {Opt_trunc_xib, "trunc_xib"}, ++ {Opt_notrunc_xib, "notrunc_xib"}, ++ ++ {Opt_plink, "plink"}, ++ {Opt_noplink, "noplink"}, ++#ifdef CONFIG_AUFS_DEBUG ++ {Opt_list_plink, "list_plink"}, ++#endif ++ ++ {Opt_udba, "udba=%s"}, ++ ++ {Opt_diropq_a, "diropq=always"}, ++ {Opt_diropq_a, "diropq=a"}, ++ {Opt_diropq_w, "diropq=whiteouted"}, ++ {Opt_diropq_w, "diropq=w"}, ++ ++ {Opt_warn_perm, "warn_perm"}, ++ {Opt_nowarn_perm, "nowarn_perm"}, ++ ++ /* keep them temporary */ ++ {Opt_ignore_silent, "coo=%s"}, ++ {Opt_ignore_silent, "nodlgt"}, ++ {Opt_ignore_silent, "nodirperm1"}, ++ {Opt_ignore_silent, "clean_plink"}, ++ ++#ifdef CONFIG_AUFS_SHWH ++ {Opt_shwh, "shwh"}, ++#endif ++ {Opt_noshwh, "noshwh"}, ++ ++ {Opt_rendir, "rendir=%d"}, ++ ++ {Opt_refrof, "refrof"}, ++ {Opt_norefrof, "norefrof"}, ++ ++ {Opt_verbose, "verbose"}, ++ {Opt_verbose, "v"}, ++ {Opt_noverbose, "noverbose"}, ++ {Opt_noverbose, "quiet"}, ++ {Opt_noverbose, "q"}, ++ {Opt_noverbose, "silent"}, ++ ++ {Opt_sum, "sum"}, ++ {Opt_nosum, "nosum"}, ++ {Opt_wsum, "wsum"}, ++ ++ {Opt_rdcache, "rdcache=%d"}, ++ {Opt_rdblk, "rdblk=%d"}, ++ {Opt_rdblk_def, "rdblk=def"}, ++ {Opt_rdhash, "rdhash=%d"}, ++ {Opt_rdhash_def, "rdhash=def"}, ++ ++ {Opt_wbr_create, "create=%s"}, ++ {Opt_wbr_create, "create_policy=%s"}, ++ {Opt_wbr_copyup, "cpup=%s"}, ++ {Opt_wbr_copyup, "copyup=%s"}, ++ {Opt_wbr_copyup, "copyup_policy=%s"}, ++ ++ /* internal use for the scripts */ ++ {Opt_ignore_silent, "si=%s"}, ++ ++ {Opt_br, "dirs=%s"}, ++ {Opt_ignore, "debug=%d"}, ++ {Opt_ignore, "delete=whiteout"}, ++ {Opt_ignore, "delete=all"}, ++ {Opt_ignore, "imap=%s"}, ++ ++ {Opt_err, NULL} ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static const char *au_parser_pattern(int val, struct match_token *token) ++{ ++ while (token->pattern) { ++ if (token->token == val) ++ return token->pattern; ++ token++; ++ } ++ BUG(); ++ return "??"; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static match_table_t brperms = { ++ {AuBrPerm_RO, AUFS_BRPERM_RO}, ++ {AuBrPerm_RR, AUFS_BRPERM_RR}, ++ {AuBrPerm_RW, AUFS_BRPERM_RW}, ++ ++ {AuBrPerm_ROWH, AUFS_BRPERM_ROWH}, ++ {AuBrPerm_RRWH, AUFS_BRPERM_RRWH}, ++ {AuBrPerm_RWNoLinkWH, AUFS_BRPERM_RWNLWH}, ++ ++ {AuBrPerm_ROWH, "nfsro"}, ++ {AuBrPerm_RO, NULL} ++}; ++ ++static int br_perm_val(char *perm) ++{ ++ int val; ++ substring_t args[MAX_OPT_ARGS]; ++ ++ val = match_token(perm, brperms, args); ++ return val; ++} ++ ++const char *au_optstr_br_perm(int brperm) ++{ ++ return au_parser_pattern(brperm, (void *)brperms); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static match_table_t udbalevel = { ++ {AuOpt_UDBA_REVAL, "reval"}, ++ {AuOpt_UDBA_NONE, "none"}, ++#ifdef CONFIG_AUFS_HINOTIFY ++ {AuOpt_UDBA_HINOTIFY, "inotify"}, ++#endif ++ {-1, NULL} ++}; ++ ++static int udba_val(char *str) ++{ ++ substring_t args[MAX_OPT_ARGS]; ++ ++ return match_token(str, udbalevel, args); ++} ++ ++const char *au_optstr_udba(int udba) ++{ ++ return au_parser_pattern(udba, (void *)udbalevel); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static match_table_t au_wbr_create_policy = { ++ {AuWbrCreate_TDP, "tdp"}, ++ {AuWbrCreate_TDP, "top-down-parent"}, ++ {AuWbrCreate_RR, "rr"}, ++ {AuWbrCreate_RR, "round-robin"}, ++ {AuWbrCreate_MFS, "mfs"}, ++ {AuWbrCreate_MFS, "most-free-space"}, ++ {AuWbrCreate_MFSV, "mfs:%d"}, ++ {AuWbrCreate_MFSV, "most-free-space:%d"}, ++ ++ {AuWbrCreate_MFSRR, "mfsrr:%d"}, ++ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"}, ++ {AuWbrCreate_PMFS, "pmfs"}, ++ {AuWbrCreate_PMFSV, "pmfs:%d"}, ++ ++ {-1, NULL} ++}; ++ ++/* ++ * cf. linux/lib/parser.c and cmdline.c ++ * gave up calling memparse() since it uses simple_strtoull() instead of ++ * strict_...(). ++ */ ++static int au_match_ull(substring_t *s, unsigned long long *result) ++{ ++ int err; ++ unsigned int len; ++ char a[32]; ++ ++ err = -ERANGE; ++ len = s->to - s->from; ++ if (len + 1 <= sizeof(a)) { ++ memcpy(a, s->from, len); ++ a[len] = '\0'; ++ err = strict_strtoull(a, 0, result); ++ } ++ return err; ++} ++ ++static int au_wbr_mfs_wmark(substring_t *arg, char *str, ++ struct au_opt_wbr_create *create) ++{ ++ int err; ++ unsigned long long ull; ++ ++ err = 0; ++ if (!au_match_ull(arg, &ull)) ++ create->mfsrr_watermark = ull; ++ else { ++ AuErr("bad integer in %s\n", str); ++ err = -EINVAL; ++ } ++ ++ return err; ++} ++ ++static int au_wbr_mfs_sec(substring_t *arg, char *str, ++ struct au_opt_wbr_create *create) ++{ ++ int n, err; ++ ++ err = 0; ++ if (!match_int(arg, &n) && 0 <= n) ++ create->mfs_second = n; ++ else { ++ AuErr("bad integer in %s\n", str); ++ err = -EINVAL; ++ } ++ ++ return err; ++} ++ ++static int au_wbr_create_val(char *str, struct au_opt_wbr_create *create) ++{ ++ int err, e; ++ substring_t args[MAX_OPT_ARGS]; ++ ++ err = match_token(str, au_wbr_create_policy, args); ++ create->wbr_create = err; ++ switch (err) { ++ case AuWbrCreate_MFSRRV: ++ e = au_wbr_mfs_wmark(&args[0], str, create); ++ if (!e) ++ e = au_wbr_mfs_sec(&args[1], str, create); ++ if (unlikely(e)) ++ err = e; ++ break; ++ case AuWbrCreate_MFSRR: ++ e = au_wbr_mfs_wmark(&args[0], str, create); ++ if (unlikely(e)) { ++ err = e; ++ break; ++ } ++ /*FALLTHROUGH*/ ++ case AuWbrCreate_MFS: ++ case AuWbrCreate_PMFS: ++ create->mfs_second = AUFS_MFS_SECOND_DEF; ++ break; ++ case AuWbrCreate_MFSV: ++ case AuWbrCreate_PMFSV: ++ e = au_wbr_mfs_sec(&args[0], str, create); ++ if (unlikely(e)) ++ err = e; ++ break; ++ } ++ ++ return err; ++} ++ ++const char *au_optstr_wbr_create(int wbr_create) ++{ ++ return au_parser_pattern(wbr_create, (void *)au_wbr_create_policy); ++} ++ ++static match_table_t au_wbr_copyup_policy = { ++ {AuWbrCopyup_TDP, "tdp"}, ++ {AuWbrCopyup_TDP, "top-down-parent"}, ++ {AuWbrCopyup_BUP, "bup"}, ++ {AuWbrCopyup_BUP, "bottom-up-parent"}, ++ {AuWbrCopyup_BU, "bu"}, ++ {AuWbrCopyup_BU, "bottom-up"}, ++ {-1, NULL} ++}; ++ ++static int au_wbr_copyup_val(char *str) ++{ ++ substring_t args[MAX_OPT_ARGS]; ++ ++ return match_token(str, au_wbr_copyup_policy, args); ++} ++ ++const char *au_optstr_wbr_copyup(int wbr_copyup) ++{ ++ return au_parser_pattern(wbr_copyup, (void *)au_wbr_copyup_policy); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY; ++ ++static void dump_opts(struct au_opts *opts) ++{ ++#ifdef CONFIG_AUFS_DEBUG ++ /* reduce stack space */ ++ union { ++ struct au_opt_add *add; ++ struct au_opt_del *del; ++ struct au_opt_mod *mod; ++ struct au_opt_xino *xino; ++ struct au_opt_xino_itrunc *xino_itrunc; ++ struct au_opt_wbr_create *create; ++ } u; ++ struct au_opt *opt; ++ ++ opt = opts->opt; ++ while (opt->type != Opt_tail) { ++ switch (opt->type) { ++ case Opt_add: ++ u.add = &opt->add; ++ AuDbg("add {b%d, %s, 0x%x, %p}\n", ++ u.add->bindex, u.add->pathname, u.add->perm, ++ u.add->path.dentry); ++ break; ++ case Opt_del: ++ case Opt_idel: ++ u.del = &opt->del; ++ AuDbg("del {%s, %p}\n", ++ u.del->pathname, u.del->h_path.dentry); ++ break; ++ case Opt_mod: ++ case Opt_imod: ++ u.mod = &opt->mod; ++ AuDbg("mod {%s, 0x%x, %p}\n", ++ u.mod->path, u.mod->perm, u.mod->h_root); ++ break; ++ case Opt_append: ++ u.add = &opt->add; ++ AuDbg("append {b%d, %s, 0x%x, %p}\n", ++ u.add->bindex, u.add->pathname, u.add->perm, ++ u.add->path.dentry); ++ break; ++ case Opt_prepend: ++ u.add = &opt->add; ++ AuDbg("prepend {b%d, %s, 0x%x, %p}\n", ++ u.add->bindex, u.add->pathname, u.add->perm, ++ u.add->path.dentry); ++ break; ++ case Opt_dirwh: ++ AuDbg("dirwh %d\n", opt->dirwh); ++ break; ++ case Opt_rdcache: ++ AuDbg("rdcache %d\n", opt->rdcache); ++ break; ++ case Opt_rdblk: ++ AuDbg("rdblk %u\n", opt->rdblk); ++ break; ++ case Opt_rdblk_def: ++ AuDbg("rdblk_def\n"); ++ break; ++ case Opt_rdhash: ++ AuDbg("rdhash %u\n", opt->rdhash); ++ break; ++ case Opt_rdhash_def: ++ AuDbg("rdhash_def\n"); ++ break; ++ case Opt_xino: ++ u.xino = &opt->xino; ++ AuDbg("xino {%s %.*s}\n", ++ u.xino->path, ++ AuDLNPair(u.xino->file->f_dentry)); ++ break; ++ case Opt_trunc_xino: ++ AuLabel(trunc_xino); ++ break; ++ case Opt_notrunc_xino: ++ AuLabel(notrunc_xino); ++ break; ++ case Opt_trunc_xino_path: ++ case Opt_itrunc_xino: ++ u.xino_itrunc = &opt->xino_itrunc; ++ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex); ++ break; ++ ++ case Opt_noxino: ++ AuLabel(noxino); ++ break; ++ case Opt_trunc_xib: ++ AuLabel(trunc_xib); ++ break; ++ case Opt_notrunc_xib: ++ AuLabel(notrunc_xib); ++ break; ++ case Opt_shwh: ++ AuLabel(shwh); ++ break; ++ case Opt_noshwh: ++ AuLabel(noshwh); ++ break; ++ case Opt_plink: ++ AuLabel(plink); ++ break; ++ case Opt_noplink: ++ AuLabel(noplink); ++ break; ++ case Opt_list_plink: ++ AuLabel(list_plink); ++ break; ++ case Opt_udba: ++ AuDbg("udba %d, %s\n", ++ opt->udba, au_optstr_udba(opt->udba)); ++ break; ++ case Opt_diropq_a: ++ AuLabel(diropq_a); ++ break; ++ case Opt_diropq_w: ++ AuLabel(diropq_w); ++ break; ++ case Opt_warn_perm: ++ AuLabel(warn_perm); ++ break; ++ case Opt_nowarn_perm: ++ AuLabel(nowarn_perm); ++ break; ++ case Opt_refrof: ++ AuLabel(refrof); ++ break; ++ case Opt_norefrof: ++ AuLabel(norefrof); ++ break; ++ case Opt_verbose: ++ AuLabel(verbose); ++ break; ++ case Opt_noverbose: ++ AuLabel(noverbose); ++ break; ++ case Opt_sum: ++ AuLabel(sum); ++ break; ++ case Opt_nosum: ++ AuLabel(nosum); ++ break; ++ case Opt_wsum: ++ AuLabel(wsum); ++ break; ++ case Opt_wbr_create: ++ u.create = &opt->wbr_create; ++ AuDbg("create %d, %s\n", u.create->wbr_create, ++ au_optstr_wbr_create(u.create->wbr_create)); ++ switch (u.create->wbr_create) { ++ case AuWbrCreate_MFSV: ++ case AuWbrCreate_PMFSV: ++ AuDbg("%d sec\n", u.create->mfs_second); ++ break; ++ case AuWbrCreate_MFSRR: ++ AuDbg("%llu watermark\n", ++ u.create->mfsrr_watermark); ++ break; ++ case AuWbrCreate_MFSRRV: ++ AuDbg("%llu watermark, %d sec\n", ++ u.create->mfsrr_watermark, ++ u.create->mfs_second); ++ break; ++ } ++ break; ++ case Opt_wbr_copyup: ++ AuDbg("copyup %d, %s\n", opt->wbr_copyup, ++ au_optstr_wbr_copyup(opt->wbr_copyup)); ++ break; ++ default: ++ BUG(); ++ } ++ opt++; ++ } ++#endif ++} ++ ++void au_opts_free(struct au_opts *opts) ++{ ++ struct au_opt *opt; ++ ++ opt = opts->opt; ++ while (opt->type != Opt_tail) { ++ switch (opt->type) { ++ case Opt_add: ++ case Opt_append: ++ case Opt_prepend: ++ path_put(&opt->add.path); ++ break; ++ case Opt_del: ++ case Opt_idel: ++ path_put(&opt->del.h_path); ++ break; ++ case Opt_mod: ++ case Opt_imod: ++ dput(opt->mod.h_root); ++ break; ++ case Opt_xino: ++ fput(opt->xino.file); ++ break; ++ } ++ opt++; ++ } ++} ++ ++static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags, ++ aufs_bindex_t bindex) ++{ ++ int err; ++ struct au_opt_add *add = &opt->add; ++ char *p; ++ ++ add->bindex = bindex; ++ add->perm = AuBrPerm_Last; ++ add->pathname = opt_str; ++ p = strchr(opt_str, '='); ++ if (p) { ++ *p++ = 0; ++ if (*p) ++ add->perm = br_perm_val(p); ++ } ++ ++ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path); ++ if (!err) { ++ if (!p) { ++ add->perm = AuBrPerm_RO; ++ if (au_test_fs_rr(add->path.dentry->d_sb)) ++ add->perm = AuBrPerm_RR; ++ else if (!bindex && !(sb_flags & MS_RDONLY)) ++ add->perm = AuBrPerm_RW; ++ } ++ opt->type = Opt_add; ++ goto out; ++ } ++ AuErr("lookup failed %s (%d)\n", add->pathname, err); ++ err = -EINVAL; ++ ++ out: ++ return err; ++} ++ ++static int au_opts_parse_del(struct au_opt_del *del, substring_t args[]) ++{ ++ int err; ++ ++ del->pathname = args[0].from; ++ AuDbg("del path %s\n", del->pathname); ++ ++ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path); ++ if (unlikely(err)) ++ AuErr("lookup failed %s (%d)\n", del->pathname, err); ++ ++ return err; ++} ++ ++#if 0 /* reserved for future use */ ++static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex, ++ struct au_opt_del *del, substring_t args[]) ++{ ++ int err; ++ struct dentry *root; ++ ++ err = -EINVAL; ++ root = sb->s_root; ++ aufs_read_lock(root, AuLock_FLUSH); ++ if (bindex < 0 || au_sbend(sb) < bindex) { ++ AuErr("out of bounds, %d\n", bindex); ++ goto out; ++ } ++ ++ err = 0; ++ del->h_path.dentry = dget(au_h_dptr(root, bindex)); ++ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex)); ++ ++ out: ++ aufs_read_unlock(root, !AuLock_IR); ++ return err; ++} ++#endif ++ ++static int au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[]) ++{ ++ int err; ++ struct path path; ++ char *p; ++ ++ err = -EINVAL; ++ mod->path = args[0].from; ++ p = strchr(mod->path, '='); ++ if (unlikely(!p)) { ++ AuErr("no permssion %s\n", args[0].from); ++ goto out; ++ } ++ ++ *p++ = 0; ++ err = vfsub_kern_path(mod->path, lkup_dirflags, &path); ++ if (unlikely(err)) { ++ AuErr("lookup failed %s (%d)\n", mod->path, err); ++ goto out; ++ } ++ ++ mod->perm = br_perm_val(p); ++ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p); ++ mod->h_root = dget(path.dentry); ++ path_put(&path); ++ ++ out: ++ return err; ++} ++ ++#if 0 /* reserved for future use */ ++static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex, ++ struct au_opt_mod *mod, substring_t args[]) ++{ ++ int err; ++ struct dentry *root; ++ ++ err = -EINVAL; ++ root = sb->s_root; ++ aufs_read_lock(root, AuLock_FLUSH); ++ if (bindex < 0 || au_sbend(sb) < bindex) { ++ AuErr("out of bounds, %d\n", bindex); ++ goto out; ++ } ++ ++ err = 0; ++ mod->perm = br_perm_val(args[1].from); ++ AuDbg("mod path %s, perm 0x%x, %s\n", ++ mod->path, mod->perm, args[1].from); ++ mod->h_root = dget(au_h_dptr(root, bindex)); ++ ++ out: ++ aufs_read_unlock(root, !AuLock_IR); ++ return err; ++} ++#endif ++ ++static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino, ++ substring_t args[]) ++{ ++ int err; ++ struct file *file; ++ ++ file = au_xino_create(sb, args[0].from, /*silent*/0); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ ++ err = -EINVAL; ++ if (unlikely(file->f_dentry->d_sb == sb)) { ++ fput(file); ++ AuErr("%s must be outside\n", args[0].from); ++ goto out; ++ } ++ ++ err = 0; ++ xino->file = file; ++ xino->path = args[0].from; ++ ++ out: ++ return err; ++} ++ ++static ++int au_opts_parse_xino_itrunc_path(struct super_block *sb, ++ struct au_opt_xino_itrunc *xino_itrunc, ++ substring_t args[]) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct path path; ++ struct dentry *root; ++ ++ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path); ++ if (unlikely(err)) { ++ AuErr("lookup failed %s (%d)\n", args[0].from, err); ++ goto out; ++ } ++ ++ xino_itrunc->bindex = -1; ++ root = sb->s_root; ++ aufs_read_lock(root, AuLock_FLUSH); ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ if (au_h_dptr(root, bindex) == path.dentry) { ++ xino_itrunc->bindex = bindex; ++ break; ++ } ++ } ++ aufs_read_unlock(root, !AuLock_IR); ++ path_put(&path); ++ ++ if (unlikely(xino_itrunc->bindex < 0)) { ++ AuErr("no such branch %s\n", args[0].from); ++ err = -EINVAL; ++ } ++ ++ out: ++ return err; ++} ++ ++/* called without aufs lock */ ++int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts) ++{ ++ int err, n, token; ++ aufs_bindex_t bindex; ++ unsigned char skipped; ++ struct dentry *root; ++ struct au_opt *opt, *opt_tail; ++ char *opt_str; ++ /* reduce the stack space */ ++ union { ++ struct au_opt_xino_itrunc *xino_itrunc; ++ struct au_opt_wbr_create *create; ++ } u; ++ struct { ++ substring_t args[MAX_OPT_ARGS]; ++ } *a; ++ ++ err = -ENOMEM; ++ a = kmalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ root = sb->s_root; ++ err = 0; ++ bindex = 0; ++ opt = opts->opt; ++ opt_tail = opt + opts->max_opt - 1; ++ opt->type = Opt_tail; ++ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) { ++ err = -EINVAL; ++ skipped = 0; ++ token = match_token(opt_str, options, a->args); ++ switch (token) { ++ case Opt_br: ++ err = 0; ++ while (!err && (opt_str = strsep(&a->args[0].from, ":")) ++ && *opt_str) { ++ err = opt_add(opt, opt_str, opts->sb_flags, ++ bindex++); ++ if (unlikely(!err && ++opt > opt_tail)) { ++ err = -E2BIG; ++ break; ++ } ++ opt->type = Opt_tail; ++ skipped = 1; ++ } ++ break; ++ case Opt_add: ++ if (unlikely(match_int(&a->args[0], &n))) { ++ AuErr("bad integer in %s\n", opt_str); ++ break; ++ } ++ bindex = n; ++ err = opt_add(opt, a->args[1].from, opts->sb_flags, ++ bindex); ++ if (!err) ++ opt->type = token; ++ break; ++ case Opt_append: ++ err = opt_add(opt, a->args[0].from, opts->sb_flags, ++ /*dummy bindex*/1); ++ if (!err) ++ opt->type = token; ++ break; ++ case Opt_prepend: ++ err = opt_add(opt, a->args[0].from, opts->sb_flags, ++ /*bindex*/0); ++ if (!err) ++ opt->type = token; ++ break; ++ case Opt_del: ++ err = au_opts_parse_del(&opt->del, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++#if 0 /* reserved for future use */ ++ case Opt_idel: ++ del->pathname = "(indexed)"; ++ if (unlikely(match_int(&args[0], &n))) { ++ AuErr("bad integer in %s\n", opt_str); ++ break; ++ } ++ err = au_opts_parse_idel(sb, n, &opt->del, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++#endif ++ case Opt_mod: ++ err = au_opts_parse_mod(&opt->mod, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++#ifdef IMOD /* reserved for future use */ ++ case Opt_imod: ++ u.mod->path = "(indexed)"; ++ if (unlikely(match_int(&a->args[0], &n))) { ++ AuErr("bad integer in %s\n", opt_str); ++ break; ++ } ++ err = au_opts_parse_imod(sb, n, &opt->mod, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++#endif ++ case Opt_xino: ++ err = au_opts_parse_xino(sb, &opt->xino, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++ ++ case Opt_trunc_xino_path: ++ err = au_opts_parse_xino_itrunc_path ++ (sb, &opt->xino_itrunc, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++ ++ case Opt_itrunc_xino: ++ u.xino_itrunc = &opt->xino_itrunc; ++ if (unlikely(match_int(&a->args[0], &n))) { ++ AuErr("bad integer in %s\n", opt_str); ++ break; ++ } ++ u.xino_itrunc->bindex = n; ++ aufs_read_lock(root, AuLock_FLUSH); ++ if (n < 0 || au_sbend(sb) < n) { ++ AuErr("out of bounds, %d\n", n); ++ aufs_read_unlock(root, !AuLock_IR); ++ break; ++ } ++ aufs_read_unlock(root, !AuLock_IR); ++ err = 0; ++ opt->type = token; ++ break; ++ ++ case Opt_dirwh: ++ if (unlikely(match_int(&a->args[0], &opt->dirwh))) ++ break; ++ err = 0; ++ opt->type = token; ++ break; ++ ++ case Opt_rdcache: ++ if (unlikely(match_int(&a->args[0], &opt->rdcache))) ++ break; ++ err = 0; ++ opt->type = token; ++ break; ++ case Opt_rdblk: ++ if (unlikely(match_int(&a->args[0], &n) ++ || n < 0 ++ || n > KMALLOC_MAX_SIZE)) { ++ AuErr("bad integer in %s\n", opt_str); ++ break; ++ } ++ if (unlikely(n && n < NAME_MAX)) { ++ AuErr("rdblk must be larger than %d\n", ++ NAME_MAX); ++ break; ++ } ++ opt->rdblk = n; ++ err = 0; ++ opt->type = token; ++ break; ++ case Opt_rdhash: ++ if (unlikely(match_int(&a->args[0], &n) ++ || n < 0 ++ || n * sizeof(struct hlist_head) ++ > KMALLOC_MAX_SIZE)) { ++ AuErr("bad integer in %s\n", opt_str); ++ break; ++ } ++ opt->rdhash = n; ++ err = 0; ++ opt->type = token; ++ break; ++ ++ case Opt_trunc_xino: ++ case Opt_notrunc_xino: ++ case Opt_noxino: ++ case Opt_trunc_xib: ++ case Opt_notrunc_xib: ++ case Opt_shwh: ++ case Opt_noshwh: ++ case Opt_plink: ++ case Opt_noplink: ++ case Opt_list_plink: ++ case Opt_diropq_a: ++ case Opt_diropq_w: ++ case Opt_warn_perm: ++ case Opt_nowarn_perm: ++ case Opt_refrof: ++ case Opt_norefrof: ++ case Opt_verbose: ++ case Opt_noverbose: ++ case Opt_sum: ++ case Opt_nosum: ++ case Opt_wsum: ++ case Opt_rdblk_def: ++ case Opt_rdhash_def: ++ err = 0; ++ opt->type = token; ++ break; ++ ++ case Opt_udba: ++ opt->udba = udba_val(a->args[0].from); ++ if (opt->udba >= 0) { ++ err = 0; ++ opt->type = token; ++ } else ++ AuErr("wrong value, %s\n", opt_str); ++ break; ++ ++ case Opt_wbr_create: ++ u.create = &opt->wbr_create; ++ u.create->wbr_create ++ = au_wbr_create_val(a->args[0].from, u.create); ++ if (u.create->wbr_create >= 0) { ++ err = 0; ++ opt->type = token; ++ } else ++ AuErr("wrong value, %s\n", opt_str); ++ break; ++ case Opt_wbr_copyup: ++ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from); ++ if (opt->wbr_copyup >= 0) { ++ err = 0; ++ opt->type = token; ++ } else ++ AuErr("wrong value, %s\n", opt_str); ++ break; ++ ++ case Opt_ignore: ++ AuWarn("ignored %s\n", opt_str); ++ /*FALLTHROUGH*/ ++ case Opt_ignore_silent: ++ skipped = 1; ++ err = 0; ++ break; ++ case Opt_err: ++ AuErr("unknown option %s\n", opt_str); ++ break; ++ } ++ ++ if (!err && !skipped) { ++ if (unlikely(++opt > opt_tail)) { ++ err = -E2BIG; ++ opt--; ++ opt->type = Opt_tail; ++ break; ++ } ++ opt->type = Opt_tail; ++ } ++ } ++ ++ kfree(a); ++ dump_opts(opts); ++ if (unlikely(err)) ++ au_opts_free(opts); ++ ++ out: ++ return err; ++} ++ ++static int au_opt_wbr_create(struct super_block *sb, ++ struct au_opt_wbr_create *create) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ err = 1; /* handled */ ++ sbinfo = au_sbi(sb); ++ if (sbinfo->si_wbr_create_ops->fin) { ++ err = sbinfo->si_wbr_create_ops->fin(sb); ++ if (!err) ++ err = 1; ++ } ++ ++ sbinfo->si_wbr_create = create->wbr_create; ++ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create; ++ switch (create->wbr_create) { ++ case AuWbrCreate_MFSRRV: ++ case AuWbrCreate_MFSRR: ++ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark; ++ /*FALLTHROUGH*/ ++ case AuWbrCreate_MFS: ++ case AuWbrCreate_MFSV: ++ case AuWbrCreate_PMFS: ++ case AuWbrCreate_PMFSV: ++ sbinfo->si_wbr_mfs.mfs_expire = create->mfs_second * HZ; ++ break; ++ } ++ ++ if (sbinfo->si_wbr_create_ops->init) ++ sbinfo->si_wbr_create_ops->init(sb); /* ignore */ ++ ++ return err; ++} ++ ++/* ++ * returns, ++ * plus: processed without an error ++ * zero: unprocessed ++ */ ++static int au_opt_simple(struct super_block *sb, struct au_opt *opt, ++ struct au_opts *opts) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ err = 1; /* handled */ ++ sbinfo = au_sbi(sb); ++ switch (opt->type) { ++ case Opt_udba: ++ sbinfo->si_mntflags &= ~AuOptMask_UDBA; ++ sbinfo->si_mntflags |= opt->udba; ++ opts->given_udba |= opt->udba; ++ break; ++ ++ case Opt_plink: ++ au_opt_set(sbinfo->si_mntflags, PLINK); ++ break; ++ case Opt_noplink: ++ if (au_opt_test(sbinfo->si_mntflags, PLINK)) ++ au_plink_put(sb); ++ au_opt_clr(sbinfo->si_mntflags, PLINK); ++ break; ++ case Opt_list_plink: ++ if (au_opt_test(sbinfo->si_mntflags, PLINK)) ++ au_plink_list(sb); ++ break; ++ ++ case Opt_diropq_a: ++ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ); ++ break; ++ case Opt_diropq_w: ++ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ); ++ break; ++ ++ case Opt_warn_perm: ++ au_opt_set(sbinfo->si_mntflags, WARN_PERM); ++ break; ++ case Opt_nowarn_perm: ++ au_opt_clr(sbinfo->si_mntflags, WARN_PERM); ++ break; ++ ++ case Opt_refrof: ++ au_opt_set(sbinfo->si_mntflags, REFROF); ++ break; ++ case Opt_norefrof: ++ au_opt_clr(sbinfo->si_mntflags, REFROF); ++ break; ++ ++ case Opt_verbose: ++ au_opt_set(sbinfo->si_mntflags, VERBOSE); ++ break; ++ case Opt_noverbose: ++ au_opt_clr(sbinfo->si_mntflags, VERBOSE); ++ break; ++ ++ case Opt_sum: ++ au_opt_set(sbinfo->si_mntflags, SUM); ++ break; ++ case Opt_wsum: ++ au_opt_clr(sbinfo->si_mntflags, SUM); ++ au_opt_set(sbinfo->si_mntflags, SUM_W); ++ case Opt_nosum: ++ au_opt_clr(sbinfo->si_mntflags, SUM); ++ au_opt_clr(sbinfo->si_mntflags, SUM_W); ++ break; ++ ++ case Opt_wbr_create: ++ err = au_opt_wbr_create(sb, &opt->wbr_create); ++ break; ++ case Opt_wbr_copyup: ++ sbinfo->si_wbr_copyup = opt->wbr_copyup; ++ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup; ++ break; ++ ++ case Opt_dirwh: ++ sbinfo->si_dirwh = opt->dirwh; ++ break; ++ ++ case Opt_rdcache: ++ sbinfo->si_rdcache = opt->rdcache * HZ; ++ break; ++ case Opt_rdblk: ++ sbinfo->si_rdblk = opt->rdblk; ++ break; ++ case Opt_rdblk_def: ++ sbinfo->si_rdblk = AUFS_RDBLK_DEF; ++ break; ++ case Opt_rdhash: ++ sbinfo->si_rdhash = opt->rdhash; ++ break; ++ case Opt_rdhash_def: ++ sbinfo->si_rdhash = AUFS_RDHASH_DEF; ++ break; ++ ++ case Opt_shwh: ++ au_opt_set(sbinfo->si_mntflags, SHWH); ++ break; ++ case Opt_noshwh: ++ au_opt_clr(sbinfo->si_mntflags, SHWH); ++ break; ++ ++ case Opt_trunc_xino: ++ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO); ++ break; ++ case Opt_notrunc_xino: ++ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO); ++ break; ++ ++ case Opt_trunc_xino_path: ++ case Opt_itrunc_xino: ++ err = au_xino_trunc(sb, opt->xino_itrunc.bindex); ++ if (!err) ++ err = 1; ++ break; ++ ++ case Opt_trunc_xib: ++ au_fset_opts(opts->flags, TRUNC_XIB); ++ break; ++ case Opt_notrunc_xib: ++ au_fclr_opts(opts->flags, TRUNC_XIB); ++ break; ++ ++ default: ++ err = 0; ++ break; ++ } ++ ++ return err; ++} ++ ++/* ++ * returns tri-state. ++ * plus: processed without an error ++ * zero: unprocessed ++ * minus: error ++ */ ++static int au_opt_br(struct super_block *sb, struct au_opt *opt, ++ struct au_opts *opts) ++{ ++ int err, do_refresh; ++ ++ err = 0; ++ switch (opt->type) { ++ case Opt_append: ++ opt->add.bindex = au_sbend(sb) + 1; ++ if (opt->add.bindex < 0) ++ opt->add.bindex = 0; ++ goto add; ++ case Opt_prepend: ++ opt->add.bindex = 0; ++ add: ++ case Opt_add: ++ err = au_br_add(sb, &opt->add, ++ au_ftest_opts(opts->flags, REMOUNT)); ++ if (!err) { ++ err = 1; ++ au_fset_opts(opts->flags, REFRESH_DIR); ++ if (au_br_whable(opt->add.perm)) ++ au_fset_opts(opts->flags, REFRESH_NONDIR); ++ } ++ break; ++ ++ case Opt_del: ++ case Opt_idel: ++ err = au_br_del(sb, &opt->del, ++ au_ftest_opts(opts->flags, REMOUNT)); ++ if (!err) { ++ err = 1; ++ au_fset_opts(opts->flags, TRUNC_XIB); ++ au_fset_opts(opts->flags, REFRESH_DIR); ++ au_fset_opts(opts->flags, REFRESH_NONDIR); ++ } ++ break; ++ ++ case Opt_mod: ++ case Opt_imod: ++ err = au_br_mod(sb, &opt->mod, ++ au_ftest_opts(opts->flags, REMOUNT), ++ &do_refresh); ++ if (!err) { ++ err = 1; ++ if (do_refresh) { ++ au_fset_opts(opts->flags, REFRESH_DIR); ++ au_fset_opts(opts->flags, REFRESH_NONDIR); ++ } ++ } ++ break; ++ } ++ ++ return err; ++} ++ ++static int au_opt_xino(struct super_block *sb, struct au_opt *opt, ++ struct au_opt_xino **opt_xino, ++ struct au_opts *opts) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct dentry *root, *parent, *h_root; ++ ++ err = 0; ++ switch (opt->type) { ++ case Opt_xino: ++ err = au_xino_set(sb, &opt->xino, ++ !!au_ftest_opts(opts->flags, REMOUNT)); ++ if (unlikely(err)) ++ break; ++ ++ *opt_xino = &opt->xino; ++ au_xino_brid_set(sb, -1); ++ ++ /* safe d_parent access */ ++ parent = opt->xino.file->f_dentry->d_parent; ++ root = sb->s_root; ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ h_root = au_h_dptr(root, bindex); ++ if (h_root == parent) { ++ au_xino_brid_set(sb, au_sbr_id(sb, bindex)); ++ break; ++ } ++ } ++ break; ++ ++ case Opt_noxino: ++ au_xino_clr(sb); ++ au_xino_brid_set(sb, -1); ++ *opt_xino = (void *)-1; ++ break; ++ } ++ ++ return err; ++} ++ ++int au_opts_verify(struct super_block *sb, unsigned long sb_flags, ++ unsigned int pending) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ unsigned char do_plink, skip, do_free; ++ struct au_branch *br; ++ struct au_wbr *wbr; ++ struct dentry *root; ++ struct inode *dir, *h_dir; ++ struct au_sbinfo *sbinfo; ++ struct au_hinode *hdir; ++ ++ SiMustAnyLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA)); ++ ++ if (!(sb_flags & MS_RDONLY)) { ++ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0)))) ++ AuWarn("first branch should be rw\n"); ++ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH))) ++ AuWarn("shwh should be used with ro\n"); ++ } ++ ++ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HINOTIFY) ++ && !au_opt_test(sbinfo->si_mntflags, XINO)) ++ AuWarn("udba=inotify requires xino\n"); ++ ++ err = 0; ++ root = sb->s_root; ++ dir = sb->s_root->d_inode; ++ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK); ++ bend = au_sbend(sb); ++ for (bindex = 0; !err && bindex <= bend; bindex++) { ++ skip = 0; ++ h_dir = au_h_iptr(dir, bindex); ++ br = au_sbr(sb, bindex); ++ do_free = 0; ++ ++ wbr = br->br_wbr; ++ if (wbr) ++ wbr_wh_read_lock(wbr); ++ ++ switch (br->br_perm) { ++ case AuBrPerm_RO: ++ case AuBrPerm_ROWH: ++ case AuBrPerm_RR: ++ case AuBrPerm_RRWH: ++ do_free = !!wbr; ++ skip = (!wbr ++ || (!wbr->wbr_whbase ++ && !wbr->wbr_plink ++ && !wbr->wbr_orph)); ++ break; ++ ++ case AuBrPerm_RWNoLinkWH: ++ /* skip = (!br->br_whbase && !br->br_orph); */ ++ skip = (!wbr || !wbr->wbr_whbase); ++ if (skip && wbr) { ++ if (do_plink) ++ skip = !!wbr->wbr_plink; ++ else ++ skip = !wbr->wbr_plink; ++ } ++ break; ++ ++ case AuBrPerm_RW: ++ /* skip = (br->br_whbase && br->br_ohph); */ ++ skip = (wbr && wbr->wbr_whbase); ++ if (skip) { ++ if (do_plink) ++ skip = !!wbr->wbr_plink; ++ else ++ skip = !wbr->wbr_plink; ++ } ++ break; ++ ++ default: ++ BUG(); ++ } ++ if (wbr) ++ wbr_wh_read_unlock(wbr); ++ ++ if (skip) ++ continue; ++ ++ hdir = au_hi(dir, bindex); ++ au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT); ++ if (wbr) ++ wbr_wh_write_lock(wbr); ++ err = au_wh_init(au_h_dptr(root, bindex), br, sb); ++ if (wbr) ++ wbr_wh_write_unlock(wbr); ++ au_hin_imtx_unlock(hdir); ++ ++ if (!err && do_free) { ++ kfree(wbr); ++ br->br_wbr = NULL; ++ } ++ } ++ ++ return err; ++} ++ ++int au_opts_mount(struct super_block *sb, struct au_opts *opts) ++{ ++ int err; ++ unsigned int tmp; ++ aufs_bindex_t bend; ++ struct au_opt *opt; ++ struct au_opt_xino *opt_xino, xino; ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ err = 0; ++ opt_xino = NULL; ++ opt = opts->opt; ++ while (err >= 0 && opt->type != Opt_tail) ++ err = au_opt_simple(sb, opt++, opts); ++ if (err > 0) ++ err = 0; ++ else if (unlikely(err < 0)) ++ goto out; ++ ++ /* disable xino and udba temporary */ ++ sbinfo = au_sbi(sb); ++ tmp = sbinfo->si_mntflags; ++ au_opt_clr(sbinfo->si_mntflags, XINO); ++ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL); ++ ++ opt = opts->opt; ++ while (err >= 0 && opt->type != Opt_tail) ++ err = au_opt_br(sb, opt++, opts); ++ if (err > 0) ++ err = 0; ++ else if (unlikely(err < 0)) ++ goto out; ++ ++ bend = au_sbend(sb); ++ if (unlikely(bend < 0)) { ++ err = -EINVAL; ++ AuErr("no branches\n"); ++ goto out; ++ } ++ ++ if (au_opt_test(tmp, XINO)) ++ au_opt_set(sbinfo->si_mntflags, XINO); ++ opt = opts->opt; ++ while (!err && opt->type != Opt_tail) ++ err = au_opt_xino(sb, opt++, &opt_xino, opts); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_opts_verify(sb, sb->s_flags, tmp); ++ if (unlikely(err)) ++ goto out; ++ ++ /* restore xino */ ++ if (au_opt_test(tmp, XINO) && !opt_xino) { ++ xino.file = au_xino_def(sb); ++ err = PTR_ERR(xino.file); ++ if (IS_ERR(xino.file)) ++ goto out; ++ ++ err = au_xino_set(sb, &xino, /*remount*/0); ++ fput(xino.file); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ /* restore udba */ ++ sbinfo->si_mntflags &= ~AuOptMask_UDBA; ++ sbinfo->si_mntflags |= (tmp & AuOptMask_UDBA); ++ if (au_opt_test(tmp, UDBA_HINOTIFY)) { ++ struct inode *dir = sb->s_root->d_inode; ++ au_reset_hinotify(dir, ++ au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO); ++ } ++ ++ out: ++ return err; ++} ++ ++int au_opts_remount(struct super_block *sb, struct au_opts *opts) ++{ ++ int err, rerr; ++ struct inode *dir; ++ struct au_opt_xino *opt_xino; ++ struct au_opt *opt; ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ dir = sb->s_root->d_inode; ++ sbinfo = au_sbi(sb); ++ err = 0; ++ opt_xino = NULL; ++ opt = opts->opt; ++ while (err >= 0 && opt->type != Opt_tail) { ++ err = au_opt_simple(sb, opt, opts); ++ if (!err) ++ err = au_opt_br(sb, opt, opts); ++ if (!err) ++ err = au_opt_xino(sb, opt, &opt_xino, opts); ++ opt++; ++ } ++ if (err > 0) ++ err = 0; ++ AuTraceErr(err); ++ /* go on even err */ ++ ++ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0); ++ if (unlikely(rerr && !err)) ++ err = rerr; ++ ++ if (au_ftest_opts(opts->flags, TRUNC_XIB)) { ++ rerr = au_xib_trunc(sb); ++ if (unlikely(rerr && !err)) ++ err = rerr; ++ } ++ ++ /* will be handled by the caller */ ++ if (!au_ftest_opts(opts->flags, REFRESH_DIR) ++ && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO))) ++ au_fset_opts(opts->flags, REFRESH_DIR); ++ ++ AuDbg("status 0x%x\n", opts->flags); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++unsigned int au_opt_udba(struct super_block *sb) ++{ ++ return au_mntflags(sb) & AuOptMask_UDBA; ++} +diff --git a/fs/aufs/opts.h b/fs/aufs/opts.h +new file mode 100644 +index 0000000..27439b1 +--- /dev/null ++++ b/fs/aufs/opts.h +@@ -0,0 +1,196 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * mount options/flags ++ */ ++ ++#ifndef __AUFS_OPTS_H__ ++#define __AUFS_OPTS_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++ ++struct file; ++struct super_block; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* mount flags */ ++#define AuOpt_XINO 1 /* external inode number bitmap ++ and translation table */ ++#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */ ++#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */ ++#define AuOpt_UDBA_REVAL (1 << 3) ++#define AuOpt_UDBA_HINOTIFY (1 << 4) ++#define AuOpt_SHWH (1 << 5) /* show whiteout */ ++#define AuOpt_PLINK (1 << 6) /* pseudo-link */ ++#define AuOpt_DIRPERM1 (1 << 7) /* unimplemented */ ++#define AuOpt_REFROF (1 << 8) /* unimplemented */ ++#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */ ++#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */ ++#define AuOpt_SUM_W (1 << 11) /* unimplemented */ ++#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */ ++#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */ ++ ++#ifndef CONFIG_AUFS_HINOTIFY ++#undef AuOpt_UDBA_HINOTIFY ++#define AuOpt_UDBA_HINOTIFY 0 ++#endif ++#ifndef CONFIG_AUFS_SHWH ++#undef AuOpt_SHWH ++#define AuOpt_SHWH 0 ++#endif ++ ++#define AuOpt_Def (AuOpt_XINO \ ++ | AuOpt_UDBA_REVAL \ ++ | AuOpt_PLINK \ ++ /* | AuOpt_DIRPERM1 */ \ ++ | AuOpt_WARN_PERM) ++#define AuOptMask_UDBA (AuOpt_UDBA_NONE \ ++ | AuOpt_UDBA_REVAL \ ++ | AuOpt_UDBA_HINOTIFY) ++ ++#define au_opt_test(flags, name) (flags & AuOpt_##name) ++#define au_opt_set(flags, name) do { \ ++ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \ ++ ((flags) |= AuOpt_##name); \ ++} while (0) ++#define au_opt_set_udba(flags, name) do { \ ++ (flags) &= ~AuOptMask_UDBA; \ ++ ((flags) |= AuOpt_##name); \ ++} while (0) ++#define au_opt_clr(flags, name) { ((flags) &= ~AuOpt_##name); } ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* policies to select one among multiple writable branches */ ++enum { ++ AuWbrCreate_TDP, /* top down parent */ ++ AuWbrCreate_RR, /* round robin */ ++ AuWbrCreate_MFS, /* most free space */ ++ AuWbrCreate_MFSV, /* mfs with seconds */ ++ AuWbrCreate_MFSRR, /* mfs then rr */ ++ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */ ++ AuWbrCreate_PMFS, /* parent and mfs */ ++ AuWbrCreate_PMFSV, /* parent and mfs with seconds */ ++ ++ AuWbrCreate_Def = AuWbrCreate_TDP ++}; ++ ++enum { ++ AuWbrCopyup_TDP, /* top down parent */ ++ AuWbrCopyup_BUP, /* bottom up parent */ ++ AuWbrCopyup_BU, /* bottom up */ ++ ++ AuWbrCopyup_Def = AuWbrCopyup_TDP ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_opt_add { ++ aufs_bindex_t bindex; ++ char *pathname; ++ int perm; ++ struct path path; ++}; ++ ++struct au_opt_del { ++ char *pathname; ++ struct path h_path; ++}; ++ ++struct au_opt_mod { ++ char *path; ++ int perm; ++ struct dentry *h_root; ++}; ++ ++struct au_opt_xino { ++ char *path; ++ struct file *file; ++}; ++ ++struct au_opt_xino_itrunc { ++ aufs_bindex_t bindex; ++}; ++ ++struct au_opt_wbr_create { ++ int wbr_create; ++ int mfs_second; ++ unsigned long long mfsrr_watermark; ++}; ++ ++struct au_opt { ++ int type; ++ union { ++ struct au_opt_xino xino; ++ struct au_opt_xino_itrunc xino_itrunc; ++ struct au_opt_add add; ++ struct au_opt_del del; ++ struct au_opt_mod mod; ++ int dirwh; ++ int rdcache; ++ unsigned int rdblk; ++ unsigned int rdhash; ++ int udba; ++ struct au_opt_wbr_create wbr_create; ++ int wbr_copyup; ++ }; ++}; ++ ++/* opts flags */ ++#define AuOpts_REMOUNT 1 ++#define AuOpts_REFRESH_DIR (1 << 1) ++#define AuOpts_REFRESH_NONDIR (1 << 2) ++#define AuOpts_TRUNC_XIB (1 << 3) ++#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name) ++#define au_fset_opts(flags, name) { (flags) |= AuOpts_##name; } ++#define au_fclr_opts(flags, name) { (flags) &= ~AuOpts_##name; } ++ ++struct au_opts { ++ struct au_opt *opt; ++ int max_opt; ++ ++ unsigned int given_udba; ++ unsigned int flags; ++ unsigned long sb_flags; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++const char *au_optstr_br_perm(int brperm); ++const char *au_optstr_udba(int udba); ++const char *au_optstr_wbr_copyup(int wbr_copyup); ++const char *au_optstr_wbr_create(int wbr_create); ++ ++void au_opts_free(struct au_opts *opts); ++int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts); ++int au_opts_verify(struct super_block *sb, unsigned long sb_flags, ++ unsigned int pending); ++int au_opts_mount(struct super_block *sb, struct au_opts *opts); ++int au_opts_remount(struct super_block *sb, struct au_opts *opts); ++ ++unsigned int au_opt_udba(struct super_block *sb); ++ ++/* ---------------------------------------------------------------------- */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_OPTS_H__ */ +diff --git a/fs/aufs/plink.c b/fs/aufs/plink.c +new file mode 100644 +index 0000000..31fc923 +--- /dev/null ++++ b/fs/aufs/plink.c +@@ -0,0 +1,396 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * pseudo-link ++ */ ++ ++#include "aufs.h" ++ ++/* ++ * during a user process maintains the pseudo-links, ++ * prohibit adding a new plink and branch manipulation. ++ */ ++void au_plink_block_maintain(struct super_block *sb) ++{ ++ struct au_sbinfo *sbi = au_sbi(sb); ++ ++ SiMustAnyLock(sb); ++ ++ /* gave up wake_up_bit() */ ++ wait_event(sbi->si_plink_wq, !au_ftest_si(sbi, MAINTAIN_PLINK)); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct pseudo_link { ++ struct list_head list; ++ struct inode *inode; ++}; ++ ++#ifdef CONFIG_AUFS_DEBUG ++void au_plink_list(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ struct list_head *plink_list; ++ struct pseudo_link *plink; ++ ++ SiMustAnyLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); ++ ++ plink_list = &sbinfo->si_plink.head; ++ spin_lock(&sbinfo->si_plink.spin); ++ list_for_each_entry(plink, plink_list, list) ++ AuDbg("%lu\n", plink->inode->i_ino); ++ spin_unlock(&sbinfo->si_plink.spin); ++} ++#endif ++ ++/* is the inode pseudo-linked? */ ++int au_plink_test(struct inode *inode) ++{ ++ int found; ++ struct au_sbinfo *sbinfo; ++ struct list_head *plink_list; ++ struct pseudo_link *plink; ++ ++ sbinfo = au_sbi(inode->i_sb); ++ AuRwMustAnyLock(&sbinfo->si_rwsem); ++ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK)); ++ ++ found = 0; ++ plink_list = &sbinfo->si_plink.head; ++ spin_lock(&sbinfo->si_plink.spin); ++ list_for_each_entry(plink, plink_list, list) ++ if (plink->inode == inode) { ++ found = 1; ++ break; ++ } ++ spin_unlock(&sbinfo->si_plink.spin); ++ return found; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * generate a name for plink. ++ * the file will be stored under AUFS_WH_PLINKDIR. ++ */ ++/* 20 is max digits length of ulong 64 */ ++#define PLINK_NAME_LEN ((20 + 1) * 2) ++ ++static int plink_name(char *name, int len, struct inode *inode, ++ aufs_bindex_t bindex) ++{ ++ int rlen; ++ struct inode *h_inode; ++ ++ h_inode = au_h_iptr(inode, bindex); ++ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino); ++ return rlen; ++} ++ ++/* lookup the plink-ed @inode under the branch at @bindex */ ++struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex) ++{ ++ struct dentry *h_dentry, *h_parent; ++ struct au_branch *br; ++ struct inode *h_dir; ++ char a[PLINK_NAME_LEN]; ++ struct qstr tgtname = { ++ .name = a ++ }; ++ ++ br = au_sbr(inode->i_sb, bindex); ++ h_parent = br->br_wbr->wbr_plink; ++ h_dir = h_parent->d_inode; ++ tgtname.len = plink_name(a, sizeof(a), inode, bindex); ++ ++ /* always superio. */ ++ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2); ++ h_dentry = au_sio_lkup_one(&tgtname, h_parent, br); ++ mutex_unlock(&h_dir->i_mutex); ++ return h_dentry; ++} ++ ++/* create a pseudo-link */ ++static int do_whplink(struct qstr *tgt, struct dentry *h_parent, ++ struct dentry *h_dentry, struct au_branch *br) ++{ ++ int err; ++ struct path h_path = { ++ .mnt = br->br_mnt ++ }; ++ struct inode *h_dir; ++ ++ h_dir = h_parent->d_inode; ++ again: ++ h_path.dentry = au_lkup_one(tgt, h_parent, br, /*nd*/NULL); ++ err = PTR_ERR(h_path.dentry); ++ if (IS_ERR(h_path.dentry)) ++ goto out; ++ ++ err = 0; ++ /* wh.plink dir is not monitored */ ++ if (h_path.dentry->d_inode ++ && h_path.dentry->d_inode != h_dentry->d_inode) { ++ err = vfsub_unlink(h_dir, &h_path, /*force*/0); ++ dput(h_path.dentry); ++ h_path.dentry = NULL; ++ if (!err) ++ goto again; ++ } ++ if (!err && !h_path.dentry->d_inode) ++ err = vfsub_link(h_dentry, h_dir, &h_path); ++ dput(h_path.dentry); ++ ++ out: ++ return err; ++} ++ ++struct do_whplink_args { ++ int *errp; ++ struct qstr *tgt; ++ struct dentry *h_parent; ++ struct dentry *h_dentry; ++ struct au_branch *br; ++}; ++ ++static void call_do_whplink(void *args) ++{ ++ struct do_whplink_args *a = args; ++ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br); ++} ++ ++static int whplink(struct dentry *h_dentry, struct inode *inode, ++ aufs_bindex_t bindex, struct au_branch *br) ++{ ++ int err, wkq_err; ++ struct au_wbr *wbr; ++ struct dentry *h_parent; ++ struct inode *h_dir; ++ char a[PLINK_NAME_LEN]; ++ struct qstr tgtname = { ++ .name = a ++ }; ++ ++ wbr = au_sbr(inode->i_sb, bindex)->br_wbr; ++ h_parent = wbr->wbr_plink; ++ h_dir = h_parent->d_inode; ++ tgtname.len = plink_name(a, sizeof(a), inode, bindex); ++ ++ /* always superio. */ ++ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2); ++ if (!au_test_wkq(current)) { ++ struct do_whplink_args args = { ++ .errp = &err, ++ .tgt = &tgtname, ++ .h_parent = h_parent, ++ .h_dentry = h_dentry, ++ .br = br ++ }; ++ wkq_err = au_wkq_wait(call_do_whplink, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } else ++ err = do_whplink(&tgtname, h_parent, h_dentry, br); ++ mutex_unlock(&h_dir->i_mutex); ++ ++ return err; ++} ++ ++/* free a single plink */ ++static void do_put_plink(struct pseudo_link *plink, int do_del) ++{ ++ iput(plink->inode); ++ if (do_del) ++ list_del(&plink->list); ++ kfree(plink); ++} ++ ++/* ++ * create a new pseudo-link for @h_dentry on @bindex. ++ * the linked inode is held in aufs @inode. ++ */ ++void au_plink_append(struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_dentry) ++{ ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ struct list_head *plink_list; ++ struct pseudo_link *plink; ++ int found, err, cnt; ++ ++ sb = inode->i_sb; ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); ++ ++ err = 0; ++ cnt = 0; ++ found = 0; ++ plink_list = &sbinfo->si_plink.head; ++ spin_lock(&sbinfo->si_plink.spin); ++ list_for_each_entry(plink, plink_list, list) { ++ cnt++; ++ if (plink->inode == inode) { ++ found = 1; ++ break; ++ } ++ } ++ if (found) { ++ spin_unlock(&sbinfo->si_plink.spin); ++ return; ++ } ++ ++ plink = NULL; ++ if (!found) { ++ plink = kmalloc(sizeof(*plink), GFP_ATOMIC); ++ if (plink) { ++ plink->inode = au_igrab(inode); ++ list_add(&plink->list, plink_list); ++ cnt++; ++ } else ++ err = -ENOMEM; ++ } ++ spin_unlock(&sbinfo->si_plink.spin); ++ ++ if (!err) { ++ au_plink_block_maintain(sb); ++ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex)); ++ } ++ ++ if (unlikely(cnt > AUFS_PLINK_WARN)) ++ AuWarn1("unexpectedly many pseudo links, %d\n", cnt); ++ if (unlikely(err)) { ++ AuWarn("err %d, damaged pseudo link.\n", err); ++ if (!found && plink) ++ do_put_plink(plink, /*do_del*/1); ++ } ++} ++ ++/* free all plinks */ ++void au_plink_put(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ struct list_head *plink_list; ++ struct pseudo_link *plink, *tmp; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); ++ ++ plink_list = &sbinfo->si_plink.head; ++ /* no spin_lock since sbinfo is write-locked */ ++ list_for_each_entry_safe(plink, tmp, plink_list, list) ++ do_put_plink(plink, 0); ++ INIT_LIST_HEAD(plink_list); ++} ++ ++/* free the plinks on a branch specified by @br_id */ ++void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id) ++{ ++ struct au_sbinfo *sbinfo; ++ struct list_head *plink_list; ++ struct pseudo_link *plink, *tmp; ++ struct inode *inode; ++ aufs_bindex_t bstart, bend, bindex; ++ unsigned char do_put; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); ++ ++ plink_list = &sbinfo->si_plink.head; ++ /* no spin_lock since sbinfo is write-locked */ ++ list_for_each_entry_safe(plink, tmp, plink_list, list) { ++ do_put = 0; ++ inode = au_igrab(plink->inode); ++ ii_write_lock_child(inode); ++ bstart = au_ibstart(inode); ++ bend = au_ibend(inode); ++ if (bstart >= 0) { ++ for (bindex = bstart; bindex <= bend; bindex++) { ++ if (!au_h_iptr(inode, bindex) ++ || au_ii_br_id(inode, bindex) != br_id) ++ continue; ++ au_set_h_iptr(inode, bindex, NULL, 0); ++ do_put = 1; ++ break; ++ } ++ } else ++ do_put_plink(plink, 1); ++ ++ if (do_put) { ++ for (bindex = bstart; bindex <= bend; bindex++) ++ if (au_h_iptr(inode, bindex)) { ++ do_put = 0; ++ break; ++ } ++ if (do_put) ++ do_put_plink(plink, 1); ++ } ++ ii_write_unlock(inode); ++ iput(inode); ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++long au_plink_ioctl(struct file *file, unsigned int cmd) ++{ ++ long err; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ ++ err = -EACCES; ++ if (!capable(CAP_SYS_ADMIN)) ++ goto out; ++ ++ err = 0; ++ sb = file->f_dentry->d_sb; ++ sbinfo = au_sbi(sb); ++ switch (cmd) { ++ case AUFS_CTL_PLINK_MAINT: ++ /* ++ * pseudo-link maintenance mode, ++ * cleared by aufs_release_dir() ++ */ ++ si_write_lock(sb); ++ if (!au_ftest_si(sbinfo, MAINTAIN_PLINK)) { ++ au_fset_si(sbinfo, MAINTAIN_PLINK); ++ au_fi(file)->fi_maintain_plink = 1; ++ } else ++ err = -EBUSY; ++ si_write_unlock(sb); ++ break; ++ case AUFS_CTL_PLINK_CLEAN: ++ aufs_write_lock(sb->s_root); ++ if (au_opt_test(sbinfo->si_mntflags, PLINK)) ++ au_plink_put(sb); ++ aufs_write_unlock(sb->s_root); ++ break; ++ default: ++ err = -EINVAL; ++ } ++ out: ++ return err; ++} +diff --git a/fs/aufs/poll.c b/fs/aufs/poll.c +new file mode 100644 +index 0000000..1a1ddae +--- /dev/null ++++ b/fs/aufs/poll.c +@@ -0,0 +1,56 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * poll operation ++ * There is only one filesystem which implements ->poll operation, currently. ++ */ ++ ++#include "aufs.h" ++ ++unsigned int aufs_poll(struct file *file, poll_table *wait) ++{ ++ unsigned int mask; ++ int err; ++ struct file *h_file; ++ struct dentry *dentry; ++ struct super_block *sb; ++ ++ /* We should pretend an error happened. */ ++ mask = POLLERR /* | POLLIN | POLLOUT */; ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ /* it is not an error if h_file has no operation */ ++ mask = DEFAULT_POLLMASK; ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ if (h_file->f_op && h_file->f_op->poll) ++ mask = h_file->f_op->poll(h_file, wait); ++ ++ di_read_unlock(dentry, AuLock_IR); ++ fi_read_unlock(file); ++ ++ out: ++ si_read_unlock(sb); ++ AuTraceErr((int)mask); ++ return mask; ++} +diff --git a/fs/aufs/rdu.c b/fs/aufs/rdu.c +new file mode 100644 +index 0000000..0a224f4 +--- /dev/null ++++ b/fs/aufs/rdu.c +@@ -0,0 +1,331 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * readdir in userspace. ++ */ ++ ++#include ++#include ++#include ++#include "aufs.h" ++ ++/* bits for struct aufs_rdu.flags */ ++#define AuRdu_CALLED 1 ++#define AuRdu_CONT (1 << 1) ++#define AuRdu_FULL (1 << 2) ++#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name) ++#define au_fset_rdu(flags, name) { (flags) |= AuRdu_##name; } ++#define au_fclr_rdu(flags, name) { (flags) &= ~AuRdu_##name; } ++ ++struct au_rdu_arg { ++ struct aufs_rdu *rdu; ++ union au_rdu_ent_ul ent; ++ unsigned long end; ++ ++ struct super_block *sb; ++ int err; ++}; ++ ++static int au_rdu_fill(void *__arg, const char *name, int nlen, ++ loff_t offset, u64 h_ino, unsigned int d_type) ++{ ++ int err, len; ++ struct au_rdu_arg *arg = __arg; ++ struct aufs_rdu *rdu = arg->rdu; ++ struct au_rdu_ent ent; ++ ++ err = 0; ++ arg->err = 0; ++ au_fset_rdu(rdu->cookie.flags, CALLED); ++ len = au_rdu_len(nlen); ++ if (arg->ent.ul + len < arg->end) { ++ ent.ino = h_ino; ++ ent.bindex = rdu->cookie.bindex; ++ ent.type = d_type; ++ ent.nlen = nlen; ++ ++ err = -EFAULT; ++ if (copy_to_user(arg->ent.e, &ent, sizeof(ent))) ++ goto out; ++ if (copy_to_user(arg->ent.e->name, name, nlen)) ++ goto out; ++ /* the terminating NULL */ ++ if (__put_user(0, arg->ent.e->name + nlen)) ++ goto out; ++ err = 0; ++ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */ ++ arg->ent.ul += len; ++ rdu->rent++; ++ } else { ++ err = -EFAULT; ++ au_fset_rdu(rdu->cookie.flags, FULL); ++ rdu->full = 1; ++ rdu->tail = arg->ent; ++ } ++ ++ out: ++ /* AuTraceErr(err); */ ++ return err; ++} ++ ++static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg) ++{ ++ int err; ++ loff_t offset; ++ struct au_rdu_cookie *cookie = &arg->rdu->cookie; ++ ++ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET); ++ err = offset; ++ if (unlikely(offset != cookie->h_pos)) ++ goto out; ++ ++ err = 0; ++ do { ++ arg->err = 0; ++ au_fclr_rdu(cookie->flags, CALLED); ++ /* smp_mb(); */ ++ err = vfsub_readdir(h_file, au_rdu_fill, arg); ++ if (err >= 0) ++ err = arg->err; ++ } while (!err ++ && au_ftest_rdu(cookie->flags, CALLED) ++ && !au_ftest_rdu(cookie->flags, FULL)); ++ cookie->h_pos = h_file->f_pos; ++ ++ out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int au_rdu(struct file *file, struct aufs_rdu *rdu) ++{ ++ int err; ++ aufs_bindex_t bend; ++ struct au_rdu_arg arg; ++ struct dentry *dentry; ++ struct inode *inode; ++ struct file *h_file; ++ struct au_rdu_cookie *cookie = &rdu->cookie; ++ ++ err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ goto out; ++ } ++ rdu->rent = 0; ++ rdu->tail = rdu->ent; ++ rdu->full = 0; ++ arg.rdu = rdu; ++ arg.ent = rdu->ent; ++ arg.end = arg.ent.ul; ++ arg.end += rdu->sz; ++ ++ err = -ENOTDIR; ++ if (unlikely(!file->f_op || !file->f_op->readdir)) ++ goto out; ++ ++ err = security_file_permission(file, MAY_READ); ++ AuTraceErr(err); ++ if (unlikely(err)) ++ goto out; ++ ++ dentry = file->f_dentry; ++ inode = dentry->d_inode; ++#if 1 ++ mutex_lock(&inode->i_mutex); ++#else ++ err = mutex_lock_killable(&inode->i_mutex); ++ AuTraceErr(err); ++ if (unlikely(err)) ++ goto out; ++#endif ++ err = -ENOENT; ++ if (unlikely(IS_DEADDIR(inode))) ++ goto out_mtx; ++ ++ arg.sb = inode->i_sb; ++ si_read_lock(arg.sb, AuLock_FLUSH); ++ fi_read_lock(file); ++ ++ err = -EAGAIN; ++ if (unlikely(au_ftest_rdu(cookie->flags, CONT) ++ && cookie->generation != au_figen(file))) ++ goto out_unlock; ++ ++ err = 0; ++ if (!rdu->blk) { ++ rdu->blk = au_sbi(arg.sb)->si_rdblk; ++ if (!rdu->blk) ++ rdu->blk = au_dir_size(file, /*dentry*/NULL); ++ } ++ bend = au_fbstart(file); ++ if (cookie->bindex < bend) ++ cookie->bindex = bend; ++ bend = au_fbend(file); ++ /* AuDbg("b%d, b%d\n", cookie->bindex, bend); */ ++ for (; !err && cookie->bindex <= bend; ++ cookie->bindex++, cookie->h_pos = 0) { ++ h_file = au_h_fptr(file, cookie->bindex); ++ if (!h_file) ++ continue; ++ ++ au_fclr_rdu(cookie->flags, FULL); ++ err = au_rdu_do(h_file, &arg); ++ AuTraceErr(err); ++ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err)) ++ break; ++ } ++ AuDbg("rent %llu\n", rdu->rent); ++ ++ if (!err && !au_ftest_rdu(cookie->flags, CONT)) { ++ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH); ++ au_fset_rdu(cookie->flags, CONT); ++ cookie->generation = au_figen(file); ++ } ++ ++ ii_read_lock_child(inode); ++ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode))); ++ ii_read_unlock(inode); ++ ++ out_unlock: ++ fi_read_unlock(file); ++ si_read_unlock(arg.sb); ++ out_mtx: ++ mutex_unlock(&inode->i_mutex); ++ out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu) ++{ ++ int err; ++ ino_t ino; ++ unsigned long long nent; ++ union au_rdu_ent_ul *u; ++ struct au_rdu_ent ent; ++ struct super_block *sb; ++ ++ err = 0; ++ nent = rdu->nent; ++ u = &rdu->ent; ++ sb = file->f_dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ while (nent-- > 0) { ++ err = !access_ok(VERIFY_WRITE, u->e, sizeof(ent)); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ break; ++ } ++ ++ err = copy_from_user(&ent, u->e, sizeof(ent)); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ break; ++ } ++ ++ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */ ++ if (!ent.wh) ++ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino); ++ else ++ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type, ++ &ino); ++ if (unlikely(err)) { ++ AuTraceErr(err); ++ break; ++ } ++ ++ err = __put_user(ino, &u->e->ino); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ break; ++ } ++ u->ul += au_rdu_len(ent.nlen); ++ } ++ si_read_unlock(sb); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_rdu_verify(struct aufs_rdu *rdu) ++{ ++ AuDbg("rdu{%llu, %p, (%u, %u) | %u | %llu, %u, %u | " ++ "%llu, b%d, 0x%x, g%u}\n", ++ rdu->sz, rdu->ent.e, rdu->verify[0], rdu->verify[1], ++ rdu->blk, ++ rdu->rent, rdu->shwh, rdu->full, ++ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags, ++ rdu->cookie.generation); ++ ++ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu) ++ && rdu->verify[AufsCtlRduV_SZ_PTR] == sizeof(rdu)) ++ return 0; ++ ++ AuDbg("%u:%u, %u:%u\n", ++ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu), ++ rdu->verify[AufsCtlRduV_SZ_PTR], (unsigned int)sizeof(rdu)); ++ return -EINVAL; ++} ++ ++long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ long err, e; ++ struct aufs_rdu rdu; ++ void __user *p = (void __user *)arg; ++ ++ err = copy_from_user(&rdu, p, sizeof(rdu)); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ goto out; ++ } ++ err = au_rdu_verify(&rdu); ++ if (unlikely(err)) ++ goto out; ++ ++ switch (cmd) { ++ case AUFS_CTL_RDU: ++ err = au_rdu(file, &rdu); ++ if (unlikely(err)) ++ break; ++ ++ e = copy_to_user(p, &rdu, sizeof(rdu)); ++ if (unlikely(e)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ } ++ break; ++ case AUFS_CTL_RDU_INO: ++ err = au_rdu_ino(file, &rdu); ++ break; ++ ++ default: ++ err = -EINVAL; ++ } ++ ++ out: ++ AuTraceErr(err); ++ return err; ++} +diff --git a/fs/aufs/rwsem.h b/fs/aufs/rwsem.h +new file mode 100644 +index 0000000..dfd2c68 +--- /dev/null ++++ b/fs/aufs/rwsem.h +@@ -0,0 +1,186 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * simple read-write semaphore wrappers ++ */ ++ ++#ifndef __AUFS_RWSEM_H__ ++#define __AUFS_RWSEM_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++ ++struct au_rwsem { ++ struct rw_semaphore rwsem; ++#ifdef CONFIG_AUFS_DEBUG ++ /* just for debugging, not almighty counter */ ++ atomic_t rcnt, wcnt; ++#endif ++}; ++ ++#ifdef CONFIG_AUFS_DEBUG ++#define AuDbgCntInit(rw) do { \ ++ atomic_set(&(rw)->rcnt, 0); \ ++ atomic_set(&(rw)->wcnt, 0); \ ++ smp_mb(); /* atomic set */ \ ++} while (0) ++ ++#define AuDbgRcntInc(rw) atomic_inc_return(&(rw)->rcnt) ++#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0) ++#define AuDbgWcntInc(rw) WARN_ON(atomic_inc_return(&(rw)->wcnt) > 1) ++#define AuDbgWcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0) ++#else ++#define AuDbgCntInit(rw) do {} while (0) ++#define AuDbgRcntInc(rw) do {} while (0) ++#define AuDbgRcntDec(rw) do {} while (0) ++#define AuDbgWcntInc(rw) do {} while (0) ++#define AuDbgWcntDec(rw) do {} while (0) ++#endif /* CONFIG_AUFS_DEBUG */ ++ ++/* to debug easier, do not make them inlined functions */ ++#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list)) ++/* rwsem_is_locked() is unusable */ ++#define AuRwMustReadLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0) ++#define AuRwMustWriteLock(rw) AuDebugOn(atomic_read(&(rw)->wcnt) <= 0) ++#define AuRwMustAnyLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \ ++ && atomic_read(&(rw)->wcnt) <= 0) ++#define AuRwDestroy(rw) AuDebugOn(atomic_read(&(rw)->rcnt) \ ++ || atomic_read(&(rw)->wcnt)) ++ ++static inline void au_rw_init(struct au_rwsem *rw) ++{ ++ AuDbgCntInit(rw); ++ init_rwsem(&rw->rwsem); ++} ++ ++static inline void au_rw_init_wlock(struct au_rwsem *rw) ++{ ++ au_rw_init(rw); ++ down_write(&rw->rwsem); ++ AuDbgWcntInc(rw); ++} ++ ++static inline void au_rw_init_wlock_nested(struct au_rwsem *rw, ++ unsigned int lsc) ++{ ++ au_rw_init(rw); ++ down_write_nested(&rw->rwsem, lsc); ++ AuDbgWcntInc(rw); ++} ++ ++static inline void au_rw_read_lock(struct au_rwsem *rw) ++{ ++ down_read(&rw->rwsem); ++ AuDbgRcntInc(rw); ++} ++ ++static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc) ++{ ++ down_read_nested(&rw->rwsem, lsc); ++ AuDbgRcntInc(rw); ++} ++ ++static inline void au_rw_read_unlock(struct au_rwsem *rw) ++{ ++ AuRwMustReadLock(rw); ++ AuDbgRcntDec(rw); ++ up_read(&rw->rwsem); ++} ++ ++static inline void au_rw_dgrade_lock(struct au_rwsem *rw) ++{ ++ AuRwMustWriteLock(rw); ++ AuDbgRcntInc(rw); ++ AuDbgWcntDec(rw); ++ downgrade_write(&rw->rwsem); ++} ++ ++static inline void au_rw_write_lock(struct au_rwsem *rw) ++{ ++ down_write(&rw->rwsem); ++ AuDbgWcntInc(rw); ++} ++ ++static inline void au_rw_write_lock_nested(struct au_rwsem *rw, ++ unsigned int lsc) ++{ ++ down_write_nested(&rw->rwsem, lsc); ++ AuDbgWcntInc(rw); ++} ++ ++static inline void au_rw_write_unlock(struct au_rwsem *rw) ++{ ++ AuRwMustWriteLock(rw); ++ AuDbgWcntDec(rw); ++ up_write(&rw->rwsem); ++} ++ ++/* why is not _nested version defined */ ++static inline int au_rw_read_trylock(struct au_rwsem *rw) ++{ ++ int ret = down_read_trylock(&rw->rwsem); ++ if (ret) ++ AuDbgRcntInc(rw); ++ return ret; ++} ++ ++static inline int au_rw_write_trylock(struct au_rwsem *rw) ++{ ++ int ret = down_write_trylock(&rw->rwsem); ++ if (ret) ++ AuDbgWcntInc(rw); ++ return ret; ++} ++ ++#undef AuDbgCntInit ++#undef AuDbgRcntInc ++#undef AuDbgRcntDec ++#undef AuDbgWcntInc ++#undef AuDbgWcntDec ++ ++#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \ ++static inline void prefix##_read_lock(param) \ ++{ au_rw_read_lock(rwsem); } \ ++static inline void prefix##_write_lock(param) \ ++{ au_rw_write_lock(rwsem); } \ ++static inline int prefix##_read_trylock(param) \ ++{ return au_rw_read_trylock(rwsem); } \ ++static inline int prefix##_write_trylock(param) \ ++{ return au_rw_write_trylock(rwsem); } ++/* why is not _nested version defined */ ++/* static inline void prefix##_read_trylock_nested(param, lsc) ++{ au_rw_read_trylock_nested(rwsem, lsc)); } ++static inline void prefix##_write_trylock_nestd(param, lsc) ++{ au_rw_write_trylock_nested(rwsem, lsc); } */ ++ ++#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \ ++static inline void prefix##_read_unlock(param) \ ++{ au_rw_read_unlock(rwsem); } \ ++static inline void prefix##_write_unlock(param) \ ++{ au_rw_write_unlock(rwsem); } \ ++static inline void prefix##_downgrade_lock(param) \ ++{ au_rw_dgrade_lock(rwsem); } ++ ++#define AuSimpleRwsemFuncs(prefix, param, rwsem) \ ++ AuSimpleLockRwsemFuncs(prefix, param, rwsem) \ ++ AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_RWSEM_H__ */ +diff --git a/fs/aufs/sbinfo.c b/fs/aufs/sbinfo.c +new file mode 100644 +index 0000000..f0650e5 +--- /dev/null ++++ b/fs/aufs/sbinfo.c +@@ -0,0 +1,208 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * superblock private data ++ */ ++ ++#include "aufs.h" ++ ++/* ++ * they are necessary regardless sysfs is disabled. ++ */ ++void au_si_free(struct kobject *kobj) ++{ ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ ++ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); ++ AuDebugOn(!list_empty(&sbinfo->si_plink.head)); ++ ++ sb = sbinfo->si_sb; ++ si_write_lock(sb); ++ au_xino_clr(sb); ++ au_br_free(sbinfo); ++ kfree(sbinfo->si_branch); ++ mutex_destroy(&sbinfo->si_xib_mtx); ++ si_write_unlock(sb); ++ AuRwDestroy(&sbinfo->si_rwsem); ++ ++ kfree(sbinfo); ++} ++ ++int au_si_alloc(struct super_block *sb) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ ++ err = -ENOMEM; ++ sbinfo = kmalloc(sizeof(*sbinfo), GFP_NOFS); ++ if (unlikely(!sbinfo)) ++ goto out; ++ ++ /* will be reallocated separately */ ++ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS); ++ if (unlikely(!sbinfo->si_branch)) ++ goto out_sbinfo; ++ ++ memset(&sbinfo->si_kobj, 0, sizeof(sbinfo->si_kobj)); ++ err = sysaufs_si_init(sbinfo); ++ if (unlikely(err)) ++ goto out_br; ++ ++ au_nwt_init(&sbinfo->si_nowait); ++ au_rw_init_wlock(&sbinfo->si_rwsem); ++ sbinfo->si_generation = 0; ++ sbinfo->au_si_status = 0; ++ sbinfo->si_bend = -1; ++ sbinfo->si_last_br_id = 0; ++ ++ sbinfo->si_wbr_copyup = AuWbrCopyup_Def; ++ sbinfo->si_wbr_create = AuWbrCreate_Def; ++ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + AuWbrCopyup_Def; ++ sbinfo->si_wbr_create_ops = au_wbr_create_ops + AuWbrCreate_Def; ++ ++ sbinfo->si_mntflags = AuOpt_Def; ++ ++ sbinfo->si_xread = NULL; ++ sbinfo->si_xwrite = NULL; ++ sbinfo->si_xib = NULL; ++ mutex_init(&sbinfo->si_xib_mtx); ++ sbinfo->si_xib_buf = NULL; ++ sbinfo->si_xino_brid = -1; ++ /* leave si_xib_last_pindex and si_xib_next_bit */ ++ ++ sbinfo->si_rdcache = AUFS_RDCACHE_DEF * HZ; ++ sbinfo->si_rdblk = AUFS_RDBLK_DEF; ++ sbinfo->si_rdhash = AUFS_RDHASH_DEF; ++ sbinfo->si_dirwh = AUFS_DIRWH_DEF; ++ ++ au_spl_init(&sbinfo->si_plink); ++ init_waitqueue_head(&sbinfo->si_plink_wq); ++ ++ /* leave other members for sysaufs and si_mnt. */ ++ sbinfo->si_sb = sb; ++ sb->s_fs_info = sbinfo; ++ au_debug_sbinfo_init(sbinfo); ++ return 0; /* success */ ++ ++ out_br: ++ kfree(sbinfo->si_branch); ++ out_sbinfo: ++ kfree(sbinfo); ++ out: ++ return err; ++} ++ ++int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr) ++{ ++ int err, sz; ++ struct au_branch **brp; ++ ++ AuRwMustWriteLock(&sbinfo->si_rwsem); ++ ++ err = -ENOMEM; ++ sz = sizeof(*brp) * (sbinfo->si_bend + 1); ++ if (unlikely(!sz)) ++ sz = sizeof(*brp); ++ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS); ++ if (brp) { ++ sbinfo->si_branch = brp; ++ err = 0; ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++unsigned int au_sigen_inc(struct super_block *sb) ++{ ++ unsigned int gen; ++ ++ SiMustWriteLock(sb); ++ ++ gen = ++au_sbi(sb)->si_generation; ++ au_update_digen(sb->s_root); ++ au_update_iigen(sb->s_root->d_inode); ++ sb->s_root->d_inode->i_version++; ++ return gen; ++} ++ ++aufs_bindex_t au_new_br_id(struct super_block *sb) ++{ ++ aufs_bindex_t br_id; ++ int i; ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ for (i = 0; i <= AUFS_BRANCH_MAX; i++) { ++ br_id = ++sbinfo->si_last_br_id; ++ if (br_id && au_br_index(sb, br_id) < 0) ++ return br_id; ++ } ++ ++ return -1; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* dentry and super_block lock. call at entry point */ ++void aufs_read_lock(struct dentry *dentry, int flags) ++{ ++ si_read_lock(dentry->d_sb, flags); ++ if (au_ftest_lock(flags, DW)) ++ di_write_lock_child(dentry); ++ else ++ di_read_lock_child(dentry, flags); ++} ++ ++void aufs_read_unlock(struct dentry *dentry, int flags) ++{ ++ if (au_ftest_lock(flags, DW)) ++ di_write_unlock(dentry); ++ else ++ di_read_unlock(dentry, flags); ++ si_read_unlock(dentry->d_sb); ++} ++ ++void aufs_write_lock(struct dentry *dentry) ++{ ++ si_write_lock(dentry->d_sb); ++ di_write_lock_child(dentry); ++} ++ ++void aufs_write_unlock(struct dentry *dentry) ++{ ++ di_write_unlock(dentry); ++ si_write_unlock(dentry->d_sb); ++} ++ ++void aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags) ++{ ++ si_read_lock(d1->d_sb, flags); ++ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR)); ++} ++ ++void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2) ++{ ++ di_write_unlock2(d1, d2); ++ si_read_unlock(d1->d_sb); ++} +diff --git a/fs/aufs/spl.h b/fs/aufs/spl.h +new file mode 100644 +index 0000000..bcbbd9a +--- /dev/null ++++ b/fs/aufs/spl.h +@@ -0,0 +1,57 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * simple list protected by a spinlock ++ */ ++ ++#ifndef __AUFS_SPL_H__ ++#define __AUFS_SPL_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++ ++struct au_splhead { ++ spinlock_t spin; ++ struct list_head head; ++}; ++ ++static inline void au_spl_init(struct au_splhead *spl) ++{ ++ spin_lock_init(&spl->spin); ++ INIT_LIST_HEAD(&spl->head); ++} ++ ++static inline void au_spl_add(struct list_head *list, struct au_splhead *spl) ++{ ++ spin_lock(&spl->spin); ++ list_add(list, &spl->head); ++ spin_unlock(&spl->spin); ++} ++ ++static inline void au_spl_del(struct list_head *list, struct au_splhead *spl) ++{ ++ spin_lock(&spl->spin); ++ list_del(list); ++ spin_unlock(&spl->spin); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_SPL_H__ */ +diff --git a/fs/aufs/super.c b/fs/aufs/super.c +new file mode 100644 +index 0000000..f5ee1fc +--- /dev/null ++++ b/fs/aufs/super.c +@@ -0,0 +1,874 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * mount and super_block operations ++ */ ++ ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++/* ++ * super_operations ++ */ ++static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused) ++{ ++ struct au_icntnr *c; ++ ++ c = au_cache_alloc_icntnr(); ++ if (c) { ++ inode_init_once(&c->vfs_inode); ++ c->vfs_inode.i_version = 1; /* sigen(sb); */ ++ c->iinfo.ii_hinode = NULL; ++ return &c->vfs_inode; ++ } ++ return NULL; ++} ++ ++static void aufs_destroy_inode(struct inode *inode) ++{ ++ au_iinfo_fin(inode); ++ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode)); ++} ++ ++struct inode *au_iget_locked(struct super_block *sb, ino_t ino) ++{ ++ struct inode *inode; ++ int err; ++ ++ inode = iget_locked(sb, ino); ++ if (unlikely(!inode)) { ++ inode = ERR_PTR(-ENOMEM); ++ goto out; ++ } ++ if (!(inode->i_state & I_NEW)) ++ goto out; ++ ++ err = au_xigen_new(inode); ++ if (!err) ++ err = au_iinfo_init(inode); ++ if (!err) ++ inode->i_version++; ++ else { ++ iget_failed(inode); ++ inode = ERR_PTR(err); ++ } ++ ++ out: ++ /* never return NULL */ ++ AuDebugOn(!inode); ++ AuTraceErrPtr(inode); ++ return inode; ++} ++ ++/* lock free root dinfo */ ++static int au_show_brs(struct seq_file *seq, struct super_block *sb) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ struct path path; ++ struct au_hdentry *hd; ++ struct au_branch *br; ++ ++ err = 0; ++ bend = au_sbend(sb); ++ hd = au_di(sb->s_root)->di_hdentry; ++ for (bindex = 0; !err && bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ path.mnt = br->br_mnt; ++ path.dentry = hd[bindex].hd_dentry; ++ err = au_seq_path(seq, &path); ++ if (err > 0) ++ err = seq_printf(seq, "=%s", ++ au_optstr_br_perm(br->br_perm)); ++ if (!err && bindex != bend) ++ err = seq_putc(seq, ':'); ++ } ++ ++ return err; ++} ++ ++static void au_show_wbr_create(struct seq_file *m, int v, ++ struct au_sbinfo *sbinfo) ++{ ++ const char *pat; ++ ++ AuRwMustAnyLock(&sbinfo->si_rwsem); ++ ++ seq_printf(m, ",create="); ++ pat = au_optstr_wbr_create(v); ++ switch (v) { ++ case AuWbrCreate_TDP: ++ case AuWbrCreate_RR: ++ case AuWbrCreate_MFS: ++ case AuWbrCreate_PMFS: ++ seq_printf(m, pat); ++ break; ++ case AuWbrCreate_MFSV: ++ seq_printf(m, /*pat*/"mfs:%lu", ++ sbinfo->si_wbr_mfs.mfs_expire / HZ); ++ break; ++ case AuWbrCreate_PMFSV: ++ seq_printf(m, /*pat*/"pmfs:%lu", ++ sbinfo->si_wbr_mfs.mfs_expire / HZ); ++ break; ++ case AuWbrCreate_MFSRR: ++ seq_printf(m, /*pat*/"mfsrr:%llu", ++ sbinfo->si_wbr_mfs.mfsrr_watermark); ++ break; ++ case AuWbrCreate_MFSRRV: ++ seq_printf(m, /*pat*/"mfsrr:%llu:%lu", ++ sbinfo->si_wbr_mfs.mfsrr_watermark, ++ sbinfo->si_wbr_mfs.mfs_expire / HZ); ++ break; ++ } ++} ++ ++static int au_show_xino(struct seq_file *seq, struct vfsmount *mnt) ++{ ++#ifdef CONFIG_SYSFS ++ return 0; ++#else ++ int err; ++ const int len = sizeof(AUFS_XINO_FNAME) - 1; ++ aufs_bindex_t bindex, brid; ++ struct super_block *sb; ++ struct qstr *name; ++ struct file *f; ++ struct dentry *d, *h_root; ++ ++ AuRwMustAnyLock(&sbinfo->si_rwsem); ++ ++ err = 0; ++ sb = mnt->mnt_sb; ++ f = au_sbi(sb)->si_xib; ++ if (!f) ++ goto out; ++ ++ /* stop printing the default xino path on the first writable branch */ ++ h_root = NULL; ++ brid = au_xino_brid(sb); ++ if (brid >= 0) { ++ bindex = au_br_index(sb, brid); ++ h_root = au_di(sb->s_root)->di_hdentry[0 + bindex].hd_dentry; ++ } ++ d = f->f_dentry; ++ name = &d->d_name; ++ /* safe ->d_parent because the file is unlinked */ ++ if (d->d_parent == h_root ++ && name->len == len ++ && !memcmp(name->name, AUFS_XINO_FNAME, len)) ++ goto out; ++ ++ seq_puts(seq, ",xino="); ++ err = au_xino_path(seq, f); ++ ++ out: ++ return err; ++#endif ++} ++ ++/* seq_file will re-call me in case of too long string */ ++static int aufs_show_options(struct seq_file *m, struct vfsmount *mnt) ++{ ++ int err, n; ++ unsigned int mnt_flags, v; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ ++#define AuBool(name, str) do { \ ++ v = au_opt_test(mnt_flags, name); \ ++ if (v != au_opt_test(AuOpt_Def, name)) \ ++ seq_printf(m, ",%s" #str, v ? "" : "no"); \ ++} while (0) ++ ++#define AuStr(name, str) do { \ ++ v = mnt_flags & AuOptMask_##name; \ ++ if (v != (AuOpt_Def & AuOptMask_##name)) \ ++ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \ ++} while (0) ++ ++#define AuUInt(name, str, val) do { \ ++ if (val != AUFS_##name##_DEF) \ ++ seq_printf(m, "," #str "=%u", val); \ ++} while (0) ++ ++ /* lock free root dinfo */ ++ sb = mnt->mnt_sb; ++ si_noflush_read_lock(sb); ++ sbinfo = au_sbi(sb); ++ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo)); ++ ++ mnt_flags = au_mntflags(sb); ++ if (au_opt_test(mnt_flags, XINO)) { ++ err = au_show_xino(m, mnt); ++ if (unlikely(err)) ++ goto out; ++ } else ++ seq_puts(m, ",noxino"); ++ ++ AuBool(TRUNC_XINO, trunc_xino); ++ AuStr(UDBA, udba); ++ AuBool(SHWH, shwh); ++ AuBool(PLINK, plink); ++ /* AuBool(DIRPERM1, dirperm1); */ ++ /* AuBool(REFROF, refrof); */ ++ ++ v = sbinfo->si_wbr_create; ++ if (v != AuWbrCreate_Def) ++ au_show_wbr_create(m, v, sbinfo); ++ ++ v = sbinfo->si_wbr_copyup; ++ if (v != AuWbrCopyup_Def) ++ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v)); ++ ++ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ); ++ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ)) ++ seq_printf(m, ",diropq=%c", v ? 'a' : 'w'); ++ ++ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh); ++ ++ n = sbinfo->si_rdcache / HZ; ++ AuUInt(RDCACHE, rdcache, n); ++ ++ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk); ++ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash); ++ ++ AuBool(SUM, sum); ++ /* AuBool(SUM_W, wsum); */ ++ AuBool(WARN_PERM, warn_perm); ++ AuBool(VERBOSE, verbose); ++ ++ out: ++ /* be sure to print "br:" last */ ++ if (!sysaufs_brs) { ++ seq_puts(m, ",br:"); ++ au_show_brs(m, sb); ++ } ++ si_read_unlock(sb); ++ return 0; ++ ++#undef Deleted ++#undef AuBool ++#undef AuStr ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* sum mode which returns the summation for statfs(2) */ ++ ++static u64 au_add_till_max(u64 a, u64 b) ++{ ++ u64 old; ++ ++ old = a; ++ a += b; ++ if (old < a) ++ return a; ++ return ULLONG_MAX; ++} ++ ++static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf) ++{ ++ int err; ++ u64 blocks, bfree, bavail, files, ffree; ++ aufs_bindex_t bend, bindex, i; ++ unsigned char shared; ++ struct vfsmount *h_mnt; ++ struct super_block *h_sb; ++ ++ blocks = 0; ++ bfree = 0; ++ bavail = 0; ++ files = 0; ++ ffree = 0; ++ ++ err = 0; ++ bend = au_sbend(sb); ++ for (bindex = bend; bindex >= 0; bindex--) { ++ h_mnt = au_sbr_mnt(sb, bindex); ++ h_sb = h_mnt->mnt_sb; ++ shared = 0; ++ for (i = bindex + 1; !shared && i <= bend; i++) ++ shared = (au_sbr_sb(sb, i) == h_sb); ++ if (shared) ++ continue; ++ ++ /* sb->s_root for NFS is unreliable */ ++ err = vfs_statfs(h_mnt->mnt_root, buf); ++ if (unlikely(err)) ++ goto out; ++ ++ blocks = au_add_till_max(blocks, buf->f_blocks); ++ bfree = au_add_till_max(bfree, buf->f_bfree); ++ bavail = au_add_till_max(bavail, buf->f_bavail); ++ files = au_add_till_max(files, buf->f_files); ++ ffree = au_add_till_max(ffree, buf->f_ffree); ++ } ++ ++ buf->f_blocks = blocks; ++ buf->f_bfree = bfree; ++ buf->f_bavail = bavail; ++ buf->f_files = files; ++ buf->f_ffree = ffree; ++ ++ out: ++ return err; ++} ++ ++static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf) ++{ ++ int err; ++ struct super_block *sb; ++ ++ /* lock free root dinfo */ ++ sb = dentry->d_sb; ++ si_noflush_read_lock(sb); ++ if (!au_opt_test(au_mntflags(sb), SUM)) ++ /* sb->s_root for NFS is unreliable */ ++ err = vfs_statfs(au_sbr_mnt(sb, 0)->mnt_root, buf); ++ else ++ err = au_statfs_sum(sb, buf); ++ si_read_unlock(sb); ++ ++ if (!err) { ++ buf->f_type = AUFS_SUPER_MAGIC; ++ buf->f_namelen -= AUFS_WH_PFX_LEN; ++ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid)); ++ } ++ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */ ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* try flushing the lower fs at aufs remount/unmount time */ ++ ++static void au_fsync_br(struct super_block *sb) ++{ ++ aufs_bindex_t bend, bindex; ++ int brperm; ++ struct au_branch *br; ++ struct super_block *h_sb; ++ ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex < bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ brperm = br->br_perm; ++ if (brperm == AuBrPerm_RR || brperm == AuBrPerm_RRWH) ++ continue; ++ h_sb = br->br_mnt->mnt_sb; ++ if (bdev_read_only(h_sb->s_bdev)) ++ continue; ++ ++ lockdep_off(); ++ down_write(&h_sb->s_umount); ++ shrink_dcache_sb(h_sb); ++ fsync_super(h_sb); ++ up_write(&h_sb->s_umount); ++ lockdep_on(); ++ } ++} ++ ++/* ++ * this IS NOT for super_operations. ++ * I guess it will be reverted someday. ++ */ ++static void aufs_umount_begin(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ sbinfo = au_sbi(sb); ++ if (!sbinfo) ++ return; ++ ++ si_write_lock(sb); ++ au_fsync_br(sb); ++ if (au_opt_test(au_mntflags(sb), PLINK)) ++ au_plink_put(sb); ++ if (sbinfo->si_wbr_create_ops->fin) ++ sbinfo->si_wbr_create_ops->fin(sb); ++ si_write_unlock(sb); ++} ++ ++/* final actions when unmounting a file system */ ++static void aufs_put_super(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ sbinfo = au_sbi(sb); ++ if (!sbinfo) ++ return; ++ ++ aufs_umount_begin(sb); ++ dbgaufs_si_fin(sbinfo); ++ kobject_put(&sbinfo->si_kobj); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * refresh dentry and inode at remount time. ++ */ ++static int do_refresh(struct dentry *dentry, mode_t type, ++ unsigned int dir_flags) ++{ ++ int err; ++ struct dentry *parent; ++ ++ di_write_lock_child(dentry); ++ parent = dget_parent(dentry); ++ di_read_lock_parent(parent, AuLock_IR); ++ ++ /* returns the number of positive dentries */ ++ err = au_refresh_hdentry(dentry, type); ++ if (err >= 0) { ++ struct inode *inode = dentry->d_inode; ++ err = au_refresh_hinode(inode, dentry); ++ if (!err && type == S_IFDIR) ++ au_reset_hinotify(inode, dir_flags); ++ } ++ if (unlikely(err)) ++ AuErr("unrecoverable error %d, %.*s\n", err, AuDLNPair(dentry)); ++ ++ di_read_unlock(parent, AuLock_IR); ++ dput(parent); ++ di_write_unlock(dentry); ++ ++ return err; ++} ++ ++static int test_dir(struct dentry *dentry, void *arg __maybe_unused) ++{ ++ return S_ISDIR(dentry->d_inode->i_mode); ++} ++ ++/* gave up consolidating with refresh_nondir() */ ++static int refresh_dir(struct dentry *root, unsigned int sigen) ++{ ++ int err, i, j, ndentry, e; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry **dentries; ++ struct inode *inode; ++ const unsigned int flags = au_hi_flags(root->d_inode, /*isdir*/1); ++ ++ err = 0; ++ list_for_each_entry(inode, &root->d_sb->s_inodes, i_sb_list) ++ if (S_ISDIR(inode->i_mode) && au_iigen(inode) != sigen) { ++ ii_write_lock_child(inode); ++ e = au_refresh_hinode_self(inode, /*do_attr*/1); ++ ii_write_unlock(inode); ++ if (unlikely(e)) { ++ AuDbg("e %d, i%lu\n", e, inode->i_ino); ++ if (!err) ++ err = e; ++ /* go on even if err */ ++ } ++ } ++ ++ e = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(e)) { ++ if (!err) ++ err = e; ++ goto out; ++ } ++ e = au_dcsub_pages(&dpages, root, test_dir, NULL); ++ if (unlikely(e)) { ++ if (!err) ++ err = e; ++ goto out_dpages; ++ } ++ ++ for (i = 0; !e && i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ dentries = dpage->dentries; ++ ndentry = dpage->ndentry; ++ for (j = 0; !e && j < ndentry; j++) { ++ struct dentry *d; ++ ++ d = dentries[j]; ++ au_dbg_verify_dir_parent(d, sigen); ++ if (au_digen(d) != sigen) { ++ e = do_refresh(d, S_IFDIR, flags); ++ if (unlikely(e && !err)) ++ err = e; ++ /* break on err */ ++ } ++ } ++ } ++ ++ out_dpages: ++ au_dpages_free(&dpages); ++ out: ++ return err; ++} ++ ++static int test_nondir(struct dentry *dentry, void *arg __maybe_unused) ++{ ++ return !S_ISDIR(dentry->d_inode->i_mode); ++} ++ ++static int refresh_nondir(struct dentry *root, unsigned int sigen, ++ int do_dentry) ++{ ++ int err, i, j, ndentry, e; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry **dentries; ++ struct inode *inode; ++ ++ err = 0; ++ list_for_each_entry(inode, &root->d_sb->s_inodes, i_sb_list) ++ if (!S_ISDIR(inode->i_mode) && au_iigen(inode) != sigen) { ++ ii_write_lock_child(inode); ++ e = au_refresh_hinode_self(inode, /*do_attr*/1); ++ ii_write_unlock(inode); ++ if (unlikely(e)) { ++ AuDbg("e %d, i%lu\n", e, inode->i_ino); ++ if (!err) ++ err = e; ++ /* go on even if err */ ++ } ++ } ++ ++ if (!do_dentry) ++ goto out; ++ ++ e = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(e)) { ++ if (!err) ++ err = e; ++ goto out; ++ } ++ e = au_dcsub_pages(&dpages, root, test_nondir, NULL); ++ if (unlikely(e)) { ++ if (!err) ++ err = e; ++ goto out_dpages; ++ } ++ ++ for (i = 0; i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ dentries = dpage->dentries; ++ ndentry = dpage->ndentry; ++ for (j = 0; j < ndentry; j++) { ++ struct dentry *d; ++ ++ d = dentries[j]; ++ au_dbg_verify_nondir_parent(d, sigen); ++ inode = d->d_inode; ++ if (inode && au_digen(d) != sigen) { ++ e = do_refresh(d, inode->i_mode & S_IFMT, ++ /*dir_flags*/0); ++ if (unlikely(e && !err)) ++ err = e; ++ /* go on even err */ ++ } ++ } ++ } ++ ++ out_dpages: ++ au_dpages_free(&dpages); ++ out: ++ return err; ++} ++ ++static void au_remount_refresh(struct super_block *sb, unsigned int flags) ++{ ++ int err; ++ unsigned int sigen; ++ struct au_sbinfo *sbinfo; ++ struct dentry *root; ++ struct inode *inode; ++ ++ au_sigen_inc(sb); ++ sigen = au_sigen(sb); ++ sbinfo = au_sbi(sb); ++ au_fclr_si(sbinfo, FAILED_REFRESH_DIRS); ++ ++ root = sb->s_root; ++ DiMustNoWaiters(root); ++ inode = root->d_inode; ++ IiMustNoWaiters(inode); ++ au_reset_hinotify(inode, au_hi_flags(inode, /*isdir*/1)); ++ di_write_unlock(root); ++ ++ err = refresh_dir(root, sigen); ++ if (unlikely(err)) { ++ au_fset_si(sbinfo, FAILED_REFRESH_DIRS); ++ AuWarn("Refreshing directories failed, ignored (%d)\n", err); ++ } ++ ++ if (au_ftest_opts(flags, REFRESH_NONDIR)) { ++ err = refresh_nondir(root, sigen, !err); ++ if (unlikely(err)) ++ AuWarn("Refreshing non-directories failed, ignored" ++ "(%d)\n", err); ++ } ++ ++ /* aufs_write_lock() calls ..._child() */ ++ di_write_lock_child(root); ++ au_cpup_attr_all(root->d_inode, /*force*/1); ++} ++ ++/* stop extra interpretation of errno in mount(8), and strange error messages */ ++static int cvt_err(int err) ++{ ++ AuTraceErr(err); ++ ++ switch (err) { ++ case -ENOENT: ++ case -ENOTDIR: ++ case -EEXIST: ++ case -EIO: ++ err = -EINVAL; ++ } ++ return err; ++} ++ ++static int aufs_remount_fs(struct super_block *sb, int *flags, char *data) ++{ ++ int err; ++ struct au_opts opts; ++ struct dentry *root; ++ struct inode *inode; ++ struct au_sbinfo *sbinfo; ++ ++ err = 0; ++ root = sb->s_root; ++ if (!data || !*data) { ++ aufs_write_lock(root); ++ err = au_opts_verify(sb, *flags, /*pending*/0); ++ if (!err) ++ au_fsync_br(sb); ++ aufs_write_unlock(root); ++ goto out; ++ } ++ ++ err = -ENOMEM; ++ memset(&opts, 0, sizeof(opts)); ++ opts.opt = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!opts.opt)) ++ goto out; ++ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); ++ opts.flags = AuOpts_REMOUNT; ++ opts.sb_flags = *flags; ++ ++ /* parse it before aufs lock */ ++ err = au_opts_parse(sb, data, &opts); ++ if (unlikely(err)) ++ goto out_opts; ++ ++ sbinfo = au_sbi(sb); ++ inode = root->d_inode; ++ mutex_lock(&inode->i_mutex); ++ aufs_write_lock(root); ++ au_fsync_br(sb); ++ ++ /* au_opts_remount() may return an error */ ++ err = au_opts_remount(sb, &opts); ++ au_opts_free(&opts); ++ ++ if (au_ftest_opts(opts.flags, REFRESH_DIR) ++ || au_ftest_opts(opts.flags, REFRESH_NONDIR)) ++ au_remount_refresh(sb, opts.flags); ++ ++ aufs_write_unlock(root); ++ mutex_unlock(&inode->i_mutex); ++ ++ out_opts: ++ free_page((unsigned long)opts.opt); ++ out: ++ err = cvt_err(err); ++ AuTraceErr(err); ++ return err; ++} ++ ++static struct super_operations aufs_sop = { ++ .alloc_inode = aufs_alloc_inode, ++ .destroy_inode = aufs_destroy_inode, ++ .drop_inode = generic_delete_inode, ++ .show_options = aufs_show_options, ++ .statfs = aufs_statfs, ++ .put_super = aufs_put_super, ++ .remount_fs = aufs_remount_fs ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int alloc_root(struct super_block *sb) ++{ ++ int err; ++ struct inode *inode; ++ struct dentry *root; ++ ++ err = -ENOMEM; ++ inode = au_iget_locked(sb, AUFS_ROOT_INO); ++ err = PTR_ERR(inode); ++ if (IS_ERR(inode)) ++ goto out; ++ ++ inode->i_op = &aufs_dir_iop; ++ inode->i_fop = &aufs_dir_fop; ++ inode->i_mode = S_IFDIR; ++ inode->i_nlink = 2; ++ unlock_new_inode(inode); ++ ++ root = d_alloc_root(inode); ++ if (unlikely(!root)) ++ goto out_iput; ++ err = PTR_ERR(root); ++ if (IS_ERR(root)) ++ goto out_iput; ++ ++ err = au_alloc_dinfo(root); ++ if (!err) { ++ sb->s_root = root; ++ return 0; /* success */ ++ } ++ dput(root); ++ goto out; /* do not iput */ ++ ++ out_iput: ++ iget_failed(inode); ++ iput(inode); ++ out: ++ return err; ++ ++} ++ ++static int aufs_fill_super(struct super_block *sb, void *raw_data, ++ int silent __maybe_unused) ++{ ++ int err; ++ struct au_opts opts; ++ struct dentry *root; ++ struct inode *inode; ++ char *arg = raw_data; ++ ++ if (unlikely(!arg || !*arg)) { ++ err = -EINVAL; ++ AuErr("no arg\n"); ++ goto out; ++ } ++ ++ err = -ENOMEM; ++ memset(&opts, 0, sizeof(opts)); ++ opts.opt = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!opts.opt)) ++ goto out; ++ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); ++ opts.sb_flags = sb->s_flags; ++ ++ err = au_si_alloc(sb); ++ if (unlikely(err)) ++ goto out_opts; ++ ++ /* all timestamps always follow the ones on the branch */ ++ sb->s_flags |= MS_NOATIME | MS_NODIRATIME; ++ sb->s_op = &aufs_sop; ++ sb->s_magic = AUFS_SUPER_MAGIC; ++ sb->s_maxbytes = 0; ++ au_export_init(sb); ++ ++ err = alloc_root(sb); ++ if (unlikely(err)) { ++ si_write_unlock(sb); ++ goto out_info; ++ } ++ root = sb->s_root; ++ inode = root->d_inode; ++ ++ /* ++ * actually we can parse options regardless aufs lock here. ++ * but at remount time, parsing must be done before aufs lock. ++ * so we follow the same rule. ++ */ ++ ii_write_lock_parent(inode); ++ aufs_write_unlock(root); ++ err = au_opts_parse(sb, arg, &opts); ++ if (unlikely(err)) ++ goto out_root; ++ ++ /* lock vfs_inode first, then aufs. */ ++ mutex_lock(&inode->i_mutex); ++ inode->i_op = &aufs_dir_iop; ++ inode->i_fop = &aufs_dir_fop; ++ aufs_write_lock(root); ++ err = au_opts_mount(sb, &opts); ++ au_opts_free(&opts); ++ if (unlikely(err)) ++ goto out_unlock; ++ aufs_write_unlock(root); ++ mutex_unlock(&inode->i_mutex); ++ goto out_opts; /* success */ ++ ++ out_unlock: ++ aufs_write_unlock(root); ++ mutex_unlock(&inode->i_mutex); ++ out_root: ++ dput(root); ++ sb->s_root = NULL; ++ out_info: ++ kobject_put(&au_sbi(sb)->si_kobj); ++ sb->s_fs_info = NULL; ++ out_opts: ++ free_page((unsigned long)opts.opt); ++ out: ++ AuTraceErr(err); ++ err = cvt_err(err); ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int aufs_get_sb(struct file_system_type *fs_type, int flags, ++ const char *dev_name __maybe_unused, void *raw_data, ++ struct vfsmount *mnt) ++{ ++ int err; ++ struct super_block *sb; ++ ++ /* all timestamps always follow the ones on the branch */ ++ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */ ++ err = get_sb_nodev(fs_type, flags, raw_data, aufs_fill_super, mnt); ++ if (!err) { ++ sb = mnt->mnt_sb; ++ si_write_lock(sb); ++ sysaufs_brs_add(sb, 0); ++ si_write_unlock(sb); ++ } ++ return err; ++} ++ ++struct file_system_type aufs_fs_type = { ++ .name = AUFS_FSTYPE, ++ .fs_flags = ++ FS_RENAME_DOES_D_MOVE /* a race between rename and others */ ++ | FS_REVAL_DOT, /* for NFS branch and udba */ ++ .get_sb = aufs_get_sb, ++ .kill_sb = generic_shutdown_super, ++ /* no need to __module_get() and module_put(). */ ++ .owner = THIS_MODULE, ++}; +diff --git a/fs/aufs/super.h b/fs/aufs/super.h +new file mode 100644 +index 0000000..850cddb +--- /dev/null ++++ b/fs/aufs/super.h +@@ -0,0 +1,384 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * super_block operations ++ */ ++ ++#ifndef __AUFS_SUPER_H__ ++#define __AUFS_SUPER_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include "rwsem.h" ++#include "spl.h" ++#include "wkq.h" ++ ++typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *); ++typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t, ++ loff_t *); ++ ++/* policies to select one among multiple writable branches */ ++struct au_wbr_copyup_operations { ++ int (*copyup)(struct dentry *dentry); ++}; ++ ++struct au_wbr_create_operations { ++ int (*create)(struct dentry *dentry, int isdir); ++ int (*init)(struct super_block *sb); ++ int (*fin)(struct super_block *sb); ++}; ++ ++struct au_wbr_mfs { ++ struct mutex mfs_lock; /* protect this structure */ ++ unsigned long mfs_jiffy; ++ unsigned long mfs_expire; ++ aufs_bindex_t mfs_bindex; ++ ++ unsigned long long mfsrr_bytes; ++ unsigned long long mfsrr_watermark; ++}; ++ ++struct au_branch; ++struct au_sbinfo { ++ /* nowait tasks in the system-wide workqueue */ ++ struct au_nowait_tasks si_nowait; ++ ++ struct au_rwsem si_rwsem; ++ ++ /* branch management */ ++ unsigned int si_generation; ++ ++ /* see above flags */ ++ unsigned char au_si_status; ++ ++ aufs_bindex_t si_bend; ++ aufs_bindex_t si_last_br_id; ++ struct au_branch **si_branch; ++ ++ /* policy to select a writable branch */ ++ unsigned char si_wbr_copyup; ++ unsigned char si_wbr_create; ++ struct au_wbr_copyup_operations *si_wbr_copyup_ops; ++ struct au_wbr_create_operations *si_wbr_create_ops; ++ ++ /* round robin */ ++ atomic_t si_wbr_rr_next; ++ ++ /* most free space */ ++ struct au_wbr_mfs si_wbr_mfs; ++ ++ /* mount flags */ ++ /* include/asm-ia64/siginfo.h defines a macro named si_flags */ ++ unsigned int si_mntflags; ++ ++ /* external inode number (bitmap and translation table) */ ++ au_readf_t si_xread; ++ au_writef_t si_xwrite; ++ struct file *si_xib; ++ struct mutex si_xib_mtx; /* protect xib members */ ++ unsigned long *si_xib_buf; ++ unsigned long si_xib_last_pindex; ++ int si_xib_next_bit; ++ aufs_bindex_t si_xino_brid; ++ /* reserved for future use */ ++ /* unsigned long long si_xib_limit; */ /* Max xib file size */ ++ ++#ifdef CONFIG_AUFS_EXPORT ++ /* i_generation */ ++ struct file *si_xigen; ++ atomic_t si_xigen_next; ++#endif ++ ++ /* vdir parameters */ ++ unsigned long si_rdcache; /* max cache time in HZ */ ++ unsigned int si_rdblk; /* deblk size */ ++ unsigned int si_rdhash; /* hash size */ ++ ++ /* ++ * If the number of whiteouts are larger than si_dirwh, leave all of ++ * them after au_whtmp_ren to reduce the cost of rmdir(2). ++ * future fsck.aufs or kernel thread will remove them later. ++ * Otherwise, remove all whiteouts and the dir in rmdir(2). ++ */ ++ unsigned int si_dirwh; ++ ++ /* ++ * rename(2) a directory with all children. ++ */ ++ /* reserved for future use */ ++ /* int si_rendir; */ ++ ++ /* pseudo_link list */ ++ struct au_splhead si_plink; ++ wait_queue_head_t si_plink_wq; ++ ++ /* ++ * sysfs and lifetime management. ++ * this is not a small structure and it may be a waste of memory in case ++ * of sysfs is disabled, particulary when many aufs-es are mounted. ++ * but using sysfs is majority. ++ */ ++ struct kobject si_kobj; ++#ifdef CONFIG_DEBUG_FS ++ struct dentry *si_dbgaufs, *si_dbgaufs_xib; ++#ifdef CONFIG_AUFS_EXPORT ++ struct dentry *si_dbgaufs_xigen; ++#endif ++#endif ++ ++ /* dirty, necessary for unmounting, sysfs and sysrq */ ++ struct super_block *si_sb; ++}; ++ ++/* sbinfo status flags */ ++/* ++ * set true when refresh_dirs() failed at remount time. ++ * then try refreshing dirs at access time again. ++ * if it is false, refreshing dirs at access time is unnecesary ++ */ ++#define AuSi_FAILED_REFRESH_DIRS 1 ++#define AuSi_MAINTAIN_PLINK (1 << 1) /* ioctl */ ++static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi, ++ unsigned int flag) ++{ ++ AuRwMustAnyLock(&sbi->si_rwsem); ++ return sbi->au_si_status & flag; ++} ++#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name) ++#define au_fset_si(sbinfo, name) do { \ ++ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \ ++ (sbinfo)->au_si_status |= AuSi_##name; \ ++} while (0) ++#define au_fclr_si(sbinfo, name) do { \ ++ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \ ++ (sbinfo)->au_si_status &= ~AuSi_##name; \ ++} while (0) ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* policy to select one among writable branches */ ++#define AuWbrCopyup(sbinfo, args...) \ ++ ((sbinfo)->si_wbr_copyup_ops->copyup(args)) ++#define AuWbrCreate(sbinfo, args...) \ ++ ((sbinfo)->si_wbr_create_ops->create(args)) ++ ++/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */ ++#define AuLock_DW 1 /* write-lock dentry */ ++#define AuLock_IR (1 << 1) /* read-lock inode */ ++#define AuLock_IW (1 << 2) /* write-lock inode */ ++#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */ ++#define AuLock_DIR (1 << 4) /* target is a dir */ ++#define au_ftest_lock(flags, name) ((flags) & AuLock_##name) ++#define au_fset_lock(flags, name) { (flags) |= AuLock_##name; } ++#define au_fclr_lock(flags, name) { (flags) &= ~AuLock_##name; } ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* super.c */ ++extern struct file_system_type aufs_fs_type; ++struct inode *au_iget_locked(struct super_block *sb, ino_t ino); ++ ++/* sbinfo.c */ ++void au_si_free(struct kobject *kobj); ++int au_si_alloc(struct super_block *sb); ++int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr); ++ ++unsigned int au_sigen_inc(struct super_block *sb); ++aufs_bindex_t au_new_br_id(struct super_block *sb); ++ ++void aufs_read_lock(struct dentry *dentry, int flags); ++void aufs_read_unlock(struct dentry *dentry, int flags); ++void aufs_write_lock(struct dentry *dentry); ++void aufs_write_unlock(struct dentry *dentry); ++void aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int isdir); ++void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2); ++ ++/* wbr_policy.c */ ++extern struct au_wbr_copyup_operations au_wbr_copyup_ops[]; ++extern struct au_wbr_create_operations au_wbr_create_ops[]; ++int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct au_sbinfo *au_sbi(struct super_block *sb) ++{ ++ return sb->s_fs_info; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_EXPORT ++void au_export_init(struct super_block *sb); ++ ++static inline int au_test_nfsd(struct task_struct *tsk) ++{ ++ return !tsk->mm && !strcmp(tsk->comm, "nfsd"); ++} ++ ++int au_xigen_inc(struct inode *inode); ++int au_xigen_new(struct inode *inode); ++int au_xigen_set(struct super_block *sb, struct file *base); ++void au_xigen_clr(struct super_block *sb); ++ ++static inline int au_busy_or_stale(void) ++{ ++ if (!au_test_nfsd(current)) ++ return -EBUSY; ++ return -ESTALE; ++} ++#else ++static inline void au_export_init(struct super_block *sb) ++{ ++ /* nothing */ ++} ++ ++static inline int au_test_nfsd(struct task_struct *tsk) ++{ ++ return 0; ++} ++ ++static inline int au_xigen_inc(struct inode *inode) ++{ ++ return 0; ++} ++ ++static inline int au_xigen_new(struct inode *inode) ++{ ++ return 0; ++} ++ ++static inline int au_xigen_set(struct super_block *sb, struct file *base) ++{ ++ return 0; ++} ++ ++static inline void au_xigen_clr(struct super_block *sb) ++{ ++ /* empty */ ++} ++ ++static inline int au_busy_or_stale(void) ++{ ++ return -EBUSY; ++} ++#endif /* CONFIG_AUFS_EXPORT */ ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo) ++{ ++ /* ++ * This function is a dynamic '__init' fucntion actually, ++ * so the tiny check for si_rwsem is unnecessary. ++ */ ++ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ ++#ifdef CONFIG_DEBUG_FS ++ sbinfo->si_dbgaufs = NULL; ++ sbinfo->si_dbgaufs_xib = NULL; ++#ifdef CONFIG_AUFS_EXPORT ++ sbinfo->si_dbgaufs_xigen = NULL; ++#endif ++#endif ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* lock superblock. mainly for entry point functions */ ++/* ++ * si_noflush_read_lock, si_noflush_write_lock, ++ * si_read_unlock, si_write_unlock, si_downgrade_lock ++ */ ++AuSimpleLockRwsemFuncs(si_noflush, struct super_block *sb, ++ &au_sbi(sb)->si_rwsem); ++AuSimpleUnlockRwsemFuncs(si, struct super_block *sb, &au_sbi(sb)->si_rwsem); ++ ++#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem) ++#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem) ++#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem) ++ ++static inline void si_read_lock(struct super_block *sb, int flags) ++{ ++ if (au_ftest_lock(flags, FLUSH)) ++ au_nwt_flush(&au_sbi(sb)->si_nowait); ++ si_noflush_read_lock(sb); ++} ++ ++static inline void si_write_lock(struct super_block *sb) ++{ ++ au_nwt_flush(&au_sbi(sb)->si_nowait); ++ si_noflush_write_lock(sb); ++} ++ ++static inline int si_read_trylock(struct super_block *sb, int flags) ++{ ++ if (au_ftest_lock(flags, FLUSH)) ++ au_nwt_flush(&au_sbi(sb)->si_nowait); ++ return si_noflush_read_trylock(sb); ++} ++ ++static inline int si_write_trylock(struct super_block *sb, int flags) ++{ ++ if (au_ftest_lock(flags, FLUSH)) ++ au_nwt_flush(&au_sbi(sb)->si_nowait); ++ return si_noflush_write_trylock(sb); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline aufs_bindex_t au_sbend(struct super_block *sb) ++{ ++ SiMustAnyLock(sb); ++ return au_sbi(sb)->si_bend; ++} ++ ++static inline unsigned int au_mntflags(struct super_block *sb) ++{ ++ SiMustAnyLock(sb); ++ return au_sbi(sb)->si_mntflags; ++} ++ ++static inline unsigned int au_sigen(struct super_block *sb) ++{ ++ SiMustAnyLock(sb); ++ return au_sbi(sb)->si_generation; ++} ++ ++static inline struct au_branch *au_sbr(struct super_block *sb, ++ aufs_bindex_t bindex) ++{ ++ SiMustAnyLock(sb); ++ return au_sbi(sb)->si_branch[0 + bindex]; ++} ++ ++static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid) ++{ ++ SiMustWriteLock(sb); ++ au_sbi(sb)->si_xino_brid = brid; ++} ++ ++static inline aufs_bindex_t au_xino_brid(struct super_block *sb) ++{ ++ SiMustAnyLock(sb); ++ return au_sbi(sb)->si_xino_brid; ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_SUPER_H__ */ +diff --git a/fs/aufs/sysaufs.c b/fs/aufs/sysaufs.c +new file mode 100644 +index 0000000..b796330 +--- /dev/null ++++ b/fs/aufs/sysaufs.c +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * sysfs interface and lifetime management ++ * they are necessary regardless sysfs is disabled. ++ */ ++ ++#include ++#include ++#include ++#include "aufs.h" ++ ++unsigned long sysaufs_si_mask; ++struct kset *sysaufs_ket; ++ ++#define AuSiAttr(_name) { \ ++ .attr = { .name = __stringify(_name), .mode = 0444 }, \ ++ .show = sysaufs_si_##_name, \ ++} ++ ++static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path); ++struct attribute *sysaufs_si_attrs[] = { ++ &sysaufs_si_attr_xi_path.attr, ++ NULL, ++}; ++ ++static struct sysfs_ops au_sbi_ops = { ++ .show = sysaufs_si_show ++}; ++ ++static struct kobj_type au_sbi_ktype = { ++ .release = au_si_free, ++ .sysfs_ops = &au_sbi_ops, ++ .default_attrs = sysaufs_si_attrs ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++int sysaufs_si_init(struct au_sbinfo *sbinfo) ++{ ++ int err; ++ ++ sbinfo->si_kobj.kset = sysaufs_ket; ++ /* cf. sysaufs_name() */ ++ err = kobject_init_and_add ++ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_ket->kobj*/NULL, ++ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo)); ++ ++ dbgaufs_si_null(sbinfo); ++ if (!err) { ++ err = dbgaufs_si_init(sbinfo); ++ if (unlikely(err)) ++ kobject_put(&sbinfo->si_kobj); ++ } ++ return err; ++} ++ ++void sysaufs_fin(void) ++{ ++ dbgaufs_fin(); ++ sysfs_remove_group(&sysaufs_ket->kobj, sysaufs_attr_group); ++ kset_unregister(sysaufs_ket); ++} ++ ++int __init sysaufs_init(void) ++{ ++ int err; ++ ++ do { ++ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask)); ++ } while (!sysaufs_si_mask); ++ ++ sysaufs_ket = kset_create_and_add(AUFS_NAME, NULL, fs_kobj); ++ err = PTR_ERR(sysaufs_ket); ++ if (IS_ERR(sysaufs_ket)) ++ goto out; ++ err = sysfs_create_group(&sysaufs_ket->kobj, sysaufs_attr_group); ++ if (unlikely(err)) { ++ kset_unregister(sysaufs_ket); ++ goto out; ++ } ++ ++ err = dbgaufs_init(); ++ if (unlikely(err)) ++ sysaufs_fin(); ++ out: ++ return err; ++} +diff --git a/fs/aufs/sysaufs.h b/fs/aufs/sysaufs.h +new file mode 100644 +index 0000000..379033a +--- /dev/null ++++ b/fs/aufs/sysaufs.h +@@ -0,0 +1,120 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * sysfs interface and mount lifetime management ++ */ ++ ++#ifndef __SYSAUFS_H__ ++#define __SYSAUFS_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include "module.h" ++ ++struct super_block; ++struct au_sbinfo; ++ ++struct sysaufs_si_attr { ++ struct attribute attr; ++ int (*show)(struct seq_file *seq, struct super_block *sb); ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* sysaufs.c */ ++extern unsigned long sysaufs_si_mask; ++extern struct kset *sysaufs_ket; ++extern struct attribute *sysaufs_si_attrs[]; ++int sysaufs_si_init(struct au_sbinfo *sbinfo); ++int __init sysaufs_init(void); ++void sysaufs_fin(void); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* some people doesn't like to show a pointer in kernel */ ++static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo) ++{ ++ return sysaufs_si_mask ^ (unsigned long)sbinfo; ++} ++ ++#define SysaufsSiNamePrefix "si_" ++#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16) ++static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name) ++{ ++ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx", ++ sysaufs_si_id(sbinfo)); ++} ++ ++struct au_branch; ++#ifdef CONFIG_SYSFS ++/* sysfs.c */ ++extern struct attribute_group *sysaufs_attr_group; ++ ++int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb); ++ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr, ++ char *buf); ++ ++void sysaufs_br_init(struct au_branch *br); ++void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex); ++void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex); ++ ++#define sysaufs_brs_init() do {} while (0) ++ ++#else ++#define sysaufs_attr_group NULL ++ ++static inline ++int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb) ++{ ++ return 0; ++} ++ ++static inline ++ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr, ++ char *buf) ++{ ++ return 0; ++} ++ ++static inline void sysaufs_br_init(struct au_branch *br) ++{ ++ /* empty */ ++} ++ ++static inline void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ /* nothing */ ++} ++ ++static inline void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ /* nothing */ ++} ++ ++static inline void sysaufs_brs_init(void) ++{ ++ sysaufs_brs = 0; ++} ++ ++#endif /* CONFIG_SYSFS */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __SYSAUFS_H__ */ +diff --git a/fs/aufs/sysfs.c b/fs/aufs/sysfs.c +new file mode 100644 +index 0000000..55602fa +--- /dev/null ++++ b/fs/aufs/sysfs.c +@@ -0,0 +1,210 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * sysfs interface ++ */ ++ ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++static struct attribute *au_attr[] = { ++ NULL, /* need to NULL terminate the list of attributes */ ++}; ++ ++static struct attribute_group sysaufs_attr_group_body = { ++ .attrs = au_attr ++}; ++ ++struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body; ++ ++/* ---------------------------------------------------------------------- */ ++ ++int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb) ++{ ++ int err; ++ ++ SiMustAnyLock(sb); ++ ++ err = 0; ++ if (au_opt_test(au_mntflags(sb), XINO)) { ++ err = au_xino_path(seq, au_sbi(sb)->si_xib); ++ seq_putc(seq, '\n'); ++ } ++ return err; ++} ++ ++/* ++ * the lifetime of branch is independent from the entry under sysfs. ++ * sysfs handles the lifetime of the entry, and never call ->show() after it is ++ * unlinked. ++ */ ++static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb, ++ aufs_bindex_t bindex) ++{ ++ struct path path; ++ struct dentry *root; ++ struct au_branch *br; ++ ++ AuDbg("b%d\n", bindex); ++ ++ root = sb->s_root; ++ di_read_lock_parent(root, !AuLock_IR); ++ br = au_sbr(sb, bindex); ++ path.mnt = br->br_mnt; ++ path.dentry = au_h_dptr(root, bindex); ++ au_seq_path(seq, &path); ++ di_read_unlock(root, !AuLock_IR); ++ seq_printf(seq, "=%s\n", au_optstr_br_perm(br->br_perm)); ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct seq_file *au_seq(char *p, ssize_t len) ++{ ++ struct seq_file *seq; ++ ++ seq = kzalloc(sizeof(*seq), GFP_NOFS); ++ if (seq) { ++ /* mutex_init(&seq.lock); */ ++ seq->buf = p; ++ seq->size = len; ++ return seq; /* success */ ++ } ++ ++ seq = ERR_PTR(-ENOMEM); ++ return seq; ++} ++ ++#define SysaufsBr_PREFIX "br" ++ ++/* todo: file size may exceed PAGE_SIZE */ ++ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr, ++ char *buf) ++{ ++ ssize_t err; ++ long l; ++ aufs_bindex_t bend; ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ struct seq_file *seq; ++ char *name; ++ struct attribute **cattr; ++ ++ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); ++ sb = sbinfo->si_sb; ++ si_noflush_read_lock(sb); ++ ++ seq = au_seq(buf, PAGE_SIZE); ++ err = PTR_ERR(seq); ++ if (IS_ERR(seq)) ++ goto out; ++ ++ name = (void *)attr->name; ++ cattr = sysaufs_si_attrs; ++ while (*cattr) { ++ if (!strcmp(name, (*cattr)->name)) { ++ err = container_of(*cattr, struct sysaufs_si_attr, attr) ++ ->show(seq, sb); ++ goto out_seq; ++ } ++ cattr++; ++ } ++ ++ bend = au_sbend(sb); ++ if (!strncmp(name, SysaufsBr_PREFIX, sizeof(SysaufsBr_PREFIX) - 1)) { ++ name += sizeof(SysaufsBr_PREFIX) - 1; ++ err = strict_strtol(name, 10, &l); ++ if (!err) { ++ if (l <= bend) ++ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l); ++ else ++ err = -ENOENT; ++ } ++ goto out_seq; ++ } ++ BUG(); ++ ++ out_seq: ++ if (!err) { ++ err = seq->count; ++ /* sysfs limit */ ++ if (unlikely(err == PAGE_SIZE)) ++ err = -EFBIG; ++ } ++ kfree(seq); ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void sysaufs_br_init(struct au_branch *br) ++{ ++ br->br_attr.name = br->br_name; ++ br->br_attr.mode = S_IRUGO; ++ br->br_attr.owner = THIS_MODULE; ++} ++ ++void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ struct au_branch *br; ++ struct kobject *kobj; ++ aufs_bindex_t bend; ++ ++ dbgaufs_brs_del(sb, bindex); ++ ++ if (!sysaufs_brs) ++ return; ++ ++ kobj = &au_sbi(sb)->si_kobj; ++ bend = au_sbend(sb); ++ for (; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ sysfs_remove_file(kobj, &br->br_attr); ++ } ++} ++ ++void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ int err; ++ aufs_bindex_t bend; ++ struct kobject *kobj; ++ struct au_branch *br; ++ ++ dbgaufs_brs_add(sb, bindex); ++ ++ if (!sysaufs_brs) ++ return; ++ ++ kobj = &au_sbi(sb)->si_kobj; ++ bend = au_sbend(sb); ++ for (; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ snprintf(br->br_name, sizeof(br->br_name), SysaufsBr_PREFIX ++ "%d", bindex); ++ err = sysfs_create_file(kobj, &br->br_attr); ++ if (unlikely(err)) ++ AuWarn("failed %s under sysfs(%d)\n", br->br_name, err); ++ } ++} +diff --git a/fs/aufs/sysrq.c b/fs/aufs/sysrq.c +new file mode 100644 +index 0000000..2e7fbef +--- /dev/null ++++ b/fs/aufs/sysrq.c +@@ -0,0 +1,115 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * magic sysrq hanlder ++ */ ++ ++#include ++#include ++#include ++/* #include */ ++#include "aufs.h" ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void sysrq_sb(struct super_block *sb) ++{ ++ char *plevel; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ ++ plevel = au_plevel; ++ au_plevel = KERN_WARNING; ++ au_debug(1); ++ ++ sbinfo = au_sbi(sb); ++ pr_warning("si=%lx\n", sysaufs_si_id(sbinfo)); ++ pr_warning(AUFS_NAME ": superblock\n"); ++ au_dpri_sb(sb); ++ pr_warning(AUFS_NAME ": root dentry\n"); ++ au_dpri_dentry(sb->s_root); ++ pr_warning(AUFS_NAME ": root inode\n"); ++ au_dpri_inode(sb->s_root->d_inode); ++#if 0 ++ struct inode *i; ++ pr_warning(AUFS_NAME ": isolated inode\n"); ++ list_for_each_entry(i, &sb->s_inodes, i_sb_list) ++ if (list_empty(&i->i_dentry)) ++ au_dpri_inode(i); ++#endif ++ pr_warning(AUFS_NAME ": files\n"); ++ list_for_each_entry(file, &sb->s_files, f_u.fu_list) ++ if (!special_file(file->f_dentry->d_inode->i_mode)) ++ au_dpri_file(file); ++ ++ au_plevel = plevel; ++ au_debug(0); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* module parameter */ ++static char *aufs_sysrq_key = "a"; ++module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO); ++MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME); ++ ++static void au_sysrq(int key __maybe_unused, ++ struct tty_struct *tty __maybe_unused) ++{ ++ struct kobject *kobj; ++ struct au_sbinfo *sbinfo; ++ ++ /* spin_lock(&sysaufs_ket->list_lock); */ ++ list_for_each_entry(kobj, &sysaufs_ket->list, entry) { ++ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); ++ sysrq_sb(sbinfo->si_sb); ++ } ++ /* spin_unlock(&sysaufs_ket->list_lock); */ ++} ++ ++static struct sysrq_key_op au_sysrq_op = { ++ .handler = au_sysrq, ++ .help_msg = "Aufs", ++ .action_msg = "Aufs", ++ .enable_mask = SYSRQ_ENABLE_DUMP ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++int __init au_sysrq_init(void) ++{ ++ int err; ++ char key; ++ ++ err = -1; ++ key = *aufs_sysrq_key; ++ if ('a' <= key && key <= 'z') ++ err = register_sysrq_key(key, &au_sysrq_op); ++ if (unlikely(err)) ++ AuErr("err %d, sysrq=%c\n", err, key); ++ return err; ++} ++ ++void au_sysrq_fin(void) ++{ ++ int err; ++ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op); ++ if (unlikely(err)) ++ AuErr("err %d (ignored)\n", err); ++} +diff --git a/fs/aufs/vdir.c b/fs/aufs/vdir.c +new file mode 100644 +index 0000000..47a0d12 +--- /dev/null ++++ b/fs/aufs/vdir.c +@@ -0,0 +1,879 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * virtual or vertical directory ++ */ ++ ++#include ++#include "aufs.h" ++ ++static unsigned int calc_size(int nlen) ++{ ++ BUILD_BUG_ON(sizeof(ino_t) != sizeof(long)); ++ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t)); ++} ++ ++static int set_deblk_end(union au_vdir_deblk_p *p, ++ union au_vdir_deblk_p *deblk_end) ++{ ++ if (calc_size(0) <= deblk_end->deblk - p->deblk) { ++ p->de->de_str.len = 0; ++ /* smp_mb(); */ ++ return 0; ++ } ++ return -1; /* error */ ++} ++ ++/* returns true or false */ ++static int is_deblk_end(union au_vdir_deblk_p *p, ++ union au_vdir_deblk_p *deblk_end) ++{ ++ if (calc_size(0) <= deblk_end->deblk - p->deblk) ++ return !p->de->de_str.len; ++ return 1; ++} ++ ++static unsigned char *last_deblk(struct au_vdir *vdir) ++{ ++ return vdir->vd_deblk[vdir->vd_nblk - 1]; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* estimate the apropriate size for name hash table */ ++unsigned int au_rdhash_est(loff_t sz) ++{ ++ unsigned int n; ++ ++ n = UINT_MAX; ++ sz >>= 10; ++ if (sz < n) ++ n = sz; ++ if (sz < AUFS_RDHASH_DEF) ++ n = AUFS_RDHASH_DEF; ++ /* AuInfo("n %u\n", n); */ ++ return n; ++} ++ ++/* ++ * the allocated memory has to be freed by ++ * au_nhash_wh_free() or au_nhash_de_free(). ++ */ ++int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp) ++{ ++ struct hlist_head *head; ++ unsigned int u; ++ ++ head = kmalloc(sizeof(*nhash->nh_head) * num_hash, gfp); ++ if (head) { ++ nhash->nh_num = num_hash; ++ nhash->nh_head = head; ++ for (u = 0; u < num_hash; u++) ++ INIT_HLIST_HEAD(head++); ++ return 0; /* success */ ++ } ++ ++ return -ENOMEM; ++} ++ ++static void nhash_count(struct hlist_head *head) ++{ ++#if 0 ++ unsigned long n; ++ struct hlist_node *pos; ++ ++ n = 0; ++ hlist_for_each(pos, head) ++ n++; ++ AuInfo("%lu\n", n); ++#endif ++} ++ ++static void au_nhash_wh_do_free(struct hlist_head *head) ++{ ++ struct au_vdir_wh *tpos; ++ struct hlist_node *pos, *node; ++ ++ hlist_for_each_entry_safe(tpos, pos, node, head, wh_hash) { ++ /* hlist_del(pos); */ ++ kfree(tpos); ++ } ++} ++ ++static void au_nhash_de_do_free(struct hlist_head *head) ++{ ++ struct au_vdir_dehstr *tpos; ++ struct hlist_node *pos, *node; ++ ++ hlist_for_each_entry_safe(tpos, pos, node, head, hash) { ++ /* hlist_del(pos); */ ++ au_cache_free_dehstr(tpos); ++ } ++} ++ ++static void au_nhash_do_free(struct au_nhash *nhash, ++ void (*free)(struct hlist_head *head)) ++{ ++ unsigned int n; ++ struct hlist_head *head; ++ ++ n = nhash->nh_num; ++ if (!n) ++ return; ++ ++ head = nhash->nh_head; ++ while (n-- > 0) { ++ nhash_count(head); ++ free(head++); ++ } ++ kfree(nhash->nh_head); ++} ++ ++void au_nhash_wh_free(struct au_nhash *whlist) ++{ ++ au_nhash_do_free(whlist, au_nhash_wh_do_free); ++} ++ ++static void au_nhash_de_free(struct au_nhash *delist) ++{ ++ au_nhash_do_free(delist, au_nhash_de_do_free); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt, ++ int limit) ++{ ++ int num; ++ unsigned int u, n; ++ struct hlist_head *head; ++ struct au_vdir_wh *tpos; ++ struct hlist_node *pos; ++ ++ num = 0; ++ n = whlist->nh_num; ++ head = whlist->nh_head; ++ for (u = 0; u < n; u++, head++) ++ hlist_for_each_entry(tpos, pos, head, wh_hash) ++ if (tpos->wh_bindex == btgt && ++num > limit) ++ return 1; ++ return 0; ++} ++ ++static struct hlist_head *au_name_hash(struct au_nhash *nhash, ++ unsigned char *name, ++ unsigned int len) ++{ ++ unsigned int v; ++ /* const unsigned int magic_bit = 12; */ ++ ++ AuDebugOn(!nhash->nh_num || !nhash->nh_head); ++ ++ v = 0; ++ while (len--) ++ v += *name++; ++ /* v = hash_long(v, magic_bit); */ ++ v %= nhash->nh_num; ++ return nhash->nh_head + v; ++} ++ ++static int au_nhash_test_name(struct au_vdir_destr *str, const char *name, ++ int nlen) ++{ ++ return str->len == nlen && !memcmp(str->name, name, nlen); ++} ++ ++/* returns found or not */ ++int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen) ++{ ++ struct hlist_head *head; ++ struct au_vdir_wh *tpos; ++ struct hlist_node *pos; ++ struct au_vdir_destr *str; ++ ++ head = au_name_hash(whlist, name, nlen); ++ hlist_for_each_entry(tpos, pos, head, wh_hash) { ++ str = &tpos->wh_str; ++ AuDbg("%.*s\n", str->len, str->name); ++ if (au_nhash_test_name(str, name, nlen)) ++ return 1; ++ } ++ return 0; ++} ++ ++/* returns found(true) or not */ ++static int test_known(struct au_nhash *delist, char *name, int nlen) ++{ ++ struct hlist_head *head; ++ struct au_vdir_dehstr *tpos; ++ struct hlist_node *pos; ++ struct au_vdir_destr *str; ++ ++ head = au_name_hash(delist, name, nlen); ++ hlist_for_each_entry(tpos, pos, head, hash) { ++ str = tpos->str; ++ AuDbg("%.*s\n", str->len, str->name); ++ if (au_nhash_test_name(str, name, nlen)) ++ return 1; ++ } ++ return 0; ++} ++ ++static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino, ++ unsigned char d_type) ++{ ++#ifdef CONFIG_AUFS_SHWH ++ wh->wh_ino = ino; ++ wh->wh_type = d_type; ++#endif ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino, ++ unsigned int d_type, aufs_bindex_t bindex, ++ unsigned char shwh) ++{ ++ int err; ++ struct au_vdir_destr *str; ++ struct au_vdir_wh *wh; ++ ++ AuDbg("%.*s\n", nlen, name); ++ AuDebugOn(!whlist->nh_num || !whlist->nh_head); ++ ++ err = -ENOMEM; ++ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS); ++ if (unlikely(!wh)) ++ goto out; ++ ++ err = 0; ++ wh->wh_bindex = bindex; ++ if (shwh) ++ au_shwh_init_wh(wh, ino, d_type); ++ str = &wh->wh_str; ++ str->len = nlen; ++ memcpy(str->name, name, nlen); ++ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen)); ++ /* smp_mb(); */ ++ ++ out: ++ return err; ++} ++ ++static int append_deblk(struct au_vdir *vdir) ++{ ++ int err; ++ unsigned long ul; ++ const unsigned int deblk_sz = vdir->vd_deblk_sz; ++ union au_vdir_deblk_p p, deblk_end; ++ unsigned char **o; ++ ++ err = -ENOMEM; ++ o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1), ++ GFP_NOFS); ++ if (unlikely(!o)) ++ goto out; ++ ++ vdir->vd_deblk = o; ++ p.deblk = kmalloc(deblk_sz, GFP_NOFS); ++ if (p.deblk) { ++ ul = vdir->vd_nblk++; ++ vdir->vd_deblk[ul] = p.deblk; ++ vdir->vd_last.ul = ul; ++ vdir->vd_last.p.deblk = p.deblk; ++ deblk_end.deblk = p.deblk + deblk_sz; ++ err = set_deblk_end(&p, &deblk_end); ++ } ++ ++ out: ++ return err; ++} ++ ++static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino, ++ unsigned int d_type, struct au_nhash *delist) ++{ ++ int err; ++ unsigned int sz; ++ const unsigned int deblk_sz = vdir->vd_deblk_sz; ++ union au_vdir_deblk_p p, *room, deblk_end; ++ struct au_vdir_dehstr *dehstr; ++ ++ p.deblk = last_deblk(vdir); ++ deblk_end.deblk = p.deblk + deblk_sz; ++ room = &vdir->vd_last.p; ++ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk ++ || !is_deblk_end(room, &deblk_end)); ++ ++ sz = calc_size(nlen); ++ if (unlikely(sz > deblk_end.deblk - room->deblk)) { ++ err = append_deblk(vdir); ++ if (unlikely(err)) ++ goto out; ++ ++ p.deblk = last_deblk(vdir); ++ deblk_end.deblk = p.deblk + deblk_sz; ++ /* smp_mb(); */ ++ AuDebugOn(room->deblk != p.deblk); ++ } ++ ++ err = -ENOMEM; ++ dehstr = au_cache_alloc_dehstr(); ++ if (unlikely(!dehstr)) ++ goto out; ++ ++ dehstr->str = &room->de->de_str; ++ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen)); ++ room->de->de_ino = ino; ++ room->de->de_type = d_type; ++ room->de->de_str.len = nlen; ++ memcpy(room->de->de_str.name, name, nlen); ++ ++ err = 0; ++ room->deblk += sz; ++ if (unlikely(set_deblk_end(room, &deblk_end))) ++ err = append_deblk(vdir); ++ /* smp_mb(); */ ++ ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_vdir_free(struct au_vdir *vdir) ++{ ++ unsigned char **deblk; ++ ++ deblk = vdir->vd_deblk; ++ while (vdir->vd_nblk--) ++ kfree(*deblk++); ++ kfree(vdir->vd_deblk); ++ au_cache_free_vdir(vdir); ++} ++ ++static struct au_vdir *alloc_vdir(struct file *file) ++{ ++ struct au_vdir *vdir; ++ struct super_block *sb; ++ int err; ++ ++ sb = file->f_dentry->d_sb; ++ SiMustAnyLock(sb); ++ ++ err = -ENOMEM; ++ vdir = au_cache_alloc_vdir(); ++ if (unlikely(!vdir)) ++ goto out; ++ ++ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS); ++ if (unlikely(!vdir->vd_deblk)) ++ goto out_free; ++ ++ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk; ++ if (!vdir->vd_deblk_sz) { ++ /* estimate the apropriate size for deblk */ ++ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL); ++ /* AuInfo("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */ ++ } ++ vdir->vd_nblk = 0; ++ vdir->vd_version = 0; ++ vdir->vd_jiffy = 0; ++ err = append_deblk(vdir); ++ if (!err) ++ return vdir; /* success */ ++ ++ kfree(vdir->vd_deblk); ++ ++ out_free: ++ au_cache_free_vdir(vdir); ++ out: ++ vdir = ERR_PTR(err); ++ return vdir; ++} ++ ++static int reinit_vdir(struct au_vdir *vdir) ++{ ++ int err; ++ union au_vdir_deblk_p p, deblk_end; ++ ++ while (vdir->vd_nblk > 1) { ++ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]); ++ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */ ++ vdir->vd_nblk--; ++ } ++ p.deblk = vdir->vd_deblk[0]; ++ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz; ++ err = set_deblk_end(&p, &deblk_end); ++ /* keep vd_dblk_sz */ ++ vdir->vd_last.ul = 0; ++ vdir->vd_last.p.deblk = vdir->vd_deblk[0]; ++ vdir->vd_version = 0; ++ vdir->vd_jiffy = 0; ++ /* smp_mb(); */ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define AuFillVdir_CALLED 1 ++#define AuFillVdir_WHABLE (1 << 1) ++#define AuFillVdir_SHWH (1 << 2) ++#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name) ++#define au_fset_fillvdir(flags, name) { (flags) |= AuFillVdir_##name; } ++#define au_fclr_fillvdir(flags, name) { (flags) &= ~AuFillVdir_##name; } ++ ++#ifndef CONFIG_AUFS_SHWH ++#undef AuFillVdir_SHWH ++#define AuFillVdir_SHWH 0 ++#endif ++ ++struct fillvdir_arg { ++ struct file *file; ++ struct au_vdir *vdir; ++ struct au_nhash delist; ++ struct au_nhash whlist; ++ aufs_bindex_t bindex; ++ unsigned int flags; ++ int err; ++}; ++ ++static int fillvdir(void *__arg, const char *__name, int nlen, ++ loff_t offset __maybe_unused, u64 h_ino, ++ unsigned int d_type) ++{ ++ struct fillvdir_arg *arg = __arg; ++ char *name = (void *)__name; ++ struct super_block *sb; ++ ino_t ino; ++ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH); ++ ++ arg->err = 0; ++ sb = arg->file->f_dentry->d_sb; ++ au_fset_fillvdir(arg->flags, CALLED); ++ /* smp_mb(); */ ++ if (nlen <= AUFS_WH_PFX_LEN ++ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { ++ if (test_known(&arg->delist, name, nlen) ++ || au_nhash_test_known_wh(&arg->whlist, name, nlen)) ++ goto out; /* already exists or whiteouted */ ++ ++ sb = arg->file->f_dentry->d_sb; ++ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino); ++ if (!arg->err) ++ arg->err = append_de(arg->vdir, name, nlen, ino, ++ d_type, &arg->delist); ++ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) { ++ name += AUFS_WH_PFX_LEN; ++ nlen -= AUFS_WH_PFX_LEN; ++ if (au_nhash_test_known_wh(&arg->whlist, name, nlen)) ++ goto out; /* already whiteouted */ ++ ++ if (shwh) ++ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type, ++ &ino); ++ if (!arg->err) ++ arg->err = au_nhash_append_wh ++ (&arg->whlist, name, nlen, ino, d_type, ++ arg->bindex, shwh); ++ } ++ ++ out: ++ if (!arg->err) ++ arg->vdir->vd_jiffy = jiffies; ++ /* smp_mb(); */ ++ AuTraceErr(arg->err); ++ return arg->err; ++} ++ ++static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir, ++ struct au_nhash *whlist, struct au_nhash *delist) ++{ ++#ifdef CONFIG_AUFS_SHWH ++ int err; ++ unsigned int nh, u; ++ struct hlist_head *head; ++ struct au_vdir_wh *tpos; ++ struct hlist_node *pos, *n; ++ char *p, *o; ++ struct au_vdir_destr *destr; ++ ++ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH)); ++ ++ err = -ENOMEM; ++ o = p = __getname(); ++ if (unlikely(!p)) ++ goto out; ++ ++ err = 0; ++ nh = whlist->nh_num; ++ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); ++ p += AUFS_WH_PFX_LEN; ++ for (u = 0; u < nh; u++) { ++ head = whlist->nh_head + u; ++ hlist_for_each_entry_safe(tpos, pos, n, head, wh_hash) { ++ destr = &tpos->wh_str; ++ memcpy(p, destr->name, destr->len); ++ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN, ++ tpos->wh_ino, tpos->wh_type, delist); ++ if (unlikely(err)) ++ break; ++ } ++ } ++ ++ __putname(o); ++ ++ out: ++ AuTraceErr(err); ++ return err; ++#else ++ return 0; ++#endif ++} ++ ++static int au_do_read_vdir(struct fillvdir_arg *arg) ++{ ++ int err; ++ unsigned int rdhash; ++ loff_t offset; ++ aufs_bindex_t bend, bindex, bstart; ++ unsigned char shwh; ++ struct file *hf, *file; ++ struct super_block *sb; ++ ++ file = arg->file; ++ sb = file->f_dentry->d_sb; ++ SiMustAnyLock(sb); ++ ++ rdhash = au_sbi(sb)->si_rdhash; ++ if (!rdhash) ++ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL)); ++ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS); ++ if (unlikely(err)) ++ goto out_delist; ++ ++ err = 0; ++ arg->flags = 0; ++ shwh = 0; ++ if (au_opt_test(au_mntflags(sb), SHWH)) { ++ shwh = 1; ++ au_fset_fillvdir(arg->flags, SHWH); ++ } ++ bstart = au_fbstart(file); ++ bend = au_fbend(file); ++ for (bindex = bstart; !err && bindex <= bend; bindex++) { ++ hf = au_h_fptr(file, bindex); ++ if (!hf) ++ continue; ++ ++ offset = vfsub_llseek(hf, 0, SEEK_SET); ++ err = offset; ++ if (unlikely(offset)) ++ break; ++ ++ arg->bindex = bindex; ++ au_fclr_fillvdir(arg->flags, WHABLE); ++ if (shwh ++ || (bindex != bend ++ && au_br_whable(au_sbr_perm(sb, bindex)))) ++ au_fset_fillvdir(arg->flags, WHABLE); ++ do { ++ arg->err = 0; ++ au_fclr_fillvdir(arg->flags, CALLED); ++ /* smp_mb(); */ ++ err = vfsub_readdir(hf, fillvdir, arg); ++ if (err >= 0) ++ err = arg->err; ++ } while (!err && au_ftest_fillvdir(arg->flags, CALLED)); ++ } ++ ++ if (!err && shwh) ++ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist); ++ ++ au_nhash_wh_free(&arg->whlist); ++ ++ out_delist: ++ au_nhash_de_free(&arg->delist); ++ out: ++ return err; ++} ++ ++static int read_vdir(struct file *file, int may_read) ++{ ++ int err; ++ unsigned long expire; ++ unsigned char do_read; ++ struct fillvdir_arg arg; ++ struct inode *inode; ++ struct au_vdir *vdir, *allocated; ++ ++ err = 0; ++ inode = file->f_dentry->d_inode; ++ IMustLock(inode); ++ SiMustAnyLock(inode->i_sb); ++ ++ allocated = NULL; ++ do_read = 0; ++ expire = au_sbi(inode->i_sb)->si_rdcache; ++ vdir = au_ivdir(inode); ++ if (!vdir) { ++ do_read = 1; ++ vdir = alloc_vdir(file); ++ err = PTR_ERR(vdir); ++ if (IS_ERR(vdir)) ++ goto out; ++ err = 0; ++ allocated = vdir; ++ } else if (may_read ++ && (inode->i_version != vdir->vd_version ++ || time_after(jiffies, vdir->vd_jiffy + expire))) { ++ do_read = 1; ++ err = reinit_vdir(vdir); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ if (!do_read) ++ return 0; /* success */ ++ ++ arg.file = file; ++ arg.vdir = vdir; ++ err = au_do_read_vdir(&arg); ++ if (!err) { ++ /* file->f_pos = 0; */ ++ vdir->vd_version = inode->i_version; ++ vdir->vd_last.ul = 0; ++ vdir->vd_last.p.deblk = vdir->vd_deblk[0]; ++ if (allocated) ++ au_set_ivdir(inode, allocated); ++ } else if (allocated) ++ au_vdir_free(allocated); ++ ++ out: ++ return err; ++} ++ ++static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src) ++{ ++ int err, rerr; ++ unsigned long ul, n; ++ const unsigned int deblk_sz = src->vd_deblk_sz; ++ ++ AuDebugOn(tgt->vd_nblk != 1); ++ ++ err = -ENOMEM; ++ if (tgt->vd_nblk < src->vd_nblk) { ++ unsigned char **p; ++ ++ p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk, ++ GFP_NOFS); ++ if (unlikely(!p)) ++ goto out; ++ tgt->vd_deblk = p; ++ } ++ ++ if (tgt->vd_deblk_sz != deblk_sz) { ++ unsigned char *p; ++ ++ tgt->vd_deblk_sz = deblk_sz; ++ p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS); ++ if (unlikely(!p)) ++ goto out; ++ tgt->vd_deblk[0] = p; ++ } ++ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz); ++ tgt->vd_version = src->vd_version; ++ tgt->vd_jiffy = src->vd_jiffy; ++ ++ n = src->vd_nblk; ++ for (ul = 1; ul < n; ul++) { ++ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz, ++ GFP_NOFS); ++ if (unlikely(!tgt->vd_deblk[ul])) ++ goto out; ++ tgt->vd_nblk++; ++ } ++ tgt->vd_nblk = n; ++ tgt->vd_last.ul = tgt->vd_last.ul; ++ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul]; ++ tgt->vd_last.p.deblk += src->vd_last.p.deblk ++ - src->vd_deblk[src->vd_last.ul]; ++ /* smp_mb(); */ ++ return 0; /* success */ ++ ++ out: ++ rerr = reinit_vdir(tgt); ++ BUG_ON(rerr); ++ return err; ++} ++ ++int au_vdir_init(struct file *file) ++{ ++ int err; ++ struct inode *inode; ++ struct au_vdir *vdir_cache, *allocated; ++ ++ err = read_vdir(file, !file->f_pos); ++ if (unlikely(err)) ++ goto out; ++ ++ allocated = NULL; ++ vdir_cache = au_fvdir_cache(file); ++ if (!vdir_cache) { ++ vdir_cache = alloc_vdir(file); ++ err = PTR_ERR(vdir_cache); ++ if (IS_ERR(vdir_cache)) ++ goto out; ++ allocated = vdir_cache; ++ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) { ++ err = reinit_vdir(vdir_cache); ++ if (unlikely(err)) ++ goto out; ++ } else ++ return 0; /* success */ ++ ++ inode = file->f_dentry->d_inode; ++ err = copy_vdir(vdir_cache, au_ivdir(inode)); ++ if (!err) { ++ file->f_version = inode->i_version; ++ if (allocated) ++ au_set_fvdir_cache(file, allocated); ++ } else if (allocated) ++ au_vdir_free(allocated); ++ ++ out: ++ return err; ++} ++ ++static loff_t calc_offset(struct au_vdir *vdir) ++{ ++ loff_t offset; ++ union au_vdir_deblk_p p; ++ ++ p.deblk = vdir->vd_deblk[vdir->vd_last.ul]; ++ offset = vdir->vd_last.p.deblk - p.deblk; ++ offset += vdir->vd_deblk_sz * vdir->vd_last.ul; ++ return offset; ++} ++ ++/* returns true or false */ ++static int seek_vdir(struct file *file) ++{ ++ int valid; ++ unsigned int deblk_sz; ++ unsigned long ul, n; ++ loff_t offset; ++ union au_vdir_deblk_p p, deblk_end; ++ struct au_vdir *vdir_cache; ++ ++ valid = 1; ++ vdir_cache = au_fvdir_cache(file); ++ offset = calc_offset(vdir_cache); ++ AuDbg("offset %lld\n", offset); ++ if (file->f_pos == offset) ++ goto out; ++ ++ vdir_cache->vd_last.ul = 0; ++ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0]; ++ if (!file->f_pos) ++ goto out; ++ ++ valid = 0; ++ deblk_sz = vdir_cache->vd_deblk_sz; ++ ul = div64_u64(file->f_pos, deblk_sz); ++ AuDbg("ul %lu\n", ul); ++ if (ul >= vdir_cache->vd_nblk) ++ goto out; ++ ++ n = vdir_cache->vd_nblk; ++ for (; ul < n; ul++) { ++ p.deblk = vdir_cache->vd_deblk[ul]; ++ deblk_end.deblk = p.deblk + deblk_sz; ++ offset = ul; ++ offset *= deblk_sz; ++ while (!is_deblk_end(&p, &deblk_end) && offset < file->f_pos) { ++ unsigned int l; ++ ++ l = calc_size(p.de->de_str.len); ++ offset += l; ++ p.deblk += l; ++ } ++ if (!is_deblk_end(&p, &deblk_end)) { ++ valid = 1; ++ vdir_cache->vd_last.ul = ul; ++ vdir_cache->vd_last.p = p; ++ break; ++ } ++ } ++ ++ out: ++ /* smp_mb(); */ ++ AuTraceErr(!valid); ++ return valid; ++} ++ ++int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir) ++{ ++ int err; ++ unsigned int l, deblk_sz; ++ union au_vdir_deblk_p deblk_end; ++ struct au_vdir *vdir_cache; ++ struct au_vdir_de *de; ++ ++ vdir_cache = au_fvdir_cache(file); ++ if (!seek_vdir(file)) ++ return 0; ++ ++ deblk_sz = vdir_cache->vd_deblk_sz; ++ while (1) { ++ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul]; ++ deblk_end.deblk += deblk_sz; ++ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) { ++ de = vdir_cache->vd_last.p.de; ++ AuDbg("%.*s, off%lld, i%lu, dt%d\n", ++ de->de_str.len, de->de_str.name, file->f_pos, ++ (unsigned long)de->de_ino, de->de_type); ++ err = filldir(dirent, de->de_str.name, de->de_str.len, ++ file->f_pos, de->de_ino, de->de_type); ++ if (unlikely(err)) { ++ AuTraceErr(err); ++ /* todo: ignore the error caused by udba? */ ++ /* return err; */ ++ return 0; ++ } ++ ++ l = calc_size(de->de_str.len); ++ vdir_cache->vd_last.p.deblk += l; ++ file->f_pos += l; ++ } ++ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) { ++ vdir_cache->vd_last.ul++; ++ vdir_cache->vd_last.p.deblk ++ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul]; ++ file->f_pos = deblk_sz * vdir_cache->vd_last.ul; ++ continue; ++ } ++ break; ++ } ++ ++ /* smp_mb(); */ ++ return 0; ++} +diff --git a/fs/aufs/vfsub.c b/fs/aufs/vfsub.c +new file mode 100644 +index 0000000..f1c3414 +--- /dev/null ++++ b/fs/aufs/vfsub.c +@@ -0,0 +1,740 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * sub-routines for VFS ++ */ ++ ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++int vfsub_update_h_iattr(struct path *h_path, int *did) ++{ ++ int err; ++ struct kstat st; ++ struct super_block *h_sb; ++ ++ /* for remote fs, leave work for its getattr or d_revalidate */ ++ /* for bad i_attr fs, handle them in aufs_getattr() */ ++ /* still some fs may acquire i_mutex. we need to skip them */ ++ err = 0; ++ if (!did) ++ did = &err; ++ h_sb = h_path->dentry->d_sb; ++ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb)); ++ if (*did) ++ err = vfs_getattr(h_path->mnt, h_path->dentry, &st); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_IMA ++#error IMA is not supported since it does not work well. Wait for their fixing. ++#endif ++ ++struct file *vfsub_filp_open(const char *path, int oflags, int mode) ++{ ++ struct file *file; ++ ++ lockdep_off(); ++ file = filp_open(path, oflags, mode); ++ lockdep_on(); ++ if (IS_ERR(file)) ++ goto out; ++ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ ++ ++ out: ++ return file; ++} ++ ++int vfsub_kern_path(const char *name, unsigned int flags, struct path *path) ++{ ++ int err; ++ ++ /* lockdep_off(); */ ++ err = kern_path(name, flags, path); ++ /* lockdep_on(); */ ++ if (!err && path->dentry->d_inode) ++ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, ++ int len) ++{ ++ struct path path = { ++ .mnt = NULL ++ }; ++ ++ IMustLock(parent->d_inode); ++ ++ path.dentry = lookup_one_len(name, parent, len); ++ if (IS_ERR(path.dentry)) ++ goto out; ++ if (path.dentry->d_inode) ++ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/ ++ ++ out: ++ return path.dentry; ++} ++ ++struct dentry *vfsub_lookup_hash(struct nameidata *nd) ++{ ++ struct path path = { ++ .mnt = nd->path.mnt ++ }; ++ ++ IMustLock(nd->path.dentry->d_inode); ++ ++ path.dentry = lookup_hash(nd); ++ if (!IS_ERR(path.dentry) && path.dentry->d_inode) ++ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/ ++ ++ return path.dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1, ++ struct dentry *d2, struct au_hinode *hdir2) ++{ ++ struct dentry *d; ++ ++ lockdep_off(); ++ d = lock_rename(d1, d2); ++ lockdep_on(); ++ au_hin_suspend(hdir1); ++ if (hdir1 != hdir2) ++ au_hin_suspend(hdir2); ++ ++ return d; ++} ++ ++void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1, ++ struct dentry *d2, struct au_hinode *hdir2) ++{ ++ au_hin_resume(hdir1); ++ if (hdir1 != hdir2) ++ au_hin_resume(hdir2); ++ lockdep_off(); ++ unlock_rename(d1, d2); ++ lockdep_on(); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int vfsub_create(struct inode *dir, struct path *path, int mode) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_mknod(path, path->dentry, mode, 0); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ if (au_test_fs_null_nd(dir->i_sb)) ++ err = vfs_create(dir, path->dentry, mode, NULL); ++ else { ++ struct nameidata h_nd; ++ ++ memset(&h_nd, 0, sizeof(h_nd)); ++ h_nd.flags = LOOKUP_CREATE; ++ h_nd.intent.open.flags = O_CREAT ++ | vfsub_fmode_to_uint(FMODE_READ); ++ h_nd.intent.open.create_mode = mode; ++ h_nd.path.dentry = path->dentry->d_parent; ++ h_nd.path.mnt = path->mnt; ++ path_get(&h_nd.path); ++ err = vfs_create(dir, path->dentry, mode, &h_nd); ++ path_put(&h_nd.path); ++ } ++ ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++int vfsub_symlink(struct inode *dir, struct path *path, const char *symname) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_symlink(path, path->dentry, symname); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ err = vfs_symlink(dir, path->dentry, symname); ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_mknod(path, path->dentry, mode, dev); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ err = vfs_mknod(dir, path->dentry, mode, dev); ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++static int au_test_nlink(struct inode *inode) ++{ ++ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */ ++ ++ if (!au_test_fs_no_limit_nlink(inode->i_sb) ++ || inode->i_nlink < link_max) ++ return 0; ++ return -EMLINK; ++} ++ ++int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ err = au_test_nlink(src_dentry->d_inode); ++ if (unlikely(err)) ++ return err; ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_link(src_dentry, path, path->dentry); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ lockdep_off(); ++ err = vfs_link(src_dentry, dir, path->dentry); ++ lockdep_on(); ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ /* fuse has different memory inode for the same inumber */ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ tmp.dentry = src_dentry; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, ++ struct inode *dir, struct path *path) ++{ ++ int err; ++ struct path tmp = { ++ .mnt = path->mnt ++ }; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ IMustLock(src_dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ tmp.dentry = src_dentry->d_parent; ++ err = security_path_rename(&tmp, src_dentry, path, path->dentry); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ lockdep_off(); ++ err = vfs_rename(src_dir, src_dentry, dir, path->dentry); ++ lockdep_on(); ++ if (!err) { ++ int did; ++ ++ tmp.dentry = d->d_parent; ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = src_dentry; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ tmp.dentry = src_dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++int vfsub_mkdir(struct inode *dir, struct path *path, int mode) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_mkdir(path, path->dentry, mode); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ err = vfs_mkdir(dir, path->dentry, mode); ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++int vfsub_rmdir(struct inode *dir, struct path *path) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_rmdir(path, path->dentry); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ lockdep_off(); ++ err = vfs_rmdir(dir, path->dentry); ++ lockdep_on(); ++ if (!err) { ++ struct path tmp = { ++ .dentry = path->dentry->d_parent, ++ .mnt = path->mnt ++ }; ++ ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, ++ loff_t *ppos) ++{ ++ ssize_t err; ++ ++ err = vfs_read(file, ubuf, count, ppos); ++ if (err >= 0) ++ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++/* todo: kernel_read()? */ ++ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, ++ loff_t *ppos) ++{ ++ ssize_t err; ++ mm_segment_t oldfs; ++ ++ oldfs = get_fs(); ++ set_fs(KERNEL_DS); ++ err = vfsub_read_u(file, (char __user *)kbuf, count, ppos); ++ set_fs(oldfs); ++ return err; ++} ++ ++ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, ++ loff_t *ppos) ++{ ++ ssize_t err; ++ ++ lockdep_off(); ++ err = vfs_write(file, ubuf, count, ppos); ++ lockdep_on(); ++ if (err >= 0) ++ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos) ++{ ++ ssize_t err; ++ mm_segment_t oldfs; ++ ++ oldfs = get_fs(); ++ set_fs(KERNEL_DS); ++ err = vfsub_write_u(file, (const char __user *)kbuf, count, ppos); ++ set_fs(oldfs); ++ return err; ++} ++ ++int vfsub_readdir(struct file *file, filldir_t filldir, void *arg) ++{ ++ int err; ++ ++ lockdep_off(); ++ err = vfs_readdir(file, filldir, arg); ++ lockdep_on(); ++ if (err >= 0) ++ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++long vfsub_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags) ++{ ++ long err; ++ ++ lockdep_off(); ++ err = do_splice_to(in, ppos, pipe, len, flags); ++ lockdep_on(); ++ if (err >= 0) ++ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags) ++{ ++ long err; ++ ++ lockdep_off(); ++ err = do_splice_from(pipe, out, ppos, len, flags); ++ lockdep_on(); ++ if (err >= 0) ++ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */ ++int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr, ++ struct file *h_file) ++{ ++ int err; ++ struct inode *h_inode; ++ ++ h_inode = h_path->dentry->d_inode; ++ if (!h_file) { ++ err = mnt_want_write(h_path->mnt); ++ if (err) ++ goto out; ++ err = inode_permission(h_inode, MAY_WRITE); ++ if (err) ++ goto out_mnt; ++ err = get_write_access(h_inode); ++ if (err) ++ goto out_mnt; ++ err = break_lease(h_inode, vfsub_fmode_to_uint(FMODE_WRITE)); ++ if (err) ++ goto out_inode; ++ } ++ ++ err = locks_verify_truncate(h_inode, h_file, length); ++ if (!err) ++ err = security_path_truncate(h_path, length, attr); ++ if (!err) { ++ lockdep_off(); ++ err = do_truncate(h_path->dentry, length, attr, h_file); ++ lockdep_on(); ++ } ++ ++ out_inode: ++ if (!h_file) ++ put_write_access(h_inode); ++ out_mnt: ++ if (!h_file) ++ mnt_drop_write(h_path->mnt); ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_vfsub_mkdir_args { ++ int *errp; ++ struct inode *dir; ++ struct path *path; ++ int mode; ++}; ++ ++static void au_call_vfsub_mkdir(void *args) ++{ ++ struct au_vfsub_mkdir_args *a = args; ++ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode); ++} ++ ++int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode) ++{ ++ int err, do_sio, wkq_err; ++ ++ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE); ++ if (!do_sio) ++ err = vfsub_mkdir(dir, path, mode); ++ else { ++ struct au_vfsub_mkdir_args args = { ++ .errp = &err, ++ .dir = dir, ++ .path = path, ++ .mode = mode ++ }; ++ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ return err; ++} ++ ++struct au_vfsub_rmdir_args { ++ int *errp; ++ struct inode *dir; ++ struct path *path; ++}; ++ ++static void au_call_vfsub_rmdir(void *args) ++{ ++ struct au_vfsub_rmdir_args *a = args; ++ *a->errp = vfsub_rmdir(a->dir, a->path); ++} ++ ++int vfsub_sio_rmdir(struct inode *dir, struct path *path) ++{ ++ int err, do_sio, wkq_err; ++ ++ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE); ++ if (!do_sio) ++ err = vfsub_rmdir(dir, path); ++ else { ++ struct au_vfsub_rmdir_args args = { ++ .errp = &err, ++ .dir = dir, ++ .path = path ++ }; ++ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct notify_change_args { ++ int *errp; ++ struct path *path; ++ struct iattr *ia; ++}; ++ ++static void call_notify_change(void *args) ++{ ++ struct notify_change_args *a = args; ++ struct inode *h_inode; ++ ++ h_inode = a->path->dentry->d_inode; ++ IMustLock(h_inode); ++ ++ *a->errp = -EPERM; ++ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) { ++ lockdep_off(); ++ *a->errp = notify_change(a->path->dentry, a->ia); ++ lockdep_on(); ++ if (!*a->errp) ++ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/ ++ } ++ AuTraceErr(*a->errp); ++} ++ ++int vfsub_notify_change(struct path *path, struct iattr *ia) ++{ ++ int err; ++ struct notify_change_args args = { ++ .errp = &err, ++ .path = path, ++ .ia = ia ++ }; ++ ++ call_notify_change(&args); ++ ++ return err; ++} ++ ++int vfsub_sio_notify_change(struct path *path, struct iattr *ia) ++{ ++ int err, wkq_err; ++ struct notify_change_args args = { ++ .errp = &err, ++ .path = path, ++ .ia = ia ++ }; ++ ++ wkq_err = au_wkq_wait(call_notify_change, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct unlink_args { ++ int *errp; ++ struct inode *dir; ++ struct path *path; ++}; ++ ++static void call_unlink(void *args) ++{ ++ struct unlink_args *a = args; ++ struct dentry *d = a->path->dentry; ++ struct inode *h_inode; ++ const int stop_sillyrename = (au_test_nfs(d->d_sb) ++ && atomic_read(&d->d_count) == 1); ++ ++ IMustLock(a->dir); ++ ++ a->path->dentry = d->d_parent; ++ *a->errp = security_path_unlink(a->path, d); ++ a->path->dentry = d; ++ if (unlikely(*a->errp)) ++ return; ++ ++ if (!stop_sillyrename) ++ dget(d); ++ h_inode = d->d_inode; ++ if (h_inode) ++ atomic_inc(&h_inode->i_count); ++ ++ lockdep_off(); ++ *a->errp = vfs_unlink(a->dir, d); ++ lockdep_on(); ++ if (!*a->errp) { ++ struct path tmp = { ++ .dentry = d->d_parent, ++ .mnt = a->path->mnt ++ }; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/ ++ } ++ ++ if (!stop_sillyrename) ++ dput(d); ++ if (h_inode) ++ iput(h_inode); ++ ++ AuTraceErr(*a->errp); ++} ++ ++/* ++ * @dir: must be locked. ++ * @dentry: target dentry. ++ */ ++int vfsub_unlink(struct inode *dir, struct path *path, int force) ++{ ++ int err; ++ struct unlink_args args = { ++ .errp = &err, ++ .dir = dir, ++ .path = path ++ }; ++ ++ if (!force) ++ call_unlink(&args); ++ else { ++ int wkq_err; ++ ++ wkq_err = au_wkq_wait(call_unlink, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ return err; ++} +diff --git a/fs/aufs/vfsub.h b/fs/aufs/vfsub.h +new file mode 100644 +index 0000000..00e7e62 +--- /dev/null ++++ b/fs/aufs/vfsub.h +@@ -0,0 +1,172 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * sub-routines for VFS ++ */ ++ ++#ifndef __AUFS_VFSUB_H__ ++#define __AUFS_VFSUB_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* lock subclass for lower inode */ ++/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */ ++/* reduce? gave up. */ ++enum { ++ AuLsc_I_Begin = I_MUTEX_QUOTA, /* 4 */ ++ AuLsc_I_PARENT, /* lower inode, parent first */ ++ AuLsc_I_PARENT2, /* copyup dirs */ ++ AuLsc_I_PARENT3, /* copyup wh */ ++ AuLsc_I_CHILD, ++ AuLsc_I_CHILD2, ++ AuLsc_I_End ++}; ++ ++/* to debug easier, do not make them inlined functions */ ++#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx)) ++#define IMustLock(i) MtxMustLock(&(i)->i_mutex) ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline void vfsub_copy_inode_size(struct inode *inode, ++ struct inode *h_inode) ++{ ++ spin_lock(&inode->i_lock); ++ fsstack_copy_inode_size(inode, h_inode); ++ spin_unlock(&inode->i_lock); ++} ++ ++int vfsub_update_h_iattr(struct path *h_path, int *did); ++struct file *vfsub_filp_open(const char *path, int oflags, int mode); ++int vfsub_kern_path(const char *name, unsigned int flags, struct path *path); ++struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, ++ int len); ++struct dentry *vfsub_lookup_hash(struct nameidata *nd); ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_hinode; ++struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1, ++ struct dentry *d2, struct au_hinode *hdir2); ++void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1, ++ struct dentry *d2, struct au_hinode *hdir2); ++ ++int vfsub_create(struct inode *dir, struct path *path, int mode); ++int vfsub_symlink(struct inode *dir, struct path *path, ++ const char *symname); ++int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev); ++int vfsub_link(struct dentry *src_dentry, struct inode *dir, ++ struct path *path); ++int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry, ++ struct inode *hdir, struct path *path); ++int vfsub_mkdir(struct inode *dir, struct path *path, int mode); ++int vfsub_rmdir(struct inode *dir, struct path *path); ++ ++/* ---------------------------------------------------------------------- */ ++ ++ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, ++ loff_t *ppos); ++ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, ++ loff_t *ppos); ++ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, ++ loff_t *ppos); ++ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, ++ loff_t *ppos); ++int vfsub_readdir(struct file *file, filldir_t filldir, void *arg); ++ ++static inline void vfsub_file_accessed(struct file *h_file) ++{ ++ file_accessed(h_file); ++ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/ ++} ++ ++static inline void vfsub_touch_atime(struct vfsmount *h_mnt, ++ struct dentry *h_dentry) ++{ ++ struct path h_path = { ++ .dentry = h_dentry, ++ .mnt = h_mnt ++ }; ++ touch_atime(h_mnt, h_dentry); ++ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/ ++} ++ ++long vfsub_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags); ++long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags); ++int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr, ++ struct file *h_file); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin) ++{ ++ loff_t err; ++ ++ lockdep_off(); ++ err = vfs_llseek(file, offset, origin); ++ lockdep_on(); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* dirty workaround for strict type of fmode_t */ ++union vfsub_fmu { ++ fmode_t fm; ++ unsigned int ui; ++}; ++ ++static inline unsigned int vfsub_fmode_to_uint(fmode_t fm) ++{ ++ union vfsub_fmu u = { ++ .fm = fm ++ }; ++ ++ BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui)); ++ ++ return u.ui; ++} ++ ++static inline fmode_t vfsub_uint_to_fmode(unsigned int ui) ++{ ++ union vfsub_fmu u = { ++ .ui = ui ++ }; ++ ++ return u.fm; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode); ++int vfsub_sio_rmdir(struct inode *dir, struct path *path); ++int vfsub_sio_notify_change(struct path *path, struct iattr *ia); ++int vfsub_notify_change(struct path *path, struct iattr *ia); ++int vfsub_unlink(struct inode *dir, struct path *path, int force); ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_VFSUB_H__ */ +diff --git a/fs/aufs/wbr_policy.c b/fs/aufs/wbr_policy.c +new file mode 100644 +index 0000000..05a8c1e +--- /dev/null ++++ b/fs/aufs/wbr_policy.c +@@ -0,0 +1,641 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * policies for selecting one among multiple writable branches ++ */ ++ ++#include ++#include "aufs.h" ++ ++/* subset of cpup_attr() */ ++static noinline_for_stack ++int au_cpdown_attr(struct path *h_path, struct dentry *h_src) ++{ ++ int err, sbits; ++ struct iattr ia; ++ struct inode *h_isrc; ++ ++ h_isrc = h_src->d_inode; ++ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID; ++ ia.ia_mode = h_isrc->i_mode; ++ ia.ia_uid = h_isrc->i_uid; ++ ia.ia_gid = h_isrc->i_gid; ++ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID)); ++ au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc); ++ err = vfsub_sio_notify_change(h_path, &ia); ++ ++ /* is this nfs only? */ ++ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) { ++ ia.ia_valid = ATTR_FORCE | ATTR_MODE; ++ ia.ia_mode = h_isrc->i_mode; ++ err = vfsub_sio_notify_change(h_path, &ia); ++ } ++ ++ return err; ++} ++ ++#define AuCpdown_PARENT_OPQ 1 ++#define AuCpdown_WHED (1 << 1) ++#define AuCpdown_MADE_DIR (1 << 2) ++#define AuCpdown_DIROPQ (1 << 3) ++#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name) ++#define au_fset_cpdown(flags, name) { (flags) |= AuCpdown_##name; } ++#define au_fclr_cpdown(flags, name) { (flags) &= ~AuCpdown_##name; } ++ ++struct au_cpdown_dir_args { ++ struct dentry *parent; ++ unsigned int flags; ++}; ++ ++static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst, ++ struct au_cpdown_dir_args *a) ++{ ++ int err; ++ struct dentry *opq_dentry; ++ ++ opq_dentry = au_diropq_create(dentry, bdst); ++ err = PTR_ERR(opq_dentry); ++ if (IS_ERR(opq_dentry)) ++ goto out; ++ dput(opq_dentry); ++ au_fset_cpdown(a->flags, DIROPQ); ++ ++ out: ++ return err; ++} ++ ++static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent, ++ struct inode *dir, aufs_bindex_t bdst) ++{ ++ int err; ++ struct path h_path; ++ struct au_branch *br; ++ ++ br = au_sbr(dentry->d_sb, bdst); ++ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br); ++ err = PTR_ERR(h_path.dentry); ++ if (IS_ERR(h_path.dentry)) ++ goto out; ++ ++ err = 0; ++ if (h_path.dentry->d_inode) { ++ h_path.mnt = br->br_mnt; ++ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path, ++ dentry); ++ } ++ dput(h_path.dentry); ++ ++ out: ++ return err; ++} ++ ++static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst, ++ struct dentry *h_parent, void *arg) ++{ ++ int err, rerr; ++ aufs_bindex_t bend, bopq, bstart; ++ unsigned char parent_opq; ++ struct path h_path; ++ struct dentry *parent; ++ struct inode *h_dir, *h_inode, *inode, *dir; ++ struct au_cpdown_dir_args *args = arg; ++ ++ bstart = au_dbstart(dentry); ++ /* dentry is di-locked */ ++ parent = dget_parent(dentry); ++ dir = parent->d_inode; ++ h_dir = h_parent->d_inode; ++ AuDebugOn(h_dir != au_h_iptr(dir, bdst)); ++ IMustLock(h_dir); ++ ++ err = au_lkup_neg(dentry, bdst); ++ if (unlikely(err < 0)) ++ goto out; ++ h_path.dentry = au_h_dptr(dentry, bdst); ++ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst); ++ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path, ++ S_IRWXU | S_IRUGO | S_IXUGO); ++ if (unlikely(err)) ++ goto out_put; ++ au_fset_cpdown(args->flags, MADE_DIR); ++ ++ bend = au_dbend(dentry); ++ bopq = au_dbdiropq(dentry); ++ au_fclr_cpdown(args->flags, WHED); ++ au_fclr_cpdown(args->flags, DIROPQ); ++ if (au_dbwh(dentry) == bdst) ++ au_fset_cpdown(args->flags, WHED); ++ if (!au_ftest_cpdown(args->flags, PARENT_OPQ) && bopq <= bdst) ++ au_fset_cpdown(args->flags, PARENT_OPQ); ++ parent_opq = (au_ftest_cpdown(args->flags, PARENT_OPQ) ++ && args->parent == dentry); ++ h_inode = h_path.dentry->d_inode; ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ if (au_ftest_cpdown(args->flags, WHED)) { ++ err = au_cpdown_dir_opq(dentry, bdst, args); ++ if (unlikely(err)) { ++ mutex_unlock(&h_inode->i_mutex); ++ goto out_dir; ++ } ++ } ++ ++ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart)); ++ mutex_unlock(&h_inode->i_mutex); ++ if (unlikely(err)) ++ goto out_opq; ++ ++ if (au_ftest_cpdown(args->flags, WHED)) { ++ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst); ++ if (unlikely(err)) ++ goto out_opq; ++ } ++ ++ inode = dentry->d_inode; ++ if (au_ibend(inode) < bdst) ++ au_set_ibend(inode, bdst); ++ au_set_h_iptr(inode, bdst, au_igrab(h_inode), ++ au_hi_flags(inode, /*isdir*/1)); ++ goto out; /* success */ ++ ++ /* revert */ ++ out_opq: ++ if (au_ftest_cpdown(args->flags, DIROPQ)) { ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ rerr = au_diropq_remove(dentry, bdst); ++ mutex_unlock(&h_inode->i_mutex); ++ if (unlikely(rerr)) { ++ AuIOErr("failed removing diropq for %.*s b%d (%d)\n", ++ AuDLNPair(dentry), bdst, rerr); ++ err = -EIO; ++ goto out; ++ } ++ } ++ out_dir: ++ if (au_ftest_cpdown(args->flags, MADE_DIR)) { ++ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path); ++ if (unlikely(rerr)) { ++ AuIOErr("failed removing %.*s b%d (%d)\n", ++ AuDLNPair(dentry), bdst, rerr); ++ err = -EIO; ++ } ++ } ++ out_put: ++ au_set_h_dptr(dentry, bdst, NULL); ++ if (au_dbend(dentry) == bdst) ++ au_update_dbend(dentry); ++ out: ++ dput(parent); ++ return err; ++} ++ ++int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst) ++{ ++ int err; ++ struct au_cpdown_dir_args args = { ++ .parent = dget_parent(dentry), ++ .flags = 0 ++ }; ++ ++ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &args); ++ dput(args.parent); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* policies for create */ ++ ++static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ for (; bindex >= 0; bindex--) ++ if (!au_br_rdonly(au_sbr(sb, bindex))) ++ return bindex; ++ return -EROFS; ++} ++ ++/* top down parent */ ++static int au_wbr_create_tdp(struct dentry *dentry, int isdir __maybe_unused) ++{ ++ int err; ++ aufs_bindex_t bstart, bindex; ++ struct super_block *sb; ++ struct dentry *parent, *h_parent; ++ ++ sb = dentry->d_sb; ++ bstart = au_dbstart(dentry); ++ err = bstart; ++ if (!au_br_rdonly(au_sbr(sb, bstart))) ++ goto out; ++ ++ err = -EROFS; ++ parent = dget_parent(dentry); ++ for (bindex = au_dbstart(parent); bindex < bstart; bindex++) { ++ h_parent = au_h_dptr(parent, bindex); ++ if (!h_parent || !h_parent->d_inode) ++ continue; ++ ++ if (!au_br_rdonly(au_sbr(sb, bindex))) { ++ err = bindex; ++ break; ++ } ++ } ++ dput(parent); ++ ++ /* bottom up here */ ++ if (unlikely(err < 0)) ++ err = au_wbr_bu(sb, bstart - 1); ++ ++ out: ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* an exception for the policy other than tdp */ ++static int au_wbr_create_exp(struct dentry *dentry) ++{ ++ int err; ++ aufs_bindex_t bwh, bdiropq; ++ struct dentry *parent; ++ ++ err = -1; ++ bwh = au_dbwh(dentry); ++ parent = dget_parent(dentry); ++ bdiropq = au_dbdiropq(parent); ++ if (bwh >= 0) { ++ if (bdiropq >= 0) ++ err = min(bdiropq, bwh); ++ else ++ err = bwh; ++ AuDbg("%d\n", err); ++ } else if (bdiropq >= 0) { ++ err = bdiropq; ++ AuDbg("%d\n", err); ++ } ++ dput(parent); ++ ++ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err))) ++ err = -1; ++ ++ AuDbg("%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* round robin */ ++static int au_wbr_create_init_rr(struct super_block *sb) ++{ ++ int err; ++ ++ err = au_wbr_bu(sb, au_sbend(sb)); ++ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */ ++ /* smp_mb(); */ ++ ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++static int au_wbr_create_rr(struct dentry *dentry, int isdir) ++{ ++ int err, nbr; ++ unsigned int u; ++ aufs_bindex_t bindex, bend; ++ struct super_block *sb; ++ atomic_t *next; ++ ++ err = au_wbr_create_exp(dentry); ++ if (err >= 0) ++ goto out; ++ ++ sb = dentry->d_sb; ++ next = &au_sbi(sb)->si_wbr_rr_next; ++ bend = au_sbend(sb); ++ nbr = bend + 1; ++ for (bindex = 0; bindex <= bend; bindex++) { ++ if (!isdir) { ++ err = atomic_dec_return(next) + 1; ++ /* modulo for 0 is meaningless */ ++ if (unlikely(!err)) ++ err = atomic_dec_return(next) + 1; ++ } else ++ err = atomic_read(next); ++ AuDbg("%d\n", err); ++ u = err; ++ err = u % nbr; ++ AuDbg("%d\n", err); ++ if (!au_br_rdonly(au_sbr(sb, err))) ++ break; ++ err = -EROFS; ++ } ++ ++ out: ++ AuDbg("%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* most free space */ ++static void au_mfs(struct dentry *dentry) ++{ ++ struct super_block *sb; ++ struct au_branch *br; ++ struct au_wbr_mfs *mfs; ++ aufs_bindex_t bindex, bend; ++ int err; ++ unsigned long long b, bavail; ++ /* reduce the stack usage */ ++ struct kstatfs *st; ++ ++ st = kmalloc(sizeof(*st), GFP_NOFS); ++ if (unlikely(!st)) { ++ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM); ++ return; ++ } ++ ++ bavail = 0; ++ sb = dentry->d_sb; ++ mfs = &au_sbi(sb)->si_wbr_mfs; ++ MtxMustLock(&mfs->mfs_lock); ++ mfs->mfs_bindex = -EROFS; ++ mfs->mfsrr_bytes = 0; ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (au_br_rdonly(br)) ++ continue; ++ ++ /* sb->s_root for NFS is unreliable */ ++ err = vfs_statfs(br->br_mnt->mnt_root, st); ++ if (unlikely(err)) { ++ AuWarn1("failed statfs, b%d, %d\n", bindex, err); ++ continue; ++ } ++ ++ /* when the available size is equal, select the lower one */ ++ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail) ++ || sizeof(b) < sizeof(st->f_bsize)); ++ b = st->f_bavail * st->f_bsize; ++ br->br_wbr->wbr_bytes = b; ++ if (b >= bavail) { ++ bavail = b; ++ mfs->mfs_bindex = bindex; ++ mfs->mfs_jiffy = jiffies; ++ } ++ } ++ ++ mfs->mfsrr_bytes = bavail; ++ AuDbg("b%d\n", mfs->mfs_bindex); ++ kfree(st); ++} ++ ++static int au_wbr_create_mfs(struct dentry *dentry, int isdir __maybe_unused) ++{ ++ int err; ++ struct super_block *sb; ++ struct au_wbr_mfs *mfs; ++ ++ err = au_wbr_create_exp(dentry); ++ if (err >= 0) ++ goto out; ++ ++ sb = dentry->d_sb; ++ mfs = &au_sbi(sb)->si_wbr_mfs; ++ mutex_lock(&mfs->mfs_lock); ++ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire) ++ || mfs->mfs_bindex < 0 ++ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex))) ++ au_mfs(dentry); ++ mutex_unlock(&mfs->mfs_lock); ++ err = mfs->mfs_bindex; ++ ++ out: ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++static int au_wbr_create_init_mfs(struct super_block *sb) ++{ ++ struct au_wbr_mfs *mfs; ++ ++ mfs = &au_sbi(sb)->si_wbr_mfs; ++ mutex_init(&mfs->mfs_lock); ++ mfs->mfs_jiffy = 0; ++ mfs->mfs_bindex = -EROFS; ++ ++ return 0; ++} ++ ++static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused) ++{ ++ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock); ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* most free space and then round robin */ ++static int au_wbr_create_mfsrr(struct dentry *dentry, int isdir) ++{ ++ int err; ++ struct au_wbr_mfs *mfs; ++ ++ err = au_wbr_create_mfs(dentry, isdir); ++ if (err >= 0) { ++ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs; ++ mutex_lock(&mfs->mfs_lock); ++ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark) ++ err = au_wbr_create_rr(dentry, isdir); ++ mutex_unlock(&mfs->mfs_lock); ++ } ++ ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++static int au_wbr_create_init_mfsrr(struct super_block *sb) ++{ ++ int err; ++ ++ au_wbr_create_init_mfs(sb); /* ignore */ ++ err = au_wbr_create_init_rr(sb); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* top down parent and most free space */ ++static int au_wbr_create_pmfs(struct dentry *dentry, int isdir) ++{ ++ int err, e2; ++ unsigned long long b; ++ aufs_bindex_t bindex, bstart, bend; ++ struct super_block *sb; ++ struct dentry *parent, *h_parent; ++ struct au_branch *br; ++ ++ err = au_wbr_create_tdp(dentry, isdir); ++ if (unlikely(err < 0)) ++ goto out; ++ parent = dget_parent(dentry); ++ bstart = au_dbstart(parent); ++ bend = au_dbtaildir(parent); ++ if (bstart == bend) ++ goto out_parent; /* success */ ++ ++ e2 = au_wbr_create_mfs(dentry, isdir); ++ if (e2 < 0) ++ goto out_parent; /* success */ ++ ++ /* when the available size is equal, select upper one */ ++ sb = dentry->d_sb; ++ br = au_sbr(sb, err); ++ b = br->br_wbr->wbr_bytes; ++ AuDbg("b%d, %llu\n", err, b); ++ ++ for (bindex = bstart; bindex <= bend; bindex++) { ++ h_parent = au_h_dptr(parent, bindex); ++ if (!h_parent || !h_parent->d_inode) ++ continue; ++ ++ br = au_sbr(sb, bindex); ++ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) { ++ b = br->br_wbr->wbr_bytes; ++ err = bindex; ++ AuDbg("b%d, %llu\n", err, b); ++ } ++ } ++ ++ out_parent: ++ dput(parent); ++ out: ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* policies for copyup */ ++ ++/* top down parent */ ++static int au_wbr_copyup_tdp(struct dentry *dentry) ++{ ++ return au_wbr_create_tdp(dentry, /*isdir, anything is ok*/0); ++} ++ ++/* bottom up parent */ ++static int au_wbr_copyup_bup(struct dentry *dentry) ++{ ++ int err; ++ aufs_bindex_t bindex, bstart; ++ struct dentry *parent, *h_parent; ++ struct super_block *sb; ++ ++ err = -EROFS; ++ sb = dentry->d_sb; ++ parent = dget_parent(dentry); ++ bstart = au_dbstart(parent); ++ for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) { ++ h_parent = au_h_dptr(parent, bindex); ++ if (!h_parent || !h_parent->d_inode) ++ continue; ++ ++ if (!au_br_rdonly(au_sbr(sb, bindex))) { ++ err = bindex; ++ break; ++ } ++ } ++ dput(parent); ++ ++ /* bottom up here */ ++ if (unlikely(err < 0)) ++ err = au_wbr_bu(sb, bstart - 1); ++ ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++/* bottom up */ ++static int au_wbr_copyup_bu(struct dentry *dentry) ++{ ++ int err; ++ ++ err = au_wbr_bu(dentry->d_sb, au_dbstart(dentry)); ++ ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_wbr_copyup_operations au_wbr_copyup_ops[] = { ++ [AuWbrCopyup_TDP] = { ++ .copyup = au_wbr_copyup_tdp ++ }, ++ [AuWbrCopyup_BUP] = { ++ .copyup = au_wbr_copyup_bup ++ }, ++ [AuWbrCopyup_BU] = { ++ .copyup = au_wbr_copyup_bu ++ } ++}; ++ ++struct au_wbr_create_operations au_wbr_create_ops[] = { ++ [AuWbrCreate_TDP] = { ++ .create = au_wbr_create_tdp ++ }, ++ [AuWbrCreate_RR] = { ++ .create = au_wbr_create_rr, ++ .init = au_wbr_create_init_rr ++ }, ++ [AuWbrCreate_MFS] = { ++ .create = au_wbr_create_mfs, ++ .init = au_wbr_create_init_mfs, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_MFSV] = { ++ .create = au_wbr_create_mfs, ++ .init = au_wbr_create_init_mfs, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_MFSRR] = { ++ .create = au_wbr_create_mfsrr, ++ .init = au_wbr_create_init_mfsrr, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_MFSRRV] = { ++ .create = au_wbr_create_mfsrr, ++ .init = au_wbr_create_init_mfsrr, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_PMFS] = { ++ .create = au_wbr_create_pmfs, ++ .init = au_wbr_create_init_mfs, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_PMFSV] = { ++ .create = au_wbr_create_pmfs, ++ .init = au_wbr_create_init_mfs, ++ .fin = au_wbr_create_fin_mfs ++ } ++}; +diff --git a/fs/aufs/whout.c b/fs/aufs/whout.c +new file mode 100644 +index 0000000..df9983b +--- /dev/null ++++ b/fs/aufs/whout.c +@@ -0,0 +1,1052 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * whiteout for logical deletion and opaque directory ++ */ ++ ++#include ++#include "aufs.h" ++ ++#define WH_MASK S_IRUGO ++ ++/* ++ * If a directory contains this file, then it is opaque. We start with the ++ * .wh. flag so that it is blocked by lookup. ++ */ ++static struct qstr diropq_name = { ++ .name = AUFS_WH_DIROPQ, ++ .len = sizeof(AUFS_WH_DIROPQ) - 1 ++}; ++ ++/* ++ * generate whiteout name, which is NOT terminated by NULL. ++ * @name: original d_name.name ++ * @len: original d_name.len ++ * @wh: whiteout qstr ++ * returns zero when succeeds, otherwise error. ++ * succeeded value as wh->name should be freed by kfree(). ++ */ ++int au_wh_name_alloc(struct qstr *wh, const struct qstr *name) ++{ ++ char *p; ++ ++ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN)) ++ return -ENAMETOOLONG; ++ ++ wh->len = name->len + AUFS_WH_PFX_LEN; ++ p = kmalloc(wh->len, GFP_NOFS); ++ wh->name = p; ++ if (p) { ++ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); ++ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len); ++ /* smp_mb(); */ ++ return 0; ++ } ++ return -ENOMEM; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * test if the @wh_name exists under @h_parent. ++ * @try_sio specifies the necessary of super-io. ++ */ ++int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, ++ struct au_branch *br, int try_sio) ++{ ++ int err; ++ struct dentry *wh_dentry; ++ struct inode *h_dir; ++ ++ h_dir = h_parent->d_inode; ++ if (!try_sio) ++ wh_dentry = au_lkup_one(wh_name, h_parent, br, /*nd*/NULL); ++ else ++ wh_dentry = au_sio_lkup_one(wh_name, h_parent, br); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out; ++ ++ err = 0; ++ if (!wh_dentry->d_inode) ++ goto out_wh; /* success */ ++ ++ err = 1; ++ if (S_ISREG(wh_dentry->d_inode->i_mode)) ++ goto out_wh; /* success */ ++ ++ err = -EIO; ++ AuIOErr("%.*s Invalid whiteout entry type 0%o.\n", ++ AuDLNPair(wh_dentry), wh_dentry->d_inode->i_mode); ++ ++ out_wh: ++ dput(wh_dentry); ++ out: ++ return err; ++} ++ ++/* ++ * test if the @h_dentry sets opaque or not. ++ */ ++int au_diropq_test(struct dentry *h_dentry, struct au_branch *br) ++{ ++ int err; ++ struct inode *h_dir; ++ ++ h_dir = h_dentry->d_inode; ++ err = au_wh_test(h_dentry, &diropq_name, br, ++ au_test_h_perm_sio(h_dir, MAY_EXEC)); ++ return err; ++} ++ ++/* ++ * returns a negative dentry whose name is unique and temporary. ++ */ ++struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br, ++ struct qstr *prefix) ++{ ++#define HEX_LEN 4 ++ struct dentry *dentry; ++ int i; ++ char defname[AUFS_WH_PFX_LEN * 2 + DNAME_INLINE_LEN_MIN + 1 ++ + HEX_LEN + 1], *name, *p; ++ static unsigned short cnt; ++ struct qstr qs; ++ ++ name = defname; ++ qs.len = sizeof(defname) - DNAME_INLINE_LEN_MIN + prefix->len - 1; ++ if (unlikely(prefix->len > DNAME_INLINE_LEN_MIN)) { ++ dentry = ERR_PTR(-ENAMETOOLONG); ++ if (unlikely(qs.len >= PATH_MAX)) ++ goto out; ++ dentry = ERR_PTR(-ENOMEM); ++ name = kmalloc(qs.len + 1, GFP_NOFS); ++ if (unlikely(!name)) ++ goto out; ++ } ++ ++ /* doubly whiteout-ed */ ++ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2); ++ p = name + AUFS_WH_PFX_LEN * 2; ++ memcpy(p, prefix->name, prefix->len); ++ p += prefix->len; ++ *p++ = '.'; ++ AuDebugOn(name + qs.len + 1 - p <= HEX_LEN); ++ ++ qs.name = name; ++ for (i = 0; i < 3; i++) { ++ sprintf(p, "%.*d", HEX_LEN, cnt++); ++ dentry = au_sio_lkup_one(&qs, h_parent, br); ++ if (IS_ERR(dentry) || !dentry->d_inode) ++ goto out_name; ++ dput(dentry); ++ } ++ /* AuWarn("could not get random name\n"); */ ++ dentry = ERR_PTR(-EEXIST); ++ AuDbg("%.*s\n", AuLNPair(&qs)); ++ BUG(); ++ ++ out_name: ++ if (name != defname) ++ kfree(name); ++ out: ++ return dentry; ++#undef HEX_LEN ++} ++ ++/* ++ * rename the @h_dentry on @br to the whiteouted temporary name. ++ */ ++int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br) ++{ ++ int err; ++ struct path h_path = { ++ .mnt = br->br_mnt ++ }; ++ struct inode *h_dir; ++ struct dentry *h_parent; ++ ++ h_parent = h_dentry->d_parent; /* dir inode is locked */ ++ h_dir = h_parent->d_inode; ++ IMustLock(h_dir); ++ ++ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name); ++ err = PTR_ERR(h_path.dentry); ++ if (IS_ERR(h_path.dentry)) ++ goto out; ++ ++ /* under the same dir, no need to lock_rename() */ ++ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path); ++ AuTraceErr(err); ++ dput(h_path.dentry); ++ ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* ++ * functions for removing a whiteout ++ */ ++ ++static int do_unlink_wh(struct inode *h_dir, struct path *h_path) ++{ ++ int force; ++ ++ /* ++ * forces superio when the dir has a sticky bit. ++ * this may be a violation of unix fs semantics. ++ */ ++ force = (h_dir->i_mode & S_ISVTX) ++ && h_path->dentry->d_inode->i_uid != current_fsuid(); ++ return vfsub_unlink(h_dir, h_path, force); ++} ++ ++int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path, ++ struct dentry *dentry) ++{ ++ int err; ++ ++ err = do_unlink_wh(h_dir, h_path); ++ if (!err && dentry) ++ au_set_dbwh(dentry, -1); ++ ++ return err; ++} ++ ++static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh, ++ struct au_branch *br) ++{ ++ int err; ++ struct path h_path = { ++ .mnt = br->br_mnt ++ }; ++ ++ err = 0; ++ h_path.dentry = au_lkup_one(wh, h_parent, br, /*nd*/NULL); ++ if (IS_ERR(h_path.dentry)) ++ err = PTR_ERR(h_path.dentry); ++ else { ++ if (h_path.dentry->d_inode ++ && S_ISREG(h_path.dentry->d_inode->i_mode)) ++ err = do_unlink_wh(h_parent->d_inode, &h_path); ++ dput(h_path.dentry); ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* ++ * initialize/clean whiteout for a branch ++ */ ++ ++static void au_wh_clean(struct inode *h_dir, struct path *whpath, ++ const int isdir) ++{ ++ int err; ++ ++ if (!whpath->dentry->d_inode) ++ return; ++ ++ err = mnt_want_write(whpath->mnt); ++ if (!err) { ++ if (isdir) ++ err = vfsub_rmdir(h_dir, whpath); ++ else ++ err = vfsub_unlink(h_dir, whpath, /*force*/0); ++ mnt_drop_write(whpath->mnt); ++ } ++ if (unlikely(err)) ++ AuWarn("failed removing %.*s (%d), ignored.\n", ++ AuDLNPair(whpath->dentry), err); ++} ++ ++static int test_linkable(struct dentry *h_root) ++{ ++ struct inode *h_dir = h_root->d_inode; ++ ++ if (h_dir->i_op->link) ++ return 0; ++ ++ AuErr("%.*s (%s) doesn't support link(2), use noplink and rw+nolwh\n", ++ AuDLNPair(h_root), au_sbtype(h_root->d_sb)); ++ return -ENOSYS; ++} ++ ++/* todo: should this mkdir be done in /sbin/mount.aufs helper? */ ++static int au_whdir(struct inode *h_dir, struct path *path) ++{ ++ int err; ++ ++ err = -EEXIST; ++ if (!path->dentry->d_inode) { ++ int mode = S_IRWXU; ++ ++ if (au_test_nfs(path->dentry->d_sb)) ++ mode |= S_IXUGO; ++ err = mnt_want_write(path->mnt); ++ if (!err) { ++ err = vfsub_mkdir(h_dir, path, mode); ++ mnt_drop_write(path->mnt); ++ } ++ } else if (S_ISDIR(path->dentry->d_inode->i_mode)) ++ err = 0; ++ else ++ AuErr("unknown %.*s exists\n", AuDLNPair(path->dentry)); ++ ++ return err; ++} ++ ++struct au_wh_base { ++ const struct qstr *name; ++ struct dentry *dentry; ++}; ++ ++static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[], ++ struct path *h_path) ++{ ++ h_path->dentry = base[AuBrWh_BASE].dentry; ++ au_wh_clean(h_dir, h_path, /*isdir*/0); ++ h_path->dentry = base[AuBrWh_PLINK].dentry; ++ au_wh_clean(h_dir, h_path, /*isdir*/1); ++ h_path->dentry = base[AuBrWh_ORPH].dentry; ++ au_wh_clean(h_dir, h_path, /*isdir*/1); ++} ++ ++/* ++ * returns tri-state, ++ * minus: error, caller should print the mesage ++ * zero: succuess ++ * plus: error, caller should NOT print the mesage ++ */ ++static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr, ++ int do_plink, struct au_wh_base base[], ++ struct path *h_path) ++{ ++ int err; ++ struct inode *h_dir; ++ ++ h_dir = h_root->d_inode; ++ h_path->dentry = base[AuBrWh_BASE].dentry; ++ au_wh_clean(h_dir, h_path, /*isdir*/0); ++ h_path->dentry = base[AuBrWh_PLINK].dentry; ++ if (do_plink) { ++ err = test_linkable(h_root); ++ if (unlikely(err)) { ++ err = 1; ++ goto out; ++ } ++ ++ err = au_whdir(h_dir, h_path); ++ if (unlikely(err)) ++ goto out; ++ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry); ++ } else ++ au_wh_clean(h_dir, h_path, /*isdir*/1); ++ h_path->dentry = base[AuBrWh_ORPH].dentry; ++ err = au_whdir(h_dir, h_path); ++ if (unlikely(err)) ++ goto out; ++ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry); ++ ++ out: ++ return err; ++} ++ ++/* ++ * for the moment, aufs supports the branch filesystem which does not support ++ * link(2). testing on FAT which does not support i_op->setattr() fully either, ++ * copyup failed. finally, such filesystem will not be used as the writable ++ * branch. ++ * ++ * returns tri-state, see above. ++ */ ++static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr, ++ int do_plink, struct au_wh_base base[], ++ struct path *h_path) ++{ ++ int err; ++ struct inode *h_dir; ++ ++ WbrWhMustWriteLock(wbr); ++ ++ err = test_linkable(h_root); ++ if (unlikely(err)) { ++ err = 1; ++ goto out; ++ } ++ ++ /* ++ * todo: should this create be done in /sbin/mount.aufs helper? ++ */ ++ err = -EEXIST; ++ h_dir = h_root->d_inode; ++ if (!base[AuBrWh_BASE].dentry->d_inode) { ++ err = mnt_want_write(h_path->mnt); ++ if (!err) { ++ h_path->dentry = base[AuBrWh_BASE].dentry; ++ err = vfsub_create(h_dir, h_path, WH_MASK); ++ mnt_drop_write(h_path->mnt); ++ } ++ } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode)) ++ err = 0; ++ else ++ AuErr("unknown %.*s/%.*s exists\n", ++ AuDLNPair(h_root), AuDLNPair(base[AuBrWh_BASE].dentry)); ++ if (unlikely(err)) ++ goto out; ++ ++ h_path->dentry = base[AuBrWh_PLINK].dentry; ++ if (do_plink) { ++ err = au_whdir(h_dir, h_path); ++ if (unlikely(err)) ++ goto out; ++ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry); ++ } else ++ au_wh_clean(h_dir, h_path, /*isdir*/1); ++ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry); ++ ++ h_path->dentry = base[AuBrWh_ORPH].dentry; ++ err = au_whdir(h_dir, h_path); ++ if (unlikely(err)) ++ goto out; ++ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry); ++ ++ out: ++ return err; ++} ++ ++/* ++ * initialize the whiteout base file/dir for @br. ++ */ ++int au_wh_init(struct dentry *h_root, struct au_branch *br, ++ struct super_block *sb) ++{ ++ int err, i; ++ const unsigned char do_plink ++ = !!au_opt_test(au_mntflags(sb), PLINK); ++ struct path path = { ++ .mnt = br->br_mnt ++ }; ++ struct inode *h_dir; ++ struct au_wbr *wbr = br->br_wbr; ++ static const struct qstr base_name[] = { ++ [AuBrWh_BASE] = { ++ .name = AUFS_BASE_NAME, ++ .len = sizeof(AUFS_BASE_NAME) - 1 ++ }, ++ [AuBrWh_PLINK] = { ++ .name = AUFS_PLINKDIR_NAME, ++ .len = sizeof(AUFS_PLINKDIR_NAME) - 1 ++ }, ++ [AuBrWh_ORPH] = { ++ .name = AUFS_ORPHDIR_NAME, ++ .len = sizeof(AUFS_ORPHDIR_NAME) - 1 ++ } ++ }; ++ struct au_wh_base base[] = { ++ [AuBrWh_BASE] = { ++ .name = base_name + AuBrWh_BASE, ++ .dentry = NULL ++ }, ++ [AuBrWh_PLINK] = { ++ .name = base_name + AuBrWh_PLINK, ++ .dentry = NULL ++ }, ++ [AuBrWh_ORPH] = { ++ .name = base_name + AuBrWh_ORPH, ++ .dentry = NULL ++ } ++ }; ++ ++ if (wbr) ++ WbrWhMustWriteLock(wbr); ++ ++ h_dir = h_root->d_inode; ++ for (i = 0; i < AuBrWh_Last; i++) { ++ /* doubly whiteouted */ ++ struct dentry *d; ++ ++ d = au_wh_lkup(h_root, (void *)base[i].name, br); ++ err = PTR_ERR(d); ++ if (IS_ERR(d)) ++ goto out; ++ ++ base[i].dentry = d; ++ AuDebugOn(wbr ++ && wbr->wbr_wh[i] ++ && wbr->wbr_wh[i] != base[i].dentry); ++ } ++ ++ if (wbr) ++ for (i = 0; i < AuBrWh_Last; i++) { ++ dput(wbr->wbr_wh[i]); ++ wbr->wbr_wh[i] = NULL; ++ } ++ ++ err = 0; ++ ++ switch (br->br_perm) { ++ case AuBrPerm_RO: ++ case AuBrPerm_ROWH: ++ case AuBrPerm_RR: ++ case AuBrPerm_RRWH: ++ au_wh_init_ro(h_dir, base, &path); ++ break; ++ ++ case AuBrPerm_RWNoLinkWH: ++ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path); ++ if (err > 0) ++ goto out; ++ else if (err) ++ goto out_err; ++ break; ++ ++ case AuBrPerm_RW: ++ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path); ++ if (err > 0) ++ goto out; ++ else if (err) ++ goto out_err; ++ break; ++ ++ default: ++ BUG(); ++ } ++ goto out; /* success */ ++ ++ out_err: ++ AuErr("an error(%d) on the writable branch %.*s(%s)\n", ++ err, AuDLNPair(h_root), au_sbtype(h_root->d_sb)); ++ out: ++ for (i = 0; i < AuBrWh_Last; i++) ++ dput(base[i].dentry); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* ++ * whiteouts are all hard-linked usually. ++ * when its link count reaches a ceiling, we create a new whiteout base ++ * asynchronously. ++ */ ++ ++struct reinit_br_wh { ++ struct super_block *sb; ++ struct au_branch *br; ++}; ++ ++static void reinit_br_wh(void *arg) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ struct path h_path; ++ struct reinit_br_wh *a = arg; ++ struct au_wbr *wbr; ++ struct inode *dir; ++ struct dentry *h_root; ++ struct au_hinode *hdir; ++ ++ err = 0; ++ wbr = a->br->br_wbr; ++ /* big aufs lock */ ++ si_noflush_write_lock(a->sb); ++ if (!au_br_writable(a->br->br_perm)) ++ goto out; ++ bindex = au_br_index(a->sb, a->br->br_id); ++ if (unlikely(bindex < 0)) ++ goto out; ++ ++ di_read_lock_parent(a->sb->s_root, AuLock_IR); ++ dir = a->sb->s_root->d_inode; ++ hdir = au_hi(dir, bindex); ++ h_root = au_h_dptr(a->sb->s_root, bindex); ++ ++ au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT); ++ wbr_wh_write_lock(wbr); ++ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode, ++ h_root, a->br); ++ if (!err) { ++ err = mnt_want_write(a->br->br_mnt); ++ if (!err) { ++ h_path.dentry = wbr->wbr_whbase; ++ h_path.mnt = a->br->br_mnt; ++ err = vfsub_unlink(hdir->hi_inode, &h_path, /*force*/0); ++ mnt_drop_write(a->br->br_mnt); ++ } ++ } else { ++ AuWarn("%.*s is moved, ignored\n", AuDLNPair(wbr->wbr_whbase)); ++ err = 0; ++ } ++ dput(wbr->wbr_whbase); ++ wbr->wbr_whbase = NULL; ++ if (!err) ++ err = au_wh_init(h_root, a->br, a->sb); ++ wbr_wh_write_unlock(wbr); ++ au_hin_imtx_unlock(hdir); ++ di_read_unlock(a->sb->s_root, AuLock_IR); ++ ++ out: ++ if (wbr) ++ atomic_dec(&wbr->wbr_wh_running); ++ atomic_dec(&a->br->br_count); ++ au_nwt_done(&au_sbi(a->sb)->si_nowait); ++ si_write_unlock(a->sb); ++ kfree(arg); ++ if (unlikely(err)) ++ AuIOErr("err %d\n", err); ++} ++ ++static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br) ++{ ++ int do_dec, wkq_err; ++ struct reinit_br_wh *arg; ++ ++ do_dec = 1; ++ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1) ++ goto out; ++ ++ /* ignore ENOMEM */ ++ arg = kmalloc(sizeof(*arg), GFP_NOFS); ++ if (arg) { ++ /* ++ * dec(wh_running), kfree(arg) and dec(br_count) ++ * in reinit function ++ */ ++ arg->sb = sb; ++ arg->br = br; ++ atomic_inc(&br->br_count); ++ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb); ++ if (unlikely(wkq_err)) { ++ atomic_dec(&br->br_wbr->wbr_wh_running); ++ atomic_dec(&br->br_count); ++ kfree(arg); ++ } ++ do_dec = 0; ++ } ++ ++ out: ++ if (do_dec) ++ atomic_dec(&br->br_wbr->wbr_wh_running); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * create the whiteout @wh. ++ */ ++static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex, ++ struct dentry *wh) ++{ ++ int err; ++ struct path h_path = { ++ .dentry = wh ++ }; ++ struct au_branch *br; ++ struct au_wbr *wbr; ++ struct dentry *h_parent; ++ struct inode *h_dir; ++ ++ h_parent = wh->d_parent; /* dir inode is locked */ ++ h_dir = h_parent->d_inode; ++ IMustLock(h_dir); ++ ++ br = au_sbr(sb, bindex); ++ h_path.mnt = br->br_mnt; ++ wbr = br->br_wbr; ++ wbr_wh_read_lock(wbr); ++ if (wbr->wbr_whbase) { ++ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path); ++ if (!err || err != -EMLINK) ++ goto out; ++ ++ /* link count full. re-initialize br_whbase. */ ++ kick_reinit_br_wh(sb, br); ++ } ++ ++ /* return this error in this context */ ++ err = vfsub_create(h_dir, &h_path, WH_MASK); ++ ++ out: ++ wbr_wh_read_unlock(wbr); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * create or remove the diropq. ++ */ ++static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int flags) ++{ ++ struct dentry *opq_dentry, *h_dentry; ++ struct super_block *sb; ++ struct au_branch *br; ++ int err; ++ ++ sb = dentry->d_sb; ++ br = au_sbr(sb, bindex); ++ h_dentry = au_h_dptr(dentry, bindex); ++ opq_dentry = au_lkup_one(&diropq_name, h_dentry, br, /*nd*/NULL); ++ if (IS_ERR(opq_dentry)) ++ goto out; ++ ++ if (au_ftest_diropq(flags, CREATE)) { ++ err = link_or_create_wh(sb, bindex, opq_dentry); ++ if (!err) { ++ au_set_dbdiropq(dentry, bindex); ++ goto out; /* success */ ++ } ++ } else { ++ struct path tmp = { ++ .dentry = opq_dentry, ++ .mnt = br->br_mnt ++ }; ++ err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp); ++ if (!err) ++ au_set_dbdiropq(dentry, -1); ++ } ++ dput(opq_dentry); ++ opq_dentry = ERR_PTR(err); ++ ++ out: ++ return opq_dentry; ++} ++ ++struct do_diropq_args { ++ struct dentry **errp; ++ struct dentry *dentry; ++ aufs_bindex_t bindex; ++ unsigned int flags; ++}; ++ ++static void call_do_diropq(void *args) ++{ ++ struct do_diropq_args *a = args; ++ *a->errp = do_diropq(a->dentry, a->bindex, a->flags); ++} ++ ++struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int flags) ++{ ++ struct dentry *diropq, *h_dentry; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE)) ++ diropq = do_diropq(dentry, bindex, flags); ++ else { ++ int wkq_err; ++ struct do_diropq_args args = { ++ .errp = &diropq, ++ .dentry = dentry, ++ .bindex = bindex, ++ .flags = flags ++ }; ++ ++ wkq_err = au_wkq_wait(call_do_diropq, &args); ++ if (unlikely(wkq_err)) ++ diropq = ERR_PTR(wkq_err); ++ } ++ ++ return diropq; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * lookup whiteout dentry. ++ * @h_parent: lower parent dentry which must exist and be locked ++ * @base_name: name of dentry which will be whiteouted ++ * returns dentry for whiteout. ++ */ ++struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name, ++ struct au_branch *br) ++{ ++ int err; ++ struct qstr wh_name; ++ struct dentry *wh_dentry; ++ ++ err = au_wh_name_alloc(&wh_name, base_name); ++ wh_dentry = ERR_PTR(err); ++ if (!err) { ++ wh_dentry = au_lkup_one(&wh_name, h_parent, br, /*nd*/NULL); ++ kfree(wh_name.name); ++ } ++ return wh_dentry; ++} ++ ++/* ++ * link/create a whiteout for @dentry on @bindex. ++ */ ++struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent) ++{ ++ struct dentry *wh_dentry; ++ struct super_block *sb; ++ int err; ++ ++ sb = dentry->d_sb; ++ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex)); ++ if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) { ++ err = link_or_create_wh(sb, bindex, wh_dentry); ++ if (!err) ++ au_set_dbwh(dentry, bindex); ++ else { ++ dput(wh_dentry); ++ wh_dentry = ERR_PTR(err); ++ } ++ } ++ ++ return wh_dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* Delete all whiteouts in this directory on branch bindex. */ ++static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist, ++ aufs_bindex_t bindex, struct au_branch *br) ++{ ++ int err; ++ unsigned long ul, n; ++ struct qstr wh_name; ++ char *p; ++ struct hlist_head *head; ++ struct au_vdir_wh *tpos; ++ struct hlist_node *pos; ++ struct au_vdir_destr *str; ++ ++ err = -ENOMEM; ++ p = __getname(); ++ wh_name.name = p; ++ if (unlikely(!wh_name.name)) ++ goto out; ++ ++ err = 0; ++ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); ++ p += AUFS_WH_PFX_LEN; ++ n = whlist->nh_num; ++ head = whlist->nh_head; ++ for (ul = 0; !err && ul < n; ul++, head++) { ++ hlist_for_each_entry(tpos, pos, head, wh_hash) { ++ if (tpos->wh_bindex != bindex) ++ continue; ++ ++ str = &tpos->wh_str; ++ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) { ++ memcpy(p, str->name, str->len); ++ wh_name.len = AUFS_WH_PFX_LEN + str->len; ++ err = unlink_wh_name(h_dentry, &wh_name, br); ++ if (!err) ++ continue; ++ break; ++ } ++ AuIOErr("whiteout name too long %.*s\n", ++ str->len, str->name); ++ err = -EIO; ++ break; ++ } ++ } ++ __putname(wh_name.name); ++ ++ out: ++ return err; ++} ++ ++struct del_wh_children_args { ++ int *errp; ++ struct dentry *h_dentry; ++ struct au_nhash *whlist; ++ aufs_bindex_t bindex; ++ struct au_branch *br; ++}; ++ ++static void call_del_wh_children(void *args) ++{ ++ struct del_wh_children_args *a = args; ++ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp) ++{ ++ struct au_whtmp_rmdir *whtmp; ++ int err; ++ unsigned int rdhash; ++ ++ SiMustAnyLock(sb); ++ ++ whtmp = kmalloc(sizeof(*whtmp), gfp); ++ if (unlikely(!whtmp)) { ++ whtmp = ERR_PTR(-ENOMEM); ++ goto out; ++ } ++ ++ whtmp->dir = NULL; ++ whtmp->wh_dentry = NULL; ++ /* no estimation for dir size */ ++ rdhash = au_sbi(sb)->si_rdhash; ++ if (!rdhash) ++ rdhash = AUFS_RDHASH_DEF; ++ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp); ++ if (unlikely(err)) { ++ kfree(whtmp); ++ whtmp = ERR_PTR(err); ++ } ++ ++ out: ++ return whtmp; ++} ++ ++void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp) ++{ ++ dput(whtmp->wh_dentry); ++ iput(whtmp->dir); ++ au_nhash_wh_free(&whtmp->whlist); ++ kfree(whtmp); ++} ++ ++/* ++ * rmdir the whiteouted temporary named dir @h_dentry. ++ * @whlist: whiteouted children. ++ */ ++int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct au_nhash *whlist) ++{ ++ int err; ++ struct path h_tmp; ++ struct inode *wh_inode, *h_dir; ++ struct au_branch *br; ++ ++ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */ ++ IMustLock(h_dir); ++ ++ br = au_sbr(dir->i_sb, bindex); ++ wh_inode = wh_dentry->d_inode; ++ mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD); ++ ++ /* ++ * someone else might change some whiteouts while we were sleeping. ++ * it means this whlist may have an obsoleted entry. ++ */ ++ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE)) ++ err = del_wh_children(wh_dentry, whlist, bindex, br); ++ else { ++ int wkq_err; ++ struct del_wh_children_args args = { ++ .errp = &err, ++ .h_dentry = wh_dentry, ++ .whlist = whlist, ++ .bindex = bindex, ++ .br = br ++ }; ++ ++ wkq_err = au_wkq_wait(call_del_wh_children, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ mutex_unlock(&wh_inode->i_mutex); ++ ++ if (!err) { ++ h_tmp.dentry = wh_dentry; ++ h_tmp.mnt = br->br_mnt; ++ err = vfsub_rmdir(h_dir, &h_tmp); ++ /* d_drop(h_dentry); */ ++ } ++ ++ if (!err) { ++ if (au_ibstart(dir) == bindex) { ++ au_cpup_attr_timesizes(dir); ++ drop_nlink(dir); ++ } ++ return 0; /* success */ ++ } ++ ++ AuWarn("failed removing %.*s(%d), ignored\n", ++ AuDLNPair(wh_dentry), err); ++ return err; ++} ++ ++static void call_rmdir_whtmp(void *args) ++{ ++ int err; ++ struct au_whtmp_rmdir *a = args; ++ struct super_block *sb; ++ struct dentry *h_parent; ++ struct inode *h_dir; ++ struct au_branch *br; ++ struct au_hinode *hdir; ++ ++ /* rmdir by nfsd may cause deadlock with this i_mutex */ ++ /* mutex_lock(&a->dir->i_mutex); */ ++ sb = a->dir->i_sb; ++ si_noflush_read_lock(sb); ++ err = au_test_ro(sb, a->bindex, NULL); ++ if (unlikely(err)) ++ goto out; ++ ++ err = -EIO; ++ br = au_sbr(sb, a->bindex); ++ ii_write_lock_parent(a->dir); ++ h_parent = dget_parent(a->wh_dentry); ++ h_dir = h_parent->d_inode; ++ hdir = au_hi(a->dir, a->bindex); ++ au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT); ++ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent, br); ++ if (!err) { ++ err = mnt_want_write(br->br_mnt); ++ if (!err) { ++ err = au_whtmp_rmdir(a->dir, a->bindex, a->wh_dentry, ++ &a->whlist); ++ mnt_drop_write(br->br_mnt); ++ } ++ } ++ au_hin_imtx_unlock(hdir); ++ dput(h_parent); ++ ii_write_unlock(a->dir); ++ ++ out: ++ /* mutex_unlock(&a->dir->i_mutex); */ ++ au_nwt_done(&au_sbi(sb)->si_nowait); ++ si_read_unlock(sb); ++ au_whtmp_rmdir_free(a); ++ if (unlikely(err)) ++ AuIOErr("err %d\n", err); ++} ++ ++void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct au_whtmp_rmdir *args) ++{ ++ int wkq_err; ++ ++ IMustLock(dir); ++ ++ /* all post-process will be done in do_rmdir_whtmp(). */ ++ args->dir = au_igrab(dir); ++ args->bindex = bindex; ++ args->wh_dentry = dget(wh_dentry); ++ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, dir->i_sb); ++ if (unlikely(wkq_err)) { ++ AuWarn("rmdir error %.*s (%d), ignored\n", ++ AuDLNPair(wh_dentry), wkq_err); ++ au_whtmp_rmdir_free(args); ++ } ++} +diff --git a/fs/aufs/whout.h b/fs/aufs/whout.h +new file mode 100644 +index 0000000..40c6926 +--- /dev/null ++++ b/fs/aufs/whout.h +@@ -0,0 +1,87 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * whiteout for logical deletion and opaque directory ++ */ ++ ++#ifndef __AUFS_WHOUT_H__ ++#define __AUFS_WHOUT_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include "dir.h" ++ ++/* whout.c */ ++int au_wh_name_alloc(struct qstr *wh, const struct qstr *name); ++struct au_branch; ++int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, ++ struct au_branch *br, int try_sio); ++int au_diropq_test(struct dentry *h_dentry, struct au_branch *br); ++struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br, ++ struct qstr *prefix); ++int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br); ++int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path, ++ struct dentry *dentry); ++int au_wh_init(struct dentry *h_parent, struct au_branch *br, ++ struct super_block *sb); ++ ++/* diropq flags */ ++#define AuDiropq_CREATE 1 ++#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name) ++#define au_fset_diropq(flags, name) { (flags) |= AuDiropq_##name; } ++#define au_fclr_diropq(flags, name) { (flags) &= ~AuDiropq_##name; } ++ ++struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int flags); ++struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name, ++ struct au_branch *br); ++struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent); ++ ++/* real rmdir for the whiteout-ed dir */ ++struct au_whtmp_rmdir { ++ struct inode *dir; ++ aufs_bindex_t bindex; ++ struct dentry *wh_dentry; ++ struct au_nhash whlist; ++}; ++ ++struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp); ++void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp); ++int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct au_nhash *whlist); ++void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct au_whtmp_rmdir *args); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct dentry *au_diropq_create(struct dentry *dentry, ++ aufs_bindex_t bindex) ++{ ++ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE); ++} ++ ++static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE)); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_WHOUT_H__ */ +diff --git a/fs/aufs/wkq.c b/fs/aufs/wkq.c +new file mode 100644 +index 0000000..89656e9 +--- /dev/null ++++ b/fs/aufs/wkq.c +@@ -0,0 +1,259 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * workqueue for asynchronous/super-io operations ++ * todo: try new dredential scheme ++ */ ++ ++#include ++#include "aufs.h" ++ ++/* internal workqueue named AUFS_WKQ_NAME */ ++static struct au_wkq { ++ struct workqueue_struct *q; ++ ++ /* balancing */ ++ atomic_t busy; ++} *au_wkq; ++ ++struct au_wkinfo { ++ struct work_struct wk; ++ struct super_block *sb; ++ ++ unsigned int flags; /* see wkq.h */ ++ ++ au_wkq_func_t func; ++ void *args; ++ ++ atomic_t *busyp; ++ struct completion *comp; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int enqueue(struct au_wkq *wkq, struct au_wkinfo *wkinfo) ++{ ++ wkinfo->busyp = &wkq->busy; ++ if (au_ftest_wkq(wkinfo->flags, WAIT)) ++ return !queue_work(wkq->q, &wkinfo->wk); ++ else ++ return !schedule_work(&wkinfo->wk); ++} ++ ++static void do_wkq(struct au_wkinfo *wkinfo) ++{ ++ unsigned int idle, n; ++ int i, idle_idx; ++ ++ while (1) { ++ if (au_ftest_wkq(wkinfo->flags, WAIT)) { ++ idle_idx = 0; ++ idle = UINT_MAX; ++ for (i = 0; i < aufs_nwkq; i++) { ++ n = atomic_inc_return(&au_wkq[i].busy); ++ if (n == 1 && !enqueue(au_wkq + i, wkinfo)) ++ return; /* success */ ++ ++ if (n < idle) { ++ idle_idx = i; ++ idle = n; ++ } ++ atomic_dec(&au_wkq[i].busy); ++ } ++ } else ++ idle_idx = aufs_nwkq; ++ ++ atomic_inc(&au_wkq[idle_idx].busy); ++ if (!enqueue(au_wkq + idle_idx, wkinfo)) ++ return; /* success */ ++ ++ /* impossible? */ ++ AuWarn1("failed to queue_work()\n"); ++ yield(); ++ } ++} ++ ++static void wkq_func(struct work_struct *wk) ++{ ++ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk); ++ ++ wkinfo->func(wkinfo->args); ++ atomic_dec_return(wkinfo->busyp); ++ if (au_ftest_wkq(wkinfo->flags, WAIT)) ++ complete(wkinfo->comp); ++ else { ++ kobject_put(&au_sbi(wkinfo->sb)->si_kobj); ++ module_put(THIS_MODULE); ++ kfree(wkinfo); ++ } ++} ++ ++/* ++ * Since struct completion is large, try allocating it dynamically. ++ */ ++#if defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) ++#define AuWkqCompDeclare(name) struct completion *comp = NULL ++ ++static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp) ++{ ++ *comp = kmalloc(sizeof(**comp), GFP_NOFS); ++ if (*comp) { ++ init_completion(*comp); ++ wkinfo->comp = *comp; ++ return 0; ++ } ++ return -ENOMEM; ++} ++ ++static void au_wkq_comp_free(struct completion *comp) ++{ ++ kfree(comp); ++} ++ ++#else ++ ++/* no braces */ ++#define AuWkqCompDeclare(name) \ ++ DECLARE_COMPLETION_ONSTACK(_ ## name); \ ++ struct completion *comp = &_ ## name ++ ++static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp) ++{ ++ wkinfo->comp = *comp; ++ return 0; ++} ++ ++static void au_wkq_comp_free(struct completion *comp __maybe_unused) ++{ ++ /* empty */ ++} ++#endif /* 4KSTACKS */ ++ ++static void au_wkq_run(struct au_wkinfo *wkinfo) ++{ ++ au_dbg_verify_kthread(); ++ INIT_WORK(&wkinfo->wk, wkq_func); ++ do_wkq(wkinfo); ++} ++ ++int au_wkq_wait(au_wkq_func_t func, void *args) ++{ ++ int err; ++ AuWkqCompDeclare(comp); ++ struct au_wkinfo wkinfo = { ++ .flags = AuWkq_WAIT, ++ .func = func, ++ .args = args ++ }; ++ ++ err = au_wkq_comp_alloc(&wkinfo, &comp); ++ if (!err) { ++ au_wkq_run(&wkinfo); ++ /* no timeout, no interrupt */ ++ wait_for_completion(wkinfo.comp); ++ au_wkq_comp_free(comp); ++ } ++ ++ return err; ++ ++} ++ ++int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb) ++{ ++ int err; ++ struct au_wkinfo *wkinfo; ++ ++ atomic_inc(&au_sbi(sb)->si_nowait.nw_len); ++ ++ /* ++ * wkq_func() must free this wkinfo. ++ * it highly depends upon the implementation of workqueue. ++ */ ++ err = 0; ++ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS); ++ if (wkinfo) { ++ wkinfo->sb = sb; ++ wkinfo->flags = !AuWkq_WAIT; ++ wkinfo->func = func; ++ wkinfo->args = args; ++ wkinfo->comp = NULL; ++ kobject_get(&au_sbi(sb)->si_kobj); ++ __module_get(THIS_MODULE); ++ ++ au_wkq_run(wkinfo); ++ } else { ++ err = -ENOMEM; ++ atomic_dec(&au_sbi(sb)->si_nowait.nw_len); ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_nwt_init(struct au_nowait_tasks *nwt) ++{ ++ atomic_set(&nwt->nw_len, 0); ++ /* smp_mb();*/ /* atomic_set */ ++ init_waitqueue_head(&nwt->nw_wq); ++} ++ ++void au_wkq_fin(void) ++{ ++ int i; ++ ++ for (i = 0; i < aufs_nwkq; i++) ++ if (au_wkq[i].q && !IS_ERR(au_wkq[i].q)) ++ destroy_workqueue(au_wkq[i].q); ++ kfree(au_wkq); ++} ++ ++int __init au_wkq_init(void) ++{ ++ int err, i; ++ struct au_wkq *nowaitq; ++ ++ /* '+1' is for accounting of nowait queue */ ++ err = -ENOMEM; ++ au_wkq = kcalloc(aufs_nwkq + 1, sizeof(*au_wkq), GFP_NOFS); ++ if (unlikely(!au_wkq)) ++ goto out; ++ ++ err = 0; ++ for (i = 0; i < aufs_nwkq; i++) { ++ au_wkq[i].q = create_singlethread_workqueue(AUFS_WKQ_NAME); ++ if (au_wkq[i].q && !IS_ERR(au_wkq[i].q)) { ++ atomic_set(&au_wkq[i].busy, 0); ++ continue; ++ } ++ ++ err = PTR_ERR(au_wkq[i].q); ++ au_wkq_fin(); ++ goto out; ++ } ++ ++ /* nowait accounting */ ++ nowaitq = au_wkq + aufs_nwkq; ++ atomic_set(&nowaitq->busy, 0); ++ nowaitq->q = NULL; ++ /* smp_mb(); */ /* atomic_set */ ++ ++ out: ++ return err; ++} +diff --git a/fs/aufs/wkq.h b/fs/aufs/wkq.h +new file mode 100644 +index 0000000..b5b6a61 +--- /dev/null ++++ b/fs/aufs/wkq.h +@@ -0,0 +1,82 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * workqueue for asynchronous/super-io operations ++ * todo: try new credentials management scheme ++ */ ++ ++#ifndef __AUFS_WKQ_H__ ++#define __AUFS_WKQ_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++ ++struct super_block; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue ++ */ ++struct au_nowait_tasks { ++ atomic_t nw_len; ++ wait_queue_head_t nw_wq; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++typedef void (*au_wkq_func_t)(void *args); ++ ++/* wkq flags */ ++#define AuWkq_WAIT 1 ++#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name) ++#define au_fset_wkq(flags, name) { (flags) |= AuWkq_##name; } ++#define au_fclr_wkq(flags, name) { (flags) &= ~AuWkq_##name; } ++ ++/* wkq.c */ ++int au_wkq_wait(au_wkq_func_t func, void *args); ++int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb); ++void au_nwt_init(struct au_nowait_tasks *nwt); ++int __init au_wkq_init(void); ++void au_wkq_fin(void); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline int au_test_wkq(struct task_struct *tsk) ++{ ++ return !tsk->mm && !strcmp(tsk->comm, AUFS_WKQ_NAME); ++} ++ ++static inline void au_nwt_done(struct au_nowait_tasks *nwt) ++{ ++ if (!atomic_dec_return(&nwt->nw_len)) ++ wake_up_all(&nwt->nw_wq); ++} ++ ++static inline int au_nwt_flush(struct au_nowait_tasks *nwt) ++{ ++ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len)); ++ return 0; ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_WKQ_H__ */ +diff --git a/fs/aufs/xino.c b/fs/aufs/xino.c +new file mode 100644 +index 0000000..da07499 +--- /dev/null ++++ b/fs/aufs/xino.c +@@ -0,0 +1,1200 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++/* ++ * external inode number translation table and bitmap ++ */ ++ ++#include ++#include ++#include ++#include "aufs.h" ++ ++ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size, ++ loff_t *pos) ++{ ++ ssize_t err; ++ mm_segment_t oldfs; ++ ++ oldfs = get_fs(); ++ set_fs(KERNEL_DS); ++ do { ++ /* todo: signal_pending? */ ++ err = func(file, (char __user *)buf, size, pos); ++ } while (err == -EAGAIN || err == -EINTR); ++ set_fs(oldfs); ++ ++#if 0 /* reserved for future use */ ++ if (err > 0) ++ fsnotify_access(file->f_dentry); ++#endif ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *buf, ++ size_t size, loff_t *pos) ++{ ++ ssize_t err; ++ mm_segment_t oldfs; ++ ++ oldfs = get_fs(); ++ set_fs(KERNEL_DS); ++ lockdep_off(); ++ do { ++ /* todo: signal_pending? */ ++ err = func(file, (const char __user *)buf, size, pos); ++ } while (err == -EAGAIN || err == -EINTR); ++ lockdep_on(); ++ set_fs(oldfs); ++ ++#if 0 /* reserved for future use */ ++ if (err > 0) ++ fsnotify_modify(file->f_dentry); ++#endif ++ ++ return err; ++} ++ ++struct do_xino_fwrite_args { ++ ssize_t *errp; ++ au_writef_t func; ++ struct file *file; ++ void *buf; ++ size_t size; ++ loff_t *pos; ++}; ++ ++static void call_do_xino_fwrite(void *args) ++{ ++ struct do_xino_fwrite_args *a = args; ++ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos); ++} ++ ++ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size, ++ loff_t *pos) ++{ ++ ssize_t err; ++ ++ /* todo: signal block and no wkq? */ ++ /* todo: new credential scheme */ ++ /* ++ * it breaks RLIMIT_FSIZE and normal user's limit, ++ * users should care about quota and real 'filesystem full.' ++ */ ++ if (!au_test_wkq(current)) { ++ int wkq_err; ++ struct do_xino_fwrite_args args = { ++ .errp = &err, ++ .func = func, ++ .file = file, ++ .buf = buf, ++ .size = size, ++ .pos = pos ++ }; ++ ++ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } else ++ err = do_xino_fwrite(func, file, buf, size, pos); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * create a new xinofile at the same place/path as @base_file. ++ */ ++struct file *au_xino_create2(struct file *base_file, struct file *copy_src) ++{ ++ struct file *file; ++ struct dentry *base, *dentry, *parent; ++ struct inode *dir; ++ struct qstr *name; ++ int err; ++ ++ base = base_file->f_dentry; ++ parent = base->d_parent; /* dir inode is locked */ ++ dir = parent->d_inode; ++ IMustLock(dir); ++ ++ file = ERR_PTR(-EINVAL); ++ name = &base->d_name; ++ dentry = vfsub_lookup_one_len(name->name, parent, name->len); ++ if (IS_ERR(dentry)) { ++ file = (void *)dentry; ++ AuErr("%.*s lookup err %ld\n", AuLNPair(name), PTR_ERR(dentry)); ++ goto out; ++ } ++ ++ /* no need to mnt_want_write() since we call dentry_open() later */ ++ err = vfs_create(dir, dentry, S_IRUGO | S_IWUGO, NULL); ++ if (unlikely(err)) { ++ file = ERR_PTR(err); ++ AuErr("%.*s create err %d\n", AuLNPair(name), err); ++ goto out_dput; ++ } ++ ++ file = dentry_open(dget(dentry), mntget(base_file->f_vfsmnt), ++ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE, ++ current_cred()); ++ if (IS_ERR(file)) { ++ AuErr("%.*s open err %ld\n", AuLNPair(name), PTR_ERR(file)); ++ goto out_dput; ++ } ++ ++ err = vfsub_unlink(dir, &file->f_path, /*force*/0); ++ if (unlikely(err)) { ++ AuErr("%.*s unlink err %d\n", AuLNPair(name), err); ++ goto out_fput; ++ } ++ ++ if (copy_src) { ++ /* no one can touch copy_src xino */ ++ err = au_copy_file(file, copy_src, ++ i_size_read(copy_src->f_dentry->d_inode)); ++ if (unlikely(err)) { ++ AuErr("%.*s copy err %d\n", AuLNPair(name), err); ++ goto out_fput; ++ } ++ } ++ goto out_dput; /* success */ ++ ++ out_fput: ++ fput(file); ++ file = ERR_PTR(err); ++ out_dput: ++ dput(dentry); ++ out: ++ return file; ++} ++ ++struct au_xino_lock_dir { ++ struct au_hinode *hdir; ++ struct dentry *parent; ++ struct mutex *mtx; ++}; ++ ++static void au_xino_lock_dir(struct super_block *sb, struct file *xino, ++ struct au_xino_lock_dir *ldir) ++{ ++ aufs_bindex_t brid, bindex; ++ ++ ldir->hdir = NULL; ++ bindex = -1; ++ brid = au_xino_brid(sb); ++ if (brid >= 0) ++ bindex = au_br_index(sb, brid); ++ if (bindex >= 0) { ++ ldir->hdir = au_hi(sb->s_root->d_inode, bindex); ++ au_hin_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT); ++ } else { ++ ldir->parent = dget_parent(xino->f_dentry); ++ ldir->mtx = &ldir->parent->d_inode->i_mutex; ++ mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT); ++ } ++} ++ ++static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir) ++{ ++ if (ldir->hdir) ++ au_hin_imtx_unlock(ldir->hdir); ++ else { ++ mutex_unlock(ldir->mtx); ++ dput(ldir->parent); ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* trucate xino files asynchronously */ ++ ++int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ int err; ++ aufs_bindex_t bi, bend; ++ struct au_branch *br; ++ struct file *new_xino, *file; ++ struct super_block *h_sb; ++ struct au_xino_lock_dir ldir; ++ ++ err = -EINVAL; ++ bend = au_sbend(sb); ++ if (unlikely(bindex < 0 || bend < bindex)) ++ goto out; ++ br = au_sbr(sb, bindex); ++ file = br->br_xino.xi_file; ++ if (!file) ++ goto out; ++ ++ au_xino_lock_dir(sb, file, &ldir); ++ /* mnt_want_write() is unnecessary here */ ++ new_xino = au_xino_create2(file, file); ++ au_xino_unlock_dir(&ldir); ++ err = PTR_ERR(new_xino); ++ if (IS_ERR(new_xino)) ++ goto out; ++ err = 0; ++ fput(file); ++ br->br_xino.xi_file = new_xino; ++ ++ h_sb = br->br_mnt->mnt_sb; ++ for (bi = 0; bi <= bend; bi++) { ++ if (unlikely(bi == bindex)) ++ continue; ++ br = au_sbr(sb, bi); ++ if (br->br_mnt->mnt_sb != h_sb) ++ continue; ++ ++ fput(br->br_xino.xi_file); ++ br->br_xino.xi_file = new_xino; ++ get_file(new_xino); ++ } ++ ++ out: ++ return err; ++} ++ ++struct xino_do_trunc_args { ++ struct super_block *sb; ++ struct au_branch *br; ++}; ++ ++static void xino_do_trunc(void *_args) ++{ ++ struct xino_do_trunc_args *args = _args; ++ struct super_block *sb; ++ struct au_branch *br; ++ struct inode *dir; ++ int err; ++ aufs_bindex_t bindex; ++ ++ err = 0; ++ sb = args->sb; ++ dir = sb->s_root->d_inode; ++ br = args->br; ++ ++ si_noflush_write_lock(sb); ++ ii_read_lock_parent(dir); ++ bindex = au_br_index(sb, br->br_id); ++ err = au_xino_trunc(sb, bindex); ++ if (!err ++ && br->br_xino.xi_file->f_dentry->d_inode->i_blocks ++ >= br->br_xino_upper) ++ br->br_xino_upper += AUFS_XINO_TRUNC_STEP; ++ ++ ii_read_unlock(dir); ++ if (unlikely(err)) ++ AuWarn("err b%d, (%d)\n", bindex, err); ++ atomic_dec(&br->br_xino_running); ++ atomic_dec(&br->br_count); ++ au_nwt_done(&au_sbi(sb)->si_nowait); ++ si_write_unlock(sb); ++ kfree(args); ++} ++ ++static void xino_try_trunc(struct super_block *sb, struct au_branch *br) ++{ ++ struct xino_do_trunc_args *args; ++ int wkq_err; ++ ++ if (br->br_xino.xi_file->f_dentry->d_inode->i_blocks ++ < br->br_xino_upper) ++ return; ++ ++ if (atomic_inc_return(&br->br_xino_running) > 1) ++ goto out; ++ ++ /* lock and kfree() will be called in trunc_xino() */ ++ args = kmalloc(sizeof(*args), GFP_NOFS); ++ if (unlikely(!args)) { ++ AuErr1("no memory\n"); ++ goto out_args; ++ } ++ ++ atomic_inc_return(&br->br_count); ++ args->sb = sb; ++ args->br = br; ++ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb); ++ if (!wkq_err) ++ return; /* success */ ++ ++ AuErr("wkq %d\n", wkq_err); ++ atomic_dec_return(&br->br_count); ++ ++ out_args: ++ kfree(args); ++ out: ++ atomic_dec_return(&br->br_xino_running); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_xino_do_write(au_writef_t write, struct file *file, ++ ino_t h_ino, ino_t ino) ++{ ++ loff_t pos; ++ ssize_t sz; ++ ++ pos = h_ino; ++ if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) { ++ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino); ++ return -EFBIG; ++ } ++ pos *= sizeof(ino); ++ sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos); ++ if (sz == sizeof(ino)) ++ return 0; /* success */ ++ ++ AuIOErr("write failed (%zd)\n", sz); ++ return -EIO; ++} ++ ++/* ++ * write @ino to the xinofile for the specified branch{@sb, @bindex} ++ * at the position of @h_ino. ++ * even if @ino is zero, it is written to the xinofile and means no entry. ++ * if the size of the xino file on a specific filesystem exceeds the watermark, ++ * try truncating it. ++ */ ++int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t ino) ++{ ++ int err; ++ unsigned int mnt_flags; ++ struct au_branch *br; ++ ++ BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max) ++ || ((loff_t)-1) > 0); ++ SiMustAnyLock(sb); ++ ++ mnt_flags = au_mntflags(sb); ++ if (!au_opt_test(mnt_flags, XINO)) ++ return 0; ++ ++ br = au_sbr(sb, bindex); ++ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file, ++ h_ino, ino); ++ if (!err) { ++ if (au_opt_test(mnt_flags, TRUNC_XINO) ++ && au_test_fs_trunc_xino(br->br_mnt->mnt_sb)) ++ xino_try_trunc(sb, br); ++ return 0; /* success */ ++ } ++ ++ AuIOErr("write failed (%d)\n", err); ++ return -EIO; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* aufs inode number bitmap */ ++ ++static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE; ++static ino_t xib_calc_ino(unsigned long pindex, int bit) ++{ ++ ino_t ino; ++ ++ AuDebugOn(bit < 0 || page_bits <= bit); ++ ino = AUFS_FIRST_INO + pindex * page_bits + bit; ++ return ino; ++} ++ ++static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit) ++{ ++ AuDebugOn(ino < AUFS_FIRST_INO); ++ ino -= AUFS_FIRST_INO; ++ *pindex = ino / page_bits; ++ *bit = ino % page_bits; ++} ++ ++static int xib_pindex(struct super_block *sb, unsigned long pindex) ++{ ++ int err; ++ loff_t pos; ++ ssize_t sz; ++ struct au_sbinfo *sbinfo; ++ struct file *xib; ++ unsigned long *p; ++ ++ sbinfo = au_sbi(sb); ++ MtxMustLock(&sbinfo->si_xib_mtx); ++ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE ++ || !au_opt_test(sbinfo->si_mntflags, XINO)); ++ ++ if (pindex == sbinfo->si_xib_last_pindex) ++ return 0; ++ ++ xib = sbinfo->si_xib; ++ p = sbinfo->si_xib_buf; ++ pos = sbinfo->si_xib_last_pindex; ++ pos *= PAGE_SIZE; ++ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos); ++ if (unlikely(sz != PAGE_SIZE)) ++ goto out; ++ ++ pos = pindex; ++ pos *= PAGE_SIZE; ++ if (i_size_read(xib->f_dentry->d_inode) >= pos + PAGE_SIZE) ++ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos); ++ else { ++ memset(p, 0, PAGE_SIZE); ++ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos); ++ } ++ if (sz == PAGE_SIZE) { ++ sbinfo->si_xib_last_pindex = pindex; ++ return 0; /* success */ ++ } ++ ++ out: ++ AuIOErr1("write failed (%zd)\n", sz); ++ err = sz; ++ if (sz >= 0) ++ err = -EIO; ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_xino_write0(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t ino) ++{ ++ int err, bit; ++ unsigned long pindex; ++ struct au_sbinfo *sbinfo; ++ ++ if (!au_opt_test(au_mntflags(sb), XINO)) ++ return 0; ++ ++ err = 0; ++ if (ino) { ++ sbinfo = au_sbi(sb); ++ xib_calc_bit(ino, &pindex, &bit); ++ AuDebugOn(page_bits <= bit); ++ mutex_lock(&sbinfo->si_xib_mtx); ++ err = xib_pindex(sb, pindex); ++ if (!err) { ++ clear_bit(bit, sbinfo->si_xib_buf); ++ sbinfo->si_xib_next_bit = bit; ++ } ++ mutex_unlock(&sbinfo->si_xib_mtx); ++ } ++ ++ if (!err) ++ err = au_xino_write(sb, bindex, h_ino, 0); ++ return err; ++} ++ ++/* get an unused inode number from bitmap */ ++ino_t au_xino_new_ino(struct super_block *sb) ++{ ++ ino_t ino; ++ unsigned long *p, pindex, ul, pend; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ int free_bit, err; ++ ++ if (!au_opt_test(au_mntflags(sb), XINO)) ++ return iunique(sb, AUFS_FIRST_INO); ++ ++ sbinfo = au_sbi(sb); ++ mutex_lock(&sbinfo->si_xib_mtx); ++ p = sbinfo->si_xib_buf; ++ free_bit = sbinfo->si_xib_next_bit; ++ if (free_bit < page_bits && !test_bit(free_bit, p)) ++ goto out; /* success */ ++ free_bit = find_first_zero_bit(p, page_bits); ++ if (free_bit < page_bits) ++ goto out; /* success */ ++ ++ pindex = sbinfo->si_xib_last_pindex; ++ for (ul = pindex - 1; ul < ULONG_MAX; ul--) { ++ err = xib_pindex(sb, ul); ++ if (unlikely(err)) ++ goto out_err; ++ free_bit = find_first_zero_bit(p, page_bits); ++ if (free_bit < page_bits) ++ goto out; /* success */ ++ } ++ ++ file = sbinfo->si_xib; ++ pend = i_size_read(file->f_dentry->d_inode) / PAGE_SIZE; ++ for (ul = pindex + 1; ul <= pend; ul++) { ++ err = xib_pindex(sb, ul); ++ if (unlikely(err)) ++ goto out_err; ++ free_bit = find_first_zero_bit(p, page_bits); ++ if (free_bit < page_bits) ++ goto out; /* success */ ++ } ++ BUG(); ++ ++ out: ++ set_bit(free_bit, p); ++ sbinfo->si_xib_next_bit++; ++ pindex = sbinfo->si_xib_last_pindex; ++ mutex_unlock(&sbinfo->si_xib_mtx); ++ ino = xib_calc_ino(pindex, free_bit); ++ AuDbg("i%lu\n", (unsigned long)ino); ++ return ino; ++ out_err: ++ mutex_unlock(&sbinfo->si_xib_mtx); ++ AuDbg("i0\n"); ++ return 0; ++} ++ ++/* ++ * read @ino from xinofile for the specified branch{@sb, @bindex} ++ * at the position of @h_ino. ++ * if @ino does not exist and @do_new is true, get new one. ++ */ ++int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t *ino) ++{ ++ int err; ++ ssize_t sz; ++ loff_t pos; ++ struct file *file; ++ struct au_sbinfo *sbinfo; ++ ++ *ino = 0; ++ if (!au_opt_test(au_mntflags(sb), XINO)) ++ return 0; /* no xino */ ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ pos = h_ino; ++ if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) { ++ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino); ++ return -EFBIG; ++ } ++ pos *= sizeof(*ino); ++ ++ file = au_sbr(sb, bindex)->br_xino.xi_file; ++ if (i_size_read(file->f_dentry->d_inode) < pos + sizeof(*ino)) ++ return 0; /* no ino */ ++ ++ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos); ++ if (sz == sizeof(*ino)) ++ return 0; /* success */ ++ ++ err = sz; ++ if (unlikely(sz >= 0)) { ++ err = -EIO; ++ AuIOErr("xino read error (%zd)\n", sz); ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* create and set a new xino file */ ++ ++struct file *au_xino_create(struct super_block *sb, char *fname, int silent) ++{ ++ struct file *file; ++ struct dentry *h_parent, *d; ++ struct inode *h_dir; ++ int err; ++ ++ /* ++ * at mount-time, and the xino file is the default path, ++ * hinotify is disabled so we have no inotify events to ignore. ++ * when a user specified the xino, we cannot get au_hdir to be ignored. ++ */ ++ file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE, ++ S_IRUGO | S_IWUGO); ++ if (IS_ERR(file)) { ++ if (!silent) ++ AuErr("open %s(%ld)\n", fname, PTR_ERR(file)); ++ return file; ++ } ++ ++ /* keep file count */ ++ h_parent = dget_parent(file->f_dentry); ++ h_dir = h_parent->d_inode; ++ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); ++ /* mnt_want_write() is unnecessary here */ ++ err = vfsub_unlink(h_dir, &file->f_path, /*force*/0); ++ mutex_unlock(&h_dir->i_mutex); ++ dput(h_parent); ++ if (unlikely(err)) { ++ if (!silent) ++ AuErr("unlink %s(%d)\n", fname, err); ++ goto out; ++ } ++ ++ err = -EINVAL; ++ d = file->f_dentry; ++ if (unlikely(sb == d->d_sb)) { ++ if (!silent) ++ AuErr("%s must be outside\n", fname); ++ goto out; ++ } ++ if (unlikely(au_test_fs_bad_xino(d->d_sb))) { ++ if (!silent) ++ AuErr("xino doesn't support %s(%s)\n", ++ fname, au_sbtype(d->d_sb)); ++ goto out; ++ } ++ return file; /* success */ ++ ++ out: ++ fput(file); ++ file = ERR_PTR(err); ++ return file; ++} ++ ++/* ++ * find another branch who is on the same filesystem of the specified ++ * branch{@btgt}. search until @bend. ++ */ ++static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt, ++ aufs_bindex_t bend) ++{ ++ aufs_bindex_t bindex; ++ struct super_block *tgt_sb = au_sbr_sb(sb, btgt); ++ ++ for (bindex = 0; bindex < btgt; bindex++) ++ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex))) ++ return bindex; ++ for (bindex++; bindex <= bend; bindex++) ++ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex))) ++ return bindex; ++ return -1; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * initialize the xinofile for the specified branch @br ++ * at the place/path where @base_file indicates. ++ * test whether another branch is on the same filesystem or not, ++ * if @do_test is true. ++ */ ++int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino, ++ struct file *base_file, int do_test) ++{ ++ int err; ++ ino_t ino; ++ aufs_bindex_t bend, bindex; ++ struct au_branch *shared_br, *b; ++ struct file *file; ++ struct super_block *tgt_sb; ++ ++ shared_br = NULL; ++ bend = au_sbend(sb); ++ if (do_test) { ++ tgt_sb = br->br_mnt->mnt_sb; ++ for (bindex = 0; bindex <= bend; bindex++) { ++ b = au_sbr(sb, bindex); ++ if (tgt_sb == b->br_mnt->mnt_sb) { ++ shared_br = b; ++ break; ++ } ++ } ++ } ++ ++ if (!shared_br || !shared_br->br_xino.xi_file) { ++ struct au_xino_lock_dir ldir; ++ ++ au_xino_lock_dir(sb, base_file, &ldir); ++ /* mnt_want_write() is unnecessary here */ ++ file = au_xino_create2(base_file, NULL); ++ au_xino_unlock_dir(&ldir); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ br->br_xino.xi_file = file; ++ } else { ++ br->br_xino.xi_file = shared_br->br_xino.xi_file; ++ get_file(br->br_xino.xi_file); ++ } ++ ++ ino = AUFS_ROOT_INO; ++ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file, ++ h_ino, ino); ++ if (!err) ++ return 0; /* success */ ++ ++ ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* trucate a xino bitmap file */ ++ ++/* todo: slow */ ++static int do_xib_restore(struct super_block *sb, struct file *file, void *page) ++{ ++ int err, bit; ++ ssize_t sz; ++ unsigned long pindex; ++ loff_t pos, pend; ++ struct au_sbinfo *sbinfo; ++ au_readf_t func; ++ ino_t *ino; ++ unsigned long *p; ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ MtxMustLock(&sbinfo->si_xib_mtx); ++ p = sbinfo->si_xib_buf; ++ func = sbinfo->si_xread; ++ pend = i_size_read(file->f_dentry->d_inode); ++ pos = 0; ++ while (pos < pend) { ++ sz = xino_fread(func, file, page, PAGE_SIZE, &pos); ++ err = sz; ++ if (unlikely(sz <= 0)) ++ goto out; ++ ++ err = 0; ++ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) { ++ if (unlikely(*ino < AUFS_FIRST_INO)) ++ continue; ++ ++ xib_calc_bit(*ino, &pindex, &bit); ++ AuDebugOn(page_bits <= bit); ++ err = xib_pindex(sb, pindex); ++ if (!err) ++ set_bit(bit, p); ++ else ++ goto out; ++ } ++ } ++ ++ out: ++ return err; ++} ++ ++static int xib_restore(struct super_block *sb) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ void *page; ++ ++ err = -ENOMEM; ++ page = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!page)) ++ goto out; ++ ++ err = 0; ++ bend = au_sbend(sb); ++ for (bindex = 0; !err && bindex <= bend; bindex++) ++ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0) ++ err = do_xib_restore ++ (sb, au_sbr(sb, bindex)->br_xino.xi_file, page); ++ else ++ AuDbg("b%d\n", bindex); ++ free_page((unsigned long)page); ++ ++ out: ++ return err; ++} ++ ++int au_xib_trunc(struct super_block *sb) ++{ ++ int err; ++ ssize_t sz; ++ loff_t pos; ++ struct au_xino_lock_dir ldir; ++ struct au_sbinfo *sbinfo; ++ unsigned long *p; ++ struct file *file; ++ ++ SiMustWriteLock(sb); ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ if (!au_opt_test(sbinfo->si_mntflags, XINO)) ++ goto out; ++ ++ file = sbinfo->si_xib; ++ if (i_size_read(file->f_dentry->d_inode) <= PAGE_SIZE) ++ goto out; ++ ++ au_xino_lock_dir(sb, file, &ldir); ++ /* mnt_want_write() is unnecessary here */ ++ file = au_xino_create2(sbinfo->si_xib, NULL); ++ au_xino_unlock_dir(&ldir); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ fput(sbinfo->si_xib); ++ sbinfo->si_xib = file; ++ ++ p = sbinfo->si_xib_buf; ++ memset(p, 0, PAGE_SIZE); ++ pos = 0; ++ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos); ++ if (unlikely(sz != PAGE_SIZE)) { ++ err = sz; ++ AuIOErr("err %d\n", err); ++ if (sz >= 0) ++ err = -EIO; ++ goto out; ++ } ++ ++ mutex_lock(&sbinfo->si_xib_mtx); ++ /* mnt_want_write() is unnecessary here */ ++ err = xib_restore(sb); ++ mutex_unlock(&sbinfo->si_xib_mtx); ++ ++out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * xino mount option handlers ++ */ ++static au_readf_t find_readf(struct file *h_file) ++{ ++ const struct file_operations *fop = h_file->f_op; ++ ++ if (fop) { ++ if (fop->read) ++ return fop->read; ++ if (fop->aio_read) ++ return do_sync_read; ++ } ++ return ERR_PTR(-ENOSYS); ++} ++ ++static au_writef_t find_writef(struct file *h_file) ++{ ++ const struct file_operations *fop = h_file->f_op; ++ ++ if (fop) { ++ if (fop->write) ++ return fop->write; ++ if (fop->aio_write) ++ return do_sync_write; ++ } ++ return ERR_PTR(-ENOSYS); ++} ++ ++/* xino bitmap */ ++static void xino_clear_xib(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ sbinfo->si_xread = NULL; ++ sbinfo->si_xwrite = NULL; ++ if (sbinfo->si_xib) ++ fput(sbinfo->si_xib); ++ sbinfo->si_xib = NULL; ++ free_page((unsigned long)sbinfo->si_xib_buf); ++ sbinfo->si_xib_buf = NULL; ++} ++ ++static int au_xino_set_xib(struct super_block *sb, struct file *base) ++{ ++ int err; ++ loff_t pos; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ file = au_xino_create2(base, sbinfo->si_xib); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ if (sbinfo->si_xib) ++ fput(sbinfo->si_xib); ++ sbinfo->si_xib = file; ++ sbinfo->si_xread = find_readf(file); ++ sbinfo->si_xwrite = find_writef(file); ++ ++ err = -ENOMEM; ++ if (!sbinfo->si_xib_buf) ++ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS); ++ if (unlikely(!sbinfo->si_xib_buf)) ++ goto out_unset; ++ ++ sbinfo->si_xib_last_pindex = 0; ++ sbinfo->si_xib_next_bit = 0; ++ if (i_size_read(file->f_dentry->d_inode) < PAGE_SIZE) { ++ pos = 0; ++ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf, ++ PAGE_SIZE, &pos); ++ if (unlikely(err != PAGE_SIZE)) ++ goto out_free; ++ } ++ err = 0; ++ goto out; /* success */ ++ ++ out_free: ++ free_page((unsigned long)sbinfo->si_xib_buf); ++ sbinfo->si_xib_buf = NULL; ++ if (err >= 0) ++ err = -EIO; ++ out_unset: ++ fput(sbinfo->si_xib); ++ sbinfo->si_xib = NULL; ++ sbinfo->si_xread = NULL; ++ sbinfo->si_xwrite = NULL; ++ out: ++ return err; ++} ++ ++/* xino for each branch */ ++static void xino_clear_br(struct super_block *sb) ++{ ++ aufs_bindex_t bindex, bend; ++ struct au_branch *br; ++ ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (!br || !br->br_xino.xi_file) ++ continue; ++ ++ fput(br->br_xino.xi_file); ++ br->br_xino.xi_file = NULL; ++ } ++} ++ ++static int au_xino_set_br(struct super_block *sb, struct file *base) ++{ ++ int err; ++ ino_t ino; ++ aufs_bindex_t bindex, bend, bshared; ++ struct { ++ struct file *old, *new; ++ } *fpair, *p; ++ struct au_branch *br; ++ struct inode *inode; ++ au_writef_t writef; ++ ++ SiMustWriteLock(sb); ++ ++ err = -ENOMEM; ++ bend = au_sbend(sb); ++ fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS); ++ if (unlikely(!fpair)) ++ goto out; ++ ++ inode = sb->s_root->d_inode; ++ ino = AUFS_ROOT_INO; ++ writef = au_sbi(sb)->si_xwrite; ++ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) { ++ br = au_sbr(sb, bindex); ++ bshared = is_sb_shared(sb, bindex, bindex - 1); ++ if (bshared >= 0) { ++ /* shared xino */ ++ *p = fpair[bshared]; ++ get_file(p->new); ++ } ++ ++ if (!p->new) { ++ /* new xino */ ++ p->old = br->br_xino.xi_file; ++ p->new = au_xino_create2(base, br->br_xino.xi_file); ++ err = PTR_ERR(p->new); ++ if (IS_ERR(p->new)) { ++ p->new = NULL; ++ goto out_pair; ++ } ++ } ++ ++ err = au_xino_do_write(writef, p->new, ++ au_h_iptr(inode, bindex)->i_ino, ino); ++ if (unlikely(err)) ++ goto out_pair; ++ } ++ ++ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) { ++ br = au_sbr(sb, bindex); ++ if (br->br_xino.xi_file) ++ fput(br->br_xino.xi_file); ++ get_file(p->new); ++ br->br_xino.xi_file = p->new; ++ } ++ ++ out_pair: ++ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) ++ if (p->new) ++ fput(p->new); ++ else ++ break; ++ kfree(fpair); ++ out: ++ return err; ++} ++ ++void au_xino_clr(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ au_xigen_clr(sb); ++ xino_clear_xib(sb); ++ xino_clear_br(sb); ++ sbinfo = au_sbi(sb); ++ /* lvalue, do not call au_mntflags() */ ++ au_opt_clr(sbinfo->si_mntflags, XINO); ++} ++ ++int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount) ++{ ++ int err, skip; ++ struct dentry *parent, *cur_parent; ++ struct qstr *dname, *cur_name; ++ struct file *cur_xino; ++ struct inode *dir; ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ parent = dget_parent(xino->file->f_dentry); ++ if (remount) { ++ skip = 0; ++ dname = &xino->file->f_dentry->d_name; ++ cur_xino = sbinfo->si_xib; ++ if (cur_xino) { ++ cur_parent = dget_parent(cur_xino->f_dentry); ++ cur_name = &cur_xino->f_dentry->d_name; ++ skip = (cur_parent == parent ++ && dname->len == cur_name->len ++ && !memcmp(dname->name, cur_name->name, ++ dname->len)); ++ dput(cur_parent); ++ } ++ if (skip) ++ goto out; ++ } ++ ++ au_opt_set(sbinfo->si_mntflags, XINO); ++ dir = parent->d_inode; ++ mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT); ++ /* mnt_want_write() is unnecessary here */ ++ err = au_xino_set_xib(sb, xino->file); ++ if (!err) ++ err = au_xigen_set(sb, xino->file); ++ if (!err) ++ err = au_xino_set_br(sb, xino->file); ++ mutex_unlock(&dir->i_mutex); ++ if (!err) ++ goto out; /* success */ ++ ++ /* reset all */ ++ AuIOErr("failed creating xino(%d).\n", err); ++ ++ out: ++ dput(parent); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * create a xinofile at the default place/path. ++ */ ++struct file *au_xino_def(struct super_block *sb) ++{ ++ struct file *file; ++ char *page, *p; ++ struct au_branch *br; ++ struct super_block *h_sb; ++ struct path path; ++ aufs_bindex_t bend, bindex, bwr; ++ ++ br = NULL; ++ bend = au_sbend(sb); ++ bwr = -1; ++ for (bindex = 0; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (au_br_writable(br->br_perm) ++ && !au_test_fs_bad_xino(br->br_mnt->mnt_sb)) { ++ bwr = bindex; ++ break; ++ } ++ } ++ ++ if (bwr >= 0) { ++ file = ERR_PTR(-ENOMEM); ++ page = __getname(); ++ if (unlikely(!page)) ++ goto out; ++ path.mnt = br->br_mnt; ++ path.dentry = au_h_dptr(sb->s_root, bwr); ++ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME)); ++ file = (void *)p; ++ if (!IS_ERR(p)) { ++ strcat(p, "/" AUFS_XINO_FNAME); ++ AuDbg("%s\n", p); ++ file = au_xino_create(sb, p, /*silent*/0); ++ if (!IS_ERR(file)) ++ au_xino_brid_set(sb, br->br_id); ++ } ++ __putname(page); ++ } else { ++ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0); ++ if (IS_ERR(file)) ++ goto out; ++ h_sb = file->f_dentry->d_sb; ++ if (unlikely(au_test_fs_bad_xino(h_sb))) { ++ AuErr("xino doesn't support %s(%s)\n", ++ AUFS_XINO_DEFPATH, au_sbtype(h_sb)); ++ fput(file); ++ file = ERR_PTR(-EINVAL); ++ } ++ if (!IS_ERR(file)) ++ au_xino_brid_set(sb, -1); ++ } ++ ++ out: ++ return file; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_xino_path(struct seq_file *seq, struct file *file) ++{ ++ int err; ++ ++ err = au_seq_path(seq, &file->f_path); ++ if (unlikely(err < 0)) ++ goto out; ++ ++ err = 0; ++#define Deleted "\\040(deleted)" ++ seq->count -= sizeof(Deleted) - 1; ++ AuDebugOn(memcmp(seq->buf + seq->count, Deleted, ++ sizeof(Deleted) - 1)); ++#undef Deleted ++ ++ out: ++ return err; ++} +diff --git a/fs/namei.c b/fs/namei.c +index 967c3db..60c01b1 100644 +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -1200,7 +1200,7 @@ out: + * needs parent already locked. Doesn't follow mounts. + * SMP-safe. + */ +-static struct dentry *lookup_hash(struct nameidata *nd) ++struct dentry *lookup_hash(struct nameidata *nd) + { + int err; + +@@ -1210,7 +1210,7 @@ static struct dentry *lookup_hash(struct nameidata *nd) + return __lookup_hash(&nd->last, nd->path.dentry, nd); + } + +-static int __lookup_one_len(const char *name, struct qstr *this, ++int __lookup_one_len(const char *name, struct qstr *this, + struct dentry *base, int len) + { + unsigned long hash; +diff --git a/fs/splice.c b/fs/splice.c +index 666953d..35beccd 100644 +--- a/fs/splice.c ++++ b/fs/splice.c +@@ -905,8 +905,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); + /* + * Attempt to initiate a splice from pipe to file. + */ +-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, +- loff_t *ppos, size_t len, unsigned int flags) ++long do_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags) + { + int ret; + +@@ -929,9 +929,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, + /* + * Attempt to initiate a splice from a file to a pipe. + */ +-static long do_splice_to(struct file *in, loff_t *ppos, +- struct pipe_inode_info *pipe, size_t len, +- unsigned int flags) ++long do_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags) + { + int ret; + +diff --git a/include/linux/Kbuild b/include/linux/Kbuild +index 3f0eaa3..6b7611f 100644 +--- a/include/linux/Kbuild ++++ b/include/linux/Kbuild +@@ -34,6 +34,7 @@ header-y += atmppp.h + header-y += atmsap.h + header-y += atmsvc.h + header-y += atm_zatm.h ++header-y += aufs_type.h + header-y += auto_fs4.h + header-y += ax25.h + header-y += b1lli.h +diff --git a/include/linux/aufs_type.h b/include/linux/aufs_type.h +new file mode 100644 +index 0000000..323c963 +--- /dev/null ++++ b/include/linux/aufs_type.h +@@ -0,0 +1,184 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs 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 ++ */ ++ ++#ifndef __AUFS_TYPE_H__ ++#define __AUFS_TYPE_H__ ++ ++#include ++#include ++ ++#define AUFS_VERSION "2-30" ++ ++/* todo? move this to linux-2.6.19/include/magic.h */ ++#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_BRANCH_MAX_127 ++typedef __s8 aufs_bindex_t; ++#define AUFS_BRANCH_MAX 127 ++#else ++typedef __s16 aufs_bindex_t; ++#ifdef CONFIG_AUFS_BRANCH_MAX_511 ++#define AUFS_BRANCH_MAX 511 ++#elif defined(CONFIG_AUFS_BRANCH_MAX_1023) ++#define AUFS_BRANCH_MAX 1023 ++#elif defined(CONFIG_AUFS_BRANCH_MAX_32767) ++#define AUFS_BRANCH_MAX 32767 ++#endif ++#endif ++ ++#ifdef __KERNEL__ ++#ifndef AUFS_BRANCH_MAX ++#error unknown CONFIG_AUFS_BRANCH_MAX value ++#endif ++#endif /* __KERNEL__ */ ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define AUFS_NAME "aufs" ++#define AUFS_FSTYPE AUFS_NAME ++ ++#define AUFS_ROOT_INO 2 ++#define AUFS_FIRST_INO 11 ++ ++#define AUFS_WH_PFX ".wh." ++#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1) ++#define AUFS_XINO_FNAME "." AUFS_NAME ".xino" ++#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME ++#define AUFS_XINO_TRUNC_INIT 64 /* blocks */ ++#define AUFS_XINO_TRUNC_STEP 4 /* blocks */ ++#define AUFS_DIRWH_DEF 3 ++#define AUFS_RDCACHE_DEF 10 /* seconds */ ++#define AUFS_RDBLK_DEF 512 /* bytes */ ++#define AUFS_RDHASH_DEF 32 ++#define AUFS_WKQ_NAME AUFS_NAME "d" ++#define AUFS_NWKQ_DEF 4 ++#define AUFS_MFS_SECOND_DEF 30 /* seconds */ ++#define AUFS_PLINK_WARN 100 /* number of plinks */ ++ ++#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */ ++#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME ++ ++#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME ++#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk" ++#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph" ++ ++/* doubly whiteouted */ ++#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME ++#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME ++#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME ++ ++/* branch permission */ ++#define AUFS_BRPERM_RW "rw" ++#define AUFS_BRPERM_RO "ro" ++#define AUFS_BRPERM_RR "rr" ++#define AUFS_BRPERM_WH "wh" ++#define AUFS_BRPERM_NLWH "nolwh" ++#define AUFS_BRPERM_ROWH AUFS_BRPERM_RO "+" AUFS_BRPERM_WH ++#define AUFS_BRPERM_RRWH AUFS_BRPERM_RR "+" AUFS_BRPERM_WH ++#define AUFS_BRPERM_RWNLWH AUFS_BRPERM_RW "+" AUFS_BRPERM_NLWH ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ioctl */ ++enum { ++ AuCtl_PLINK_MAINT, ++ AuCtl_PLINK_CLEAN, ++ ++ /* readdir in userspace */ ++ AuCtl_RDU, ++ AuCtl_RDU_INO ++}; ++ ++/* borrowed from linux/include/linux/kernel.h */ ++#ifndef ALIGN ++#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1) ++#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) ++#endif ++ ++/* borrowed from linux/include/linux/compiler-gcc3.h */ ++#ifndef __aligned ++#define __aligned(x) __attribute__((aligned(x))) ++#define __packed __attribute__((packed)) ++#endif ++ ++struct au_rdu_cookie { ++ __u64 h_pos; ++ __s16 bindex; ++ __u8 flags; ++ __u8 pad; ++ __u32 generation; ++} __aligned(8); ++ ++struct au_rdu_ent { ++ __u64 ino; ++ __s16 bindex; ++ __u8 type; ++ __u8 nlen; ++ __u8 wh; ++ char name[0]; ++} __aligned(8); ++ ++static inline int au_rdu_len(int nlen) ++{ ++ /* include the terminating NULL */ ++ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1, ++ sizeof(__u64)); ++} ++ ++union au_rdu_ent_ul { ++ struct au_rdu_ent __user *e; ++ unsigned long ul; ++}; ++ ++enum { ++ AufsCtlRduV_SZ, ++ AufsCtlRduV_SZ_PTR, ++ AufsCtlRduV_End ++}; ++ ++struct aufs_rdu { ++ /* input */ ++ union { ++ __u64 sz; /* AuCtl_RDU */ ++ __u64 nent; /* AuCtl_RDU_INO */ ++ }; ++ union au_rdu_ent_ul ent; ++ __u16 verify[AufsCtlRduV_End]; ++ ++ /* input/output */ ++ __u32 blk; ++ ++ /* output */ ++ union au_rdu_ent_ul tail; ++ /* number of entries which were added in a single call */ ++ __u64 rent; ++ __u8 full; ++ __u8 shwh; ++ ++ struct au_rdu_cookie cookie; ++} __aligned(8); ++ ++#define AuCtlType 'A' ++#define AUFS_CTL_PLINK_MAINT _IO(AuCtlType, AuCtl_PLINK_MAINT) ++#define AUFS_CTL_PLINK_CLEAN _IO(AuCtlType, AuCtl_PLINK_CLEAN) ++#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu) ++#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu) ++ ++#endif /* __AUFS_TYPE_H__ */ +diff --git a/include/linux/namei.h b/include/linux/namei.h +index 518098f..42a5279 100644 +--- a/include/linux/namei.h ++++ b/include/linux/namei.h +@@ -74,6 +74,9 @@ extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry + extern struct file *nameidata_to_filp(struct nameidata *nd, int flags); + extern void release_open_intent(struct nameidata *); + ++extern struct dentry *lookup_hash(struct nameidata *nd); ++extern int __lookup_one_len(const char *name, struct qstr *this, ++ struct dentry *base, int len); + extern struct dentry *lookup_one_len(const char *, struct dentry *, int); + extern struct dentry *lookup_one_noperm(const char *, struct dentry *); + +diff --git a/include/linux/splice.h b/include/linux/splice.h +index 5f3faa9..d2f8660 100644 +--- a/include/linux/splice.h ++++ b/include/linux/splice.h +@@ -83,4 +83,10 @@ extern ssize_t splice_to_pipe(struct pipe_inode_info *, + extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *, + splice_direct_actor *); + ++extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags); ++extern long do_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags); ++ + #endif diff --git a/recipes/linux/linux-2.6.30/i686/defconfig b/recipes/linux/linux-2.6.30/i686/defconfig index 21157c49e1..3a29855b6b 100644 --- a/recipes/linux/linux-2.6.30/i686/defconfig +++ b/recipes/linux/linux-2.6.30/i686/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.30 -# Sat Aug 15 17:22:38 2009 +# Thu Sep 10 13:00:34 2009 # # CONFIG_64BIT is not set CONFIG_X86_32=y @@ -4216,6 +4216,18 @@ CONFIG_UFS_FS=m # CONFIG_UFS_DEBUG is not set CONFIG_EXOFS_FS=m # CONFIG_EXOFS_DEBUG is not set +CONFIG_AUFS_FS=y +CONFIG_AUFS_BRANCH_MAX_127=y +# CONFIG_AUFS_BRANCH_MAX_511 is not set +# CONFIG_AUFS_BRANCH_MAX_1023 is not set +# CONFIG_AUFS_BRANCH_MAX_32767 is not set +# CONFIG_AUFS_HINOTIFY is not set +# CONFIG_AUFS_RDU is not set +# CONFIG_AUFS_SHWH is not set +# CONFIG_AUFS_BR_RAMFS is not set +# CONFIG_AUFS_BR_FUSE is not set +# CONFIG_AUFS_DEBUG is not set +CONFIG_AUFS_BDEV_LOOP=y CONFIG_NILFS2_FS=m CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m diff --git a/recipes/linux/linux_2.6.30.bb b/recipes/linux/linux_2.6.30.bb index 706b48bbff..21603f6c45 100644 --- a/recipes/linux/linux_2.6.30.bb +++ b/recipes/linux/linux_2.6.30.bb @@ -1,6 +1,6 @@ require linux.inc -PR = "r2" +PR = "r3" S = "${WORKDIR}/linux-${PV}" @@ -16,6 +16,7 @@ DEFAULT_PREFERENCE_at91sam9263ek = "-1" SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-${PV}.tar.bz2 \ http://maxim.org.za/AT91RM9200/2.6/2.6.30-at91.patch.gz;patch=1 \ + file://aufs2-30.patch;patch=1 \ file://defconfig" SRC_URI_append_mpc8315e-rdb = " file://mpc8315erdb-add-msi-to-dts.patch;patch=1" -- cgit v1.2.3 From 62cbf42efeb5c7087064dcf23b14ce280f07f082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20L=C3=BCbbe?= Date: Thu, 10 Sep 2009 19:34:40 +0000 Subject: i686-generic: add more devices tables --- conf/machine/i686-generic.conf | 5 +++++ files/device_table_add-loop.txt | 1 + files/device_table_add-scsi.txt | 2 ++ 3 files changed, 8 insertions(+) create mode 100644 files/device_table_add-loop.txt create mode 100644 files/device_table_add-scsi.txt diff --git a/conf/machine/i686-generic.conf b/conf/machine/i686-generic.conf index 56353777c3..3179d401af 100644 --- a/conf/machine/i686-generic.conf +++ b/conf/machine/i686-generic.conf @@ -17,6 +17,11 @@ GLIBC_ADDONS = "nptl" GLIBC_EXTRA_OECONF = "--with-tls" IMAGE_FSTYPES ?= "ext2.gz" +IMAGE_DEVICE_TABLES = " \ + files/device_table-minimal.txt \ + files/device_table_add-loop.txt \ + files/device_table_add-scsi.txt \ +" MACHINE_FEATURES = "kernel26 screen keyboard pci usbhost acpi ext2 x86" MACHINE_EXTRA_RRECOMMENDS = " kernel-modules" diff --git a/files/device_table_add-loop.txt b/files/device_table_add-loop.txt new file mode 100644 index 0000000000..0176135df2 --- /dev/null +++ b/files/device_table_add-loop.txt @@ -0,0 +1 @@ +/dev/loop b 664 0 0 7 0 0 1 2 diff --git a/files/device_table_add-scsi.txt b/files/device_table_add-scsi.txt new file mode 100644 index 0000000000..74d7725185 --- /dev/null +++ b/files/device_table_add-scsi.txt @@ -0,0 +1,2 @@ +/dev/sda b 660 0 6 8 0 - - - +/dev/sda b 660 0 6 8 1 1 1 16 -- cgit v1.2.3 From b2cf1ca47ec7785b69e078500ceeed3e647dec4e Mon Sep 17 00:00:00 2001 From: Omar Barron Date: Thu, 17 Sep 2009 18:01:27 -0500 Subject: omapzoom2.conf: added machine conf for linux-omap-zoomsync kernel --- conf/machine/omapzoom2.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/machine/omapzoom2.conf b/conf/machine/omapzoom2.conf index abfec5e674..7d0a72b5d7 100644 --- a/conf/machine/omapzoom2.conf +++ b/conf/machine/omapzoom2.conf @@ -23,7 +23,7 @@ EXTRA_IMAGECMD_jffs2 = "-lnp " # Guesswork SERIAL_CONSOLE = "115200 ttyS3" -PREFERRED_PROVIDER_virtual/kernel = "linux-omapandroid" +PREFERRED_PROVIDER_virtual/kernel = "linux-omap-zoomsync" KERNEL_IMAGETYPE = "uImage" -- cgit v1.2.3 From 0d0ff49487cefda83b5180dd6f77d21824eac4a5 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Fri, 18 Sep 2009 12:00:48 +0100 Subject: linux-omap-zoomsync/omapzoom2/defconfig : enable twl4030 keypad driver --- recipes/linux/linux-omap-zoomsync/omapzoom2/defconfig | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/recipes/linux/linux-omap-zoomsync/omapzoom2/defconfig b/recipes/linux/linux-omap-zoomsync/omapzoom2/defconfig index f38376d09e..5666bc9785 100755 --- a/recipes/linux/linux-omap-zoomsync/omapzoom2/defconfig +++ b/recipes/linux/linux-omap-zoomsync/omapzoom2/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.31-rc7-omap1 -# Thu Sep 17 13:41:00 2009 +# Fri Sep 18 11:52:16 2009 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -707,7 +707,16 @@ CONFIG_INPUT_EVDEV=y # # Input Device Drivers # -# CONFIG_INPUT_KEYBOARD is not set +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_KEYBOARD_TWL4030=y +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set @@ -738,7 +747,10 @@ CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI=y # # Hardware I/O ports # -# CONFIG_SERIO is not set +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set # -- cgit v1.2.3 From 224b85126291b31bf3ecb00201890f785de2ea60 Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 13:17:49 +0200 Subject: xerces-j 2.9.1: Added (from Jalimo SVN). xerces-j-native 2.9.1: Dito. --- recipes/xerces-j/xerces-j-native_2.9.1.bb | 8 ++++++ recipes/xerces-j/xerces-j_2.9.1.bb | 45 +++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 recipes/xerces-j/xerces-j-native_2.9.1.bb create mode 100644 recipes/xerces-j/xerces-j_2.9.1.bb diff --git a/recipes/xerces-j/xerces-j-native_2.9.1.bb b/recipes/xerces-j/xerces-j-native_2.9.1.bb new file mode 100644 index 0000000000..9238ad9ff2 --- /dev/null +++ b/recipes/xerces-j/xerces-j-native_2.9.1.bb @@ -0,0 +1,8 @@ +require xerces-j_${PV}.bb + +S = "${WORKDIR}/xerces-2_9_1" + +inherit java-native + +DEPENDS = "fastjar-native jaxp1.3-native xml-commons-resolver1.1-native" +RDEPENDS = "" diff --git a/recipes/xerces-j/xerces-j_2.9.1.bb b/recipes/xerces-j/xerces-j_2.9.1.bb new file mode 100644 index 0000000000..9a1b4c7956 --- /dev/null +++ b/recipes/xerces-j/xerces-j_2.9.1.bb @@ -0,0 +1,45 @@ +DESCRIPTION = "Reference implementation of XNI, the Xerces Native Interface, and also a fully conforming XML Schema processor." +LICENSES = "AL2.0" +AUTHOR = "Apache Software Foundation" + +SRC_URI = "http://www.apache.org/dist/xerces/j/Xerces-J-src.${PV}.tar.gz" + +S = "${WORKDIR}/xerces-2_9_1" + +inherit java-library + +JPN = "libxerces2-java" + +DEPENDS = "fastjar-native jaxp1.3 xml-commons-resolver1.1" +RDEPENDS = "libjaxp1.3-java libxml-commons-resolver1.1-java" + +do_unpackpost() { + find src -exec \ + sed -i -e "s|@impl.name@|Xerces-J ${PV}|" \ + -e "s|@impl.version@|${PV}|" {} \; +} + +addtask unpackpost after do_unpack before do_patch + +JARFILENAME = "xercesImpl.jar" +ALTJARFILENAMES = "" + +do_compile() { + mkdir -p build + + # Prepend the bootclasspath with the earlier XML API to make + # compilation succeed. + oe_makeclasspath bcp -s jaxp-1.3 resolver + bcp=$bcp:${STAGING_DATADIR_NATIVE}/classpath/glibj.zip + + javac -sourcepath src -d build -bootclasspath $bcp `find src -name "*.java"` + + (cd src && find org ! -name "*.java" -exec cp {} ../build/{} \;) + + fastjar -C build -c -m src/manifest.xerces -f ${JARFILENAME} . + + # Like Debian we provide a symlink called xmlParserAPIs.jar pointing to the JAXP + # classes. + ln -sf ${D}${datadir_java}/xmlParserAPIs.jar jaxp-1.3.jar + +} -- cgit v1.2.3 From e815e80bdf71c0c4cf0469d0b362be6dfe37e075 Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 13:40:54 +0200 Subject: jlex 1.2.6: Added (from Jalimo SVN). jlex-native 1.2.6: Dito. --- recipes/jlex/files/jlex | 5 +++++ recipes/jlex/jlex-native_1.2.6.bb | 23 +++++++++++++++++++++++ recipes/jlex/jlex_1.2.6.bb | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100755 recipes/jlex/files/jlex create mode 100644 recipes/jlex/jlex-native_1.2.6.bb create mode 100644 recipes/jlex/jlex_1.2.6.bb diff --git a/recipes/jlex/files/jlex b/recipes/jlex/files/jlex new file mode 100755 index 0000000000..7a9e756239 --- /dev/null +++ b/recipes/jlex/files/jlex @@ -0,0 +1,5 @@ +#!/bin/sh + +cp=OE_STAGING_DATADIR_JAVA/OE_JLEX_JAR + +exec OE_STAGING_BINDIR/java -cp $cp JLex.Main "$@" diff --git a/recipes/jlex/jlex-native_1.2.6.bb b/recipes/jlex/jlex-native_1.2.6.bb new file mode 100644 index 0000000000..6f8194b145 --- /dev/null +++ b/recipes/jlex/jlex-native_1.2.6.bb @@ -0,0 +1,23 @@ +require jlex_${PV}.bb + +inherit java-native + +DEPENDS += "virtual/java-native" +RDEPENDS = "" + +do_configure() { + sed -i \ + -e "s|OE_STAGING_BINDIR|${STAGING_BINDIR_NATIVE}|" \ + -e "s|OE_STAGING_DATADIR_JAVA|${STAGING_DATADIR_JAVA_NATIVE}|" \ + -e "s|OE_JLEX_JAR|${BP}.jar|" \ + ${WORKDIR}/jlex +} + +do_install_append() { + : +} + +do_stage_append() { + install -d ${STAGING_BINDIR} + install -m 0755 jlex ${STAGING_BINDIR} +} diff --git a/recipes/jlex/jlex_1.2.6.bb b/recipes/jlex/jlex_1.2.6.bb new file mode 100644 index 0000000000..05401df972 --- /dev/null +++ b/recipes/jlex/jlex_1.2.6.bb @@ -0,0 +1,39 @@ +DESCRIPTION = "Lexical analyzer generator for Java" +AUTHOR = "Elliot Berk, A. Appel, C. Scott Ananian" + +DEPENDS = "fastjar-native" +RDEPENDS = "java2-runtime" + +inherit java-library + +SRC_URI = "\ + http://www.cs.princeton.edu/~appel/modern/java/JLex/Archive/${PV}/Main.java \ + file://jlex \ + " + +S = "${WORKDIR}" + +do_configure() { + sed -i \ + -e "s|OE_STAGING_BINDIR|${bindir}|" \ + -e "s|OE_STAGING_DATADIR_JAVA|${datadir_java}|" \ + -e "s|OE_JLEX_JAR|${BP}.jar|" \ + ${WORKDIR}/jlex +} + +do_compile() { + mkdir -p build + + javac -d build Main.java + + fastjar -C build -c -f ${BP}.jar . +} + +do_install_append() { + install -d ${D}${bindir} + install -m 0755 jlex ${D}${bindir}/ +} + +PACKAGES = "${PN}" + +FILES_${PN} += "${datadir_java}" -- cgit v1.2.3 From d9fef0c7c9c064337223f847af28b6da4a180ced Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 13:42:32 +0200 Subject: cup 0.10k: New recipe (from Jalimo SVN). cup-native 0.10k: Dito. --- recipes/cup/cup-native_0.10k.bb | 24 ++++++++++++++++++++++++ recipes/cup/cup_0.10k.bb | 39 +++++++++++++++++++++++++++++++++++++++ recipes/cup/files/cup | 5 +++++ 3 files changed, 68 insertions(+) create mode 100644 recipes/cup/cup-native_0.10k.bb create mode 100644 recipes/cup/cup_0.10k.bb create mode 100755 recipes/cup/files/cup diff --git a/recipes/cup/cup-native_0.10k.bb b/recipes/cup/cup-native_0.10k.bb new file mode 100644 index 0000000000..2eb325fe1a --- /dev/null +++ b/recipes/cup/cup-native_0.10k.bb @@ -0,0 +1,24 @@ +require cup_${PV}.bb + +inherit java-native + +DEPENDS += "virtual/java-native" +RDEPENDS = "" + +do_configure() { + sed -i \ + -e "s|OE_STAGING_BINDIR|${STAGING_BINDIR_NATIVE}|" \ + -e "s|OE_STAGING_DATADIR_JAVA|${STAGING_DATADIR_JAVA_NATIVE}|" \ + -e "s|OE_CUP_JAR|${BP}.jar|" \ + ${WORKDIR}/cup +} + +do_install_append() { + : +} + +do_stage_append() { + install -d ${STAGING_BINDIR} + install -m 0755 ${WORKDIR}/cup ${STAGING_BINDIR} +} + diff --git a/recipes/cup/cup_0.10k.bb b/recipes/cup/cup_0.10k.bb new file mode 100644 index 0000000000..09d9644f74 --- /dev/null +++ b/recipes/cup/cup_0.10k.bb @@ -0,0 +1,39 @@ +DESCRIPTION = "Lexical analyzer generator for Java" +AUTHOR = "Elliot Berk, A. Appel, C. Scott Ananian" + +DEPENDS = "virtual/javac-native fastjar-native" +RDEPENDS = "java2-runtime" + +inherit java-library + +SRC_URI = "\ + http://www.cs.princeton.edu/~appel/modern/java/CUP/java_${BPN}_v10k.tar.gz \ + file://cup \ + " + +S = "${WORKDIR}/java_cup" + +do_configure() { + sed -i \ + -e "s|OE_STAGING_BINDIR|${bindir}|" \ + -e "s|OE_STAGING_DATADIR_JAVA|${data_java}|" \ + -e "s|OE_CUP_JAR|${BP}.jar|" \ + ${WORKDIR}/cup +} + +do_compile() { + mkdir -p build + + javac -d build `find . -name "*.java"` + + fastjar -C build -c -f ${BP}.jar . +} + +do_install_append() { + install -d ${D}${bindir} + install -m 0755 ${WORKDIR}/cup ${D}${bindir} +} + +PACKAGES = "${PN}" + +FILES_${PN} += "${datadir_java}" diff --git a/recipes/cup/files/cup b/recipes/cup/files/cup new file mode 100755 index 0000000000..34b4f05956 --- /dev/null +++ b/recipes/cup/files/cup @@ -0,0 +1,5 @@ +#!/bin/sh + +cp=OE_STAGING_DATADIR_JAVA/OE_CUP_JAR + +exec OE_STAGING_BINDIR/java -cp $cp java_cup.Main "$@" -- cgit v1.2.3 From f380fe99daeec7a31b9f094d06c54eaa3c5770bd Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 13:50:02 +0200 Subject: jaxp1.3 1.3.04: New recipe (from Jalimo SVN). jaxp1.3-native 1.3.04: Dito. xml-commons-resolver1.1 1.2: Dito. xml-commons-resolver1.1-native 1.2: Dito. --- recipes/xml-commons/jaxp1.3-native_1.3.04.bb | 4 +++ recipes/xml-commons/jaxp1.3_1.3.04.bb | 24 +++++++++++++++ .../xml-commons-resolver1.1-native_1.2.bb | 6 ++++ recipes/xml-commons/xml-commons-resolver1.1_1.2.bb | 35 ++++++++++++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 recipes/xml-commons/jaxp1.3-native_1.3.04.bb create mode 100644 recipes/xml-commons/jaxp1.3_1.3.04.bb create mode 100644 recipes/xml-commons/xml-commons-resolver1.1-native_1.2.bb create mode 100644 recipes/xml-commons/xml-commons-resolver1.1_1.2.bb diff --git a/recipes/xml-commons/jaxp1.3-native_1.3.04.bb b/recipes/xml-commons/jaxp1.3-native_1.3.04.bb new file mode 100644 index 0000000000..ae94b80140 --- /dev/null +++ b/recipes/xml-commons/jaxp1.3-native_1.3.04.bb @@ -0,0 +1,4 @@ +require jaxp1.3_${PV}.bb + +inherit java-native + diff --git a/recipes/xml-commons/jaxp1.3_1.3.04.bb b/recipes/xml-commons/jaxp1.3_1.3.04.bb new file mode 100644 index 0000000000..f66ae574fa --- /dev/null +++ b/recipes/xml-commons/jaxp1.3_1.3.04.bb @@ -0,0 +1,24 @@ +DESCRIPTION = "Java XML parser and transformer APIs (DOM, SAX, JAXP, TrAX)" +LICENSES = "AL2.0 W3C Public Domain" +AUTHOR = "Apache Software Foundation" + +SRC_URI = "http://archive.apache.org/dist/xml/commons/source/xml-commons-external-${PV}-src.tar.gz" + +inherit java-library + +S = "${WORKDIR}" + +DEPENDS = "fastjar-native" + +JARFILENAME = "jaxp-1.3.jar" +ALTJARFILENAMES = "xml-apis.jar" + +do_compile() { + mkdir -p build/license + javac -d build `find javax org -name \*.java` + + cp LICENSE.*.txt README.*.txt build/license + + fastjar -c -m manifest.commons -f ${JARFILENAME} -C build . +} + diff --git a/recipes/xml-commons/xml-commons-resolver1.1-native_1.2.bb b/recipes/xml-commons/xml-commons-resolver1.1-native_1.2.bb new file mode 100644 index 0000000000..382be4373d --- /dev/null +++ b/recipes/xml-commons/xml-commons-resolver1.1-native_1.2.bb @@ -0,0 +1,6 @@ +require xml-commons-resolver1.1_${PV}.bb + +inherit java-native + +DEPENDS = "fastjar-native jaxp1.3-native" + diff --git a/recipes/xml-commons/xml-commons-resolver1.1_1.2.bb b/recipes/xml-commons/xml-commons-resolver1.1_1.2.bb new file mode 100644 index 0000000000..9059dba28a --- /dev/null +++ b/recipes/xml-commons/xml-commons-resolver1.1_1.2.bb @@ -0,0 +1,35 @@ +DESCRIPTION = "Library to resolve various public or system identifiers into accessible URLs (Java)" +LICENSES = "AL2.0" +AUTHOR = "Apache Software Foundation" + +SRC_URI = "http://archive.apache.org/dist/xml/commons/xml-commons-resolver-${PV}.tar.gz" + +inherit java-library + +S = "${WORKDIR}/xml-commons-resolver-${PV}" + +DEPENDS = "fastjar-native jaxp1.3" + +do_unpackpost() { + find src -exec \ + sed -i -e "s|@impl.name@|XmlResolver|" \ + -e "s|@impl.version@|1.2|" {} \; +} + +addtask unpackpost after do_unpack before do_patch + +JARFILENAME = "resolver.jar" +ALTJARFILENAMES = "" + +do_compile() { + mkdir -p build + + cp=${STAGING_DATADIR_JAVA}/jaxp1.3.jar + + javac -sourcepath src -d build -classpath $cp `find src -name "*.java" -and -not -wholename "*tests*"` + + (cd src && find org -name "*.xml" -o -name "*.txt" -o -name "*.src" -exec cp {} ../build/{} \;) + + fastjar -C build -c -m src/manifest.resolver -f ${JARFILENAME} org +} + -- cgit v1.2.3 From e48d77d6dca005d16345c004caf1be716db12e3b Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 13:53:07 +0200 Subject: bcel 5.2: New recipe (from Jalimo SVN). bcel-native 5.2: Dito. --- recipes/bcel/bcel-native_5.2.bb | 6 ++++++ recipes/bcel/bcel_5.2.bb | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 recipes/bcel/bcel-native_5.2.bb create mode 100644 recipes/bcel/bcel_5.2.bb diff --git a/recipes/bcel/bcel-native_5.2.bb b/recipes/bcel/bcel-native_5.2.bb new file mode 100644 index 0000000000..478b770bff --- /dev/null +++ b/recipes/bcel/bcel-native_5.2.bb @@ -0,0 +1,6 @@ +require bcel_${PV}.bb + +inherit java-native + +DEPENDS = "fastjar-native xerces-j-native regexp-native" + diff --git a/recipes/bcel/bcel_5.2.bb b/recipes/bcel/bcel_5.2.bb new file mode 100644 index 0000000000..faf6043c00 --- /dev/null +++ b/recipes/bcel/bcel_5.2.bb @@ -0,0 +1,19 @@ +DESCRIPTION = "Java Bytecode manipulation library" +LICENSE = "AL2.0" +AUTHOR = "Apache Software Foundation" + +SRC_URI = "http://archive.apache.org/dist/jakarta/bcel/source/${BP}-src.tar.gz" + +inherit java-library + +DEPENDS = "fastjar-native xerces-j regexp" + +do_compile() { + mkdir -p build + + oe_makeclasspath cp -s xercesImpl regexp + + javac -sourcepath src/java -d build -cp $cp `find src/java -name \*.java` + + fastjar -C build -c -f ${JARFILENAME} . +} -- cgit v1.2.3 From f4a8de9123820855fcb4efd1a1755ead587a7fa7 Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 13:54:58 +0200 Subject: regexp 1.5: New recipe (from Jalimo SVN). regexp-native 1.5: Dito. --- recipes/jakarta-libs/regexp-native_1.5.bb | 4 ++++ recipes/jakarta-libs/regexp_1.5.bb | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 recipes/jakarta-libs/regexp-native_1.5.bb create mode 100644 recipes/jakarta-libs/regexp_1.5.bb diff --git a/recipes/jakarta-libs/regexp-native_1.5.bb b/recipes/jakarta-libs/regexp-native_1.5.bb new file mode 100644 index 0000000000..679da37783 --- /dev/null +++ b/recipes/jakarta-libs/regexp-native_1.5.bb @@ -0,0 +1,4 @@ +require regexp_${PV}.bb + +inherit java-native + diff --git a/recipes/jakarta-libs/regexp_1.5.bb b/recipes/jakarta-libs/regexp_1.5.bb new file mode 100644 index 0000000000..9ae6c35d42 --- /dev/null +++ b/recipes/jakarta-libs/regexp_1.5.bb @@ -0,0 +1,19 @@ +DESCRIPTION = "Java Regular Expression package" +LICENSE = "AL2.0" +AUTHOR = "Apache Software Foundation" + +SRC_URI = "http://archive.apache.org/dist/jakarta/regexp/source/jakarta-${BP}.tar.gz" + +inherit java-library + +S = "${WORKDIR}/jakarta-${BP}" + +DEPENDS = "fastjar-native" + +do_compile() { + mkdir -p build + + javac -sourcepath src/java -d build `find src/java -name \*.java` + + fastjar -C build -c -f ${JARFILENAME} . +} -- cgit v1.2.3 From 6c6d824e983eeab87607c36a4da3ec18d698d116 Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 14:01:28 +0200 Subject: xalan-j 2.7.1: New recipe (from Jalimo SVN). xalan-j-native 2.7.1: Dito. --- recipes/xalan-j/xalan-j-native_2.7.1.bb | 14 ++++++++ recipes/xalan-j/xalan-j_2.7.1.bb | 57 +++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 recipes/xalan-j/xalan-j-native_2.7.1.bb create mode 100644 recipes/xalan-j/xalan-j_2.7.1.bb diff --git a/recipes/xalan-j/xalan-j-native_2.7.1.bb b/recipes/xalan-j/xalan-j-native_2.7.1.bb new file mode 100644 index 0000000000..371362a286 --- /dev/null +++ b/recipes/xalan-j/xalan-j-native_2.7.1.bb @@ -0,0 +1,14 @@ +require xalan-j_${PV}.bb + +DEPENDS = "\ + fastjar-native \ + xerces-j-native regexp-native jlex-native cup-native jaxp1.3-native bcel-native \ + " + +inherit java-native + + +do_install_append() { + : +} + diff --git a/recipes/xalan-j/xalan-j_2.7.1.bb b/recipes/xalan-j/xalan-j_2.7.1.bb new file mode 100644 index 0000000000..2d6d885a70 --- /dev/null +++ b/recipes/xalan-j/xalan-j_2.7.1.bb @@ -0,0 +1,57 @@ +DESCRIPTION = "Java XSLT processor" +LICENSE = "AL2.0" + +AUTHOR = "Apache Software Foundation" +HOMEPAGE = "http://xml.apache.org/xalan-j + +DEPENDS = "fastjar-native xerces-j regexp jlex cup jaxp1.3 bcel" + +SRC_URI = "\ + http://archive.apache.org/dist/xml/${BPN}/${BPN}_2_7_1-src.tar.gz \ + http://archive.apache.org/dist/jakarta/bsf/source/bsf-src-2.4.0.tar.gz \ + " + +S = "${WORKDIR}/${BPN}_2_7_1" + +inherit java-library + +JPN = "libxalan2-java" + +JARFILENAME = "xalan2-${PV}.jar" +ALTJARFILENAMES = "xalan2.jar" + +do_compile() { + mkdir -p build + + oe_makeclasspath cp -s xercesImpl regexp jlex cup bcel jaxp-1.3 + scp="src:${WORKDIR}/bsf-2.4.0/src" + + javac -J-Xmx512M -sourcepath $scp -cp $cp -d build `find src -name \*.java` + (cd src && find org -name "*.properties" -exec cp {} ../build/{} \;) + + # Remove BSF classes + rm -rf build-xalan/org/apache/bsf + + mkdir -p build-serializer/org/apache/xml + mv build/org/apache/xml/serializer build-serializer/org/apache/xml + + fastjar -C build -c -f ${JARFILENAME} . + fastjar -C build-serializer -c -f serializer-${PV}.jar . +} + +do_install_append() { + oe_jarinstall serializer-${PV}.jar serializer.jar + + # Like Debian we provide a symlink called xml-apis pointing to the JAXP + # classes. + ln -sf ${D}${datadir_java}/xml-apis.jar jaxp-1.3.jar +} + +do_stage_append() { + oe_jarinstall -s serializer-${PV}.jar serializer.jar +} + +PACKAGES = "libxalan2-serializer-java ${JPN}" + +FILES_libxalan2-serializer-java = "${datadir_java}/serializer*.jar" + -- cgit v1.2.3 From e90cec1338a3a60cbabaff3590c503edd0e10033 Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 14:05:43 +0200 Subject: inetlib 1.1.1: New recipe (from Jalimo SVN). inetlib-native 1.1.1: Dito. --- recipes/classpath/inetlib-1.1.1/datadir_java.patch | 23 +++++++++++++++++ recipes/classpath/inetlib-native_1.1.1.bb | 3 +++ recipes/classpath/inetlib_1.1.1.bb | 30 ++++++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 recipes/classpath/inetlib-1.1.1/datadir_java.patch create mode 100644 recipes/classpath/inetlib-native_1.1.1.bb create mode 100644 recipes/classpath/inetlib_1.1.1.bb diff --git a/recipes/classpath/inetlib-1.1.1/datadir_java.patch b/recipes/classpath/inetlib-1.1.1/datadir_java.patch new file mode 100644 index 0000000000..16302cdafe --- /dev/null +++ b/recipes/classpath/inetlib-1.1.1/datadir_java.patch @@ -0,0 +1,23 @@ +Index: inetlib-1.1.1/Makefile.am +=================================================================== +--- inetlib-1.1.1.orig/Makefile.am 2008-03-01 10:49:49.000000000 +0100 ++++ inetlib-1.1.1/Makefile.am 2008-03-01 10:52:21.000000000 +0100 +@@ -7,6 +7,8 @@ + JAVADOC = @JAVADOC@ + JAVADOCFLAGS = @JAVADOCFLAGS@ + ++JARDIR = $(datadir)/java ++ + src = @srcdir@/source + dst = classes + doc = @srcdir@/docs +@@ -280,7 +282,7 @@ + find $(dst) -name '*.class' -exec rm -f '{}' ';' + + install-data-local: +- $(mkinstalldirs) $(prefix)/share/java +- $(INSTALL_DATA) $(inetlib_jar) $(prefix)/share/java ++ $(mkinstalldirs) $(DESTDIR)/$(JARDIR) ++ $(INSTALL_DATA) $(inetlib_jar) $(DESTDIR)/$(JARDIR) + + # End of Makefile.am diff --git a/recipes/classpath/inetlib-native_1.1.1.bb b/recipes/classpath/inetlib-native_1.1.1.bb new file mode 100644 index 0000000000..53ee782c81 --- /dev/null +++ b/recipes/classpath/inetlib-native_1.1.1.bb @@ -0,0 +1,3 @@ +require inetlib_${PV}.bb + +inherit native diff --git a/recipes/classpath/inetlib_1.1.1.bb b/recipes/classpath/inetlib_1.1.1.bb new file mode 100644 index 0000000000..1fba4b4e7c --- /dev/null +++ b/recipes/classpath/inetlib_1.1.1.bb @@ -0,0 +1,30 @@ +DESCRIPTION = "A Java library of clients for common internet protocols" +LICENSE = "GPL + library exception" +AUTHOR = "GNU Classpath" +HOMEPAGE = "http://gnu.org/software/classpath/inetlib.html" + +SRC_URI = "\ + http://ftp.gnu.org/gnu/classpath/${BP}.tar.gz \ + file://datadir_java.patch;patch=1 \ + " + +inherit java-library autotools + +DEPENDS = "fastjar-native" + +JPN = "libgnuinet-java" + +export JAVAC = "javac" + +export JAVA = "java" + +# We fake this, it is not neccessary anyway. +export JAVADOC = "true" + +do_compile() { + oe_runmake JARDIR=${datadir_java} inetlib_jar=${JARFILENAME} +} + +do_install_append() { + java_install +} -- cgit v1.2.3 From 9360aebebce14938c89e5f7f9c411573f541d899 Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 14:07:14 +0200 Subject: gnujaf 1.1.1: New recipe (from Jalimo SVN). gnujaf-native 1.1.1: Dito. gnumail 1.1.2: Dito. gnumail-native 1.1.2: Dito. --- recipes/classpathx/gnujaf-1.1.1/datadir_java.patch | 23 ++++++++++++ recipes/classpathx/gnujaf-native_1.1.1.bb | 3 ++ recipes/classpathx/gnujaf_1.1.1.bb | 35 ++++++++++++++++++ .../classpathx/gnumail-1.1.2/datadir_java.patch | 25 +++++++++++++ recipes/classpathx/gnumail-native_1.1.2.bb | 5 +++ recipes/classpathx/gnumail_1.1.2.bb | 42 ++++++++++++++++++++++ 6 files changed, 133 insertions(+) create mode 100644 recipes/classpathx/gnujaf-1.1.1/datadir_java.patch create mode 100644 recipes/classpathx/gnujaf-native_1.1.1.bb create mode 100644 recipes/classpathx/gnujaf_1.1.1.bb create mode 100644 recipes/classpathx/gnumail-1.1.2/datadir_java.patch create mode 100644 recipes/classpathx/gnumail-native_1.1.2.bb create mode 100644 recipes/classpathx/gnumail_1.1.2.bb diff --git a/recipes/classpathx/gnujaf-1.1.1/datadir_java.patch b/recipes/classpathx/gnujaf-1.1.1/datadir_java.patch new file mode 100644 index 0000000000..807a1cbf6d --- /dev/null +++ b/recipes/classpathx/gnujaf-1.1.1/datadir_java.patch @@ -0,0 +1,23 @@ +Index: activation-1.1.1/Makefile.am +=================================================================== +--- activation-1.1.1.orig/Makefile.am 2008-03-01 10:30:06.000000000 +0100 ++++ activation-1.1.1/Makefile.am 2008-03-01 10:31:04.000000000 +0100 +@@ -7,6 +7,8 @@ + JAVADOC = @JAVADOC@ + JAVADOCFLAGS = @JAVADOCFLAGS@ + ++JARDIR = $(datadir)/java ++ + src = @srcdir@/source + dst = classes + doc = @srcdir@/docs +@@ -92,7 +94,7 @@ + $(RM) config.log config.status + + install-data-local: +- @srcdir@/mkinstalldirs $(DESTDIR)/$(datadir)/java +- $(INSTALL_DATA) $(activation_jar) $(DESTDIR)/$(datadir)/java ++ @srcdir@/mkinstalldirs $(DESTDIR)/$(JARDIR) ++ $(INSTALL_DATA) $(activation_jar) $(DESTDIR)/$(JARDIR) + + # End of Makefile.am diff --git a/recipes/classpathx/gnujaf-native_1.1.1.bb b/recipes/classpathx/gnujaf-native_1.1.1.bb new file mode 100644 index 0000000000..0e3e485c92 --- /dev/null +++ b/recipes/classpathx/gnujaf-native_1.1.1.bb @@ -0,0 +1,3 @@ +require gnujaf_${PV}.bb + +inherit java-native diff --git a/recipes/classpathx/gnujaf_1.1.1.bb b/recipes/classpathx/gnujaf_1.1.1.bb new file mode 100644 index 0000000000..1ae47172e7 --- /dev/null +++ b/recipes/classpathx/gnujaf_1.1.1.bb @@ -0,0 +1,35 @@ +DESCRIPTION = "Provides a mean to type data and locate components suitable for performing various kinds of action on it." +LICENSE = "GPL + library exception" +AUTHOR = "GNU ClasspathX" + +SRC_URI = "\ + http://ftp.gnu.org/gnu/classpathx/activation-${PV}.tar.gz \ + file://datadir_java.patch;patch=1 \ + " + +# java-library must be last (it defines do_stage) +inherit autotools java-library + +S = "${WORKDIR}/activation-${PV}" + +DEPENDS = "fastjar-native" + +export JAVAC = "javac" + +# Fake javadoc +export JAVADOC = "true" + +JARFILENAME = "activation-${PV}.jar" +ALTJARFILENAMES = "activation.jar gnujaf.jar" + +do_compile() { + mkdir -p build + + javac -sourcepath source -d build `find source -name "*.java"` + + fastjar -C build -c -f ${JARFILENAME} . +} + +do_install() { + java_install +} diff --git a/recipes/classpathx/gnumail-1.1.2/datadir_java.patch b/recipes/classpathx/gnumail-1.1.2/datadir_java.patch new file mode 100644 index 0000000000..50e908d232 --- /dev/null +++ b/recipes/classpathx/gnumail-1.1.2/datadir_java.patch @@ -0,0 +1,25 @@ +Index: mail-1.1.2/Makefile.am +=================================================================== +--- mail-1.1.2.orig/Makefile.am 2008-03-01 11:13:36.000000000 +0100 ++++ mail-1.1.2/Makefile.am 2008-03-01 11:17:49.000000000 +0100 +@@ -7,6 +7,8 @@ + JAVADOC = @JAVADOC@ + JAVADOCFLAGS = @JAVADOCFLAGS@ + ++JARDIR = $(datadir)/java ++ + src = @srcdir@/source + dst = classes + doc = @srcdir@/docs +@@ -433,8 +435,8 @@ + rm -rf $(gnumail_jar) $(providers_jar) META-INF $(dst) $(doc) + + install-data-local: +- @srcdir@/mkinstalldirs $(DESTDIR)/$(datadir)/java +- $(INSTALL_DATA) $(gnumail_jar) $(DESTDIR)/$(datadir)/java +- $(INSTALL_DATA) $(providers_jar) $(DESTDIR)/$(datadir)/java ++ @srcdir@/mkinstalldirs $(DESTDIR)/$(JARDIR) ++ $(INSTALL_DATA) $(gnumail_jar) $(DESTDIR)/$(JARDIR) ++ $(INSTALL_DATA) $(providers_jar) $(DESTDIR)/$(JARDIR) + + # End of Makefile.am diff --git a/recipes/classpathx/gnumail-native_1.1.2.bb b/recipes/classpathx/gnumail-native_1.1.2.bb new file mode 100644 index 0000000000..486645213c --- /dev/null +++ b/recipes/classpathx/gnumail-native_1.1.2.bb @@ -0,0 +1,5 @@ +require gnumail_${PV}.bb + +inherit native + +DEPENDS = "fastjar-native gnujaf-native inetlib-native" diff --git a/recipes/classpathx/gnumail_1.1.2.bb b/recipes/classpathx/gnumail_1.1.2.bb new file mode 100644 index 0000000000..adcb1e8c1f --- /dev/null +++ b/recipes/classpathx/gnumail_1.1.2.bb @@ -0,0 +1,42 @@ +DESCRIPTION = "GNU's free implementation of the JavaMail API specification" +LICENSE = "GPL + library exception" +AUTHOR = "GNU ClasspathX" + +SRC_URI = "\ + http://ftp.gnu.org/gnu/classpathx/mail-${PV}.tar.gz \ + file://datadir_java.patch;patch=1 \ + " + +inherit java-library autotools + +S = "${WORKDIR}/mail-${PV}" + +DEPENDS = "fastjar-native gnujaf inetlib" + +export JAVAC = "javac" +export JAVA = "java" + +# Fake javadoc +export JAVADOC = "true" + +EXTRA_OECONF = "\ + --with-inetlib-jar=${STAGING_DATADIR_JAVA} \ + --with-activation-jar=${STAGING_DATADIR_JAVA} \ + " + +do_compile() { + oe_runmake \ + JARDIR=${datadir_java} \ + gnumail_jar=${JARFILENAME} \ + providers_jar=${P}-providers.jar +} + +do_install() { + java_install + oe_jarinstall ${P}-providers.jar ${PN}-providers.jar +} + +do_stage() { + java_stage + oe_jarinstall -s ${P}-providers.jar ${PN}-providers.jar +} -- cgit v1.2.3 From 4fa1b8b0741b8d1bc1ce11cef98e1d284a1fd6ef Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 14:16:00 +0200 Subject: jacl 1.4.1: New recipe (from Jalimo SVN). jacl-native 1.4.1: Dito. --- recipes/jacl/jacl-native_1.4.1.bb | 4 ++++ recipes/jacl/jacl_1.4.1.bb | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 recipes/jacl/jacl-native_1.4.1.bb create mode 100644 recipes/jacl/jacl_1.4.1.bb diff --git a/recipes/jacl/jacl-native_1.4.1.bb b/recipes/jacl/jacl-native_1.4.1.bb new file mode 100644 index 0000000000..b0a0638dde --- /dev/null +++ b/recipes/jacl/jacl-native_1.4.1.bb @@ -0,0 +1,4 @@ +require jacl_${PV}.bb + +inherit java-native + diff --git a/recipes/jacl/jacl_1.4.1.bb b/recipes/jacl/jacl_1.4.1.bb new file mode 100644 index 0000000000..7c66c3ef7c --- /dev/null +++ b/recipes/jacl/jacl_1.4.1.bb @@ -0,0 +1,20 @@ +DESCRIPTION = "Tcl interpreter for Java" +LICENSES = "BSD" + +HOMEPAGE = "http://sourceforge.net/projects/tcljava" + +SRC_URI = "http://downloads.sourceforge.net/tcljava/jacl${PV}.tar.gz" + +inherit java-library + +S = "${WORKDIR}/jacl${PV}" + +DEPENDS = "fastjar-native" + +do_compile() { + mkdir -p build + + javac -sourcepath src/tcljava:src/jacl -d build `find src/tcljava src/jacl -name "*.java"` + + fastjar -C build -c -f ${JARFILENAME} . +} -- cgit v1.2.3 From 02d7af7ebb75a90929200905cfb6d3f8b07dbd11 Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 14:17:18 +0200 Subject: jsch 0.1.40: New recipe (from Jalimo SVN). jsch-native 0.1.40: Dito. jzlib 1.0.7: Dito. jzlib-native 1.0.7: Dito. --- recipes/jcraft/jsch-native_0.1.40.bb | 8 ++++++++ recipes/jcraft/jsch_0.1.40.bb | 21 +++++++++++++++++++++ recipes/jcraft/jzlib-native_1.0.7.bb | 6 ++++++ recipes/jcraft/jzlib_1.0.7.bb | 18 ++++++++++++++++++ 4 files changed, 53 insertions(+) create mode 100644 recipes/jcraft/jsch-native_0.1.40.bb create mode 100644 recipes/jcraft/jsch_0.1.40.bb create mode 100644 recipes/jcraft/jzlib-native_1.0.7.bb create mode 100644 recipes/jcraft/jzlib_1.0.7.bb diff --git a/recipes/jcraft/jsch-native_0.1.40.bb b/recipes/jcraft/jsch-native_0.1.40.bb new file mode 100644 index 0000000000..a93fa76c7f --- /dev/null +++ b/recipes/jcraft/jsch-native_0.1.40.bb @@ -0,0 +1,8 @@ +require jsch_${PV}.bb + +S = "${WORKDIR}/jsch-${PV}" + +inherit java-native + +DEPENDS = "fastjar-native jzlib-native" +RDEPENDS = "" diff --git a/recipes/jcraft/jsch_0.1.40.bb b/recipes/jcraft/jsch_0.1.40.bb new file mode 100644 index 0000000000..a61888fd7d --- /dev/null +++ b/recipes/jcraft/jsch_0.1.40.bb @@ -0,0 +1,21 @@ +DESCRIPTION = "SSH implementation in Java" +LICENSES = "BSD" + +HOMEPAGE = "http://www.jcraft.com/jsch" + +SRC_URI = "${SOURCEFORGE_MIRROR}/jsch/jsch-${PV}.zip" + +inherit java-library + +DEPENDS = "fastjar-native jzlib" +RDEPENDS = "libjzlib-java" + +do_compile() { + mkdir -p build + + oe_makeclasspath cp -s jzlib + + javac -sourcepath src -cp $cp -d build `find src -name "*.java"` + + fastjar -C build -c -f ${JARFILENAME} . +} diff --git a/recipes/jcraft/jzlib-native_1.0.7.bb b/recipes/jcraft/jzlib-native_1.0.7.bb new file mode 100644 index 0000000000..e430a15cf9 --- /dev/null +++ b/recipes/jcraft/jzlib-native_1.0.7.bb @@ -0,0 +1,6 @@ +require jzlib_${PV}.bb + +S = "${WORKDIR}/jzlib-${PV}" + +inherit java-native + diff --git a/recipes/jcraft/jzlib_1.0.7.bb b/recipes/jcraft/jzlib_1.0.7.bb new file mode 100644 index 0000000000..4759e90b46 --- /dev/null +++ b/recipes/jcraft/jzlib_1.0.7.bb @@ -0,0 +1,18 @@ +DESCRIPTION = "zlib implementation in Java" +LICENSES = "BSD" + +HOMEPAGE = "http://www.jcraft.com/jzlib" + +SRC_URI = "http://www.jcraft.com/jzlib/jzlib-${PV}.tar.gz" + +inherit java-library + +DEPENDS = "fastjar-native" + +do_compile() { + mkdir -p build + + javac -sourcepath . -d build `find com -name "*.java"` + + fastjar -C build -c -f ${JARFILENAME} . +} -- cgit v1.2.3 From 7b686c7c52bd214593ed21f3715cb5656c74916b Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 14:18:50 +0200 Subject: jdepend 2.9: New recipe (from Jalimo SVN). jdepend-native 2.9: Dito. --- recipes/jdepend/jdepend-native_2.9.bb | 4 ++++ recipes/jdepend/jdepend_2.9.bb | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 recipes/jdepend/jdepend-native_2.9.bb create mode 100644 recipes/jdepend/jdepend_2.9.bb diff --git a/recipes/jdepend/jdepend-native_2.9.bb b/recipes/jdepend/jdepend-native_2.9.bb new file mode 100644 index 0000000000..dc6251746e --- /dev/null +++ b/recipes/jdepend/jdepend-native_2.9.bb @@ -0,0 +1,4 @@ +require jdepend_${PV}.bb + +inherit java-native + diff --git a/recipes/jdepend/jdepend_2.9.bb b/recipes/jdepend/jdepend_2.9.bb new file mode 100644 index 0000000000..fc70eac442 --- /dev/null +++ b/recipes/jdepend/jdepend_2.9.bb @@ -0,0 +1,20 @@ +DESCRIPTION = "Design quality metrics generator for each Java" + +# see http://www.clarkware.com/software/license.txt +LICENSE = "BSD" + +HOMEPAGE = "http://clarkware.com/software/JDepend.html" + +SRC_URI = "http://www.clarkware.com/software/jdepend-${PV}.zip" + +inherit java-library + +DEPENDS = "fastjar-native" + +do_compile() { + mkdir -p build + + javac -sourcepath src -d build `find src -name "*.java"` + + fastjar -C build -c -f ${JARFILENAME} . +} -- cgit v1.2.3 From 8987e7ad7ddb8175029361a993b816b9a7cc9fdb Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 14:22:30 +0200 Subject: junit 3.8.2: New recipe (from Jalimo SVN). junit-native 3.8.2: Dito. junit4 4.3.1: Dito. junit4-native 4.3.1: Dito. --- recipes/junit/junit-native_3.8.2.bb | 4 ++++ recipes/junit/junit4-native_4.3.1.bb | 4 ++++ recipes/junit/junit4_4.3.1.bb | 23 +++++++++++++++++++++++ recipes/junit/junit_3.8.2.bb | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+) create mode 100644 recipes/junit/junit-native_3.8.2.bb create mode 100644 recipes/junit/junit4-native_4.3.1.bb create mode 100644 recipes/junit/junit4_4.3.1.bb create mode 100644 recipes/junit/junit_3.8.2.bb diff --git a/recipes/junit/junit-native_3.8.2.bb b/recipes/junit/junit-native_3.8.2.bb new file mode 100644 index 0000000000..305351f058 --- /dev/null +++ b/recipes/junit/junit-native_3.8.2.bb @@ -0,0 +1,4 @@ +require junit_${PV}.bb + +inherit java-native + diff --git a/recipes/junit/junit4-native_4.3.1.bb b/recipes/junit/junit4-native_4.3.1.bb new file mode 100644 index 0000000000..eb843a9ab5 --- /dev/null +++ b/recipes/junit/junit4-native_4.3.1.bb @@ -0,0 +1,4 @@ +require junit4_${PV}.bb + +inherit java-native + diff --git a/recipes/junit/junit4_4.3.1.bb b/recipes/junit/junit4_4.3.1.bb new file mode 100644 index 0000000000..2733aff2e1 --- /dev/null +++ b/recipes/junit/junit4_4.3.1.bb @@ -0,0 +1,23 @@ +DESCRIPTION = "JUnit is a testing framework for Java" +LICENSES = "CPL" +AUTHOR = "junit.org" +HOMEPAGE = "http://www.junit.org" + +SRC_URI = "http://downloads.sourceforge.net/junit/junit-${PV}-src.jar" + +S = "${WORKDIR}" + +inherit java-library + +DEPENDS = "fastjar-native" + +do_compile() { + mkdir -p build + + # Workaround for jamvm. + bcp=${STAGING_DATADIR_NATIVE}/classpath/glibj.zip + + javac -source 5.0 -bootclasspath $bcp -sourcepath . -d build `find . -name "*.java"` + + fastjar -C build -c -f ${JARFILENAME} . +} diff --git a/recipes/junit/junit_3.8.2.bb b/recipes/junit/junit_3.8.2.bb new file mode 100644 index 0000000000..2ba54b63a7 --- /dev/null +++ b/recipes/junit/junit_3.8.2.bb @@ -0,0 +1,34 @@ +DESCRIPTION = "JUnit is a testing framework for Java" +LICENSES = "CPL" +AUTHOR = "junit.org" +HOMEPAGE = "http://www.junit.org" + +SRC_URI = "http://downloads.sourceforge.net/junit/junit${PV}.zip" + +S = "${WORKDIR}/junit${PV}" + +inherit java-library + +DEPENDS = "fastjar-native" + +do_unpackpost() { + mkdir -p src + + # Prevent deletion by do_removebinaries. + mv src.jar src.zip + + unzip src.zip -d src +} + +addtask unpackpost before do_removebinaries after do_unpack + +do_compile() { + mkdir -p build + + # Workaround for jamvm. + bcp=${STAGING_DATADIR_NATIVE}/classpath/glibj.zip + + javac -bootclasspath $bcp -sourcepath src -d build `find src -name "*.java"` + + fastjar -C build -c -f ${JARFILENAME} . +} -- cgit v1.2.3 From 544342567663c18e802dcfdbdcb12fc1d75bf803 Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 14:24:59 +0200 Subject: rhino 1.7r1: New recipe (from Jalimo SVN). rhino-native 1.7r1: Dito. --- recipes/mozilla/rhino-native_1.7r1.bb | 5 +++++ recipes/mozilla/rhino/rhino | 8 +++++++ recipes/mozilla/rhino/rhino-jsc | 8 +++++++ recipes/mozilla/rhino_1.7r1.bb | 42 +++++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+) create mode 100644 recipes/mozilla/rhino-native_1.7r1.bb create mode 100644 recipes/mozilla/rhino/rhino create mode 100644 recipes/mozilla/rhino/rhino-jsc create mode 100644 recipes/mozilla/rhino_1.7r1.bb diff --git a/recipes/mozilla/rhino-native_1.7r1.bb b/recipes/mozilla/rhino-native_1.7r1.bb new file mode 100644 index 0000000000..1b563603f8 --- /dev/null +++ b/recipes/mozilla/rhino-native_1.7r1.bb @@ -0,0 +1,5 @@ +require rhino_${PV}.bb + +inherit java-native + +RDEPENDS_${PN} = "" diff --git a/recipes/mozilla/rhino/rhino b/recipes/mozilla/rhino/rhino new file mode 100644 index 0000000000..e2f87f690a --- /dev/null +++ b/recipes/mozilla/rhino/rhino @@ -0,0 +1,8 @@ +#!/bin/sh + +if [ ! $JAVA ]; then + JAVA=java +fi + +$JAVA -jar /usr/share/java/js.jar $@ + diff --git a/recipes/mozilla/rhino/rhino-jsc b/recipes/mozilla/rhino/rhino-jsc new file mode 100644 index 0000000000..d5f50e8451 --- /dev/null +++ b/recipes/mozilla/rhino/rhino-jsc @@ -0,0 +1,8 @@ +#!/bin/sh + +if [ ! $JAVA ]; then + JAVA=java +fi + +$JAVA -cp .:/usr/share/java/js.jar org.mozilla.javascript.tools.jsc.Main $@ + diff --git a/recipes/mozilla/rhino_1.7r1.bb b/recipes/mozilla/rhino_1.7r1.bb new file mode 100644 index 0000000000..e9268704d9 --- /dev/null +++ b/recipes/mozilla/rhino_1.7r1.bb @@ -0,0 +1,42 @@ +DESCRIPTION = "Lexical analyzer generator for Java" + +LICENSE = "GPL MPL" + +DEPENDS = "fastjar-native" + +inherit java-library + +SRC_URI = "\ + ftp://ftp.mozilla.org/pub/mozilla.org/js/rhino1_7R1.zip \ + file://rhino \ + file://rhino-jsc \ + " + +S = "${WORKDIR}/rhino1_7R1" + +PACKAGES = "${JPN} rhino" + +FILES_${PN} = "${bindir}/rhino ${bindir}/rhino-jsc" +RDEPENDS_${PN} = "java2-runtime ${JPN}" + +do_compile() { + mkdir -p build + + # Compatibility fix for jamvm which has non-genericised + # java.lang classes. :( + bcp_arg="-bootclasspath ${STAGING_DATADIR_NATIVE}/classpath/glibj.zip" + + javac $bcp_arg -source 1.5 -sourcepath src -d build `find src -name "*.java"` + + mkdir -p build/org/mozilla/javascript/resources + cp src/org/mozilla/javascript/resources/*.properties build/org/mozilla/javascript/resources + + fastjar -m ${S}/src/manifest -C build -c -f ${JARFILENAME} . +} + +do_install_append() { + install -d ${D}${bindir} + + install -m 0755 ${WORKDIR}/rhino ${D}${bindir} + install -m 0755 ${WORKDIR}/rhino-jsc ${D}${bindir} +} -- cgit v1.2.3 From 16d63d991053d6499aaf9cd3e89efb979d5bf2ff Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 14:26:33 +0200 Subject: jsp2.0 5.5.26: New recipe (from Jalimo SVN). servlet2.3 4.1.37: Dito. servlet2.3-native 4.1.37: Dito. servlet2.4 5.5.26: Dito. --- recipes/servlet-api/jsp2.0_5.5.26.bb | 42 +++++++++++++++++++++++++ recipes/servlet-api/servlet2.3-native_4.1.37.bb | 4 +++ recipes/servlet-api/servlet2.3_4.1.37.bb | 41 ++++++++++++++++++++++++ recipes/servlet-api/servlet2.4_5.5.26.bb | 38 ++++++++++++++++++++++ 4 files changed, 125 insertions(+) create mode 100644 recipes/servlet-api/jsp2.0_5.5.26.bb create mode 100644 recipes/servlet-api/servlet2.3-native_4.1.37.bb create mode 100644 recipes/servlet-api/servlet2.3_4.1.37.bb create mode 100644 recipes/servlet-api/servlet2.4_5.5.26.bb diff --git a/recipes/servlet-api/jsp2.0_5.5.26.bb b/recipes/servlet-api/jsp2.0_5.5.26.bb new file mode 100644 index 0000000000..6a5f3b6f71 --- /dev/null +++ b/recipes/servlet-api/jsp2.0_5.5.26.bb @@ -0,0 +1,42 @@ +DESCRIPTION = "Java Server Page (JSP) API 2.0 (from Tomcat 5.5)" +LICENSE = "AL2.0" +AUTHOR = "Apache Software Foundation" + +SRC_URI = "http://archive.apache.org/dist/tomcat/tomcat-5/v${PV}/src/apache-tomcat-${PV}-src.tar.gz" + +S = "${WORKDIR}/apache-tomcat-${PV}-src/servletapi/jsr152" + +inherit java-library + +DEPENDS = "fastjar-native servlet2.4" +RDEPENDS = "libservlet2.4-java" + +# Value of implementation.revision in build.xml +IMPL_REVISION = "public_draft" + +JARFILENAME = "jsp-api-2.0.${IMPL_REVISION}.jar" +ALTJARFILENAMES = "jsp-api-2.0.jar jsp-api.jar" + +do_unpackpost() { + sed -i -e "s|@implementation.version@|${IMPL_REVISION}|" src/etc/manifest +} + +addtask unpackpost after do_unpack before do_patch + +do_compile() { + mkdir -p build + + oe_makeclasspath cp -s servlet-api-2.4` + javac -sourcepath src/share -d build -cp $cp `find src/share/javax -name \*.java` + + # Copy extraneous files according to build.xml's compile task + (cd src/share && find . -name "*.properties" -exec cp {} ../../build/{} \;) + + mkdir -p build/javax/servlet/jsp/resources + cp src/share/dtd/jsp*.dtd build/javax/servlet/jsp/resources + cp src/share/dtd/jsp*.xsd build/javax/servlet/jsp/resources + cp src/share/dtd/web-jsp*.dtd build/javax/servlet/jsp/resources + cp src/share/dtd/web-jsp*.xsd build/javax/servlet/jsp/resources + + fastjar -C build -c -m src/etc/manifest -f ${JARFILENAME} . +} diff --git a/recipes/servlet-api/servlet2.3-native_4.1.37.bb b/recipes/servlet-api/servlet2.3-native_4.1.37.bb new file mode 100644 index 0000000000..c06f5f499c --- /dev/null +++ b/recipes/servlet-api/servlet2.3-native_4.1.37.bb @@ -0,0 +1,4 @@ +require servlet2.3_${PV}.bb + +inherit java-native + diff --git a/recipes/servlet-api/servlet2.3_4.1.37.bb b/recipes/servlet-api/servlet2.3_4.1.37.bb new file mode 100644 index 0000000000..6176161d3d --- /dev/null +++ b/recipes/servlet-api/servlet2.3_4.1.37.bb @@ -0,0 +1,41 @@ +DESCRIPTION = "Servlet API 2.3 (from Tomcat 4.1)" +LICENSE = "AL2.0" +AUTHOR = "Apache Software Foundation" + +SRC_URI = "http://archive.apache.org/dist/tomcat/tomcat-4/v${PV}/src/apache-tomcat-${PV}-src.tar.gz" + +inherit java-library + +S = "${WORKDIR}/apache-tomcat-${PV}-src/servletapi" + +DEPENDS = "fastjar-native" + +# Value of implementation.revision in build.xml +IMPL_REVISION = "1" + +JARFILENAME = "servlet-2.3.${IMPL_REVISION}.jar" +ALTJARFILENAMES = "servlet-2.3.jar servlet2.3.jar" + +do_unpackpost() { + sed -i -e "s|@implementation.version@|${IMPL_REVISION}|" src/etc/manifest +} + +addtask unpackpost after do_unpack before do_patch + +do_compile() { + mkdir -p build + + javac -sourcepath src/share -d build `find src/share/javax -name \*.java` + + # Copy extraneous files according to build.xml's compile task + (cd src/share && find . -name "*.properties" -exec cp {} ../../build/{} \;) + + mkdir -p build/javax/servlet/resources + cp src/share/dtd/web-app*.dtd build/javax/servlet/resources + + mkdir -p build/javax/servlet/jsp/resources + cp src/share/dtd/web-jsptaglibrary*.dtd build/javax/servlet/jsp/resources + cp src/share/dtd/jspxml.* build/javax/servlet/jsp/resources + + fastjar -C build -c -m src/etc/manifest -f ${JARFILENAME} . +} diff --git a/recipes/servlet-api/servlet2.4_5.5.26.bb b/recipes/servlet-api/servlet2.4_5.5.26.bb new file mode 100644 index 0000000000..c4af1abba7 --- /dev/null +++ b/recipes/servlet-api/servlet2.4_5.5.26.bb @@ -0,0 +1,38 @@ +DESCRIPTION = "Servlet API 2.4 (from Tomcat 5.5)" +LICENSE = "AL2.0" +AUTHOR = "Apache Software Foundation" + +SRC_URI = "http://archive.apache.org/dist/tomcat/tomcat-5/v${PV}/src/apache-tomcat-${PV}-src.tar.gz" + +S = "${WORKDIR}/apache-tomcat-${PV}-src/servletapi/jsr154" + +inherit java-library + +DEPENDS = "fastjar-native" + +# Value of implementation.revision in build.xml +IMPL_REVISION = "1" + +JARFILENAME = "servlet-api-2.4.${IMPL_REVISION}.jar" +ALTJARFILENAMES = "servlet-api-2.4.jar servlet-api.jar servlet2.4.jar" + +do_unpackpost() { + sed -i -e "s|2.3.@implementation.version@|2.4.${IMPL_REVISION}|" src/etc/manifest +} + +addtask unpackpost after do_unpack before do_patch + +do_compile() { + mkdir -p build + + javac -sourcepath src/share -d build `find src/share/javax -name \*.java` + + # Copy extraneous files according to build.xml's compile task + (cd src/share && find . -name "*.properties" -exec cp {} ../../build/{} \;) + + mkdir -p build/javax/servlet/resources + cp src/share/dtd/jsp*.dtd build/javax/servlet/resources + cp src/share/dtd/web-jsp*.dtd build/javax/servlet/resources + + fastjar -C build -c -m src/etc/manifest -f ${JARFILENAME} . +} -- cgit v1.2.3 From f807b0604d74e14b46eb9b36ba317dd411639be5 Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 14:28:17 +0200 Subject: hsqldb 1.8.0.10: New recipe (from Jalimo SVN). --- recipes/hsqldb/hsqldb_1.8.0.10.bb | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 recipes/hsqldb/hsqldb_1.8.0.10.bb diff --git a/recipes/hsqldb/hsqldb_1.8.0.10.bb b/recipes/hsqldb/hsqldb_1.8.0.10.bb new file mode 100644 index 0000000000..ab3b1cd7e6 --- /dev/null +++ b/recipes/hsqldb/hsqldb_1.8.0.10.bb @@ -0,0 +1,36 @@ +DESCRIPTION = "Lightweight 100% Java SQL Database Engine" +# BSD-like +LICENSE = "HypersonicSQL" + +AUTHOR = "HSQLDB Development Group" +HOMEPAGE = "http://hsqldb.org" + +SRC_URI = "${SOURCEFORGE_MIRROR}/hsqldb/hsqldb_1_8_0_10.zip" + +S = "${WORKDIR}/${PN}" + +inherit java-library + +DEPENDS = "fastjar-native servlet2.4" + +do_compile() { + # Build instructions according to build/buildJDK14.bat + mkdir -p classes + + oe_makeclasspath cp -s servlet-api-2.4 + + javac -sourcepath src -cp $cp -d build `find src -name "*.java" -and -not -wholename "*test*"` + + mkdir -p classes/org/hsqldb/util + mkdir -p classes/org/hsqldb/util/sqltool + mkdir -p classes/org/hsqldb/resources + + cp src/org/hsqldb/util/*.gif classes/org/hsqldb/util/ + cp src/org/hsqldb/util/*.png classes/org/hsqldb/util/ + cp src/org/hsqldb/util/*.properties classes/org/hsqldb/util/ + cp src/org/hsqldb/util/sqltool/*.text classes/org/hsqldb/util/sqltool/ + + cp src/org/hsqldb/resources/*.properties classes/org/hsqldb/resources + + fastjar -C classes -c -f ${JARFILENAME} . +} -- cgit v1.2.3 From 41f689d2e82499b2cabd8808726335f80e38522f Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 14:32:58 +0200 Subject: icommand-bluez 0.7: New recipe (from Jalimo SVN). --- recipes/icommand/files/makefile.patch | 42 ++++++++++++++++++++++++++++++++++ recipes/icommand/icommand-bluez_0.7.bb | 34 +++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 recipes/icommand/files/makefile.patch create mode 100644 recipes/icommand/icommand-bluez_0.7.bb diff --git a/recipes/icommand/files/makefile.patch b/recipes/icommand/files/makefile.patch new file mode 100644 index 0000000000..3377f461f1 --- /dev/null +++ b/recipes/icommand/files/makefile.patch @@ -0,0 +1,42 @@ +Index: Release/makefile +=================================================================== +--- Release.orig/makefile 2008-02-21 14:39:13.000000000 +0100 ++++ Release/makefile 2008-02-21 15:31:48.000000000 +0100 +@@ -4,6 +4,8 @@ + + -include ../makefile.init + ++CC?=gcc ++ + RM := rm -rf + + # All of the sources participating in the build are defined here +@@ -28,7 +30,7 @@ + libicmdbluez.so: $(OBJS) $(USER_OBJS) + @echo 'Building target: $@' + @echo 'Invoking: GCC C Linker' +- gcc -shared -o"libicmdbluez.so" $(OBJS) $(USER_OBJS) $(LIBS) ++ $(CC) $(LDFLAGS) -shared -o"libicmdbluez.so" $(OBJS) $(USER_OBJS) $(LIBS) + @echo 'Finished building target: $@' + @echo ' ' + +Index: Release/subdir.mk +=================================================================== +--- Release.orig/subdir.mk 2008-02-21 14:39:13.000000000 +0100 ++++ Release/subdir.mk 2008-02-21 15:30:36.000000000 +0100 +@@ -12,12 +12,14 @@ + C_DEPS += \ + ./icmdbluez.d + ++CC?=gcc ++ + + # Each subdirectory must supply rules for building sources it contributes + %.o: ../%.c + @echo 'Building file: $<' + @echo 'Invoking: GCC C Compiler' +- gcc -I/usr/include/bluetooth -I/usr/lib/jvm/java-6-sun/include -I/usr/lib/jvm/java-6-sun/include/linux -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o"$@" "$<" ++ $(CC) $(CFLAGS) $(INCLUDES) -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o"$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + diff --git a/recipes/icommand/icommand-bluez_0.7.bb b/recipes/icommand/icommand-bluez_0.7.bb new file mode 100644 index 0000000000..70d78f02d0 --- /dev/null +++ b/recipes/icommand/icommand-bluez_0.7.bb @@ -0,0 +1,34 @@ +DESCRIPTION = "iCommand bluez binding" +LICENSE = "LGPL" +SECTION = "libs" +HOMEPAGE = "http://sourceforge.net/projects/nxtcommand/" +AUTHOR = "Brian Bagnall " + +inherit java + +SRC_URI = "\ + svn://nxtcommand.svn.sourceforge.net/svnroot/nxtcommand;module=icommand-projects/trunk/icommand-bluez;rev=134;proto=https \ + file://makefile.patch;patch=1 \ + " + +DEPENDS = "bluez-libs" + +S = "${WORKDIR}/icommand-projects/trunk/icommand-bluez/Release" + +do_compile() { + oe_runmake -f makefile clean + oe_runmake -f makefile all \ + INCLUDES="-I${STAGING_INCDIR}/classpath " \ + LIBS="-lbluetooth" +} + +do_install() { + oe_libinstall -so libicmdbluez ${D}${libdir_jni} +} + +PACKAGES = "${PN}-jni ${PN}-jni-dbg" + +RDEPENDS_${PN}-jni = "bluez-libs" + +FILES_${PN}-jni = "${libdir_jni}/lib*.so" +FILES_${PN}-jni-dbg = "${libdir_jni}/.debug/lib*.so" -- cgit v1.2.3 From 9ffda150b390d90d6b184421c0ddc2edaf290910 Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 14:38:34 +0200 Subject: oro 2.0.8: New recipe (from Jalimo SVN). oro-native 2.0.8: Dito. --- recipes/jakarta-libs/oro-native_2.0.8.bb | 4 ++++ recipes/jakarta-libs/oro_2.0.8.bb | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 recipes/jakarta-libs/oro-native_2.0.8.bb create mode 100644 recipes/jakarta-libs/oro_2.0.8.bb diff --git a/recipes/jakarta-libs/oro-native_2.0.8.bb b/recipes/jakarta-libs/oro-native_2.0.8.bb new file mode 100644 index 0000000000..2630ed9b0f --- /dev/null +++ b/recipes/jakarta-libs/oro-native_2.0.8.bb @@ -0,0 +1,4 @@ +require oro_${PV}.bb + +inherit java-native + diff --git a/recipes/jakarta-libs/oro_2.0.8.bb b/recipes/jakarta-libs/oro_2.0.8.bb new file mode 100644 index 0000000000..47ee9f29e0 --- /dev/null +++ b/recipes/jakarta-libs/oro_2.0.8.bb @@ -0,0 +1,19 @@ +DESCRIPTION = "Perl5-compatible regular expressions library for Java" +LICENSE = "AL2.0" +AUTHOR = "Apache Software Foundation" + +SRC_URI = "http://www.apache.org/dist/jakarta/oro/source/jakarta-${BP}.tar.gz" + +inherit java-library + +S = "${WORKDIR}/jakarta-${BP}" + +DEPENDS = "fastjar-native" + +do_compile() { + mkdir -p build + + javac -sourcepath src/java -d build `find src/java -name \*.java` + + fastjar -C build -c -f ${JARFILENAME} org +} -- cgit v1.2.3 From 4e0f215f2be53b7471d86681765a0c8c1e95d98c Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 14:38:58 +0200 Subject: avalon-framework-api 4.3: New recipe (from Jalimo SVN). avalon-framework-api-native 4.3: Dito. --- .../avalon-framework-api-native_4.3.bb | 4 ++++ recipes/jakarta-libs/avalon-framework-api_4.3.bb | 28 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 recipes/jakarta-libs/avalon-framework-api-native_4.3.bb create mode 100644 recipes/jakarta-libs/avalon-framework-api_4.3.bb diff --git a/recipes/jakarta-libs/avalon-framework-api-native_4.3.bb b/recipes/jakarta-libs/avalon-framework-api-native_4.3.bb new file mode 100644 index 0000000000..6733b34ef0 --- /dev/null +++ b/recipes/jakarta-libs/avalon-framework-api-native_4.3.bb @@ -0,0 +1,4 @@ +require avalon-framework-api_${PV}.bb + +inherit java-native + diff --git a/recipes/jakarta-libs/avalon-framework-api_4.3.bb b/recipes/jakarta-libs/avalon-framework-api_4.3.bb new file mode 100644 index 0000000000..74ec2c4456 --- /dev/null +++ b/recipes/jakarta-libs/avalon-framework-api_4.3.bb @@ -0,0 +1,28 @@ +DESCRIPTION = "Common way for components to be created, initialized, configured, started. (API-only)" +LICENSE = "AL2.0" +AUTHOR = "Apache Software Foundation" + +SRC_URI = "\ + http://www.apache.org/dist/excalibur/avalon-framework/source/${BP}-src.tar.gz \ + http://www.apache.org/dist/avalon/logkit/source/logkit-1.2.2-src.tar.gz \ + " + +inherit java-library + +DEPENDS = "fastjar-native" + +do_compile() { + mkdir -p build + + # Allow reaching method definitions from logkit (stupid cyclic dependency). + srcpath=src/java:${WORKDIR}/logkit-1.2.2-dev/src/java + + javac -sourcepath $srcpath -d build `find src/java -name "*.java"` + + # Remove classes that belong to logkit ... + rm -rf ${S}/build/org/apache/log + + fastjar -C build -c -f ${JARFILENAME} . +} + + -- cgit v1.2.3 From a80a0cb84d7b898d4fd8d560136b28f526915327 Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 14:39:36 +0200 Subject: logkit 1.2.2: New recipe (from Jalimo SVN). logkit-native 1.2.2: Dito. --- recipes/jakarta-libs/logkit-native_1.2.2.bb | 6 ++++++ recipes/jakarta-libs/logkit_1.2.2.bb | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 recipes/jakarta-libs/logkit-native_1.2.2.bb create mode 100644 recipes/jakarta-libs/logkit_1.2.2.bb diff --git a/recipes/jakarta-libs/logkit-native_1.2.2.bb b/recipes/jakarta-libs/logkit-native_1.2.2.bb new file mode 100644 index 0000000000..479f597a32 --- /dev/null +++ b/recipes/jakarta-libs/logkit-native_1.2.2.bb @@ -0,0 +1,6 @@ +require logkit_${PV}.bb + +inherit java-native + +DEPENDS = "fastjar-native oro-native servlet2.3-native gnumail-native gnujaf-native log4j1.2-native avalon-framework-api-native" + diff --git a/recipes/jakarta-libs/logkit_1.2.2.bb b/recipes/jakarta-libs/logkit_1.2.2.bb new file mode 100644 index 0000000000..58d496cd08 --- /dev/null +++ b/recipes/jakarta-libs/logkit_1.2.2.bb @@ -0,0 +1,25 @@ +DESCRIPTION = "Logging toolkit designed for secure performance orientated logging in Java applications" +LICENSE = "AL2.0" +AUTHOR = "Apache Software Foundation" + +SRC_URI = "http://www.apache.org/dist/avalon/logkit/source/${BP}-src.tar.gz" + +inherit java-library + +S = "${WORKDIR}/${BP}-dev" + +DEPENDS = "fastjar-native oro servlet2.3 gnumail gnujaf log4j1.2 avalon-framework-api" + +do_compile() { + mkdir -p build + + oe_makeclasspath cp -s oro servlet-2.3 activation gnumail log4j-1.2 avalon-framework-api + + # Built everything but the JMS and JMX classes (like in Debian) + javac -encoding ISO8859-1 -sourcepath src/java -cp $cp -d build \ + `find src/java -name \*.java -and -not \( -iwholename "*jms*" -or -wholename "*test*" \)` + + (cd src/java && find . -name "*.properties" -exec cp {} ../../build/{} \;) + + fastjar -C build -c -f ${JARFILENAME} . +} -- cgit v1.2.3 From 3b6557acfeac7fdf55c5938ae1ecf9de597f0d8d Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 14:42:18 +0200 Subject: log4j 1.2.15: New recipe (from Jalimo SVN). log4j-native 1.2.15: Dito. --- recipes/jakarta-libs/log4j1.2-native_1.2.15.bb | 6 ++++++ recipes/jakarta-libs/log4j1.2_1.2.15.bb | 27 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 recipes/jakarta-libs/log4j1.2-native_1.2.15.bb create mode 100644 recipes/jakarta-libs/log4j1.2_1.2.15.bb diff --git a/recipes/jakarta-libs/log4j1.2-native_1.2.15.bb b/recipes/jakarta-libs/log4j1.2-native_1.2.15.bb new file mode 100644 index 0000000000..49ccee1ff3 --- /dev/null +++ b/recipes/jakarta-libs/log4j1.2-native_1.2.15.bb @@ -0,0 +1,6 @@ +require log4j1.2_${PV}.bb + +inherit java-native + +DEPENDS = "fastjar-native gnumail-native gnujaf-native" + diff --git a/recipes/jakarta-libs/log4j1.2_1.2.15.bb b/recipes/jakarta-libs/log4j1.2_1.2.15.bb new file mode 100644 index 0000000000..cb83afd514 --- /dev/null +++ b/recipes/jakarta-libs/log4j1.2_1.2.15.bb @@ -0,0 +1,27 @@ +DESCRIPTION = "Java library to help the programmer output log statements to a variety of output targets" +LICENSE = "AL2.0" +AUTHOR = "Apache Software Foundation" + +SRC_URI = "http://archive.apache.org/dist/logging/log4j/${PV}/apache-log4j-${PV}.tar.gz" + +inherit java-library + +S = "${WORKDIR}/apache-log4j-${PV}" + +DEPENDS = "fastjar-native gnumail gnujaf" + +JARFILENAME = "log4j-${PV}.jar" +ALTJARFILENAMES = "log4j-1.2.jar log4j1.2.jar" + +do_compile() { + mkdir -p build + + oe_makeclasspath cp -s activation gnumail + + # Built everything but the JMS and JMX classes (like in Debian) + javac -sourcepath src/main/java -cp $cp -d build `find src/main/java -name "*.java" -and -not \( -iwholename "*jms*" -or -iwholename "*jmx*" \)` + + cp -r src/main/resources/* build/ + + fastjar -C build -c -f ${JARFILENAME} . +} -- cgit v1.2.3 From ff52f57646c898b7377cfda8d1365dc9e1ffe946 Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 14:44:01 +0200 Subject: commons-logging 1.1.1: New recipe (from Jalimo SVN). commons-logging-native 1.1.1: Dito. --- .../commons-logging-native_1.1.1.bb | 6 +++ recipes/jakarta-commons/commons-logging_1.1.1.bb | 12 +++++ recipes/jakarta-commons/jakarta-commons.inc | 62 ++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 recipes/jakarta-commons/commons-logging-native_1.1.1.bb create mode 100644 recipes/jakarta-commons/commons-logging_1.1.1.bb create mode 100644 recipes/jakarta-commons/jakarta-commons.inc diff --git a/recipes/jakarta-commons/commons-logging-native_1.1.1.bb b/recipes/jakarta-commons/commons-logging-native_1.1.1.bb new file mode 100644 index 0000000000..843750129f --- /dev/null +++ b/recipes/jakarta-commons/commons-logging-native_1.1.1.bb @@ -0,0 +1,6 @@ +require commons-logging_${PV}.bb + +inherit java-native + +DEPENDS = "fastjar-native log4j1.2-native servlet2.3-native logkit-native" + diff --git a/recipes/jakarta-commons/commons-logging_1.1.1.bb b/recipes/jakarta-commons/commons-logging_1.1.1.bb new file mode 100644 index 0000000000..f1d94eb731 --- /dev/null +++ b/recipes/jakarta-commons/commons-logging_1.1.1.bb @@ -0,0 +1,12 @@ +require jakarta-commons.inc + +DESCRIPTION = "Java Internet protocol suite library" + +SRC_URI = "http://www.apache.org/dist/commons/logging/source/${BP}-src.tar.gz" + +DEPENDS += "log4j1.2 servlet2.3 logkit" + +CP = "log4j-1.2 servlet-2.3 logkit" + +COMPILE_FINDARGS = "-name '*.java' -and -not -name '*Avalon*'" + diff --git a/recipes/jakarta-commons/jakarta-commons.inc b/recipes/jakarta-commons/jakarta-commons.inc new file mode 100644 index 0000000000..48cbe170c2 --- /dev/null +++ b/recipes/jakarta-commons/jakarta-commons.inc @@ -0,0 +1,62 @@ +LICENSE = "AL2.0" +AUTHOR = "Apache Software Foundation" + +inherit java-library + +DEPENDS = "fastjar-native" + +S = "${WORKDIR}/${BP}-src" + +# Directory in which the projects sources are located. +MAINSOURCES = "src/java" + +# Directories which should appear in the -sourcepath argument. +COMPILE_SOURCEPATH = "src/java" + +COMPILE_FINDARGS = "-name '*.java'" +FINDARGS = "-name '*.properties'" + +# Directories to be removed after compilation. +CLEAN_PATH = "" + +# Some projects have a replaceable version number in their manifest template. +do_unpackpost() { + if [ -d src/conf ] + then + find src/conf -exec \ + sed -i -e "s|@version@|${PV}|" {} \; + fi +} + +addtask unpackpost after do_unpack before do_patch +# Compile step is very similar for Jakarta commons packages +do_compile() { + mkdir -p build + + if [ "${CP}" ] + then + oe_makeclasspath cp -s ${CP} + else + cp=. + fi + + echo "javac -sourcepath ${COMPILE_SOURCEPATH} -cp $cp -d build \`find ${MAINSOURCES} ${COMPILE_FINDARGS}\`" + javac -sourcepath ${COMPILE_SOURCEPATH} -cp $cp -d build `find ${MAINSOURCES} ${COMPILE_FINDARGS}` + + # Copy extraneous files + echo "(cd ${MAINSOURCES} && find . ${FINDARGS} -exec cp {} ../../build/{} \;)" + (cd ${MAINSOURCES} && find . ${FINDARGS} -exec cp {} ../../build/{} \;) + + # Optionally remove stuff after compilation (needed for sourcepath hacks). + if [ ${CLEAN_PATH} ]; then + rm -rf ${CLEAN_PATH} + fi + + # Some projects have manifest, some have not. This works for both. + if [ -f src/conf/MANIFEST.MF ] + then + fastjar -C build -c -m src/conf/MANIFEST.MF -f ${JARFILENAME} . + else + fastjar -C build -c -f ${JARFILENAME} . + fi +} -- cgit v1.2.3 From 61af8065e555f57f697689f5092209b0f8f5b51a Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 14:45:02 +0200 Subject: bsf 2.4.0: New recipe (from Jalimo SVN). bsf-native 2.4.0: Dito. --- recipes/jakarta-libs/bsf-native_2.4.0.bb | 8 ++++++++ recipes/jakarta-libs/bsf_2.4.0.bb | 24 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 recipes/jakarta-libs/bsf-native_2.4.0.bb create mode 100644 recipes/jakarta-libs/bsf_2.4.0.bb diff --git a/recipes/jakarta-libs/bsf-native_2.4.0.bb b/recipes/jakarta-libs/bsf-native_2.4.0.bb new file mode 100644 index 0000000000..9b3c1dd11c --- /dev/null +++ b/recipes/jakarta-libs/bsf-native_2.4.0.bb @@ -0,0 +1,8 @@ +require bsf_${PV}.bb + +S = "${WORKDIR}/bsf-${PV}" + +inherit java-native + +DEPENDS = "fastjar-native jacl-native commons-logging-native rhino-native xalan-j-native bcel-native" + diff --git a/recipes/jakarta-libs/bsf_2.4.0.bb b/recipes/jakarta-libs/bsf_2.4.0.bb new file mode 100644 index 0000000000..e853ea1381 --- /dev/null +++ b/recipes/jakarta-libs/bsf_2.4.0.bb @@ -0,0 +1,24 @@ +DESCRIPTION = "Bean Scripting Framework package" +LICENSES = "AL2.0" +AUTHOR = "Apache Software Foundation" + +SRC_URI = "http://archive.apache.org/dist/jakarta/bsf/source/bsf-src-${PV}.tar.gz" + +inherit java-library + +DEPENDS = "fastjar-native jacl commons-logging rhino xalan-j bcel" + +do_compile() { + mkdir -p build + + oe_makeclasspath cp -s commons-logging jacl rhino bcel xalan2 + + # Remove netrexx and jython support + rm -Rf src/org/apache/bsf/engines/netrexx + rm -Rf src/org/apache/bsf/engines/jython + + javac -sourcepath src -cp $cp -d build `find src -name "*.java"` + + fastjar -C build -c -f ${JARFILENAME} . +} + -- cgit v1.2.3 From 3bdf095afc7ba974492e0bcf04f790ccd6adde71 Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 14:46:04 +0200 Subject: commons-beanutils 1.8.0: New recipe (from Jalimo SVN). commons-cli 1.1: Dito. commons-collections 2.1.1: Dito. commons-collections3 3.2.1: Dito. commons-configuration 1.5: Dito. commons-digester 1.8: Dito. commons-discovery 0.4: Dito. commons-el 1.0: Dito. commons-fileupload 1.2.1: Dito. commons-httpclient 3.1: Dito. commons-io 1.4: Dito. commons-jxpath 1.3: Dito. commons-lang 2.4: Dito. commons-net: Dito. commons-net-native: Dito. commons-pool 1.4: Dito. --- recipes/jakarta-commons/commons-beanutils_1.8.0.bb | 10 ++++++++++ recipes/jakarta-commons/commons-cli_1.1.bb | 7 +++++++ recipes/jakarta-commons/commons-codec_1.3.bb | 7 +++++++ recipes/jakarta-commons/commons-collections3_3.2.1.bb | 8 ++++++++ recipes/jakarta-commons/commons-collections_2.1.1.bb | 6 ++++++ recipes/jakarta-commons/commons-configuration_1.5.bb | 19 +++++++++++++++++++ recipes/jakarta-commons/commons-digester_1.8.bb | 12 ++++++++++++ recipes/jakarta-commons/commons-discovery_0.4.bb | 10 ++++++++++ recipes/jakarta-commons/commons-el_1.0.bb | 14 ++++++++++++++ recipes/jakarta-commons/commons-fileupload_1.2.1.bb | 14 ++++++++++++++ recipes/jakarta-commons/commons-httpclient_3.1.bb | 13 +++++++++++++ recipes/jakarta-commons/commons-io_1.4.bb | 5 +++++ recipes/jakarta-commons/commons-jxpath_1.3.bb | 10 ++++++++++ recipes/jakarta-commons/commons-lang_2.4.bb | 6 ++++++ recipes/jakarta-commons/commons-net-native_1.4.1.bb | 7 +++++++ recipes/jakarta-commons/commons-net_1.4.1.bb | 14 ++++++++++++++ recipes/jakarta-commons/commons-pool_1.4.bb | 5 +++++ 17 files changed, 167 insertions(+) create mode 100644 recipes/jakarta-commons/commons-beanutils_1.8.0.bb create mode 100644 recipes/jakarta-commons/commons-cli_1.1.bb create mode 100644 recipes/jakarta-commons/commons-codec_1.3.bb create mode 100644 recipes/jakarta-commons/commons-collections3_3.2.1.bb create mode 100644 recipes/jakarta-commons/commons-collections_2.1.1.bb create mode 100644 recipes/jakarta-commons/commons-configuration_1.5.bb create mode 100644 recipes/jakarta-commons/commons-digester_1.8.bb create mode 100644 recipes/jakarta-commons/commons-discovery_0.4.bb create mode 100644 recipes/jakarta-commons/commons-el_1.0.bb create mode 100644 recipes/jakarta-commons/commons-fileupload_1.2.1.bb create mode 100644 recipes/jakarta-commons/commons-httpclient_3.1.bb create mode 100644 recipes/jakarta-commons/commons-io_1.4.bb create mode 100644 recipes/jakarta-commons/commons-jxpath_1.3.bb create mode 100644 recipes/jakarta-commons/commons-lang_2.4.bb create mode 100644 recipes/jakarta-commons/commons-net-native_1.4.1.bb create mode 100644 recipes/jakarta-commons/commons-net_1.4.1.bb create mode 100644 recipes/jakarta-commons/commons-pool_1.4.bb diff --git a/recipes/jakarta-commons/commons-beanutils_1.8.0.bb b/recipes/jakarta-commons/commons-beanutils_1.8.0.bb new file mode 100644 index 0000000000..092752a253 --- /dev/null +++ b/recipes/jakarta-commons/commons-beanutils_1.8.0.bb @@ -0,0 +1,10 @@ +require jakarta-commons.inc + +DESCRIPTION = "Static utility methods useful in manipulating Java classes that conform to the JavaBeans Specification" + +SRC_URI = "http://www.apache.org/dist/commons/beanutils/source/${BP}-src.tar.gz" + +DEPENDS += "commons-collections3 commons-logging" +RDEPENDS = "libcommons-collections3-java libcommons-logging-java" + +CP = "commons-collections3 commons-logging" diff --git a/recipes/jakarta-commons/commons-cli_1.1.bb b/recipes/jakarta-commons/commons-cli_1.1.bb new file mode 100644 index 0000000000..ca09789494 --- /dev/null +++ b/recipes/jakarta-commons/commons-cli_1.1.bb @@ -0,0 +1,7 @@ +require jakarta-commons.inc + +DESCRIPTION = "Java argument parsing helper classes" + +SRC_URI = "http://www.apache.org/dist/commons/cli/source/${BP}-src.tar.gz" + + diff --git a/recipes/jakarta-commons/commons-codec_1.3.bb b/recipes/jakarta-commons/commons-codec_1.3.bb new file mode 100644 index 0000000000..9ad18a12ea --- /dev/null +++ b/recipes/jakarta-commons/commons-codec_1.3.bb @@ -0,0 +1,7 @@ +require jakarta-commons.inc + +DESCRIPTION = "Java library with simple encoder and decoders for various formats such as Base64 and Hexadecimal" + +SRC_URI = "http://www.apache.org/dist/commons/codec/source/${BP}-src.tar.gz" + +S = "${WORKDIR}/${BP}" diff --git a/recipes/jakarta-commons/commons-collections3_3.2.1.bb b/recipes/jakarta-commons/commons-collections3_3.2.1.bb new file mode 100644 index 0000000000..dcde0c74f5 --- /dev/null +++ b/recipes/jakarta-commons/commons-collections3_3.2.1.bb @@ -0,0 +1,8 @@ +require jakarta-commons.inc + +DESCRIPTION = "A set of abstract data type interfaces and implementations that offer a wealth of useful functionality and a solid foundation for extending that functionality" + +SRC_URI = "http://www.apache.org/dist/commons/collections/source/commons-collections-${PV}-src.tar.gz" + +S = "${WORKDIR}/commons-collections-${PV}-src" + diff --git a/recipes/jakarta-commons/commons-collections_2.1.1.bb b/recipes/jakarta-commons/commons-collections_2.1.1.bb new file mode 100644 index 0000000000..23766abf25 --- /dev/null +++ b/recipes/jakarta-commons/commons-collections_2.1.1.bb @@ -0,0 +1,6 @@ +require jakarta-commons.inc + +DESCRIPTION = "A set of abstract data type interfaces and implementations that offer a wealth of useful functionality and a solid foundation for extending that functionality" + +SRC_URI = "http://www.apache.org/dist/commons/collections/source/${BP}-src.tar.gz" + diff --git a/recipes/jakarta-commons/commons-configuration_1.5.bb b/recipes/jakarta-commons/commons-configuration_1.5.bb new file mode 100644 index 0000000000..b30b8d998f --- /dev/null +++ b/recipes/jakarta-commons/commons-configuration_1.5.bb @@ -0,0 +1,19 @@ +require jakarta-commons.inc + +DESCRIPTION = "Generic configuration interface for Java applications" + +SRC_URI = "\ + http://www.apache.org/dist/commons/configuration/source/${BP}-src.tar.gz \ + http://ftp.hosting-studio.de/pub/linux/apache/ant/source/apache-ant-1.7.1-src.tar.bz2 \ +" + +DEPENDS += "commons-logging commons-collections3 commons-beanutils commons-codec commons-digester commons-jxpath commons-lang servlet2.4" +RDEPENDS = "libcommons-logging-java libcommons-collections3-java libcommons-beanutils-java libcommons-codec-java libcommons-digester-java libcommons-jxpath-java libcommons-lang-java libservlet2.4-java" + +CP = "commons-logging commons-collections3 commons-beanutils commons-codec commons-digester commons-jxpath commons-lang servlet-api-2.4" + +# Makes use of -sourcepath hack: We inject Ant sourcefiles into the build and remove them +# afterwards. +COMPILE_SOURCEPATH = "${WORKDIR}/apache-ant-1.7.1/src/main:src/java" + +CLEAN_PATH = "build/org/apache/tools" diff --git a/recipes/jakarta-commons/commons-digester_1.8.bb b/recipes/jakarta-commons/commons-digester_1.8.bb new file mode 100644 index 0000000000..28bcef3881 --- /dev/null +++ b/recipes/jakarta-commons/commons-digester_1.8.bb @@ -0,0 +1,12 @@ +require jakarta-commons.inc + +DESCRIPTION = "Converts XML to a Java object by a set of mapping rules." + +SRC_URI = "http://www.apache.org/dist/commons/digester/source/${BP}-src.tar.gz" + +DEPENDS += "commons-logging commons-beanutils" +RDEPENDS = "libcommons-logging-java libcommons-beanutils-java" + +CP = "commons-logging commons-beanutils" + +FINDARGS = "-name '*.dtd'" diff --git a/recipes/jakarta-commons/commons-discovery_0.4.bb b/recipes/jakarta-commons/commons-discovery_0.4.bb new file mode 100644 index 0000000000..a16fb5e3fe --- /dev/null +++ b/recipes/jakarta-commons/commons-discovery_0.4.bb @@ -0,0 +1,10 @@ +require jakarta-commons.inc + +DESCRIPTION = "discovering, or finding, implementations for pluggable interfaces" + +SRC_URI = "http://www.apache.org/dist/commons/discovery/source/${BP}-src.tar.gz" + +DEPENDS += "commons-logging" +RDEPENDS = "libcommons-logging-java" + +CP = "commons-logging" diff --git a/recipes/jakarta-commons/commons-el_1.0.bb b/recipes/jakarta-commons/commons-el_1.0.bb new file mode 100644 index 0000000000..03d2a9b88c --- /dev/null +++ b/recipes/jakarta-commons/commons-el_1.0.bb @@ -0,0 +1,14 @@ +require jakarta-commons.inc + +DESCRIPTION = "Implementation of the JSP2.0 Expression Language API" + +SRC_URI = "http://www.apache.org/dist/commons/el/source/${BP}-src.tar.gz" + +DEPENDS += "jsp2.0 servlet2.4" +RDEPENDS = "libjsp2.0-java libservlet2.4-java" + +CP = "jsp-api-2.0 servlet-api-2.4" + +FINDARGS = "\( -name '*.properties' -or -name '*.jj' \)" + + diff --git a/recipes/jakarta-commons/commons-fileupload_1.2.1.bb b/recipes/jakarta-commons/commons-fileupload_1.2.1.bb new file mode 100644 index 0000000000..063a14bac6 --- /dev/null +++ b/recipes/jakarta-commons/commons-fileupload_1.2.1.bb @@ -0,0 +1,14 @@ +require jakarta-commons.inc + +DESCRIPTION = "Robust, high-performance, file upload capability for Java servlets and web applications" + +SRC_URI = "http://www.apache.org/dist/commons/fileupload/source/${BP}-src.tar.gz" + +DEPENDS += "commons-beanutils commons-io servlet2.3" +RDEPENDS = "libcommons-beanutils-java libcommons-io-java libservlet2.3-java" + +CP = "commons-beanutils commons-io servlet-2.3" + +# Exclude portlet stuff from compilation like Debian does. +COMPILE_FINDARGS = "-name '*.java' -not -wholename '*portlet*'" + diff --git a/recipes/jakarta-commons/commons-httpclient_3.1.bb b/recipes/jakarta-commons/commons-httpclient_3.1.bb new file mode 100644 index 0000000000..18e2980888 --- /dev/null +++ b/recipes/jakarta-commons/commons-httpclient_3.1.bb @@ -0,0 +1,13 @@ +require jakarta-commons.inc + +DESCRIPTION = "Efficient, up-to-date, and feature-rich package implementing the client side of the most recent HTTP standards and recommendations" + +SRC_URI = "http://www.apache.org/dist/httpcomponents/commons-httpclient/source/${BP}-src.tar.gz" + +S = "${WORKDIR}/${BP}" + +DEPENDS += "commons-logging commons-codec" +RDEPENDS = "libcommons-logging-java libcommons-codec-java" + +CP = "commons-logging commons-codec" + diff --git a/recipes/jakarta-commons/commons-io_1.4.bb b/recipes/jakarta-commons/commons-io_1.4.bb new file mode 100644 index 0000000000..76fdec829c --- /dev/null +++ b/recipes/jakarta-commons/commons-io_1.4.bb @@ -0,0 +1,5 @@ +require jakarta-commons.inc + +DESCRIPTION = "Java library with utility classes, stream implementations, file filters and endian classes" + +SRC_URI = "http://www.apache.org/dist/commons/io/source/${BP}-src.tar.gz" diff --git a/recipes/jakarta-commons/commons-jxpath_1.3.bb b/recipes/jakarta-commons/commons-jxpath_1.3.bb new file mode 100644 index 0000000000..5fabef04cd --- /dev/null +++ b/recipes/jakarta-commons/commons-jxpath_1.3.bb @@ -0,0 +1,10 @@ +require jakarta-commons.inc + +DESCRIPTION = "JXPath interpreter for Java" + +SRC_URI = "http://www.apache.org/dist/commons/jxpath/source/${BP}-src.tar.gz" + +DEPENDS += "commons-logging commons-collections3 commons-beanutils servlet2.3 jdom" +RDEPENDS = "libcommons-logging-java libcommons-collections3-java libcommons-beanutils-java libservlet2.3-java libjdom-java" + +CP = "commons-logging commons-collections3 commons-beanutils servlet-2.3 jdom" diff --git a/recipes/jakarta-commons/commons-lang_2.4.bb b/recipes/jakarta-commons/commons-lang_2.4.bb new file mode 100644 index 0000000000..2b7e6986aa --- /dev/null +++ b/recipes/jakarta-commons/commons-lang_2.4.bb @@ -0,0 +1,6 @@ +require jakarta-commons.inc + +DESCRIPTION = "Set of Java classes that provide helper methods for the standard java.lang classes" + +SRC_URI = "http://www.apache.org/dist/commons/lang/source/${BP}-src.tar.gz" + diff --git a/recipes/jakarta-commons/commons-net-native_1.4.1.bb b/recipes/jakarta-commons/commons-net-native_1.4.1.bb new file mode 100644 index 0000000000..f1d39ea8c2 --- /dev/null +++ b/recipes/jakarta-commons/commons-net-native_1.4.1.bb @@ -0,0 +1,7 @@ +require commons-net_${PV}.bb + +inherit java-native + +DEPENDS = "fastjar-native oro-native" +RDEPENDS = "" + diff --git a/recipes/jakarta-commons/commons-net_1.4.1.bb b/recipes/jakarta-commons/commons-net_1.4.1.bb new file mode 100644 index 0000000000..4fccea5cdf --- /dev/null +++ b/recipes/jakarta-commons/commons-net_1.4.1.bb @@ -0,0 +1,14 @@ +require jakarta-commons.inc + +DESCRIPTION = "Java Internet protocol suite library" + +SRC_URI = "http://www.apache.org/dist/commons/net/source/${BP}-src.tar.gz" + +S = "${WORKDIR}/${BP}" + +DEPENDS += "oro" +RDEPENDS = "liboro-java" + +CP = "oro" + +MAINSOURCES = "src/java/org" diff --git a/recipes/jakarta-commons/commons-pool_1.4.bb b/recipes/jakarta-commons/commons-pool_1.4.bb new file mode 100644 index 0000000000..152f429916 --- /dev/null +++ b/recipes/jakarta-commons/commons-pool_1.4.bb @@ -0,0 +1,5 @@ +require jakarta-commons.inc + +DESCRIPTION = "Java Object-pooling API" + +SRC_URI = "http://www.apache.org/dist/commons/pool/source/${BP}-src.tar.gz" -- cgit v1.2.3 From 83be2434e283e53f545fb433b8a1373710d880c1 Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 15:00:18 +0200 Subject: ant-native 1.7.1: New recipe (from Jalimo SVN). --- recipes/ant/ant-native_1.7.1.bb | 64 +++++++++++++++++++++++++++++++++++++++++ recipes/ant/files/ant | 10 +++++++ 2 files changed, 74 insertions(+) create mode 100644 recipes/ant/ant-native_1.7.1.bb create mode 100755 recipes/ant/files/ant diff --git a/recipes/ant/ant-native_1.7.1.bb b/recipes/ant/ant-native_1.7.1.bb new file mode 100644 index 0000000000..baf40e0ecf --- /dev/null +++ b/recipes/ant/ant-native_1.7.1.bb @@ -0,0 +1,64 @@ +DESCRIPTION = "Another Neat Tool - build system for Java" +LICENSE = "AL2.0" + +AUTHOR = "Apache Software Foundation" +HOMEPAGE = "http://ant.apache.org" + +SRC_URI = "\ + http://ftp.riken.jp/net/apache/ant/source/apache-ant-${PV}-src.tar.gz \ + file://ant \ + " + +S = "${WORKDIR}/apache-ant-${PV}" + +inherit java-library java-native + +DEPENDS = "\ + fastjar-native \ + jsch-native bsf-native xalan-j-native xerces-j-native \ + xml-commons-resolver1.1-native gnumail-native gnujaf-native \ + bcel-native regexp-native log4j1.2-native antlr-native oro-native \ + junit-native jdepend-native commons-net-native commons-logging-native \ + " + +do_removecruft() { + # Removes thing that need proprietary Jar files or are otherwise problematic + rm -rf ${S}/src/main/org/apache/tools/ant/taskdefs/optional/image + rm -rf ${S}/src/main/org/apache/tools/ant/types/optional/image + rm -rf ${S}/src/main/org/apache/tools/ant/taskdefs/optional/ejb + rm -rf ${S}/src/main/org/apache/tools/ant/taskdefs/optional/scm + rm -rf ${S}/src/main/org/apache/tools/ant/taskdefs/optional/starteam + rm -rf ${S}/src/main/org/apache/tools/ant/taskdefs/optional/NetRexxC.java +} + +addtask removecruft before do_patch after do_unpack + +do_compile() { + mkdir -p build + + oe_makeclasspath cp -s jsch bsf xalan2 xercesImpl resolver gnumail gnujaf bcel regexp log4j1.2 antlr oro junit jdepend commons-net commons-logging + cp=build:$cp + + find src/main -name "*.java" > java_files + + javac -sourcepath src/main -cp $cp -d build @java_files + + mkdir -p build/org/apache/tools/ant/types/conditions + + cp -r src/resources/org build/ + (cd src/main && find . \( -name "*.properties" -or -name "*.xml" -or -name "*.mf" \) -exec cp {} ../../build/{} \;) + + echo "VERSION=${PV}" > build/org/apache/tools/ant/version.txt + echo "DATE=`date -R`" >> build/org/apache/tools/ant/version.txt + + fastjar -C build -c -f ${JARFILENAME} . + + oe_makeclasspath cp -s ecj-bootstrap jsch bsf xalan2 xercesImpl resolver gnumail gnujaf bcel regexp log4j1.2 antlr oro junit jdepend commons-net commons-logging + cp=${STAGING_DATADIR_JAVA_NATIVE}/ant.jar:${STAGING_DATADIR}/classpath/tools.zip:$cp + sed -i -e"s|@JAR_FILE@|$cp|" ${WORKDIR}/ant +} + +do_stage_append() { + install -d ${bindir} + install -m 0755 ${WORKDIR}/ant ${bindir} +} diff --git a/recipes/ant/files/ant b/recipes/ant/files/ant new file mode 100755 index 0000000000..bb282a91a7 --- /dev/null +++ b/recipes/ant/files/ant @@ -0,0 +1,10 @@ +#!/bin/sh + +export CLASSPATH +CLASSPATH=$CLASSPATH:@JAR_FILE@ + +if [ ! $JAVA ];then + JAVA=java +fi + +$JAVA org.apache.tools.ant.launch.Launcher $* -- cgit v1.2.3 From 04800cfdf823ea3003eb1164c4d5dfd7e1db5679 Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 15:59:52 +0200 Subject: conf/checksums.ini: Fixed URL for jdom 1.1. --- conf/checksums.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/checksums.ini b/conf/checksums.ini index 2b8ec2028a..cce539180b 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -12034,7 +12034,7 @@ sha256=202de62e2f3d0667cc464720d5897d0ccb29767ec24e0a4d4c5bd6c4d37425a4 md5=b70924c697584ab7955050d7a9b4de57 sha256=dae79e8c56090ac3fb4ac3fe0df9faf6a0c9694a89ef978dce0ab970557ad264 -[http://www.jdom.org/dist/binary/jdom-1.1.tar.gz] +[http://www.jdom.org/dist/binary/archive/jdom-1.1.tar.gz] md5=22745cbaaddb12884ed8ee09083d8fe2 sha256=a13549087141be24ad176b659afdc2c675f1ffa5288ff999a193d6d44a282056 -- cgit v1.2.3 From 2e7c334a4f6b0882ee90c8be91f81d24e4d82496 Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 16:04:01 +0200 Subject: dom4j 1.6.1: New recipe (for Jalimo SVN). dom4j-native 1.6.1: Dito. jaxen 1.1.1: Dito. xom 1.1: Dito. xpp2 2.1.10: Dito. xpp3 1.1.3.4.0: Dito. --- recipes/xml-commons/dom4j-1.6.1/debian.patch | 1628 ++++++++++++++++++++ recipes/xml-commons/dom4j_1.6.1.bb | 30 + recipes/xml-commons/jaxen_1.1.1.bb | 28 + recipes/xml-commons/jdom_1.1.bb | 23 + .../xml-commons/xom-1.1/04_remove_sun_import.patch | 27 + recipes/xml-commons/xom_1.1.bb | 37 + recipes/xml-commons/xpp2_2.1.10.bb | 31 + recipes/xml-commons/xpp3_1.1.3.4.O.bb | 50 + 8 files changed, 1854 insertions(+) create mode 100644 recipes/xml-commons/dom4j-1.6.1/debian.patch create mode 100644 recipes/xml-commons/dom4j_1.6.1.bb create mode 100644 recipes/xml-commons/jaxen_1.1.1.bb create mode 100644 recipes/xml-commons/jdom_1.1.bb create mode 100644 recipes/xml-commons/xom-1.1/04_remove_sun_import.patch create mode 100644 recipes/xml-commons/xom_1.1.bb create mode 100644 recipes/xml-commons/xpp2_2.1.10.bb create mode 100644 recipes/xml-commons/xpp3_1.1.3.4.O.bb diff --git a/recipes/xml-commons/dom4j-1.6.1/debian.patch b/recipes/xml-commons/dom4j-1.6.1/debian.patch new file mode 100644 index 0000000000..87fda85740 --- /dev/null +++ b/recipes/xml-commons/dom4j-1.6.1/debian.patch @@ -0,0 +1,1628 @@ +--- dom4j-1.6.1+dfsg.orig/src/java/org/jaxen/dom4j/DocumentNavigator.java ++++ dom4j-1.6.1+dfsg/src/java/org/jaxen/dom4j/DocumentNavigator.java +@@ -0,0 +1,501 @@ ++package org.jaxen.dom4j; ++ ++/* ++ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/dom4j/DocumentNavigator.java,v 1.33 2006/07/03 13:17:30 elharo Exp $ ++ * $Revision: 1.33 $ ++ * $Date: 2006/07/03 13:17:30 $ ++ * ++ * ==================================================================== ++ * ++ * Copyright 2000-2005 bob mcwhirter & James Strachan. ++ * All rights reserved. ++ * ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are ++ * met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * 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. ++ * ++ * * Neither the name of the Jaxen Project nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * 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. ++ * ++ * ==================================================================== ++ * This software consists of voluntary contributions made by many ++ * individuals on behalf of the Jaxen Project and was originally ++ * created by bob mcwhirter and ++ * James Strachan . For more information on the ++ * Jaxen Project, please see . ++ * ++ * $Id: DocumentNavigator.java,v 1.33 2006/07/03 13:17:30 elharo Exp $ ++*/ ++ ++import java.util.ArrayList; ++import java.util.HashSet; ++import java.util.Iterator; ++import java.util.List; ++ ++import org.dom4j.Attribute; ++import org.dom4j.Branch; ++import org.dom4j.CDATA; ++import org.dom4j.Comment; ++import org.dom4j.Document; ++import org.dom4j.DocumentException; ++import org.dom4j.Element; ++import org.dom4j.Namespace; ++import org.dom4j.Node; ++import org.dom4j.ProcessingInstruction; ++import org.dom4j.QName; ++import org.dom4j.Text; ++import org.dom4j.io.SAXReader; ++import org.jaxen.DefaultNavigator; ++import org.jaxen.FunctionCallException; ++import org.jaxen.NamedAccessNavigator; ++import org.jaxen.Navigator; ++import org.jaxen.XPath; ++import org.jaxen.JaxenConstants; ++import org.jaxen.saxpath.SAXPathException; ++import org.jaxen.util.SingleObjectIterator; ++ ++/** ++ * Interface for navigating around the DOM4J object model. ++ * ++ *

++ * This class is not intended for direct usage, but is ++ * used by the Jaxen engine during evaluation. ++ *

++ * ++ * @see XPath ++ * ++ * @author bob mcwhirter ++ * @author Stephen Colebourne ++ */ ++public class DocumentNavigator extends DefaultNavigator implements NamedAccessNavigator ++{ ++ ++ /** ++ * ++ */ ++ private static final long serialVersionUID = 5582300797286535936L; ++ private transient SAXReader reader; ++ ++ /** Singleton implementation. ++ */ ++ private static class Singleton ++ { ++ /** Singleton instance. ++ */ ++ private static DocumentNavigator instance = new DocumentNavigator(); ++ } ++ ++ /** Retrieve the singleton instance of this DocumentNavigator. ++ */ ++ public static Navigator getInstance() ++ { ++ return Singleton.instance; ++ } ++ ++ public boolean isElement(Object obj) ++ { ++ return obj instanceof Element; ++ } ++ ++ public boolean isComment(Object obj) ++ { ++ return obj instanceof Comment; ++ } ++ ++ public boolean isText(Object obj) ++ { ++ return ( obj instanceof Text ++ || ++ obj instanceof CDATA ); ++ } ++ ++ public boolean isAttribute(Object obj) ++ { ++ return obj instanceof Attribute; ++ } ++ ++ public boolean isProcessingInstruction(Object obj) ++ { ++ return obj instanceof ProcessingInstruction; ++ } ++ ++ public boolean isDocument(Object obj) ++ { ++ return obj instanceof Document; ++ } ++ ++ public boolean isNamespace(Object obj) ++ { ++ return obj instanceof Namespace; ++ } ++ ++ public String getElementName(Object obj) ++ { ++ Element elem = (Element) obj; ++ ++ return elem.getName(); ++ } ++ ++ public String getElementNamespaceUri(Object obj) ++ { ++ Element elem = (Element) obj; ++ ++ String uri = elem.getNamespaceURI(); ++ if ( uri == null) ++ return ""; ++ else ++ return uri; ++ } ++ ++ public String getElementQName(Object obj) ++ { ++ Element elem = (Element) obj; ++ ++ return elem.getQualifiedName(); ++ } ++ ++ public String getAttributeName(Object obj) ++ { ++ Attribute attr = (Attribute) obj; ++ ++ return attr.getName(); ++ } ++ ++ public String getAttributeNamespaceUri(Object obj) ++ { ++ Attribute attr = (Attribute) obj; ++ ++ String uri = attr.getNamespaceURI(); ++ if ( uri == null) ++ return ""; ++ else ++ return uri; ++ } ++ ++ public String getAttributeQName(Object obj) ++ { ++ Attribute attr = (Attribute) obj; ++ ++ return attr.getQualifiedName(); ++ } ++ ++ public Iterator getChildAxisIterator(Object contextNode) ++ { ++ Iterator result = null; ++ if ( contextNode instanceof Branch ) ++ { ++ Branch node = (Branch) contextNode; ++ result = node.nodeIterator(); ++ } ++ if (result != null) { ++ return result; ++ } ++ return JaxenConstants.EMPTY_ITERATOR; ++ } ++ ++ /** ++ * Retrieves an Iterator over the child elements that ++ * match the supplied name. ++ * ++ * @param contextNode the origin context node ++ * @param localName the local name of the children to return, always present ++ * @param namespacePrefix the prefix of the namespace of the children to return ++ * @param namespaceURI the uri of the namespace of the children to return ++ * ++ * @return an Iterator that traverses the named children, or null if none ++ */ ++ public Iterator getChildAxisIterator( ++ Object contextNode, String localName, String namespacePrefix, String namespaceURI) { ++ ++ if ( contextNode instanceof Element ) { ++ Element node = (Element) contextNode; ++ return node.elementIterator(QName.get(localName, namespacePrefix, namespaceURI)); ++ } ++ if ( contextNode instanceof Document ) { ++ Document node = (Document) contextNode; ++ Element el = node.getRootElement(); ++ if (el == null || el.getName().equals(localName) == false) { ++ return JaxenConstants.EMPTY_ITERATOR; ++ } ++ if (namespaceURI != null) { ++ if (namespaceURI.equals(el.getNamespaceURI()) == false) { ++ return JaxenConstants.EMPTY_ITERATOR; ++ } ++ } ++ return new SingleObjectIterator(el); ++ } ++ ++ return JaxenConstants.EMPTY_ITERATOR; ++ } ++ ++ public Iterator getParentAxisIterator(Object contextNode) ++ { ++ if ( contextNode instanceof Document ) ++ { ++ return JaxenConstants.EMPTY_ITERATOR; ++ } ++ ++ Node node = (Node) contextNode; ++ ++ Object parent = node.getParent(); ++ ++ if ( parent == null ) ++ { ++ parent = node.getDocument(); ++ } ++ ++ return new SingleObjectIterator( parent ); ++ } ++ ++ public Iterator getAttributeAxisIterator(Object contextNode) ++ { ++ if ( ! ( contextNode instanceof Element ) ) ++ { ++ return JaxenConstants.EMPTY_ITERATOR; ++ } ++ ++ Element elem = (Element) contextNode; ++ ++ return elem.attributeIterator(); ++ } ++ ++ /** ++ * Retrieves an Iterator over the attribute elements that ++ * match the supplied name. ++ * ++ * @param contextNode the origin context node ++ * @param localName the local name of the attributes to return, always present ++ * @param namespacePrefix the prefix of the namespace of the attributes to return ++ * @param namespaceURI the URI of the namespace of the attributes to return ++ * @return an Iterator that traverses the named attributes, not null ++ */ ++ public Iterator getAttributeAxisIterator( ++ Object contextNode, String localName, String namespacePrefix, String namespaceURI) { ++ ++ if ( contextNode instanceof Element ) { ++ Element node = (Element) contextNode; ++ Attribute attr = node.attribute(QName.get(localName, namespacePrefix, namespaceURI)); ++ if (attr == null) { ++ return JaxenConstants.EMPTY_ITERATOR; ++ } ++ return new SingleObjectIterator(attr); ++ } ++ return JaxenConstants.EMPTY_ITERATOR; ++ } ++ ++ public Iterator getNamespaceAxisIterator(Object contextNode) ++ { ++ if ( ! ( contextNode instanceof Element ) ) ++ { ++ return JaxenConstants.EMPTY_ITERATOR; ++ } ++ ++ Element element = (Element) contextNode; ++ List nsList = new ArrayList(); ++ HashSet prefixes = new HashSet(); ++ for ( Element context = element; context != null; context = context.getParent() ) { ++ List declaredNS = new ArrayList(context.declaredNamespaces()); ++ declaredNS.add(context.getNamespace()); ++ ++ for ( Iterator iter = context.attributes().iterator(); iter.hasNext(); ) ++ { ++ Attribute attr = (Attribute) iter.next(); ++ declaredNS.add(attr.getNamespace()); ++ } ++ ++ for ( Iterator iter = declaredNS.iterator(); iter.hasNext(); ) ++ { ++ Namespace namespace = (Namespace) iter.next(); ++ if (namespace != Namespace.NO_NAMESPACE) ++ { ++ String prefix = namespace.getPrefix(); ++ if ( ! prefixes.contains( prefix ) ) { ++ prefixes.add( prefix ); ++ nsList.add( namespace.asXPathResult( element ) ); ++ } ++ } ++ } ++ } ++ nsList.add( Namespace.XML_NAMESPACE.asXPathResult( element ) ); ++ return nsList.iterator(); ++ } ++ ++ public Object getDocumentNode(Object contextNode) ++ { ++ if ( contextNode instanceof Document ) ++ { ++ return contextNode; ++ } ++ else if ( contextNode instanceof Node ) ++ { ++ Node node = (Node) contextNode; ++ return node.getDocument(); ++ } ++ return null; ++ } ++ ++ /** Returns a parsed form of the given XPath string, which will be suitable ++ * for queries on DOM4J documents. ++ */ ++ public XPath parseXPath (String xpath) throws SAXPathException ++ { ++ return new Dom4jXPath(xpath); ++ } ++ ++ public Object getParentNode(Object contextNode) ++ { ++ if ( contextNode instanceof Node ) ++ { ++ Node node = (Node) contextNode; ++ Object answer = node.getParent(); ++ if ( answer == null ) ++ { ++ answer = node.getDocument(); ++ if (answer == contextNode) { ++ return null; ++ } ++ } ++ return answer; ++ } ++ return null; ++ } ++ ++ public String getTextStringValue(Object obj) ++ { ++ return getNodeStringValue( (Node) obj ); ++ } ++ ++ public String getElementStringValue(Object obj) ++ { ++ return getNodeStringValue( (Node) obj ); ++ } ++ ++ public String getAttributeStringValue(Object obj) ++ { ++ return getNodeStringValue( (Node) obj ); ++ } ++ ++ private String getNodeStringValue(Node node) ++ { ++ return node.getStringValue(); ++ } ++ ++ public String getNamespaceStringValue(Object obj) ++ { ++ Namespace ns = (Namespace) obj; ++ ++ return ns.getURI(); ++ } ++ ++ public String getNamespacePrefix(Object obj) ++ { ++ Namespace ns = (Namespace) obj; ++ ++ return ns.getPrefix(); ++ } ++ ++ public String getCommentStringValue(Object obj) ++ { ++ Comment cmt = (Comment) obj; ++ ++ return cmt.getText(); ++ } ++ ++ public String translateNamespacePrefixToUri(String prefix, Object context) ++ { ++ Element element = null; ++ if ( context instanceof Element ) ++ { ++ element = (Element) context; ++ } ++ else if ( context instanceof Node ) ++ { ++ Node node = (Node) context; ++ element = node.getParent(); ++ } ++ if ( element != null ) ++ { ++ Namespace namespace = element.getNamespaceForPrefix( prefix ); ++ ++ if ( namespace != null ) ++ { ++ return namespace.getURI(); ++ } ++ } ++ return null; ++ } ++ ++ public short getNodeType(Object node) ++ { ++ if ( node instanceof Node ) ++ { ++ return ((Node) node).getNodeType(); ++ } ++ return 0; ++ } ++ ++ public Object getDocument(String uri) throws FunctionCallException ++ { ++ try ++ { ++ return getSAXReader().read( uri ); ++ } ++ catch (DocumentException e) ++ { ++ throw new FunctionCallException("Failed to parse document for URI: " + uri, e); ++ } ++ } ++ ++ public String getProcessingInstructionTarget(Object obj) ++ { ++ ProcessingInstruction pi = (ProcessingInstruction) obj; ++ ++ return pi.getTarget(); ++ } ++ ++ public String getProcessingInstructionData(Object obj) ++ { ++ ProcessingInstruction pi = (ProcessingInstruction) obj; ++ ++ return pi.getText(); ++ } ++ ++ // Properties ++ //------------------------------------------------------------------------- ++ public SAXReader getSAXReader() ++ { ++ if ( reader == null ) ++ { ++ reader = new SAXReader(); ++ reader.setMergeAdjacentText( true ); ++ } ++ return reader; ++ } ++ ++ public void setSAXReader(SAXReader reader) ++ { ++ this.reader = reader; ++ } ++ ++} +--- dom4j-1.6.1+dfsg.orig/src/java/org/jaxen/dom4j/Dom4jXPath.java ++++ dom4j-1.6.1+dfsg/src/java/org/jaxen/dom4j/Dom4jXPath.java +@@ -0,0 +1,94 @@ ++/* ++ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/dom4j/Dom4jXPath.java,v 1.8 2006/06/03 20:44:53 elharo Exp $ ++ * $Revision: 1.8 $ ++ * $Date: 2006/06/03 20:44:53 $ ++ * ++ * ==================================================================== ++ * ++ * Copyright 2000-2002 bob mcwhirter & James Strachan. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are ++ * met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * 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. ++ * ++ * * Neither the name of the Jaxen Project nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * 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. ++ * ++ * ==================================================================== ++ * This software consists of voluntary contributions made by many ++ * individuals on behalf of the Jaxen Project and was originally ++ * created by bob mcwhirter and ++ * James Strachan . For more information on the ++ * Jaxen Project, please see . ++ * ++ * $Id: Dom4jXPath.java,v 1.8 2006/06/03 20:44:53 elharo Exp $ ++ */ ++ ++ ++ ++package org.jaxen.dom4j; ++ ++import org.jaxen.BaseXPath; ++import org.jaxen.JaxenException; ++ ++/** An XPath implementation for the dom4j model ++ * ++ *

This is the main entry point for matching an XPath against a DOM ++ * tree. You create a compiled XPath object, then match it against ++ * one or more context nodes using the {@link #selectNodes(Object)} ++ * method, as in the following example:

++ * ++ *
++ * Node node = ...;
++ * XPath path = new Dom4jXPath("a/b/c");
++ * List results = path.selectNodes(node);
++ * 
++ * ++ * @see BaseXPath ++ * @see The dom4j website ++ * ++ * @author bob mcwhirter ++ * @author James Strachan ++ * ++ * @version $Revision: 1.8 $ ++ */ ++public class Dom4jXPath extends BaseXPath ++{ ++ /** ++ * ++ */ ++ private static final long serialVersionUID = -75510941087659775L; ++ ++ /** Construct given an XPath expression string. ++ * ++ * @param xpathExpr the XPath expression ++ * ++ * @throws JaxenException if there is a syntax error while ++ * parsing the expression ++ */ ++ public Dom4jXPath(String xpathExpr) throws JaxenException ++ { ++ super( xpathExpr, DocumentNavigator.getInstance() ); ++ } ++} +--- dom4j-1.6.1+dfsg.orig/src/java/org/dom4j/dom/DOMAttribute.java ++++ dom4j-1.6.1+dfsg/src/java/org/dom4j/dom/DOMAttribute.java +@@ -14,7 +14,10 @@ + import org.w3c.dom.DOMException; + import org.w3c.dom.Document; + import org.w3c.dom.NamedNodeMap; ++import org.w3c.dom.Node; + import org.w3c.dom.NodeList; ++import org.w3c.dom.TypeInfo; ++import org.w3c.dom.UserDataHandler; + + /** + *

+@@ -179,6 +182,76 @@ + public org.w3c.dom.Element getOwnerElement() { + return DOMNodeHelper.asDOMElement(getParent()); + } ++ ++ public TypeInfo getSchemaTypeInfo() { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isId() { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String getBaseURI() { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public short compareDocumentPosition(Node other) throws DOMException { ++ // TODO Auto-generated method stub ++ return 0; ++ } ++ ++ public String getTextContent() throws DOMException { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public void setTextContent(String textContent) throws DOMException { ++ // TODO Auto-generated method stub ++ ++ } ++ ++ public boolean isSameNode(Node other) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupPrefix(String namespaceURI) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isDefaultNamespace(String namespaceURI) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupNamespaceURI(String prefix) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isEqualNode(Node arg) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public Object getFeature(String feature, String version) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object setUserData(String key, Object data, UserDataHandler handler) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object getUserData(String key) { ++ // TODO Auto-generated method stub ++ return null; ++ } + } + + /* +--- dom4j-1.6.1+dfsg.orig/src/java/org/dom4j/dom/DOMCDATA.java ++++ dom4j-1.6.1+dfsg/src/java/org/dom4j/dom/DOMCDATA.java +@@ -14,7 +14,10 @@ + import org.w3c.dom.DOMException; + import org.w3c.dom.Document; + import org.w3c.dom.NamedNodeMap; ++import org.w3c.dom.Node; + import org.w3c.dom.NodeList; ++import org.w3c.dom.Text; ++import org.w3c.dom.UserDataHandler; + + /** + *

+@@ -225,6 +228,81 @@ + protected CDATA createCDATA(String text) { + return new DOMCDATA(text); + } ++ ++ public boolean isElementContentWhitespace() { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String getWholeText() { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Text replaceWholeText(String content) throws DOMException { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public String getBaseURI() { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public short compareDocumentPosition(Node other) throws DOMException { ++ // TODO Auto-generated method stub ++ return 0; ++ } ++ ++ public String getTextContent() throws DOMException { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public void setTextContent(String textContent) throws DOMException { ++ // TODO Auto-generated method stub ++ ++ } ++ ++ public boolean isSameNode(Node other) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupPrefix(String namespaceURI) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isDefaultNamespace(String namespaceURI) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupNamespaceURI(String prefix) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isEqualNode(Node arg) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public Object getFeature(String feature, String version) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object setUserData(String key, Object data, UserDataHandler handler) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object getUserData(String key) { ++ // TODO Auto-generated method stub ++ return null; ++ } + } + + /* +--- dom4j-1.6.1+dfsg.orig/src/java/org/dom4j/dom/DOMComment.java ++++ dom4j-1.6.1+dfsg/src/java/org/dom4j/dom/DOMComment.java +@@ -13,7 +13,9 @@ + import org.w3c.dom.DOMException; + import org.w3c.dom.Document; + import org.w3c.dom.NamedNodeMap; ++import org.w3c.dom.Node; + import org.w3c.dom.NodeList; ++import org.w3c.dom.UserDataHandler; + + /** + *

+@@ -187,6 +189,66 @@ + throws DOMException { + DOMNodeHelper.replaceData(this, offset, count, arg); + } ++ ++ public String getBaseURI() { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public short compareDocumentPosition(Node other) throws DOMException { ++ // TODO Auto-generated method stub ++ return 0; ++ } ++ ++ public String getTextContent() throws DOMException { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public void setTextContent(String textContent) throws DOMException { ++ // TODO Auto-generated method stub ++ ++ } ++ ++ public boolean isSameNode(Node other) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupPrefix(String namespaceURI) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isDefaultNamespace(String namespaceURI) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupNamespaceURI(String prefix) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isEqualNode(Node arg) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public Object getFeature(String feature, String version) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object setUserData(String key, Object data, UserDataHandler handler) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object getUserData(String key) { ++ // TODO Auto-generated method stub ++ return null; ++ } + } + + /* +--- dom4j-1.6.1+dfsg.orig/src/java/org/dom4j/dom/DOMDocumentFactory.java ++++ dom4j-1.6.1+dfsg/src/java/org/dom4j/dom/DOMDocumentFactory.java +@@ -174,6 +174,11 @@ + docType.getPublicId(), docType.getSystemId()); + } + } ++ ++ public Object getFeature(String arg0, String arg1) { ++ // TODO Auto-generated method stub ++ return null; ++ } + } + + +@@ -213,4 +218,4 @@ + * POSSIBILITY OF SUCH DAMAGE. + * + * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved. +- */ +\ No newline at end of file ++ */ +--- dom4j-1.6.1+dfsg.orig/src/java/org/dom4j/dom/DOMDocument.java ++++ dom4j-1.6.1+dfsg/src/java/org/dom4j/dom/DOMDocument.java +@@ -15,12 +15,15 @@ + + import org.w3c.dom.Attr; + import org.w3c.dom.CDATASection; ++import org.w3c.dom.DOMConfiguration; + import org.w3c.dom.DOMException; + import org.w3c.dom.Document; + import org.w3c.dom.EntityReference; + import org.w3c.dom.NamedNodeMap; ++import org.w3c.dom.Node; + import org.w3c.dom.NodeList; + import org.w3c.dom.ProcessingInstruction; ++import org.w3c.dom.UserDataHandler; + + /** + *

+@@ -301,6 +304,136 @@ + return super.getDocumentFactory(); + } + } ++ ++ public String getInputEncoding() { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public String getXmlEncoding() { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean getXmlStandalone() { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public void setXmlStandalone(boolean arg0) throws DOMException { ++ // TODO Auto-generated method stub ++ ++ } ++ ++ public String getXmlVersion() { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public void setXmlVersion(String arg0) throws DOMException { ++ // TODO Auto-generated method stub ++ ++ } ++ ++ public boolean getStrictErrorChecking() { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public void setStrictErrorChecking(boolean arg0) { ++ // TODO Auto-generated method stub ++ ++ } ++ ++ public String getDocumentURI() { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public void setDocumentURI(String arg0) { ++ // TODO Auto-generated method stub ++ ++ } ++ ++ public Node adoptNode(Node arg0) throws DOMException { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public DOMConfiguration getDomConfig() { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public void normalizeDocument() { ++ // TODO Auto-generated method stub ++ ++ } ++ ++ public Node renameNode(Node arg0, String arg1, String arg2) throws DOMException { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public String getBaseURI() { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public short compareDocumentPosition(Node arg0) throws DOMException { ++ // TODO Auto-generated method stub ++ return 0; ++ } ++ ++ public String getTextContent() throws DOMException { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public void setTextContent(String arg0) throws DOMException { ++ // TODO Auto-generated method stub ++ ++ } ++ ++ public boolean isSameNode(Node arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupPrefix(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isDefaultNamespace(String arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupNamespaceURI(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isEqualNode(Node arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public Object getFeature(String arg0, String arg1) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object setUserData(String arg0, Object arg1, UserDataHandler arg2) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object getUserData(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } + } + + /* +--- dom4j-1.6.1+dfsg.orig/src/java/org/dom4j/dom/DOMDocumentType.java ++++ dom4j-1.6.1+dfsg/src/java/org/dom4j/dom/DOMDocumentType.java +@@ -12,7 +12,9 @@ + import org.w3c.dom.DOMException; + import org.w3c.dom.Document; + import org.w3c.dom.NamedNodeMap; ++import org.w3c.dom.Node; + import org.w3c.dom.NodeList; ++import org.w3c.dom.UserDataHandler; + + /** + *

+@@ -177,6 +179,66 @@ + public String getInternalSubset() { + return getElementName(); + } ++ ++ public String getBaseURI() { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public short compareDocumentPosition(Node arg0) throws DOMException { ++ // TODO Auto-generated method stub ++ return 0; ++ } ++ ++ public String getTextContent() throws DOMException { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public void setTextContent(String arg0) throws DOMException { ++ // TODO Auto-generated method stub ++ ++ } ++ ++ public boolean isSameNode(Node arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupPrefix(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isDefaultNamespace(String arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupNamespaceURI(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isEqualNode(Node arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public Object getFeature(String arg0, String arg1) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object setUserData(String arg0, Object arg1, UserDataHandler arg2) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object getUserData(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } + } + + /* +--- dom4j-1.6.1+dfsg.orig/src/java/org/dom4j/dom/DOMElement.java ++++ dom4j-1.6.1+dfsg/src/java/org/dom4j/dom/DOMElement.java +@@ -16,11 +16,14 @@ + import org.dom4j.QName; + import org.dom4j.tree.DefaultElement; + ++import org.w3c.dom.Attr; + import org.w3c.dom.DOMException; + import org.w3c.dom.Document; + import org.w3c.dom.NamedNodeMap; + import org.w3c.dom.Node; + import org.w3c.dom.NodeList; ++import org.w3c.dom.TypeInfo; ++import org.w3c.dom.UserDataHandler; + + /** + *

+@@ -389,6 +392,86 @@ + + return getDocumentFactory().createQName(localName, prefix, namespace); + } ++ ++ public TypeInfo getSchemaTypeInfo() { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public void setIdAttribute(String arg0, boolean arg1) throws DOMException { ++ // TODO Auto-generated method stub ++ ++ } ++ ++ public void setIdAttributeNS(String arg0, String arg1, boolean arg2) throws DOMException { ++ // TODO Auto-generated method stub ++ ++ } ++ ++ public void setIdAttributeNode(Attr arg0, boolean arg1) throws DOMException { ++ // TODO Auto-generated method stub ++ ++ } ++ ++ public String getBaseURI() { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public short compareDocumentPosition(Node arg0) throws DOMException { ++ // TODO Auto-generated method stub ++ return 0; ++ } ++ ++ public String getTextContent() throws DOMException { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public void setTextContent(String arg0) throws DOMException { ++ // TODO Auto-generated method stub ++ ++ } ++ ++ public boolean isSameNode(Node arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupPrefix(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isDefaultNamespace(String arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupNamespaceURI(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isEqualNode(Node arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public Object getFeature(String arg0, String arg1) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object setUserData(String arg0, Object arg1, UserDataHandler arg2) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object getUserData(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } + } + + /* +--- dom4j-1.6.1+dfsg.orig/src/java/org/dom4j/dom/DOMEntityReference.java ++++ dom4j-1.6.1+dfsg/src/java/org/dom4j/dom/DOMEntityReference.java +@@ -13,7 +13,9 @@ + import org.w3c.dom.DOMException; + import org.w3c.dom.Document; + import org.w3c.dom.NamedNodeMap; ++import org.w3c.dom.Node; + import org.w3c.dom.NodeList; ++import org.w3c.dom.UserDataHandler; + + /** + *

+@@ -166,6 +168,66 @@ + public boolean hasAttributes() { + return DOMNodeHelper.hasAttributes(this); + } ++ ++ public String getBaseURI() { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public short compareDocumentPosition(Node arg0) throws DOMException { ++ // TODO Auto-generated method stub ++ return 0; ++ } ++ ++ public String getTextContent() throws DOMException { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public void setTextContent(String arg0) throws DOMException { ++ // TODO Auto-generated method stub ++ ++ } ++ ++ public boolean isSameNode(Node arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupPrefix(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isDefaultNamespace(String arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupNamespaceURI(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isEqualNode(Node arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public Object getFeature(String arg0, String arg1) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object setUserData(String arg0, Object arg1, UserDataHandler arg2) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object getUserData(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } + } + + /* +--- dom4j-1.6.1+dfsg.orig/src/java/org/dom4j/dom/DOMNamespace.java ++++ dom4j-1.6.1+dfsg/src/java/org/dom4j/dom/DOMNamespace.java +@@ -13,7 +13,9 @@ + import org.w3c.dom.DOMException; + import org.w3c.dom.Document; + import org.w3c.dom.NamedNodeMap; ++import org.w3c.dom.Node; + import org.w3c.dom.NodeList; ++import org.w3c.dom.UserDataHandler; + + /** + *

+@@ -140,6 +142,66 @@ + public boolean hasAttributes() { + return DOMNodeHelper.hasAttributes(this); + } ++ ++ public String getBaseURI() { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public short compareDocumentPosition(Node arg0) throws DOMException { ++ // TODO Auto-generated method stub ++ return 0; ++ } ++ ++ public String getTextContent() throws DOMException { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public void setTextContent(String arg0) throws DOMException { ++ // TODO Auto-generated method stub ++ ++ } ++ ++ public boolean isSameNode(Node arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupPrefix(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isDefaultNamespace(String arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupNamespaceURI(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isEqualNode(Node arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public Object getFeature(String arg0, String arg1) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object setUserData(String arg0, Object arg1, UserDataHandler arg2) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object getUserData(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } + } + + /* +--- dom4j-1.6.1+dfsg.orig/src/java/org/dom4j/dom/DOMProcessingInstruction.java ++++ dom4j-1.6.1+dfsg/src/java/org/dom4j/dom/DOMProcessingInstruction.java +@@ -15,7 +15,9 @@ + import org.w3c.dom.DOMException; + import org.w3c.dom.Document; + import org.w3c.dom.NamedNodeMap; ++import org.w3c.dom.Node; + import org.w3c.dom.NodeList; ++import org.w3c.dom.UserDataHandler; + + /** + *

+@@ -177,6 +179,66 @@ + } + } + ++ public String getBaseURI() { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public short compareDocumentPosition(Node arg0) throws DOMException { ++ // TODO Auto-generated method stub ++ return 0; ++ } ++ ++ public String getTextContent() throws DOMException { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public void setTextContent(String arg0) throws DOMException { ++ // TODO Auto-generated method stub ++ ++ } ++ ++ public boolean isSameNode(Node arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupPrefix(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isDefaultNamespace(String arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupNamespaceURI(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isEqualNode(Node arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public Object getFeature(String arg0, String arg1) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object setUserData(String arg0, Object arg1, UserDataHandler arg2) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object getUserData(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ + // Implementation methods + // ------------------------------------------------------------------------- + } +--- dom4j-1.6.1+dfsg.orig/src/java/org/dom4j/dom/DOMText.java ++++ dom4j-1.6.1+dfsg/src/java/org/dom4j/dom/DOMText.java +@@ -14,7 +14,9 @@ + import org.w3c.dom.DOMException; + import org.w3c.dom.Document; + import org.w3c.dom.NamedNodeMap; ++import org.w3c.dom.Node; + import org.w3c.dom.NodeList; ++import org.w3c.dom.UserDataHandler; + + /** + *

+@@ -224,6 +226,81 @@ + protected Text createText(String text) { + return new DOMText(text); + } ++ ++ public boolean isElementContentWhitespace() { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String getWholeText() { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public org.w3c.dom.Text replaceWholeText(String arg0) throws DOMException { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public String getBaseURI() { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public short compareDocumentPosition(Node arg0) throws DOMException { ++ // TODO Auto-generated method stub ++ return 0; ++ } ++ ++ public String getTextContent() throws DOMException { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public void setTextContent(String arg0) throws DOMException { ++ // TODO Auto-generated method stub ++ ++ } ++ ++ public boolean isSameNode(Node arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupPrefix(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isDefaultNamespace(String arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public String lookupNamespaceURI(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public boolean isEqualNode(Node arg0) { ++ // TODO Auto-generated method stub ++ return false; ++ } ++ ++ public Object getFeature(String arg0, String arg1) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object setUserData(String arg0, Object arg1, UserDataHandler arg2) { ++ // TODO Auto-generated method stub ++ return null; ++ } ++ ++ public Object getUserData(String arg0) { ++ // TODO Auto-generated method stub ++ return null; ++ } + } + + /* +--- dom4j-1.6.1+dfsg.orig/src/java/org/dom4j/tree/NamespaceCache.java ++++ dom4j-1.6.1+dfsg/src/java/org/dom4j/tree/NamespaceCache.java +@@ -26,42 +26,46 @@ + * @version $Revision: 1.15 $ + */ + public class NamespaceCache { +- private static final String CONCURRENTREADERHASHMAP_CLASS +- = "EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap"; ++ private static final String BACKPORT_CONCURRENTHASHMAP_CLASS ++ = "edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap"; ++ private static final String OSWEGO_CONCURRENTHASHMAP_CLASS ++ = "EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap"; + + /** + * Cache of {@link Map}instances indexed by URI which contain caches of + * {@link Namespace}for each prefix + */ +- protected static Map cache; ++ protected static Map cache = newConcurrentHashMap(); + + /** + * Cache of {@link Namespace}instances indexed by URI for default + * namespaces with no prefixes + */ +- protected static Map noPrefixCache; ++ protected static Map noPrefixCache = newConcurrentHashMap(); + +- static { ++ protected static Map newConcurrentHashMap() ++ { + /* Try the java.util.concurrent.ConcurrentHashMap first. */ + try { + Class clazz = Class + .forName("java.util.concurrent.ConcurrentHashMap"); + Constructor construct = clazz.getConstructor(new Class[] { + Integer.TYPE, Float.TYPE, Integer.TYPE }); +- cache = (Map) construct.newInstance(new Object[] {new Integer(11), ++ return (Map) construct.newInstance(new Object[] {new Integer(11), + new Float(0.75f), new Integer(1) }); +- noPrefixCache = (Map) construct.newInstance(new Object[] { +- new Integer(11), new Float(0.75f), new Integer(1) }); + } catch (Throwable t1) { +- /* Try to use the util.concurrent library (if in classpath) */ + try { +- Class clazz = Class.forName(CONCURRENTREADERHASHMAP_CLASS); +- cache = (Map) clazz.newInstance(); +- noPrefixCache = (Map) clazz.newInstance(); ++ /* Try to use the backport-util-concurrent library */ ++ Class clazz = Class.forName(BACKPORT_CONCURRENTHASHMAP_CLASS); ++ return (Map) clazz.newInstance(); + } catch (Throwable t2) { +- /* If previous implementations fail, use internal one */ +- cache = new ConcurrentReaderHashMap(); +- noPrefixCache = new ConcurrentReaderHashMap(); ++ try { ++ /* Try to use the oswego concurrent library */ ++ Class clazz = Class.forName(OSWEGO_CONCURRENTHASHMAP_CLASS); ++ return (Map) clazz.newInstance(); ++ } catch (Throwable t3) { ++ return null; ++ } + } + } + } +@@ -154,7 +158,7 @@ + answer = (Map) cache.get(uri); + + if (answer == null) { +- answer = new ConcurrentReaderHashMap(); ++ answer = newConcurrentHashMap(); + cache.put(uri, answer); + } + } diff --git a/recipes/xml-commons/dom4j_1.6.1.bb b/recipes/xml-commons/dom4j_1.6.1.bb new file mode 100644 index 0000000000..343e1d9225 --- /dev/null +++ b/recipes/xml-commons/dom4j_1.6.1.bb @@ -0,0 +1,30 @@ +DESCRIPTION = "dom4j is a simple and flexible Java library for working with XML, XPath and XSLT" +LICENSE = "BSD" + +HOMEPAGE = "http://dom4j.org + +DEPENDS = "fastjar-native xerces-j xalan-j xpp2 xpp3 jaxen" + +SRC_URI = "\ + ${SOURCEFORGE_MIRROR}/dom4j/${P}.tar.gz \ + http://apache.org/dist/ws/jaxme/source/ws-jaxme-0.5.2-src.tar.gz \ + file://debian.patch;patch=1 \ + " + +inherit java-library + +do_compile() { + mkdir -p build + + oe_makeclasspath cp -s xercesImpl xalan2 xpp2 xpp3 jaxen + scp="src/java:${WORKDIR}/ws-jaxme-0.5.2/src/api" + + javac -sourcepath $scp -cp $cp -d build `find src/java -name "*.java" -and -not -wholename "*datatype*"` + (cd src && find org -name "*.properties" -exec cp {} ../build/{} \;) + + rm -rf build/org/w3c + rm -rf build/javax + + fastjar -C build -c -f ${JARFILENAME} . +} + diff --git a/recipes/xml-commons/jaxen_1.1.1.bb b/recipes/xml-commons/jaxen_1.1.1.bb new file mode 100644 index 0000000000..d78f303cde --- /dev/null +++ b/recipes/xml-commons/jaxen_1.1.1.bb @@ -0,0 +1,28 @@ +DESCRIPTION = "XPath library written in Java" +LICENSE = "BSD" + +HOMEPAGE = "http://jaxen.codehaus.org/ + +DEPENDS = "fastjar-native xerces-j xom" + +SRC_URI = "\ + http://dist.codehaus.org/jaxen/distributions/jaxen-${PV}-src.tar.gz \ + http://www.jdom.org/dist/binary/archive/jdom-1.1.tar.gz \ + " + +inherit java-library + +do_compile() { + mkdir -p build + + oe_makeclasspath cp -s xercesImpl xom + scp="src/java/main:${WORKDIR}/jdom-1.1/src/java" + + javac -sourcepath $scp -cp $cp -d build `find src/java/main -name "*.java" -and -not -wholename "*dom4j*"` + (cd src && find org -name "*.properties" -exec cp {} ../build/{} \;) + + rm -rf build/org/jdom + + fastjar -C build -c -f ${JARFILENAME} . +} + diff --git a/recipes/xml-commons/jdom_1.1.bb b/recipes/xml-commons/jdom_1.1.bb new file mode 100644 index 0000000000..e4be922b9e --- /dev/null +++ b/recipes/xml-commons/jdom_1.1.bb @@ -0,0 +1,23 @@ +DESCRIPTION = "Parses, manipulates, and outputs XML using standard Java constructs" +LICENSE = "BSD" + +HOMEPAGE = "http://jdom.org/ + +DEPENDS = "fastjar-native jaxen" + +SRC_URI = "\ + http://www.jdom.org/dist/binary/archive/jdom-${PV}.tar.gz \ + " + +inherit java-library + +do_compile() { + mkdir -p build + + oe_makeclasspath cp -s jaxen + + javac -sourcepath src/java -cp $cp -d build `find src/java -name "*.java"` + + fastjar -C build -c -f ${JARFILENAME} . +} + diff --git a/recipes/xml-commons/xom-1.1/04_remove_sun_import.patch b/recipes/xml-commons/xom-1.1/04_remove_sun_import.patch new file mode 100644 index 0000000000..71f659d9da --- /dev/null +++ b/recipes/xml-commons/xom-1.1/04_remove_sun_import.patch @@ -0,0 +1,27 @@ +diff -Nur xom-1.1/src15/nu/xom/JDK15XML1_0Parser.java xom-1.1.new/src15/nu/xom/JDK15XML1_0Parser.java +--- xom-1.1/src15/nu/xom/JDK15XML1_0Parser.java 2004-08-17 19:18:30.000000000 +0530 ++++ xom-1.1.new/src15/nu/xom/JDK15XML1_0Parser.java 2007-11-13 15:25:08.000000000 +0530 +@@ -24,9 +24,9 @@ + + import org.xml.sax.SAXException; + +-import com.sun.org.apache.xerces.internal.parsers.SAXParser; +-import com.sun.org.apache.xerces.internal.parsers.DTDConfiguration; +-import com.sun.org.apache.xerces.internal.impl.Constants ++import org.apache.xerces.parsers.SAXParser; ++import org.apache.xerces.parsers.DTDConfiguration; ++import org.apache.xerces.impl.Constants + ; + /** + *

+@@ -47,8 +47,8 @@ + + super(new DTDConfiguration()); + // workaround for Java 1.5 beta 2 bugs +- com.sun.org.apache.xerces.internal.util.SecurityManager manager +- = new com.sun.org.apache.xerces.internal.util.SecurityManager(); ++ org.apache.xerces.util.SecurityManager manager ++ = new org.apache.xerces.util.SecurityManager(); + setProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY, manager); + + } diff --git a/recipes/xml-commons/xom_1.1.bb b/recipes/xml-commons/xom_1.1.bb new file mode 100644 index 0000000000..1ef64a49f2 --- /dev/null +++ b/recipes/xml-commons/xom_1.1.bb @@ -0,0 +1,37 @@ +DESCRIPTION = "Tree-based API for processing XML with Java" +LICENSE = "LGPL" + +HOMEPAGE = "http://xom.nu" + +SRC_URI = "\ + http://www.cafeconleche.org/XOM/${P}-src.tar.gz \ + http://dist.codehaus.org/jaxen/distributions/jaxen-1.1.1-src.tar.gz \ + file://04_remove_sun_import.patch;patch=1 \ + " + +S = "${WORKDIR}/XOM" + +inherit java-library + +DEPENDS = "fastjar-native xerces-j xalan-j" + +do_compile() { + mkdir -p build + + oe_makeclasspath cp -s xercesImpl xalan2 + cp=build:$cp + + scp="${WORKDIR}/jaxen-1.1.1/src/java/main" + + javac -sourcepath src:$scp -cp $cp -d build `find src -name "*.java" -and -not \( -wholename "*tests*" -or -wholename "*samples*" -or -wholename "*tools*" \)` + javac -sourcepath fatsrc:$scp -cp $cp -d build `find fatsrc -name "*.java" -and -not \( -wholename "*tests*" -or -wholename "*samples*" -or -wholename "*tools*" \)` + javac -sourcepath src15:$scp -cp $cp -d build `find src15 -name "*.java" -and -not \( -wholename "*tests*" -or -wholename "*samples*" -or -wholename "*tools*" \)` + + (cd src && find . -name "*.properties" -exec cp {} ../build/{} \;) + + # Remove Jaxen classes from build + rm -rf build/org/jaxen + rm -rf build/org/w3c + + fastjar -C build -c -f ${JARFILENAME} . +} diff --git a/recipes/xml-commons/xpp2_2.1.10.bb b/recipes/xml-commons/xpp2_2.1.10.bb new file mode 100644 index 0000000000..0321ea65fa --- /dev/null +++ b/recipes/xml-commons/xpp2_2.1.10.bb @@ -0,0 +1,31 @@ +DESCRIPTION = "Streaming pull XML parser for java" +LICENSE = "BSD-like" + +HOMEPAGE = "http://www.extreme.indiana.edu/xgws/xsoap/xpp/" + +SRC_URI = "http://www.extreme.indiana.edu/xgws/xsoap/xpp/download/PullParser2/PullParser2.1.10.tgz" + +S = "${WORKDIR}/PullParser${PV}" + +inherit java-library + +DEPENDS = "fastjar-native virtual/javac-native" + +do_compile() { + if [ -d build-oe ]; then + rm -rf build-oe + fi + mkdir -p build-oe + + sourcepath="src/java/drivers/jaxp11:src/java/drivers/sax2:src/java/impl/factory:src/java/impl/format:src/java/impl/node:src/java/impl/pullparser:src/java/impl/tag:src/java/intf" + + findpath="${sourcepath//:/ }" + + javac -sourcepath $sourcepath -d build-oe `find $findpath -name "*.java"` + + mkdir -p build-oe/META-INF/services + cp src/java/drivers/jaxp11/META-INF/services/javax.xml.parsers.SAXParserFactory build-oe/META-INF/services + cp src/java/impl/factory/META-INF/services/org.gjt.xpp.XmlPullParserFactory build-oe/META-INF/services + + fastjar -C build-oe -c -f ${JARFILENAME} . +} diff --git a/recipes/xml-commons/xpp3_1.1.3.4.O.bb b/recipes/xml-commons/xpp3_1.1.3.4.O.bb new file mode 100644 index 0000000000..ff8b13d076 --- /dev/null +++ b/recipes/xml-commons/xpp3_1.1.3.4.O.bb @@ -0,0 +1,50 @@ +DESCRIPTION = "Streaming pull XML parser for Java (3rd edition)" +LICENSE = "BSD-like" + +HOMEPAGE = "http://www.extreme.indiana.edu/xgws/xsoap/xpp/mxp1" + +SRC_URI = "http://www.extreme.indiana.edu/dist/java-repository/xpp3/distributions/${P}_src.tgz" + +inherit java-library + +DEPENDS = "fastjar-native virtual/javac-native" + +PACKAGES = "libxpp3-xpath-java ${JPN}" + +do_compile() { + if [ -d build-oe ]; then + rm -rf build-oe + fi + mkdir -p build-oe + + sourcepath="src/java/api:src/java/builder:src/java/dom2_builder:src/java/mxp1_min:src/java/mxp1_standard:src/java/parser_pool:src/java/sax2_driver:src/java/serializer_impl:src/java/util:src/java/wrapper" + findpath="${sourcepath//:/ }" + + javac -sourcepath $sourcepath -d build-oe `find $findpath -name "*.java"` + + mkdir -p build-oe/META-INF/services + cp src/java/mxp1_standard/META-INF/services/org.xml* build-oe/META-INF/services + fastjar -C build-oe -c -f ${JARFILENAME} . + + if [ -d build-xpath ]; then + rm -rf build-xpath + fi + mkdir -p build-xpath + + sourcepath="src/java/xpath" + findpath="${sourcepath//:/ }" + javac -sourcepath $sourcepath -cp build-oe -d build-xpath `find $findpath -name "*.java"` + + fastjar -C build-xpath -c -f xpp3-xpath-${PV}.jar . +} + +do_install_append() { + oe_jarinstall xpp3-xpath-${PV}.jar xpp3-xpath.jar +} + +do_stage_append() { + oe_jarinstall -s xpp3-xpath-${PV}.jar xpp3-xpath.jar +} + +FILES_libxpp3-xpath-java = "${datadir}/java/xpp3-xpath*" + -- cgit v1.2.3 From f6c552dcea001e78ec461bfa488508404fcbcdac Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 16:43:51 +0200 Subject: poi 3.0: New recipe (from Jalimo SVN). --- recipes/jakarta-libs/poi_3.0.bb | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 recipes/jakarta-libs/poi_3.0.bb diff --git a/recipes/jakarta-libs/poi_3.0.bb b/recipes/jakarta-libs/poi_3.0.bb new file mode 100644 index 0000000000..9538861930 --- /dev/null +++ b/recipes/jakarta-libs/poi_3.0.bb @@ -0,0 +1,24 @@ +DESCRIPTION = "Java library for manipulating various file formats based upon Microsoft's OLE 2 Compound Document" +LICENSE = "AL2.0" +AUTHOR = "Apache Software Foundation" + +SRC_URI = "http://www.apache.org/dist/jakarta/poi/release/src/${BPN}-src-${PV}-FINAL-20070503.tar.gz" + +S = "${WORKDIR}/${BPN}-3.0-rc4" + +inherit java-library + +DEPENDS = "fastjar-native commons-collections3 commons-logging commons-lang commons-beanutils log4j1.2 xalan-j" + +do_compile() { + mkdir -p build + + oe_makeclasspath cp -s commons-collections3 commons-logging commons-lang commons-beanutils log4j-1.2 xalan2 + + javac -sourcepath src/java -cp $cp -d build \ + `find src/java -name \*.java` + + (cd src/java && find . -name "*.properties" -exec cp {} ../../build/{} \;) + + fastjar -C build -c -f ${JARFILENAME} . +} -- cgit v1.2.3 From 74fc79f49e272a234ba00513c512f0a32e14ad0c Mon Sep 17 00:00:00 2001 From: Robert Schuster Date: Fri, 18 Sep 2009 16:44:09 +0200 Subject: jaxme 0.5.2: New recipe (from Jalimo SVN). --- recipes/xml-commons/jaxme_0.5.2.bb | 66 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 recipes/xml-commons/jaxme_0.5.2.bb diff --git a/recipes/xml-commons/jaxme_0.5.2.bb b/recipes/xml-commons/jaxme_0.5.2.bb new file mode 100644 index 0000000000..c5bf4fbe9d --- /dev/null +++ b/recipes/xml-commons/jaxme_0.5.2.bb @@ -0,0 +1,66 @@ +DESCRIPTION = "Implementation of the JAXB API" +LICENSE = "AL2.0" + +AUTHOR = "Apache Software Foundation" +HOMEPAGE = "http://ws.apache.org/jaxme" + +SRC_URI = "\ + http://apache.org/dist/ws/jaxme/source/ws-${P}-src.tar.gz \ + http://ftp.hosting-studio.de/pub/linux/apache/ant/source/apache-ant-1.7.1-src.tar.bz2 \ + " + +S = "${WORKDIR}/ws-${P}" + +inherit java-library + +DEPENDS = "fastjar-native log4j1.2 xerces-j xalan-j commons-codec hsqldb antlr antlr-native" + +do_compile() { + oe_makeclasspath cp -s log4j-1.2 xercesImpl xalan2 commons-codec hsqldb antlr + cp=build-api:build-jaxme:build-js:build-xs:build-pm:$cp + + + jaxme_build src/api build-api $cp jaxmeapi-${PV}.jar + + runantlr -o src/js/org/apache/ws/jaxme/js/jparser src/js/org/apache/ws/jaxme/js/jparser/java15.g + jaxme_build src/js build-js $cp jaxmejs-${PV}.jar + + jaxme_build src/xs build-xs $cp jaxmexs-${PV}.jar + + jaxme_build src/jaxme build-jaxme $cp ${JARFILENAME} + +# jaxme_build src/pm build-pm $cp jaxmepm-${PV}.jar +} + +do_install_append() { + oe_jarinstall jaxmeapi-${PV}.jar jaxmeapi.jar + oe_jarinstall jaxmejs-${PV}.jar jaxmejs.jar + oe_jarinstall jaxmexs-${PV}.jar jaxmexs.jar + oe_jarinstall jaxmepm-${PV}.jar jaxmepm.jar +} + +do_stage_append() { + oe_jarinstall -s jaxmeapi-${PV}.jar jaxmeapi.jar + oe_jarinstall -s jaxmejs-${PV}.jar jaxmejs.jar + oe_jarinstall -s jaxmexs-${PV}.jar jaxmexs.jar + oe_jarinstall -s jaxmepm-${PV}.jar jaxmepm.jar +} + +# Compile helper +# 1 - source dir +# 2 - dest dir +# 3 - classpath +# 4 - jar file name +jaxme_build() { + mkdir -p $2 + + ant_sourcepath=${WORKDIR}/apache-ant-1.7.1/src/main + + echo "javac -sourcepath $ant_sourcepath:$1 -cp $3 -d $2 \`find $1 -name "*.java"\`" + javac -sourcepath $ant_sourcepath:$1 -cp $3 -d $2 `find $1 -name "*.java" -and -not \( -wholename "*junit*" -or -wholename "*examples*" \) ` + (cd $1 && find . -name "*.properties" -exec cp {} ${S}/$2/{} \;) + + rm -rf $2/org/apache/tools + + fastjar -C $2 -c -f $4 . +} -- cgit v1.2.3 From 876a2f7420a42d88981095c05cf20fe0aa45d948 Mon Sep 17 00:00:00 2001 From: Henning Heinold Date: Fri, 18 Sep 2009 18:18:41 +0200 Subject: ti: switch download url from dir.com to dir.local * dir.com is a registered domain * no bump of versions needed --- conf/checksums.ini | 22 +++++++++++----------- recipes/ti/ti-cgt6x-native_6.0.21.bb | 2 +- recipes/ti/ti-cgt6x-native_6.1.9.bb | 2 +- recipes/ti/ti-cmem-module_2.23.1.bb | 2 +- recipes/ti/ti-cmem-module_2.23.bb | 2 +- recipes/ti/ti-cmem-module_2.24.01.bb | 2 +- recipes/ti/ti-codec-combo-omapl137_1.0.bb | 2 +- recipes/ti/ti-codec-engine_2.23.1.bb | 2 +- recipes/ti/ti-codec-engine_2.24.01.bb | 2 +- recipes/ti/ti-dspbios-native_5.33.02.bb | 2 +- recipes/ti/ti-dspbios-native_5.33.04.bb | 2 +- recipes/ti/ti-dsplink-module_1.61.3.bb | 2 +- recipes/ti/ti-lpm-module_2.23.1.bb | 2 +- recipes/ti/ti-lpm-module_2.24.01.bb | 2 +- recipes/ti/ti-sdma-module_2.23.1.bb | 2 +- recipes/ti/ti-sdma-module_2.24.01.bb | 2 +- recipes/ti/ti-xdctools-native_3.10.03.bb | 2 +- 17 files changed, 27 insertions(+), 27 deletions(-) diff --git a/conf/checksums.ini b/conf/checksums.ini index cce539180b..4cb7070745 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -1094,11 +1094,11 @@ sha256=6fd69febfd804437a9d5b610502c6d3c2caabef7a4832a3bcac2357515adaa71 md5=e65a007157e3e26807db52299497109d sha256=e064a939bf7e37774b89a39515ecf96c4d19c81e050bcf0dae28d1eab4d86196 -[http://install.source.dir.com/TI-C6x-CGT-v6.0.16-eval.tar.gz] +[http://install.source.dir.local/TI-C6x-CGT-v6.0.16-eval.tar.gz] md5=152fdf383df154b33478a0312752bade sha256=0eb1d3af0a02179edb91b5468972265f13c3a89990549f289233c0784937ab9e -[http://install.source.dir.com/TI-C6x-CGT-v6.0.21-eval.tar.gz] +[http://install.source.dir.local/TI-C6x-CGT-v6.0.21-eval.tar.gz] md5=65c8166ad0edb468c5327d1109d84229 sha256=6011f7a10fa71a540503fc8d54140728022ec89eb8bc2ef344002bb11cf25667 @@ -2766,11 +2766,11 @@ sha256=bd2ea10ffc2bf62a917b05f4fbe3d02212589c2bc177fa0c51a9c874d3da528a md5=73e76bdd997fa945d71edcfbdd356c15 sha256=18f72b922a9a346f6c43b20fd86eba76cfd27a8d118ea32fa879050ddebe0267 -[http://install.source.dir.com/bios_setuplinux_5_33_02.bin] +[http://install.source.dir.local/bios_setuplinux_5_33_02.bin] md5=64f61b08d091625c0912cb9de33242af sha256=506e07715028811b8d945c85c54ae07bc33bdd8afff1611cbb30d154ba86d04e -[http://install.source.dir.com/bios_setuplinux_5_33_04.bin] +[http://install.source.dir.local/bios_setuplinux_5_33_04.bin] md5=fcffe1618f20024fd6580f47cdc0059b sha256=2c1e7feec569a19d3093b136da6aa03574f94052810fe7a78cc81eb37adda24b @@ -3962,7 +3962,7 @@ sha256=d391829686eb002ace3ffbfed75c35e877b42c1884c9359791634b5b57126797 md5=d8f3bbfbcc337d9776991d9561f451f3 sha256=773ce12045ce98c3be4b1845547435f1b7798996fa3170dea72c7c15aa5ca79d -[http://install.source.dir.com/codec_engine_2_23_01.tar.gz] +[http://install.source.dir.local/codec_engine_2_23_01.tar.gz] md5=581f548714a53d818ac355a1e4aacfa4 sha256=32c96ec23642d827bcbc865ac490fe7f2eeec2e04448980c4eb70d0fb25f74d8 @@ -3970,7 +3970,7 @@ sha256=32c96ec23642d827bcbc865ac490fe7f2eeec2e04448980c4eb70d0fb25f74d8 md5=581f548714a53d818ac355a1e4aacfa4 sha256=32c96ec23642d827bcbc865ac490fe7f2eeec2e04448980c4eb70d0fb25f74d8 -[http://install.source.dir.com/codec_engine_2_24_01.tar.gz] +[http://install.source.dir.local/codec_engine_2_24_01.tar.gz] md5=39b0002fc7c4f2b9ddb0bbc2eeb26dc6 sha256=59567c414943d2c7c0135f402e0df58bf81bf5027c06bd84fefce5ad9f98254f @@ -5330,7 +5330,7 @@ sha256=15dd793e32fc9aba1266c2ccb8e98856c61be2e9de214285aa09152a47da1836 md5=2b53c067c683266379dddbb38e65cb45 sha256=b1a0508444241c61585321eaadc32f476ef441f267636fbd0fb2f0c7ebf0fcbb -[http://install.source.dir.com/dsplink_1_61_03.tar.gz] +[http://install.source.dir.local/dsplink_1_61_03.tar.gz] md5=9df12389c8b955b5f8cfefe6df20b1d6 sha256=1037b9cb872590356d055dbf8006e25d68370721e0e5b4518529495db6de70d9 @@ -16270,7 +16270,7 @@ sha256=8f563e178ac29c64fcc0144c60d415092d998194a6797c7b45a95802d2df8410 md5=c0b7c36232d3910c425d03e56d0f532b sha256=6f11fc04a1f3f04ebb996723fc86ca363c3959ca1ef76d1057db9db3ea5a98d0 -[http://install.source.dir.com/local_power_manager_1_24.tar.gz] +[http://install.source.dir.local/local_power_manager_1_24.tar.gz] md5=1a11261872f683e0699af64258e5f68a sha256=106ce2ddb3f35fc72ab00a1391bca21f57b04f75b12115bcadd37516e2a0ee28 @@ -24098,11 +24098,11 @@ sha256=11b067df2ce38baa36566bd29ab14bbf2f7c0fcc15e01a5be2a6a85000c39104 md5=e6388feb0ffcd189af779f165c124b4d sha256=6b964fb220a46438adf6ec37082da66332a3ce74ca4913b863b17d9ab720681f -[http://install.source.dir.com/ti_cgt_c6000_6.0.21_setup_linux_x86.bin] +[http://install.source.dir.local/ti_cgt_c6000_6.0.21_setup_linux_x86.bin] md5=5bfeaacb628b56005a8865a177af01e4 sha256=fcfa98e2c8ff18e8e6d5b2ff5e94f20b719150fe7bb4a130cfa360e02df2156a -[http://install.source.dir.com/ti_cgt_c6000_6.1.9_setup_linux_x86.bin] +[http://install.source.dir.local/ti_cgt_c6000_6.1.9_setup_linux_x86.bin] md5=8354845032c0ce8e3da3f250505d0e21 sha256=da26d02c1b98b95343f19ea273b3536beddd94feb2a773a6cb66efebfdff35c0 @@ -25986,7 +25986,7 @@ sha256=74e882e9fee7ebeb274caf43071afff92531b8a41f34650376146a131166012d md5=ceaccde801650ffbffc1e5b0657960d2 sha256=4511dc4df6ebb320a4a516b3b712c86f6924e5ee9832618f58ebba06c64712ea -[http://install.source.dir.com/xdctools_setuplinux_3_10_03.bin] +[http://install.source.dir.local/xdctools_setuplinux_3_10_03.bin] md5=8f0f8af016b97fb612ec11afaaf5a9e7 sha256=d398bfb7a5d9657b802db835c28db892ec8fe54cf332420edef0b3ba1c231fcb diff --git a/recipes/ti/ti-cgt6x-native_6.0.21.bb b/recipes/ti/ti-cgt6x-native_6.0.21.bb index e030b81f43..f98ce63d6c 100644 --- a/recipes/ti/ti-cgt6x-native_6.0.21.bb +++ b/recipes/ti/ti-cgt6x-native_6.0.21.bb @@ -3,7 +3,7 @@ inherit native # download ti_cgt_c6000_6.0.21_setup_linux_x86.bin from https://www-a.ti.com/downloads/sds_support/TICodegenerationTools/download.htm and copy in Arago (or OE) download directory. -SRC_URI = "http://install.source.dir.com/ti_cgt_c6000_6.0.21_setup_linux_x86.bin" +SRC_URI = "http://install.source.dir.local/ti_cgt_c6000_6.0.21_setup_linux_x86.bin" BINFILE="ti_cgt_c6000_6.0.21_setup_linux_x86.bin" diff --git a/recipes/ti/ti-cgt6x-native_6.1.9.bb b/recipes/ti/ti-cgt6x-native_6.1.9.bb index 55c1b6ca06..f8d9d98c1b 100644 --- a/recipes/ti/ti-cgt6x-native_6.1.9.bb +++ b/recipes/ti/ti-cgt6x-native_6.1.9.bb @@ -3,7 +3,7 @@ inherit native # download ti_cgt_c6000_6.1.9_setup_linux_x86.bin from https://www-a.ti.com/downloads/sds_support/TICodegenerationTools/download.htm and copy in Arago (or OE) download directory. -SRC_URI = "http://install.source.dir.com/ti_cgt_c6000_6.1.9_setup_linux_x86.bin" +SRC_URI = "http://install.source.dir.local/ti_cgt_c6000_6.1.9_setup_linux_x86.bin" BINFILE = "ti_cgt_c6000_6.1.9_setup_linux_x86.bin" diff --git a/recipes/ti/ti-cmem-module_2.23.1.bb b/recipes/ti/ti-cmem-module_2.23.1.bb index 0704993033..7af1216cd3 100644 --- a/recipes/ti/ti-cmem-module_2.23.1.bb +++ b/recipes/ti/ti-cmem-module_2.23.1.bb @@ -7,7 +7,7 @@ RDEPENDS = "update-modules" # Download codec_engine_2_23_01.tar.gz from https://www-a.ti.com/downloads/sds_support/targetcontent/CE/ce_2_23/index.html and copy in Arago (or OE) download directory. -SRC_URI = "http://install.source.dir.com/codec_engine_2_23_01.tar.gz \ +SRC_URI = "http://install.source.dir.local/codec_engine_2_23_01.tar.gz \ file://cmem-remove-show-pte-function.patch;patch=1 " # Set the source directory diff --git a/recipes/ti/ti-cmem-module_2.23.bb b/recipes/ti/ti-cmem-module_2.23.bb index 60324fbc30..0200369501 100644 --- a/recipes/ti/ti-cmem-module_2.23.bb +++ b/recipes/ti/ti-cmem-module_2.23.bb @@ -5,7 +5,7 @@ inherit module DEPENDS = "virtual/kernel perl-native" RDEPENDS = "update-modules" -SRC_URI = "http://install.source.dir.com/codec_engine_2_23.tar.gz" +SRC_URI = "http://install.source.dir.local/codec_engine_2_23.tar.gz" # Set the source directory S = "${WORKDIR}/codec_engine_2_23" diff --git a/recipes/ti/ti-cmem-module_2.24.01.bb b/recipes/ti/ti-cmem-module_2.24.01.bb index 7f5394647f..625d292a55 100644 --- a/recipes/ti/ti-cmem-module_2.24.01.bb +++ b/recipes/ti/ti-cmem-module_2.24.01.bb @@ -5,7 +5,7 @@ inherit module DEPENDS = "virtual/kernel perl-native" RDEPENDS = "update-modules" -SRC_URI = "http://install.source.dir.com/codec_engine_2_24_01.tar.gz \ +SRC_URI = "http://install.source.dir.local/codec_engine_2_24_01.tar.gz \ file://cmem-remove-show-pte-function.patch;patch=1 " # Set the source directory diff --git a/recipes/ti/ti-codec-combo-omapl137_1.0.bb b/recipes/ti/ti-codec-combo-omapl137_1.0.bb index 6ffefc7e48..25baa694f5 100644 --- a/recipes/ti/ti-codec-combo-omapl137_1.0.bb +++ b/recipes/ti/ti-codec-combo-omapl137_1.0.bb @@ -1,7 +1,7 @@ require ti-codec.inc # Should be replaced with real http URL, but for now create codec combo tar from DVSDK installation. -SRC_URI = "http://install.source.dir.com/omapl137_dvsdk_combos_1_0.tar.gz" +SRC_URI = "http://install.source.dir.local/omapl137_dvsdk_combos_1_0.tar.gz" S = "${WORKDIR}/omapl137_dvsdk_combos_1_0" diff --git a/recipes/ti/ti-codec-engine_2.23.1.bb b/recipes/ti/ti-codec-engine_2.23.1.bb index a0e6a2ca7a..2a2b3a248b 100644 --- a/recipes/ti/ti-codec-engine_2.23.1.bb +++ b/recipes/ti/ti-codec-engine_2.23.1.bb @@ -12,7 +12,7 @@ PV = "2231" # Download codec_engine_2_23_01.tar.gz from https://www-a.ti.com/downloads/sds_support/targetcontent/CE/ce_2_23/index.html and copy in Arago (or OE) download directory. -SRC_URI = "http://install.source.dir.com/codec_engine_2_23_01.tar.gz " +SRC_URI = "http://install.source.dir.local/codec_engine_2_23_01.tar.gz " # Set the source directory S = "${WORKDIR}/codec_engine_2_23_01" diff --git a/recipes/ti/ti-codec-engine_2.24.01.bb b/recipes/ti/ti-codec-engine_2.24.01.bb index 187e76c9c9..b2cebe3068 100644 --- a/recipes/ti/ti-codec-engine_2.24.01.bb +++ b/recipes/ti/ti-codec-engine_2.24.01.bb @@ -11,7 +11,7 @@ DEPENDS_dm355-evm += "ti-xdctools-native" PR = "r7" PV = "2241" -SRC_URI = "http://install.source.dir.com/codec_engine_2_24_01.tar.gz " +SRC_URI = "http://install.source.dir.local/codec_engine_2_24_01.tar.gz " # Set the source directory S = "${WORKDIR}/codec_engine_2_24_01" diff --git a/recipes/ti/ti-dspbios-native_5.33.02.bb b/recipes/ti/ti-dspbios-native_5.33.02.bb index 9e224434c4..02c2d5690f 100644 --- a/recipes/ti/ti-dspbios-native_5.33.02.bb +++ b/recipes/ti/ti-dspbios-native_5.33.02.bb @@ -3,7 +3,7 @@ inherit native # download bios_setuplinux_5_33_02.bin from https://www-a.ti.com/downloads/sds_support/targetcontent/bios/bios_5_33/bios_5_33_02/index_external.html and copy in Arago (or OE) installation directory -SRC_URI = "http://install.source.dir.com/bios_setuplinux_5_33_02.bin" +SRC_URI = "http://install.source.dir.local/bios_setuplinux_5_33_02.bin" BINFILE="bios_setuplinux_5_33_02.bin" S = "${WORKDIR}/bios_5_33_02" diff --git a/recipes/ti/ti-dspbios-native_5.33.04.bb b/recipes/ti/ti-dspbios-native_5.33.04.bb index d5667f04dd..430260fb9a 100644 --- a/recipes/ti/ti-dspbios-native_5.33.04.bb +++ b/recipes/ti/ti-dspbios-native_5.33.04.bb @@ -3,7 +3,7 @@ inherit native # download bios_setuplinux_5_33_04.bin from https://www-a.ti.com/downloads/sds_support/targetcontent/bios/bios_5_33/bios_5_33_04/index_external.html and copy in Arago (or OE) installation directory -SRC_URI = "http://install.source.dir.com/bios_setuplinux_5_33_04.bin" +SRC_URI = "http://install.source.dir.local/bios_setuplinux_5_33_04.bin" BINFILE="bios_setuplinux_5_33_04.bin" S = "${WORKDIR}/bios_5_33_04" diff --git a/recipes/ti/ti-dsplink-module_1.61.3.bb b/recipes/ti/ti-dsplink-module_1.61.3.bb index 7febdc86bc..c19ed7e8c7 100644 --- a/recipes/ti/ti-dsplink-module_1.61.3.bb +++ b/recipes/ti/ti-dsplink-module_1.61.3.bb @@ -11,7 +11,7 @@ DEPENDS += "virtual/kernel perl-native ti-dspbios-native ti-cgt6x-native update MACHINE_KERNEL_PR_append = "a" PV = "1613" -SRC_URI = "http://install.source.dir.com/dsplink_1_61_03.tar.gz \ +SRC_URI = "http://install.source.dir.local/dsplink_1_61_03.tar.gz \ file://loadmodules-ti-dsplink-apps.sh \ file://unloadmodules-ti-dsplink-apps.sh" diff --git a/recipes/ti/ti-lpm-module_2.23.1.bb b/recipes/ti/ti-lpm-module_2.23.1.bb index 7e0356dc55..6186f538c9 100644 --- a/recipes/ti/ti-lpm-module_2.23.1.bb +++ b/recipes/ti/ti-lpm-module_2.23.1.bb @@ -11,7 +11,7 @@ PV = "2231" # Download codec_engine_2_23_01.tar.gz from https://www-a.ti.com/downloads/sds_support/targetcontent/CE/ce_2_23/index.html and copy in Arago (or OE) download directory. -SRC_URI = "http://install.source.dir.com/codec_engine_2_23_01.tar.gz " +SRC_URI = "http://install.source.dir.local/codec_engine_2_23_01.tar.gz " # Set the source directory S = "${WORKDIR}/codec_engine_2_23_01" diff --git a/recipes/ti/ti-lpm-module_2.24.01.bb b/recipes/ti/ti-lpm-module_2.24.01.bb index 7f47a0d232..8c41dbf8c2 100644 --- a/recipes/ti/ti-lpm-module_2.24.01.bb +++ b/recipes/ti/ti-lpm-module_2.24.01.bb @@ -11,7 +11,7 @@ MACHINE_KERNEL_PR_append = "a" PV = "2241" -SRC_URI = "http://install.source.dir.com/local_power_manager_1_24.tar.gz" +SRC_URI = "http://install.source.dir.local/local_power_manager_1_24.tar.gz" # Set the source directory S = "${WORKDIR}/local_power_manager_1_24" diff --git a/recipes/ti/ti-sdma-module_2.23.1.bb b/recipes/ti/ti-sdma-module_2.23.1.bb index 5925b18a61..b64cd9b2bc 100644 --- a/recipes/ti/ti-sdma-module_2.23.1.bb +++ b/recipes/ti/ti-sdma-module_2.23.1.bb @@ -11,7 +11,7 @@ PV = "2231" # Download codec_engine_2_23_01.tar.gz from https://www-a.ti.com/downloads/sds_support/targetcontent/CE/ce_2_23/index.html and copy in Arago (or OE) download directory. -SRC_URI = "http://install.source.dir.com/codec_engine_2_23_01.tar.gz " +SRC_URI = "http://install.source.dir.local/codec_engine_2_23_01.tar.gz " # Set the source directory S = "${WORKDIR}/codec_engine_2_23_01" diff --git a/recipes/ti/ti-sdma-module_2.24.01.bb b/recipes/ti/ti-sdma-module_2.24.01.bb index 2d9b3a8df7..b5e3bc313e 100644 --- a/recipes/ti/ti-sdma-module_2.24.01.bb +++ b/recipes/ti/ti-sdma-module_2.24.01.bb @@ -9,7 +9,7 @@ MACHINE_KERNEL_PR_append = "a" PV = "2241" -SRC_URI = "http://install.source.dir.com/codec_engine_2_24_01.tar.gz " +SRC_URI = "http://install.source.dir.local/codec_engine_2_24_01.tar.gz " # Set the source directory S = "${WORKDIR}/codec_engine_2_24_01" diff --git a/recipes/ti/ti-xdctools-native_3.10.03.bb b/recipes/ti/ti-xdctools-native_3.10.03.bb index 1d6ee675b5..ca1b7f5f0f 100644 --- a/recipes/ti/ti-xdctools-native_3.10.03.bb +++ b/recipes/ti/ti-xdctools-native_3.10.03.bb @@ -3,7 +3,7 @@ require ti-xdctools.inc # download xdctools_setuplinux_3_10_03.bin from https://www-a.ti.com/downloads/sds_support/targetcontent/rtsc/xdctools_3_10/xdctools_3_10_03/index_external.html and copy in Arago (or OE) download directory -SRC_URI = "http://install.source.dir.com/xdctools_setuplinux_3_10_03.bin" +SRC_URI = "http://install.source.dir.local/xdctools_setuplinux_3_10_03.bin" BINFILE="xdctools_setuplinux_3_10_03.bin" S = "${WORKDIR}/xdctools_3_10_03" -- cgit v1.2.3 From 72d9084abfcbc8c12f9902fe9f916320d3c7b55a Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 18 Sep 2009 19:22:27 +0200 Subject: pidgin update to 2.6.2 --- conf/checksums.ini | 52 ++++++++++++++++++++++++++++++++++++++++++ recipes/pidgin/pidgin_2.6.2.bb | 19 +++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 recipes/pidgin/pidgin_2.6.2.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index 4cb7070745..37152d1586 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -1094,10 +1094,18 @@ sha256=6fd69febfd804437a9d5b610502c6d3c2caabef7a4832a3bcac2357515adaa71 md5=e65a007157e3e26807db52299497109d sha256=e064a939bf7e37774b89a39515ecf96c4d19c81e050bcf0dae28d1eab4d86196 +[http://install.source.dir.com/TI-C6x-CGT-v6.0.16-eval.tar.gz] +md5=152fdf383df154b33478a0312752bade +sha256=0eb1d3af0a02179edb91b5468972265f13c3a89990549f289233c0784937ab9e + [http://install.source.dir.local/TI-C6x-CGT-v6.0.16-eval.tar.gz] md5=152fdf383df154b33478a0312752bade sha256=0eb1d3af0a02179edb91b5468972265f13c3a89990549f289233c0784937ab9e +[http://install.source.dir.com/TI-C6x-CGT-v6.0.21-eval.tar.gz] +md5=65c8166ad0edb468c5327d1109d84229 +sha256=6011f7a10fa71a540503fc8d54140728022ec89eb8bc2ef344002bb11cf25667 + [http://install.source.dir.local/TI-C6x-CGT-v6.0.21-eval.tar.gz] md5=65c8166ad0edb468c5327d1109d84229 sha256=6011f7a10fa71a540503fc8d54140728022ec89eb8bc2ef344002bb11cf25667 @@ -2766,10 +2774,18 @@ sha256=bd2ea10ffc2bf62a917b05f4fbe3d02212589c2bc177fa0c51a9c874d3da528a md5=73e76bdd997fa945d71edcfbdd356c15 sha256=18f72b922a9a346f6c43b20fd86eba76cfd27a8d118ea32fa879050ddebe0267 +[http://install.source.dir.com/bios_setuplinux_5_33_02.bin] +md5=64f61b08d091625c0912cb9de33242af +sha256=506e07715028811b8d945c85c54ae07bc33bdd8afff1611cbb30d154ba86d04e + [http://install.source.dir.local/bios_setuplinux_5_33_02.bin] md5=64f61b08d091625c0912cb9de33242af sha256=506e07715028811b8d945c85c54ae07bc33bdd8afff1611cbb30d154ba86d04e +[http://install.source.dir.com/bios_setuplinux_5_33_04.bin] +md5=fcffe1618f20024fd6580f47cdc0059b +sha256=2c1e7feec569a19d3093b136da6aa03574f94052810fe7a78cc81eb37adda24b + [http://install.source.dir.local/bios_setuplinux_5_33_04.bin] md5=fcffe1618f20024fd6580f47cdc0059b sha256=2c1e7feec569a19d3093b136da6aa03574f94052810fe7a78cc81eb37adda24b @@ -3962,6 +3978,10 @@ sha256=d391829686eb002ace3ffbfed75c35e877b42c1884c9359791634b5b57126797 md5=d8f3bbfbcc337d9776991d9561f451f3 sha256=773ce12045ce98c3be4b1845547435f1b7798996fa3170dea72c7c15aa5ca79d +[http://install.source.dir.com/codec_engine_2_23_01.tar.gz] +md5=581f548714a53d818ac355a1e4aacfa4 +sha256=32c96ec23642d827bcbc865ac490fe7f2eeec2e04448980c4eb70d0fb25f74d8 + [http://install.source.dir.local/codec_engine_2_23_01.tar.gz] md5=581f548714a53d818ac355a1e4aacfa4 sha256=32c96ec23642d827bcbc865ac490fe7f2eeec2e04448980c4eb70d0fb25f74d8 @@ -3970,6 +3990,10 @@ sha256=32c96ec23642d827bcbc865ac490fe7f2eeec2e04448980c4eb70d0fb25f74d8 md5=581f548714a53d818ac355a1e4aacfa4 sha256=32c96ec23642d827bcbc865ac490fe7f2eeec2e04448980c4eb70d0fb25f74d8 +[http://install.source.dir.com/codec_engine_2_24_01.tar.gz] +md5=39b0002fc7c4f2b9ddb0bbc2eeb26dc6 +sha256=59567c414943d2c7c0135f402e0df58bf81bf5027c06bd84fefce5ad9f98254f + [http://install.source.dir.local/codec_engine_2_24_01.tar.gz] md5=39b0002fc7c4f2b9ddb0bbc2eeb26dc6 sha256=59567c414943d2c7c0135f402e0df58bf81bf5027c06bd84fefce5ad9f98254f @@ -5330,6 +5354,10 @@ sha256=15dd793e32fc9aba1266c2ccb8e98856c61be2e9de214285aa09152a47da1836 md5=2b53c067c683266379dddbb38e65cb45 sha256=b1a0508444241c61585321eaadc32f476ef441f267636fbd0fb2f0c7ebf0fcbb +[http://install.source.dir.com/dsplink_1_61_03.tar.gz] +md5=9df12389c8b955b5f8cfefe6df20b1d6 +sha256=1037b9cb872590356d055dbf8006e25d68370721e0e5b4518529495db6de70d9 + [http://install.source.dir.local/dsplink_1_61_03.tar.gz] md5=9df12389c8b955b5f8cfefe6df20b1d6 sha256=1037b9cb872590356d055dbf8006e25d68370721e0e5b4518529495db6de70d9 @@ -12038,6 +12066,10 @@ sha256=dae79e8c56090ac3fb4ac3fe0df9faf6a0c9694a89ef978dce0ab970557ad264 md5=22745cbaaddb12884ed8ee09083d8fe2 sha256=a13549087141be24ad176b659afdc2c675f1ffa5288ff999a193d6d44a282056 +[http://www.jdom.org/dist/binary/jdom-1.1.tar.gz] +md5=22745cbaaddb12884ed8ee09083d8fe2 +sha256=a13549087141be24ad176b659afdc2c675f1ffa5288ff999a193d6d44a282056 + [http://www.rpsys.net/openzaurus/patches/archive/jffs2_longfilename-r1.patch] md5=1e30c4f6d5148d8462c41b7f58738531 sha256=f01a8f0975905597aaccd2d6647331aac14615b67a37ccf626bb2ea45db13294 @@ -16270,6 +16302,10 @@ sha256=8f563e178ac29c64fcc0144c60d415092d998194a6797c7b45a95802d2df8410 md5=c0b7c36232d3910c425d03e56d0f532b sha256=6f11fc04a1f3f04ebb996723fc86ca363c3959ca1ef76d1057db9db3ea5a98d0 +[http://install.source.dir.com/local_power_manager_1_24.tar.gz] +md5=1a11261872f683e0699af64258e5f68a +sha256=106ce2ddb3f35fc72ab00a1391bca21f57b04f75b12115bcadd37516e2a0ee28 + [http://install.source.dir.local/local_power_manager_1_24.tar.gz] md5=1a11261872f683e0699af64258e5f68a sha256=106ce2ddb3f35fc72ab00a1391bca21f57b04f75b12115bcadd37516e2a0ee28 @@ -19966,6 +20002,10 @@ sha256=912c934425fc40535fc79eb9082f6f823808d8ea8ecdd370d0b8ceec4b97ad82 md5=c207407dca71c6357c82135875e472f0 sha256=2f79da1f127dd05f9404494ebc794f8cda919764fd2424f79df31f3b0f9dfd21 +[http://downloads.sourceforge.net/pidgin/pidgin-2.6.2.tar.bz2] +md5=a1bbb3c9be7d4ee1f53590d319cbfa72 +sha256=acbadfd4d725e628ab8906f87438b26ebf86e67d219bbdcf07a9ccd18bdaafd6 + [ftp://ftp.cac.washington.edu/pine/pine4.64.tar.Z] md5=75af127948cc0c701d424d22d621f792 sha256=62c7b97695cb486e420afbbbe21bef853dd68a71665d867ffef50cb34dfba5f4 @@ -24098,10 +24138,18 @@ sha256=11b067df2ce38baa36566bd29ab14bbf2f7c0fcc15e01a5be2a6a85000c39104 md5=e6388feb0ffcd189af779f165c124b4d sha256=6b964fb220a46438adf6ec37082da66332a3ce74ca4913b863b17d9ab720681f +[http://install.source.dir.com/ti_cgt_c6000_6.0.21_setup_linux_x86.bin] +md5=5bfeaacb628b56005a8865a177af01e4 +sha256=fcfa98e2c8ff18e8e6d5b2ff5e94f20b719150fe7bb4a130cfa360e02df2156a + [http://install.source.dir.local/ti_cgt_c6000_6.0.21_setup_linux_x86.bin] md5=5bfeaacb628b56005a8865a177af01e4 sha256=fcfa98e2c8ff18e8e6d5b2ff5e94f20b719150fe7bb4a130cfa360e02df2156a +[http://install.source.dir.com/ti_cgt_c6000_6.1.9_setup_linux_x86.bin] +md5=8354845032c0ce8e3da3f250505d0e21 +sha256=da26d02c1b98b95343f19ea273b3536beddd94feb2a773a6cb66efebfdff35c0 + [http://install.source.dir.local/ti_cgt_c6000_6.1.9_setup_linux_x86.bin] md5=8354845032c0ce8e3da3f250505d0e21 sha256=da26d02c1b98b95343f19ea273b3536beddd94feb2a773a6cb66efebfdff35c0 @@ -25986,6 +26034,10 @@ sha256=74e882e9fee7ebeb274caf43071afff92531b8a41f34650376146a131166012d md5=ceaccde801650ffbffc1e5b0657960d2 sha256=4511dc4df6ebb320a4a516b3b712c86f6924e5ee9832618f58ebba06c64712ea +[http://install.source.dir.com/xdctools_setuplinux_3_10_03.bin] +md5=8f0f8af016b97fb612ec11afaaf5a9e7 +sha256=d398bfb7a5d9657b802db835c28db892ec8fe54cf332420edef0b3ba1c231fcb + [http://install.source.dir.local/xdctools_setuplinux_3_10_03.bin] md5=8f0f8af016b97fb612ec11afaaf5a9e7 sha256=d398bfb7a5d9657b802db835c28db892ec8fe54cf332420edef0b3ba1c231fcb diff --git a/recipes/pidgin/pidgin_2.6.2.bb b/recipes/pidgin/pidgin_2.6.2.bb new file mode 100644 index 0000000000..e7cb9d6cde --- /dev/null +++ b/recipes/pidgin/pidgin_2.6.2.bb @@ -0,0 +1,19 @@ +require pidgin.inc + +DEPENDS += "farsight2" + +SRC_URI = "\ + ${SOURCEFORGE_MIRROR}/pidgin/pidgin-${PV}.tar.bz2 \ + file://sanitize-configure.ac.patch;patch=1 \ + file://gconf-no-errors.patch;patch=1 \ + file://pidgin.desktop-set-icon.patch;patch=1 \ + file://purple-OE-branding-25.patch;patch=1 \ + file://pidgin-cross-python.patch;patch=1 \ +" + +EXTRA_OECONF += "\ + --disable-gtkspell \ + --disable-meanwhile \ + --disable-nm \ + --disable-screensaver \ +" -- cgit v1.2.3 From 37ccccb96d9e7c337772064dc56f35af15e648d4 Mon Sep 17 00:00:00 2001 From: Phil Blundell Date: Fri, 18 Sep 2009 19:20:41 +0100 Subject: apply patch from drow to fix linking of thumb binaries --- recipes/binutils/binutils-2.19.51/thumb-func.patch | 55 ++++++++++++++++++++++ recipes/binutils/binutils_2.19.51.bb | 3 +- 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 recipes/binutils/binutils-2.19.51/thumb-func.patch diff --git a/recipes/binutils/binutils-2.19.51/thumb-func.patch b/recipes/binutils/binutils-2.19.51/thumb-func.patch new file mode 100644 index 0000000000..9c18eff3ba --- /dev/null +++ b/recipes/binutils/binutils-2.19.51/thumb-func.patch @@ -0,0 +1,55 @@ +Index: elf32-arm.c +=================================================================== +RCS file: /cvs/src/src/bfd/elf32-arm.c,v +retrieving revision 1.211 +retrieving revision 1.212 +diff -u -r1.211 -r1.212 +--- src/bfd/elf32-arm.c 29 Aug 2009 22:10:58 -0000 1.211 ++++ src/bfd/elf32-arm.c 9 Sep 2009 18:36:10 -0000 1.212 +@@ -7036,6 +7036,9 @@ + + splt->output_offset + + h->plt.offset); + *unresolved_reloc_p = FALSE; ++ /* The PLT entry is in ARM mode, regardless of the ++ target function. */ ++ sym_flags = STT_FUNC; + } + + from = (input_section->output_section->vma +@@ -7452,10 +7455,14 @@ + /* If the Thumb BLX instruction is available, convert the + BL to a BLX instruction to call the ARM-mode PLT entry. */ + lower_insn = (lower_insn & ~0x1000) | 0x0800; ++ sym_flags = STT_FUNC; + } + else +- /* Target the Thumb stub before the ARM PLT entry. */ +- value -= PLT_THUMB_STUB_SIZE; ++ { ++ /* Target the Thumb stub before the ARM PLT entry. */ ++ value -= PLT_THUMB_STUB_SIZE; ++ sym_flags = STT_ARM_TFUNC; ++ } + *unresolved_reloc_p = FALSE; + } + +@@ -11449,13 +11456,13 @@ + { + h->root.u.def.section = s; + h->root.u.def.value = h->plt.offset; +- } + +- /* Make sure the function is not marked as Thumb, in case +- it is the target of an ABS32 relocation, which will +- point to the PLT entry. */ +- if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC) +- h->type = ELF_ST_INFO (ELF_ST_BIND (h->type), STT_FUNC); ++ /* Make sure the function is not marked as Thumb, in case ++ it is the target of an ABS32 relocation, which will ++ point to the PLT entry. */ ++ if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC) ++ h->type = ELF_ST_INFO (ELF_ST_BIND (h->type), STT_FUNC); ++ } + + /* Make room for this entry. */ + s->size += htab->plt_entry_size; diff --git a/recipes/binutils/binutils_2.19.51.bb b/recipes/binutils/binutils_2.19.51.bb index 20e86c7f10..a49445db2b 100644 --- a/recipes/binutils/binutils_2.19.51.bb +++ b/recipes/binutils/binutils_2.19.51.bb @@ -1,4 +1,4 @@ -PR = "r1" +PR = "r2" require binutils.inc LICENSE = "GPLv3" @@ -13,6 +13,7 @@ SRC_URI = "\ file://binutils-uclibc-gas-needs-libm.patch;patch=1 \ file://binutils-arm-pr7093.patch;patch=1 \ file://ld-stub-crash.patch;patch=1;pnum=0 \ + file://thumb-func.patch;patch=1 \ " # powerpc patches -- cgit v1.2.3 From ba4bad720fc2ea3629875bb03ae1be06ad005a18 Mon Sep 17 00:00:00 2001 From: Andrea Adami Date: Fri, 18 Sep 2009 22:33:16 +0200 Subject: packaged-staging: fix populate_staging_postamble after staging-split by base package arch (introduced by f876463527bd9ae92a09159fdb4899b4a4d19121) --- classes/packaged-staging.bbclass | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/packaged-staging.bbclass b/classes/packaged-staging.bbclass index 33acb90a2b..3b97f593b8 100644 --- a/classes/packaged-staging.bbclass +++ b/classes/packaged-staging.bbclass @@ -284,7 +284,7 @@ populate_staging_postamble () { if [ "$exitcode" != "5" -a "$exitcode" != "0" ]; then exit $exitcode fi - stage-manager -p ${CROSS_DIR} -c ${DEPLOY_DIR_PSTAGE}/stamp-cache-cross -u -d ${PSTAGE_TMPDIR_STAGE}/cross + stage-manager -p ${CROSS_DIR} -c ${DEPLOY_DIR_PSTAGE}/stamp-cache-cross -u -d ${PSTAGE_TMPDIR_STAGE}/cross/${BASE_PACKAGE_ARCH} if [ "$exitcode" != "5" -a "$exitcode" != "0" ]; then exit $exitcode fi -- cgit v1.2.3 From a95c355af46bdc395cc8e1141682ab802ac48130 Mon Sep 17 00:00:00 2001 From: Andrea Adami Date: Sat, 12 Sep 2009 02:28:18 +0200 Subject: package_ipk.bbclass: force recreation of DEPLOY_DIR_IPK. The dir is removed wiping tmp. --- classes/package_ipk.bbclass | 1 + 1 file changed, 1 insertion(+) diff --git a/classes/package_ipk.bbclass b/classes/package_ipk.bbclass index e5561082fd..b48f8781eb 100644 --- a/classes/package_ipk.bbclass +++ b/classes/package_ipk.bbclass @@ -85,6 +85,7 @@ do_package_update_index_ipk () { return fi + mkdir -p ${DEPLOY_DIR_IPK} touch ${DEPLOY_DIR_IPK}/Packages ipkg-make-index -r ${DEPLOY_DIR_IPK}/Packages -p ${DEPLOY_DIR_IPK}/Packages -l ${DEPLOY_DIR_IPK}/Packages.filelist -m ${DEPLOY_DIR_IPK} -- cgit v1.2.3 From 82e740b54d24abc4a4b93d60d2d5b5e96432e128 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Fri, 18 Sep 2009 17:11:45 -0700 Subject: tzcode-native_2009k.bb, tzdata_2009m.bb: New timezone data * Add new recipes for latest zoneinfo data * Resort to INC_PR * Abstract out common parts into .inc files. Signed-off-by: Khem Raj --- conf/checksums.ini | 8 ++ recipes/tzcode/tzcode-native.inc | 17 ++++ recipes/tzcode/tzcode-native_2007k.bb | 22 +---- recipes/tzcode/tzcode-native_2009k.bb | 5 + recipes/tzdata/tzdata.inc | 172 +++++++++++++++++++++++++++++++++ recipes/tzdata/tzdata_2007k.bb | 175 +--------------------------------- recipes/tzdata/tzdata_2009m.bb | 3 + 7 files changed, 212 insertions(+), 190 deletions(-) create mode 100644 recipes/tzcode/tzcode-native.inc create mode 100644 recipes/tzcode/tzcode-native_2009k.bb create mode 100644 recipes/tzdata/tzdata.inc create mode 100644 recipes/tzdata/tzdata_2009m.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index 37152d1586..0af44b1cf3 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -24550,6 +24550,10 @@ sha256=1e5630747b12d82e106ff52173f890fe1975e2e72768872db8c64de9eace33d4 md5=1f1de10e168b78681756cc6411ea8145 sha256=1e5630747b12d82e106ff52173f890fe1975e2e72768872db8c64de9eace33d4 +[ftp://elsie.nci.nih.gov/pub/tzcode2009k.tar.gz] +md5=d181116286661375966a350e3e358cfa +sha256=2581f4ce19b11e4218ad0b2859679485af1cefe036f52643c8fb20024c8f5d45 + [ftp://elsie.nci.nih.gov/pub/tzdata2007e.tar.gz] md5=b74e5f71714e5222340f1fb30da30a76 sha256=51d14a60ea12aa901bf91e5d39ea30c13ffdc299640e8ec9cb0d35a128874767 @@ -24574,6 +24578,10 @@ sha256=37e986086ce1a1ccb9a4f24c2b77ede54f0eae2ee9959e7a191a49cedb405783 md5=dbeb9a327bbff77ab4078488b8c5323a sha256=633d76612d73a7add41a3b90fe5721ea5f4282d52bd8408b9d4fab261443aa6c +[ftp://elsie.nci.nih.gov/pub/tzdata2009m.tar.gz] +md5=5314fe1483c7c1be17c50f2c2171e06b +sha256=7609980204940ceaf74b5a48d15ea0c079eaec627e149cf3d986cfed268881fe + [ftp://ftp.pl.debian.org/pub/debian/pool/main/t/tzdata/tzdata_2007h.orig.tar.gz] md5=8b766bb807c1f7c0c02ff798ea5db80e sha256=b4c6367ab85de8f148c903bb25dc69de7a7d7d05f204f58880a16a8b81bf93de diff --git a/recipes/tzcode/tzcode-native.inc b/recipes/tzcode/tzcode-native.inc new file mode 100644 index 0000000000..8d3d6ddee7 --- /dev/null +++ b/recipes/tzcode/tzcode-native.inc @@ -0,0 +1,17 @@ +DESCRIPTION = "tzcode, timezone zoneinfo utils -- zic, zdump, tzselect" +INC_PR = "r1" + +S = "${WORKDIR}" + +inherit native + +do_stage () { + install -d ${STAGING_BINDIR_NATIVE} + install -m 755 zic ${STAGING_BINDIR_NATIVE}/ + install -m 755 zdump ${STAGING_BINDIR_NATIVE}/ + install -m 755 tzselect ${STAGING_BINDIR_NATIVE}/ +} + +do_install () { + : +} diff --git a/recipes/tzcode/tzcode-native_2007k.bb b/recipes/tzcode/tzcode-native_2007k.bb index 6593cc3a24..fe0fb87a9a 100644 --- a/recipes/tzcode/tzcode-native_2007k.bb +++ b/recipes/tzcode/tzcode-native_2007k.bb @@ -1,21 +1,7 @@ -DESCRIPTION = "tzcode, timezone zoneinfo utils -- zic, zdump, tzselect" -PR = "r0" - +require tzcode-native.inc SRC_URI = "\ - http://bent.latency.net/bent/darcs/zoneinfo-2007k/src/tzcode${PV}.tar.gz \ - http://bent.latency.net/bent/darcs/zoneinfo-2007k/src/tzdata${PV}.tar.gz \ + http://bent.latency.net/bent/darcs/zoneinfo-${PV}/src/tzcode${PV}.tar.gz \ + http://bent.latency.net/bent/darcs/zoneinfo-${PV}/src/tzdata${PV}.tar.gz \ " -S = "${WORKDIR}" - -inherit native - -do_stage () { - install -d ${STAGING_BINDIR_NATIVE} - install -m 755 zic ${STAGING_BINDIR_NATIVE}/ - install -m 755 zdump ${STAGING_BINDIR_NATIVE}/ - install -m 755 tzselect ${STAGING_BINDIR_NATIVE}/ -} -do_install () { - : -} +PR = "${INC_PR}.0" diff --git a/recipes/tzcode/tzcode-native_2009k.bb b/recipes/tzcode/tzcode-native_2009k.bb new file mode 100644 index 0000000000..59babb4856 --- /dev/null +++ b/recipes/tzcode/tzcode-native_2009k.bb @@ -0,0 +1,5 @@ +require tzcode-native.inc +SRC_URI = "ftp://elsie.nci.nih.gov/pub/tzcode${PV}.tar.gz \ + ftp://elsie.nci.nih.gov/pub/tzdata2009m.tar.gz \ + " +PR = "${INC_PR}.0" diff --git a/recipes/tzdata/tzdata.inc b/recipes/tzdata/tzdata.inc new file mode 100644 index 0000000000..71de930761 --- /dev/null +++ b/recipes/tzdata/tzdata.inc @@ -0,0 +1,172 @@ +DESCRIPTION = "Timezone data" +SECTION = "base" +PRIORITY = "optional" +DEPENDS = "tzcode-native" + +INC_PR = "r4" + +DEFAULT_TIMEZONE ?= "Europe/London" + +RCONFLICTS= "timezones timezone-africa timezone-america timezone-antarctica \ + timezone-arctic timezone-asia timezone-atlantic \ + timezone-australia timezone-europe timezone-indian \ + timezone-iso3166.tab timezone-pacific timezone-zone.tab" + +SRC_URI = "http://bent.latency.net/bent/darcs/zoneinfo-${PV}/src/tzdata${PV}.tar.gz" + +S = "${WORKDIR}" + +TZONES= "africa antarctica asia australasia europe northamerica southamerica \ + factory solar87 solar88 solar89 etcetera backward systemv \ +# pacificnew \ + " + +CONFFILES_${PN} = "${sysconfdir}/timezone ${sysconfdir}/localtime" + +do_compile () { + mkdir -p build + for zone in ${TZONES}; do \ + ${STAGING_BINDIR_NATIVE}/zic -d ${WORKDIR}/build${datadir}/zoneinfo -L /dev/null \ + -y ${S}/yearistype.sh ${S}/${zone} ; \ + ${STAGING_BINDIR_NATIVE}/zic -d ${WORKDIR}}/build${datadir}/zoneinfo/posix -L /dev/null \ + -y ${S}/yearistype.sh ${S}/${zone} ; \ + ${STAGING_BINDIR_NATIVE}/zic -d ${WORKDIR}}/build${datadir}/zoneinfo/right -L ${S}/leapseconds \ + -y ${S}/yearistype.sh ${S}/${zone} ; \ + done +} + +do_install () { + install -d ${D}${prefix} ${D}${datadir}/zoneinfo + cp -pPR ${WORKDIR}/build${prefix}/* ${D}${prefix} + + # Install a sane default for timezones + install -d ${D}${sysconfdir} + echo ${DEFAULT_TIMEZONE} > ${D}${sysconfdir}/timezone + cp -pPR ${WORKDIR}/build${datadir}/zoneinfo/${DEFAULT_TIMEZONE} ${D}${sysconfdir}/localtime +} + +# Packages primarily organized by directory with a major city +# in most time zones in the base package + +PACKAGES = "${PN}-dbg tzdata tzdata-misc tzdata-posix tzdata-right tzdata-africa \ + tzdata-americas tzdata-antarctica tzdata-arctic tzdata-asia \ + tzdata-atlantic tzdata-australia tzdata-europe tzdata-pacific" + +ALLOW_EMPTY_${PN}-dbg = "1" + +FILES_tzdata-africa += "${datadir}/zoneinfo/Africa/*" +RPROVIDES_tzdata-africa = "tzdata-africa" + +FILES_tzdata-americas += "${datadir}/zoneinfo/America/* \ + ${datadir}/zoneinfo/US/* \ + ${datadir}/zoneinfo/Brazil/* \ + ${datadir}/zoneinfo/Canada/* \ + ${datadir}/zoneinfo/Mexico/* \ + ${datadir}/zoneinfo/Chile/*" +RPROVIDES_tzdata-americas = "tzdata-americas" + +FILES_tzdata-antarctica += "${datadir}/zoneinfo/Antarctica/*" +RPROVIDES_tzdata-antarctica = "tzdata-antarctica" + +FILES_tzdata-arctic += "${datadir}/zoneinfo/Arctic/*" +RPROVIDES_tzdata-arctic = "tzdata-arctic" + +FILES_tzdata-asia += "${datadir}/zoneinfo/Asia/* \ + ${datadir}/zoneinfo/Indian/* \ + ${datadir}/zoneinfo/Mideast/*" +RPROVIDES_tzdata-asia = "tzdata-asia" + +FILES_tzdata-atlantic += "${datadir}/zoneinfo/Atlantic/*" +RPROVIDES_tzdata-atlantic = "tzdata-atlantic" + +FILES_tzdata-australia += "${datadir}/zoneinfo/Australia/*" +RPROVIDES_tzdata-australia = "tzdata-australia" + +FILES_tzdata-europe += "${datadir}/zoneinfo/Europe/*" +RPROVIDES_tzdata-europe = "tzdata-europe" + +FILES_tzdata-pacific += "${datadir}/zoneinfo/Pacific/*" +RPROVIDES_tzdata-pacific = "tzdata-pacific" + +FILES_tzdata-posix += "${datadir}/zoneinfo/posix/*" +RPROVIDES_tzdata-posix = "tzdata-posix" + +FILES_tzdata-right += "${datadir}/zoneinfo/right/*" +RPROVIDES_tzdata-right = "tzdata-right" + + +FILES_tzdata-misc += "${datadir}/zoneinfo/Cuba \ + ${datadir}/zoneinfo/Egypt \ + ${datadir}/zoneinfo/Eire \ + ${datadir}/zoneinfo/Factory \ + ${datadir}/zoneinfo/GB-Eire \ + ${datadir}/zoneinfo/Hongkong \ + ${datadir}/zoneinfo/Iceland \ + ${datadir}/zoneinfo/Iran \ + ${datadir}/zoneinfo/Israel \ + ${datadir}/zoneinfo/Jamaica \ + ${datadir}/zoneinfo/Japan \ + ${datadir}/zoneinfo/Kwajalein \ + ${datadir}/zoneinfo/Libya \ + ${datadir}/zoneinfo/Navajo \ + ${datadir}/zoneinfo/Poland \ + ${datadir}/zoneinfo/Portugal \ + ${datadir}/zoneinfo/Singapore \ + ${datadir}/zoneinfo/Turkey" +RPROVIDES_tzdata-misc = "tzdata-misc" + + +FILES_${PN} += "${datadir}/zoneinfo/Pacific/Honolulu \ + ${datadir}/zoneinfo/America/Anchorage \ + ${datadir}/zoneinfo/America/Los_Angeles \ + ${datadir}/zoneinfo/America/Denver \ + ${datadir}/zoneinfo/America/Chicago \ + ${datadir}/zoneinfo/America/New_York \ + ${datadir}/zoneinfo/America/Caracas \ + ${datadir}/zoneinfo/America/Sao_Paulo \ + ${datadir}/zoneinfo/Europe/London \ + ${datadir}/zoneinfo/Europe/Paris \ + ${datadir}/zoneinfo/Africa/Cairo \ + ${datadir}/zoneinfo/Europe/Moscow \ + ${datadir}/zoneinfo/Asia/Dubai \ + ${datadir}/zoneinfo/Asia/Karachi \ + ${datadir}/zoneinfo/Asia/Dhaka \ + ${datadir}/zoneinfo/Asia/Bankok \ + ${datadir}/zoneinfo/Asia/Hong_Kong \ + ${datadir}/zoneinfo/Asia/Tokyo \ + ${datadir}/zoneinfo/Australia/Perth \ + ${datadir}/zoneinfo/Australia/Darwin \ + ${datadir}/zoneinfo/Australia/Adelaide \ + ${datadir}/zoneinfo/Australia/Brisbane \ + ${datadir}/zoneinfo/Australia/Sydney \ + ${datadir}/zoneinfo/Pacific/Noumea \ + ${datadir}/zoneinfo/CET \ + ${datadir}/zoneinfo/CST6CDT \ + ${datadir}/zoneinfo/EET \ + ${datadir}/zoneinfo/EST \ + ${datadir}/zoneinfo/EST5EDT \ + ${datadir}/zoneinfo/GB \ + ${datadir}/zoneinfo/GMT \ + ${datadir}/zoneinfo/GMT+0 \ + ${datadir}/zoneinfo/GMT-0 \ + ${datadir}/zoneinfo/GMT0 \ + ${datadir}/zoneinfo/Greenwich \ + ${datadir}/zoneinfo/HST \ + ${datadir}/zoneinfo/MET \ + ${datadir}/zoneinfo/MST \ + ${datadir}/zoneinfo/MST7MDT \ + ${datadir}/zoneinfo/NZ \ + ${datadir}/zoneinfo/NZ-CHAT \ + ${datadir}/zoneinfo/PRC \ + ${datadir}/zoneinfo/PST8PDT \ + ${datadir}/zoneinfo/ROC \ + ${datadir}/zoneinfo/ROK \ + ${datadir}/zoneinfo/UCT \ + ${datadir}/zoneinfo/UTC \ + ${datadir}/zoneinfo/Universal \ + ${datadir}/zoneinfo/W-SU \ + ${datadir}/zoneinfo/WET \ + ${datadir}/zoneinfo/Zulu \ + ${datadir}/zoneinfo/Etc/* \ + ${sysconfdir}/localtime \ + ${sysconfdir}/timezone " diff --git a/recipes/tzdata/tzdata_2007k.bb b/recipes/tzdata/tzdata_2007k.bb index f126a99c3e..7bb66718d6 100644 --- a/recipes/tzdata/tzdata_2007k.bb +++ b/recipes/tzdata/tzdata_2007k.bb @@ -1,172 +1,3 @@ -DESCRIPTION = "Timezone data" -SECTION = "base" -PRIORITY = "optional" -DEPENDS = "tzcode-native" - -PR = "r4" - -DEFAULT_TIMEZONE ?= "Europe/London" - -RCONFLICTS= "timezones timezone-africa timezone-america timezone-antarctica \ - timezone-arctic timezone-asia timezone-atlantic \ - timezone-australia timezone-europe timezone-indian \ - timezone-iso3166.tab timezone-pacific timezone-zone.tab" - -SRC_URI = "http://bent.latency.net/bent/darcs/zoneinfo-2007k/src/tzdata${PV}.tar.gz" - -S = "${WORKDIR}" - -TZONES= "africa antarctica asia australasia europe northamerica southamerica \ - factory solar87 solar88 solar89 etcetera backward systemv \ -# pacificnew \ - " - -CONFFILES_${PN} = "${sysconfdir}/timezone ${sysconfdir}/localtime" - -do_compile () { - mkdir -p build - for zone in ${TZONES}; do \ - ${STAGING_BINDIR_NATIVE}/zic -d ${WORKDIR}/build${datadir}/zoneinfo -L /dev/null \ - -y ${S}/yearistype.sh ${S}/${zone} ; \ - ${STAGING_BINDIR_NATIVE}/zic -d ${WORKDIR}}/build${datadir}/zoneinfo/posix -L /dev/null \ - -y ${S}/yearistype.sh ${S}/${zone} ; \ - ${STAGING_BINDIR_NATIVE}/zic -d ${WORKDIR}}/build${datadir}/zoneinfo/right -L ${S}/leapseconds \ - -y ${S}/yearistype.sh ${S}/${zone} ; \ - done -} - -do_install () { - install -d ${D}${prefix} ${D}${datadir}/zoneinfo - cp -pPR ${WORKDIR}/build${prefix}/* ${D}${prefix} - - # Install a sane default for timezones - install -d ${D}${sysconfdir} - echo ${DEFAULT_TIMEZONE} > ${D}${sysconfdir}/timezone - cp -pPR ${WORKDIR}/build${datadir}/zoneinfo/${DEFAULT_TIMEZONE} ${D}${sysconfdir}/localtime -} - -# Packages primarily organized by directory with a major city -# in most time zones in the base package - -PACKAGES = "${PN}-dbg tzdata tzdata-misc tzdata-posix tzdata-right tzdata-africa \ - tzdata-americas tzdata-antarctica tzdata-arctic tzdata-asia \ - tzdata-atlantic tzdata-australia tzdata-europe tzdata-pacific" - -ALLOW_EMPTY_${PN}-dbg = "1" - -FILES_tzdata-africa += "${datadir}/zoneinfo/Africa/*" -RPROVIDES_tzdata-africa = "tzdata-africa" - -FILES_tzdata-americas += "${datadir}/zoneinfo/America/* \ - ${datadir}/zoneinfo/US/* \ - ${datadir}/zoneinfo/Brazil/* \ - ${datadir}/zoneinfo/Canada/* \ - ${datadir}/zoneinfo/Mexico/* \ - ${datadir}/zoneinfo/Chile/*" -RPROVIDES_tzdata-americas = "tzdata-americas" - -FILES_tzdata-antarctica += "${datadir}/zoneinfo/Antarctica/*" -RPROVIDES_tzdata-antarctica = "tzdata-antarctica" - -FILES_tzdata-arctic += "${datadir}/zoneinfo/Arctic/*" -RPROVIDES_tzdata-arctic = "tzdata-arctic" - -FILES_tzdata-asia += "${datadir}/zoneinfo/Asia/* \ - ${datadir}/zoneinfo/Indian/* \ - ${datadir}/zoneinfo/Mideast/*" -RPROVIDES_tzdata-asia = "tzdata-asia" - -FILES_tzdata-atlantic += "${datadir}/zoneinfo/Atlantic/*" -RPROVIDES_tzdata-atlantic = "tzdata-atlantic" - -FILES_tzdata-australia += "${datadir}/zoneinfo/Australia/*" -RPROVIDES_tzdata-australia = "tzdata-australia" - -FILES_tzdata-europe += "${datadir}/zoneinfo/Europe/*" -RPROVIDES_tzdata-europe = "tzdata-europe" - -FILES_tzdata-pacific += "${datadir}/zoneinfo/Pacific/*" -RPROVIDES_tzdata-pacific = "tzdata-pacific" - -FILES_tzdata-posix += "${datadir}/zoneinfo/posix/*" -RPROVIDES_tzdata-posix = "tzdata-posix" - -FILES_tzdata-right += "${datadir}/zoneinfo/right/*" -RPROVIDES_tzdata-right = "tzdata-right" - - -FILES_tzdata-misc += "${datadir}/zoneinfo/Cuba \ - ${datadir}/zoneinfo/Egypt \ - ${datadir}/zoneinfo/Eire \ - ${datadir}/zoneinfo/Factory \ - ${datadir}/zoneinfo/GB-Eire \ - ${datadir}/zoneinfo/Hongkong \ - ${datadir}/zoneinfo/Iceland \ - ${datadir}/zoneinfo/Iran \ - ${datadir}/zoneinfo/Israel \ - ${datadir}/zoneinfo/Jamaica \ - ${datadir}/zoneinfo/Japan \ - ${datadir}/zoneinfo/Kwajalein \ - ${datadir}/zoneinfo/Libya \ - ${datadir}/zoneinfo/Navajo \ - ${datadir}/zoneinfo/Poland \ - ${datadir}/zoneinfo/Portugal \ - ${datadir}/zoneinfo/Singapore \ - ${datadir}/zoneinfo/Turkey" -RPROVIDES_tzdata-misc = "tzdata-misc" - - -FILES_${PN} += "${datadir}/zoneinfo/Pacific/Honolulu \ - ${datadir}/zoneinfo/America/Anchorage \ - ${datadir}/zoneinfo/America/Los_Angeles \ - ${datadir}/zoneinfo/America/Denver \ - ${datadir}/zoneinfo/America/Chicago \ - ${datadir}/zoneinfo/America/New_York \ - ${datadir}/zoneinfo/America/Caracas \ - ${datadir}/zoneinfo/America/Sao_Paulo \ - ${datadir}/zoneinfo/Europe/London \ - ${datadir}/zoneinfo/Europe/Paris \ - ${datadir}/zoneinfo/Africa/Cairo \ - ${datadir}/zoneinfo/Europe/Moscow \ - ${datadir}/zoneinfo/Asia/Dubai \ - ${datadir}/zoneinfo/Asia/Karachi \ - ${datadir}/zoneinfo/Asia/Dhaka \ - ${datadir}/zoneinfo/Asia/Bankok \ - ${datadir}/zoneinfo/Asia/Hong_Kong \ - ${datadir}/zoneinfo/Asia/Tokyo \ - ${datadir}/zoneinfo/Australia/Perth \ - ${datadir}/zoneinfo/Australia/Darwin \ - ${datadir}/zoneinfo/Australia/Adelaide \ - ${datadir}/zoneinfo/Australia/Brisbane \ - ${datadir}/zoneinfo/Australia/Sydney \ - ${datadir}/zoneinfo/Pacific/Noumea \ - ${datadir}/zoneinfo/CET \ - ${datadir}/zoneinfo/CST6CDT \ - ${datadir}/zoneinfo/EET \ - ${datadir}/zoneinfo/EST \ - ${datadir}/zoneinfo/EST5EDT \ - ${datadir}/zoneinfo/GB \ - ${datadir}/zoneinfo/GMT \ - ${datadir}/zoneinfo/GMT+0 \ - ${datadir}/zoneinfo/GMT-0 \ - ${datadir}/zoneinfo/GMT0 \ - ${datadir}/zoneinfo/Greenwich \ - ${datadir}/zoneinfo/HST \ - ${datadir}/zoneinfo/MET \ - ${datadir}/zoneinfo/MST \ - ${datadir}/zoneinfo/MST7MDT \ - ${datadir}/zoneinfo/NZ \ - ${datadir}/zoneinfo/NZ-CHAT \ - ${datadir}/zoneinfo/PRC \ - ${datadir}/zoneinfo/PST8PDT \ - ${datadir}/zoneinfo/ROC \ - ${datadir}/zoneinfo/ROK \ - ${datadir}/zoneinfo/UCT \ - ${datadir}/zoneinfo/UTC \ - ${datadir}/zoneinfo/Universal \ - ${datadir}/zoneinfo/W-SU \ - ${datadir}/zoneinfo/WET \ - ${datadir}/zoneinfo/Zulu \ - ${datadir}/zoneinfo/Etc/* \ - ${sysconfdir}/localtime \ - ${sysconfdir}/timezone " +require tzdata.inc +SRC_URI = "http://bent.latency.net/bent/darcs/zoneinfo-${PV}/src/tzdata${PV}.tar.gz" +PR = "${INC_PR}.0" diff --git a/recipes/tzdata/tzdata_2009m.bb b/recipes/tzdata/tzdata_2009m.bb new file mode 100644 index 0000000000..17c2dd4f0c --- /dev/null +++ b/recipes/tzdata/tzdata_2009m.bb @@ -0,0 +1,3 @@ +require tzdata.inc +SRC_URI = "ftp://elsie.nci.nih.gov/pub/tzdata${PV}.tar.gz" +PR = "${INC_PR}.0" -- cgit v1.2.3 From 07342fa6ce47e95d53230787594f0e30145534fa Mon Sep 17 00:00:00 2001 From: Michael 'Mickey' Lauer Date: Fri, 18 Sep 2009 09:01:20 +0000 Subject: libcanberra: add 0.17; misc bug fixes and includes vapi bindings now --- recipes/pulseaudio/libcanberra_0.17.bb | 60 ++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 recipes/pulseaudio/libcanberra_0.17.bb diff --git a/recipes/pulseaudio/libcanberra_0.17.bb b/recipes/pulseaudio/libcanberra_0.17.bb new file mode 100644 index 0000000000..50a2f82853 --- /dev/null +++ b/recipes/pulseaudio/libcanberra_0.17.bb @@ -0,0 +1,60 @@ +DESCRIPTION = "Libcanberra is an implementation of the XDG Sound Theme and Name \ +Specifications, for generating event sounds on free desktops." +LICENSE = "LGPL" +DEPENDS = "alsa-lib gstreamer gtk+ libvorbis pulseaudio" +SECTION = "libs/multimedia" +AUTHOR = "Lennart Poettering" +HOMEPAGE = "http://0pointer.de/lennart/projects/libcanberra" +PR = "r0" + +inherit autotools_stage vala +AUTOTOOLS_STAGE_PKGCONFIG = "1" + +SRC_URI = "http://0pointer.de/lennart/projects/libcanberra/libcanberra-${PV}.tar.gz" + +EXTRA_OECONF = "\ + --enable-alsa \ + --enable-gstreamer \ + --enable-gtk \ + --enable-multi \ + --enable-null \ + --disable-oss \ +# enable pulse again when pulseaudio >= 0.9.11 is the default in OE + --disable-pulse \ + --disable-tdb \ +" + +# This needs autoconf 2.62, which isn't used by any distro in OE atm +do_configure() { + gnu-configize --force + oe_runconf +} + +# TODO: Test more fine granular version +#OE_LT_RPATH_ALLOW=":${libdir}/${P}:" +OE_LT_RPATH_ALLOW = "any" +OE_LT_RPATH_ALLOW[export] = "1" + +python populate_packages_prepend() { + plugindir = bb.data.expand('${libdir}/${P}/', d) + do_split_packages(d, plugindir, '^libcanberra-(.*)\.so$', 'libcanberra-%s', '%s support library', extra_depends='' ) +} + +PACKAGES =+ "${PN}-gtk" + +PACKAGES_DYNAMIC = "libcanberra-*" + +FILES_${PN}-gtk = "\ + ${sysconfdir}/gconf \ + ${bindir}/* \ + ${libdir}/libcanberra-gtk.so.* \ + ${libdir}/gtk-2.0/modules/* \ + ${datadir}/gnome \ +" +FILES_${PN}-dev += "\ + ${libdir}/${P}/*.la \ +" +FILES_${PN}-dbg += "\ + ${libdir}/gtk-2.0/modules/.debug \ + ${libdir}/${P}/.debug \ +" -- cgit v1.2.3 From a12a9f2b508323846f10113027ba82f0dd1e780b Mon Sep 17 00:00:00 2001 From: Michael 'Mickey' Lauer Date: Sat, 19 Sep 2009 12:32:02 +0000 Subject: checksums: add libcanberra 0.17 and vala 0.7.6-fso2 --- conf/checksums.ini | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/conf/checksums.ini b/conf/checksums.ini index 0af44b1cf3..3de7e0c2ba 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -13358,6 +13358,10 @@ sha256=04a70135de89ec7971a7ffa6516cf7699329cc01056595d524a6250a9d049709 md5=b182ab134a911ba6c42ea2b727eda13e sha256=879f9ab798ae287048518ebb55132bbab905bea4b830a90f27a04df6d08d2a5e +[http://0pointer.de/lennart/projects/libcanberra/libcanberra-0.17.tar.gz] +md5=d1f5c5956d65d289566197e620be1a2e +sha256=5f41fa3cc992721709d3761601dcd9d57e4ec26f113e115005feb7aab9920257 + [http://kernel.org//pub/linux/libs/security/linux-privs/kernel-2.4/libcap-1.10.tar.bz2] md5=4426a413128142cab89eb2e6f13d8571 sha256=66c3f033fdc8f9ba0bd9d0ae2d1f2c11f9fa51bf0d1418e5cb75e29e6577a5bc @@ -25142,10 +25146,6 @@ sha256=dbd7c9200d45e9278498817490092c468aa31ec9815f30d71deb5b5009401b64 md5=92216c6ffb9fe0dee80c22603ee0bbb0 sha256=564463e9e4a2603a33bb29abb9011c9fcd7108d86054b19bd163b295c0511567 -[http://download.gnome.org/sources/vala/${MAJV}/vala-0.5.4.tar.bz2] -md5=9aa42745fd87e55655adde0dc14f928c -sha256=faf0b7863161927e1502c8829f24e23aad404d305305728a4f37a4824d73fdab - [http://download.gnome.org/sources/vala/0.5/vala-0.5.4.tar.bz2] md5=9aa42745fd87e55655adde0dc14f928c sha256=faf0b7863161927e1502c8829f24e23aad404d305305728a4f37a4824d73fdab @@ -25170,6 +25170,10 @@ sha256=9d1cb3661e6c15059e4eecce323b3f118c243d1f17a1883e2b2d7ca0a16987e5 md5=1a10e3c3d7c8eab324ecb0d8b81732bd sha256=4dfd1ff2793f71ab11d842ff4379a676a30af4287b7b6892ba9733bf7b691c10 +[http://www.freesmartphone.org/sources/vala-0.7.6-fso2.tar.gz] +md5=ca44d7e733e4f2058a1e5e8a0aa5d2e0 +sha256=59295d46010c19f7b23f46e60522e6161ffc44685ef20fc04aca8b54d3fd7ef0 + [http://www.valgrind.org/downloads/valgrind-3.2.1.tar.bz2] md5=9407d33961186814cef0e6ecedfd6318 sha256=7f9a15d7be16ca03a0912191e8d55a486bf69690e11bb76ccece3eaff3730a33 -- cgit v1.2.3 From d7f889b1a94b7e84ca593659c285c3ccdbfd2fe8 Mon Sep 17 00:00:00 2001 From: Michael 'Mickey' Lauer Date: Sat, 19 Sep 2009 12:32:30 +0000 Subject: vala: update to 0.7.6-fso2 --- recipes/vala/vala-native_0.7.5+fso2.bb | 8 -------- recipes/vala/vala-native_0.7.6-fso2.bb | 6 ++++++ recipes/vala/vala.inc | 3 +-- recipes/vala/vala_0.7.5+fso2.bb | 6 ------ recipes/vala/vala_0.7.6-fso2.bb | 6 ++++++ 5 files changed, 13 insertions(+), 16 deletions(-) delete mode 100644 recipes/vala/vala-native_0.7.5+fso2.bb create mode 100644 recipes/vala/vala-native_0.7.6-fso2.bb delete mode 100644 recipes/vala/vala_0.7.5+fso2.bb create mode 100644 recipes/vala/vala_0.7.6-fso2.bb diff --git a/recipes/vala/vala-native_0.7.5+fso2.bb b/recipes/vala/vala-native_0.7.5+fso2.bb deleted file mode 100644 index 7a73cf5736..0000000000 --- a/recipes/vala/vala-native_0.7.5+fso2.bb +++ /dev/null @@ -1,8 +0,0 @@ -require vala.inc -inherit native -DEPENDS = "glib-2.0-native" - -VALA_FSO_RELEASE = "0.7.5-fso2" -PV = "0.7.4+${VALA_FSO_RELEASE}" -PR = "${INC_PR}.0" - diff --git a/recipes/vala/vala-native_0.7.6-fso2.bb b/recipes/vala/vala-native_0.7.6-fso2.bb new file mode 100644 index 0000000000..b7ff8a7dad --- /dev/null +++ b/recipes/vala/vala-native_0.7.6-fso2.bb @@ -0,0 +1,6 @@ +require vala.inc +inherit native +DEPENDS = "glib-2.0-native" + +PR = "${INC_PR}.0" + diff --git a/recipes/vala/vala.inc b/recipes/vala/vala.inc index fa1cf6aaa8..7c1e70a456 100644 --- a/recipes/vala/vala.inc +++ b/recipes/vala/vala.inc @@ -6,8 +6,7 @@ HOMEPAGE = "http://vala-project.org" LICENSE = "LGPL" INC_PR = "r0" -SRC_URI = "http://www.freesmartphone.org/sources/vala-${VALA_FSO_RELEASE}.tar.gz" -S = "${WORKDIR}/vala-${VALA_FSO_RELEASE}" +SRC_URI = "http://www.freesmartphone.org/sources/vala-${PV}.tar.gz" inherit autotools_stage diff --git a/recipes/vala/vala_0.7.5+fso2.bb b/recipes/vala/vala_0.7.5+fso2.bb deleted file mode 100644 index fff355ebaf..0000000000 --- a/recipes/vala/vala_0.7.5+fso2.bb +++ /dev/null @@ -1,6 +0,0 @@ -require vala.inc -VALA_FSO_RELEASE = "0.7.5-fso2" -PV = "0.7.4+${VALA_FSO_RELEASE}" -PR = "${INC_PR}.0" - - diff --git a/recipes/vala/vala_0.7.6-fso2.bb b/recipes/vala/vala_0.7.6-fso2.bb new file mode 100644 index 0000000000..fff355ebaf --- /dev/null +++ b/recipes/vala/vala_0.7.6-fso2.bb @@ -0,0 +1,6 @@ +require vala.inc +VALA_FSO_RELEASE = "0.7.5-fso2" +PV = "0.7.4+${VALA_FSO_RELEASE}" +PR = "${INC_PR}.0" + + -- cgit v1.2.3 From b50202f4be562e271f3c3acc15e6f6d1f98619e8 Mon Sep 17 00:00:00 2001 From: Phil Blundell Date: Sat, 19 Sep 2009 13:36:48 +0100 Subject: micro: set PREFERRED_ARM_INSTRUCTION_SET weakly so local.conf can override --- conf/distro/micro.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/distro/micro.conf b/conf/distro/micro.conf index 5ee6f9b393..43b00f7958 100644 --- a/conf/distro/micro.conf +++ b/conf/distro/micro.conf @@ -62,7 +62,7 @@ MACHINE_KERNEL_VERSION = "2.6" ############################################################################# LIBC ?= "eglibc" PREFERRED_BINUTILS = "2.19.51" -PREFERRED_ARM_INSTRUCTION_SET = "thumb" +PREFERRED_ARM_INSTRUCTION_SET ?= "thumb" require conf/distro/include/sane-toolchain.inc ############################################################################# -- cgit v1.2.3 From d5b4f3993861f3cbe6232f34281777f48c2c6c70 Mon Sep 17 00:00:00 2001 From: Michael 'Mickey' Lauer Date: Sat, 19 Sep 2009 14:47:13 +0200 Subject: fso2-console-image: new recipe for fso2-compliance --- recipes/images/fso2-console-image.bb | 15 +++++++++++++++ recipes/tasks/task-fso2-compliance.bb | 10 +++++----- 2 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 recipes/images/fso2-console-image.bb diff --git a/recipes/images/fso2-console-image.bb b/recipes/images/fso2-console-image.bb new file mode 100644 index 0000000000..60bd6fc720 --- /dev/null +++ b/recipes/images/fso2-console-image.bb @@ -0,0 +1,15 @@ +#------------------------------------------------------ +# FSO-compliant Console Image Recipe +#------------------------------------------------------ + +require fso-image.inc + +PV = "1.1" +PR = "r1" + +IMAGE_INSTALL = "\ + task-base \ + task-fso2-compliance \ + task-cli-tools \ + task-cli-tools-python \ +" diff --git a/recipes/tasks/task-fso2-compliance.bb b/recipes/tasks/task-fso2-compliance.bb index 3746cd34ab..dbc298d670 100644 --- a/recipes/tasks/task-fso2-compliance.bb +++ b/recipes/tasks/task-fso2-compliance.bb @@ -22,7 +22,7 @@ RDEPENDS_${PN} = "\ fso-alsa-data \ fso-apm \ fso-gpsd \ - fso-monitord \ +# fso-monitord \ connman \ connman-scripts \ connman-plugin-bluetooth \ @@ -42,8 +42,8 @@ RRECOMMENDS_${PN} = "\ fso-abyss \ wmiconfig \ \ - tzdata \ - tzdata-americas \ - tzdata-asia \ - tzdata-europe \ +# tzdata \ +# tzdata-americas \ +# tzdata-asia \ +# tzdata-europe \ " -- cgit v1.2.3 From d9aac9ea22d75ef8ade18dbce3ef5c9bccaed3be Mon Sep 17 00:00:00 2001 From: Leon Woestenberg Date: Sat, 19 Sep 2009 00:44:46 +0200 Subject: linux-kirkwood: Add kernel support for openrd-base. Signed-off-by: Leon Woestenberg --- conf/machine/include/kirkwood.inc | 2 +- recipes/linux/linux-kirkwood/openrd-base/.config | 1812 ---------------------- recipes/linux/linux-kirkwood_2.6.31.bb | 33 + 3 files changed, 34 insertions(+), 1813 deletions(-) delete mode 100644 recipes/linux/linux-kirkwood/openrd-base/.config create mode 100644 recipes/linux/linux-kirkwood_2.6.31.bb diff --git a/conf/machine/include/kirkwood.inc b/conf/machine/include/kirkwood.inc index 64ef38b16c..3fc0654c14 100644 --- a/conf/machine/include/kirkwood.inc +++ b/conf/machine/include/kirkwood.inc @@ -11,7 +11,7 @@ USE_DEVFS = "0" PREFERRED_PROVIDER_virtual/bootloader = "" PREFERRED_PROVIDER_virtual/kernel = "linux-kirkwood" -MACHINE_KERNEL_PR = "r9" +MACHINE_KERNEL_PR = "r10" IMAGE_FSTYPES += "tar.gz ubi" SERIAL_CONSOLE = "ttyS0 115200" diff --git a/recipes/linux/linux-kirkwood/openrd-base/.config b/recipes/linux/linux-kirkwood/openrd-base/.config deleted file mode 100644 index adb4ca64f1..0000000000 --- a/recipes/linux/linux-kirkwood/openrd-base/.config +++ /dev/null @@ -1,1812 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.31-rc9 -# Mon Sep 14 00:31:10 2009 -# -CONFIG_ARM=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_GENERIC_GPIO=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_HAVE_LATENCYTOP_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_VECTORS_BASE=0xffff0000 -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -CONFIG_CONSTRUCTORS=y - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_LOCK_KERNEL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set - -# -# RCU Subsystem -# -CONFIG_CLASSIC_RCU=y -# CONFIG_TREE_RCU is not set -# CONFIG_PREEMPT_RCU is not set -# CONFIG_TREE_RCU_TRACE is not set -# CONFIG_PREEMPT_RCU_TRACE is not set -# CONFIG_IKCONFIG is not set -CONFIG_LOG_BUF_SHIFT=19 -# CONFIG_GROUP_SCHED is not set -# CONFIG_CGROUPS is not set -# CONFIG_SYSFS_DEPRECATED_V2 is not set -# CONFIG_RELAY is not set -CONFIG_NAMESPACES=y -# CONFIG_UTS_NS is not set -# CONFIG_IPC_NS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set -# CONFIG_NET_NS is not set -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_ANON_INODES=y -# CONFIG_EMBEDDED is not set -CONFIG_UID16=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_AIO=y - -# -# Performance Counters -# -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_PCI_QUIRKS=y -CONFIG_SLUB_DEBUG=y -# CONFIG_STRIP_ASM_SYMS is not set -CONFIG_COMPAT_BRK=y -# CONFIG_SLAB is not set -CONFIG_SLUB=y -# CONFIG_SLOB is not set -CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y -CONFIG_MARKERS=y -CONFIG_OPROFILE=y -CONFIG_HAVE_OPROFILE=y -CONFIG_KPROBES=y -CONFIG_KRETPROBES=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y - -# -# GCOV-based kernel profiling -# -# CONFIG_GCOV_KERNEL is not set -# CONFIG_SLOW_WORK is not set -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_BLOCK=y -CONFIG_LBDAF=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_INTEGRITY is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" -# CONFIG_FREEZER is not set - -# -# System Type -# -# CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_AT91 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_GEMINI is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_MXC is not set -# CONFIG_ARCH_STMP3XXX is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_IOP13XX is not set -# CONFIG_ARCH_IOP32X is not set -# CONFIG_ARCH_IOP33X is not set -# CONFIG_ARCH_IXP23XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_L7200 is not set -CONFIG_ARCH_KIRKWOOD=y -# CONFIG_ARCH_LOKI is not set -# CONFIG_ARCH_MV78XX0 is not set -# CONFIG_ARCH_ORION5X is not set -# CONFIG_ARCH_MMP is not set -# CONFIG_ARCH_KS8695 is not set -# CONFIG_ARCH_NS9XXX is not set -# CONFIG_ARCH_W90X900 is not set -# CONFIG_ARCH_PNX4008 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_MSM is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_S3C64XX is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_LH7A40X is not set -# CONFIG_ARCH_U300 is not set -# CONFIG_ARCH_DAVINCI is not set -# CONFIG_ARCH_OMAP is not set - -# -# Marvell Kirkwood Implementations -# -# CONFIG_MACH_DB88F6281_BP is not set -# CONFIG_MACH_RD88F6192_NAS is not set -# CONFIG_MACH_RD88F6281 is not set -# CONFIG_MACH_MV88F6281GTW_GE is not set -# CONFIG_MACH_SHEEVAPLUG is not set -# CONFIG_MACH_TS219 is not set -CONFIG_MACH_OPENRD_BASE=y -CONFIG_PLAT_ORION=y - -# -# Processor Type -# -CONFIG_CPU_32=y -CONFIG_CPU_FEROCEON=y -# CONFIG_CPU_FEROCEON_OLD_ID is not set -CONFIG_CPU_32v5=y -CONFIG_CPU_ABRT_EV5T=y -CONFIG_CPU_PABRT_NOIFAR=y -CONFIG_CPU_CACHE_VIVT=y -CONFIG_CPU_COPY_FEROCEON=y -CONFIG_CPU_TLB_FEROCEON=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y - -# -# Processor Features -# -CONFIG_ARM_THUMB=y -# CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_DISABLE is not set -CONFIG_OUTER_CACHE=y -CONFIG_CACHE_FEROCEON_L2=y -# CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH is not set - -# -# Bus support -# -CONFIG_PCI=y -CONFIG_PCI_SYSCALL=y -# CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_PCI_LEGACY=y -CONFIG_PCI_DEBUG=y -# CONFIG_PCI_STUB is not set -# CONFIG_PCI_IOV is not set -# CONFIG_PCCARD is not set - -# -# Kernel Features -# -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -CONFIG_VMSPLIT_3G=y -# CONFIG_VMSPLIT_2G is not set -# CONFIG_VMSPLIT_1G is not set -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_PREEMPT=y -CONFIG_HZ=100 -CONFIG_AEABI=y -# CONFIG_OABI_COMPAT is not set -# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -# CONFIG_HIGHMEM is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4096 -# CONFIG_PHYS_ADDR_T_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 -CONFIG_VIRT_TO_BUS=y -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -CONFIG_ALIGNMENT_TRAP=y -CONFIG_UACCESS_WITH_MEMCPY=y - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="" -# CONFIG_XIP_KERNEL is not set -# CONFIG_KEXEC is not set - -# -# CPU Power Management -# -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_LADDER=y -CONFIG_CPU_IDLE_GOV_MENU=y - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -# CONFIG_VFP is not set - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_HAVE_AOUT=y -# CONFIG_BINFMT_AOUT is not set -# CONFIG_BINFMT_MISC is not set - -# -# Power management options -# -# CONFIG_PM is not set -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_LRO=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -CONFIG_NET_DSA=y -# CONFIG_NET_DSA_TAG_DSA is not set -CONFIG_NET_DSA_TAG_EDSA=y -# CONFIG_NET_DSA_TAG_TRAILER is not set -CONFIG_NET_DSA_MV88E6XXX=y -# CONFIG_NET_DSA_MV88E6060 is not set -# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set -# CONFIG_NET_DSA_MV88E6131 is not set -CONFIG_NET_DSA_MV88E6123_61_65=y -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_PHONET is not set -# CONFIG_IEEE802154 is not set -# CONFIG_NET_SCHED is not set -# CONFIG_DCB is not set - -# -# Network testing -# -CONFIG_NET_PKTGEN=m -# CONFIG_NET_TCPPROBE is not set -# CONFIG_NET_DROP_MONITOR is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set -CONFIG_WIRELESS=y -CONFIG_CFG80211=y -# CONFIG_CFG80211_REG_DEBUG is not set -# CONFIG_CFG80211_DEBUGFS is not set -CONFIG_WIRELESS_OLD_REGULATORY=y -CONFIG_WIRELESS_EXT=y -CONFIG_WIRELESS_EXT_SYSFS=y -CONFIG_LIB80211=y -# CONFIG_LIB80211_DEBUG is not set -CONFIG_MAC80211=y -CONFIG_MAC80211_DEFAULT_PS=y -CONFIG_MAC80211_DEFAULT_PS_VALUE=1 - -# -# Rate control algorithm selection -# -CONFIG_MAC80211_RC_MINSTREL=y -# CONFIG_MAC80211_RC_DEFAULT_PID is not set -CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y -CONFIG_MAC80211_RC_DEFAULT="minstrel" -# CONFIG_MAC80211_LEDS is not set -# CONFIG_MAC80211_DEBUGFS is not set -# CONFIG_MAC80211_DEBUG_MENU is not set -# CONFIG_WIMAX is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_TESTS is not set -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y -# CONFIG_MTD_AFS_PARTS is not set -# CONFIG_MTD_AR7_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_GEN_PROBE=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_NOSWAP=y -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -CONFIG_MTD_CFI_GEOMETRY=y -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_OTP is not set -CONFIG_MTD_CFI_INTELEXT=y -# CONFIG_MTD_CFI_AMDSTD is not set -CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_PHYSMAP=y -# CONFIG_MTD_PHYSMAP_COMPAT is not set -# CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_IMPA7 is not set -# CONFIG_MTD_INTEL_VR_NOR is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_DATAFLASH is not set -CONFIG_MTD_M25P80=y -CONFIG_M25PXX_USE_FAST_READ=y -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -CONFIG_MTD_NAND=y -# CONFIG_MTD_NAND_VERIFY_WRITE is not set -# CONFIG_MTD_NAND_ECC_SMC is not set -# CONFIG_MTD_NAND_MUSEUM_IDS is not set -# CONFIG_MTD_NAND_GPIO is not set -CONFIG_MTD_NAND_IDS=y -# CONFIG_MTD_NAND_DISKONCHIP is not set -# CONFIG_MTD_NAND_CAFE is not set -# CONFIG_MTD_NAND_NANDSIM is not set -# CONFIG_MTD_NAND_PLATFORM is not set -# CONFIG_MTD_ALAUDA is not set -CONFIG_MTD_NAND_ORION=y -# CONFIG_MTD_ONENAND is not set - -# -# LPDDR flash memory drivers -# -# CONFIG_MTD_LPDDR is not set - -# -# UBI - Unsorted block images -# -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_MTD_UBI_BEB_RESERVE=1 -# CONFIG_MTD_UBI_GLUEBI is not set - -# -# UBI debugging options -# -CONFIG_MTD_UBI_DEBUG=y -# CONFIG_MTD_UBI_DEBUG_MSG is not set -CONFIG_MTD_UBI_DEBUG_PARANOID=y -# CONFIG_MTD_UBI_DEBUG_DISABLE_BGT is not set -# CONFIG_MTD_UBI_DEBUG_EMULATE_BITFLIPS is not set -# CONFIG_MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES is not set -# CONFIG_MTD_UBI_DEBUG_EMULATE_ERASE_FAILURES is not set - -# -# Additional UBI debugging messages -# -# CONFIG_MTD_UBI_DEBUG_MSG_BLD is not set -# CONFIG_MTD_UBI_DEBUG_MSG_EBA is not set -# CONFIG_MTD_UBI_DEBUG_MSG_WL is not set -# CONFIG_MTD_UBI_DEBUG_MSG_IO is not set -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_MG_DISK is not set -# CONFIG_MISC_DEVICES is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_SCSI_PROC_FS is not set - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=m -# CONFIG_BLK_DEV_SR_VENDOR is not set -CONFIG_CHR_DEV_SG=m -# CONFIG_CHR_DEV_SCH is not set -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_SCSI_BNX2_ISCSI is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_MVSAS is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_MPT2SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_LIBFC is not set -# CONFIG_LIBFCOE is not set -# CONFIG_FCOE is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_SRP is not set -# CONFIG_SCSI_DH is not set -# CONFIG_SCSI_OSD_INITIATOR is not set -CONFIG_ATA=y -# CONFIG_ATA_NONSTANDARD is not set -CONFIG_SATA_PMP=y -CONFIG_SATA_AHCI=y -# CONFIG_SATA_SIL24 is not set -CONFIG_ATA_SFF=y -# CONFIG_SATA_SVW is not set -# CONFIG_ATA_PIIX is not set -CONFIG_SATA_MV=y -# CONFIG_SATA_NV is not set -# CONFIG_PDC_ADMA is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_SX4 is not set -# CONFIG_SATA_SIL is not set -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_ULI is not set -# CONFIG_SATA_VIA is not set -# CONFIG_SATA_VITESSE is not set -# CONFIG_SATA_INIC162X is not set -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_CMD640_PCI is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_ATA_GENERIC is not set -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_IT8213 is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_MARVELL is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NINJA32 is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_NS87415 is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RZ1000 is not set -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set -# CONFIG_PATA_SCH is not set -# CONFIG_MD is not set -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# You can enable one or both FireWire driver stacks. -# - -# -# See the help texts for more information. -# -# CONFIG_FIREWIRE is not set -# CONFIG_IEEE1394 is not set -# CONFIG_I2O is not set -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_VETH is not set -# CONFIG_ARCNET is not set -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -CONFIG_MARVELL_PHY=y -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_NATIONAL_PHY is not set -# CONFIG_STE10XP is not set -# CONFIG_LSI_ET1011C_PHY is not set -# CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_AX88796 is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_SMC91X is not set -# CONFIG_DM9000 is not set -# CONFIG_ENC28J60 is not set -# CONFIG_ETHOC is not set -# CONFIG_SMC911X is not set -# CONFIG_SMSC911X is not set -# CONFIG_DNET is not set -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set -# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set -# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_E100 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_R6040 is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SMSC9420 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_KS8842 is not set -# CONFIG_KS8851 is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_SC92031 is not set -# CONFIG_ATL2 is not set -CONFIG_NETDEV_1000=y -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_E1000E is not set -# CONFIG_IP1000 is not set -# CONFIG_IGB is not set -# CONFIG_IGBVF is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -# CONFIG_CNIC is not set -CONFIG_MV643XX_ETH=y -# CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set -# CONFIG_ATL1E is not set -# CONFIG_ATL1C is not set -# CONFIG_JME is not set -# CONFIG_NETDEV_10000 is not set -# CONFIG_TR is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -CONFIG_WLAN_80211=y -CONFIG_LIBERTAS=y -# CONFIG_LIBERTAS_USB is not set -CONFIG_LIBERTAS_SDIO=y -# CONFIG_LIBERTAS_SPI is not set -# CONFIG_LIBERTAS_DEBUG is not set -# CONFIG_LIBERTAS_THINFIRM is not set -# CONFIG_ATMEL is not set -# CONFIG_AT76C50X_USB is not set -# CONFIG_PRISM54 is not set -# CONFIG_USB_ZD1201 is not set -# CONFIG_USB_NET_RNDIS_WLAN is not set -# CONFIG_RTL8180 is not set -# CONFIG_RTL8187 is not set -# CONFIG_ADM8211 is not set -# CONFIG_MAC80211_HWSIM is not set -# CONFIG_MWL8K is not set -# CONFIG_P54_COMMON is not set -# CONFIG_ATH5K is not set -# CONFIG_ATH9K is not set -# CONFIG_AR9170_USB is not set -# CONFIG_IPW2100 is not set -# CONFIG_IPW2200 is not set -# CONFIG_IWLWIFI is not set -# CONFIG_HOSTAP is not set -# CONFIG_B43 is not set -# CONFIG_B43LEGACY is not set -# CONFIG_ZD1211RW is not set -# CONFIG_RT2X00 is not set -# CONFIG_HERMES is not set -# CONFIG_WL12XX is not set -# CONFIG_IWM is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_LKKBD is not set -CONFIG_KEYBOARD_GPIO=y -# CONFIG_KEYBOARD_MATRIX is not set -# CONFIG_KEYBOARD_LM8323 is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_PCIPS2 is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -# CONFIG_DEVKMEM is not set -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_NOZOMI is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_MAX3100 is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=16 -# CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -CONFIG_DEVPORT=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_HELPER_AUTO=y - -# -# I2C Hardware Bus support -# - -# -# PC SMBus host controller drivers -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_ISCH is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -# CONFIG_I2C_GPIO is not set -CONFIG_I2C_MV64XXX=y -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_SIMTEC is not set - -# -# External I2C/SMBus adapter drivers -# -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_TINY_USB is not set - -# -# Graphics adapter I2C/DDC channel drivers -# -# CONFIG_I2C_VOODOO3 is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_DS1682 is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set -CONFIG_SPI=y -# CONFIG_SPI_DEBUG is not set -CONFIG_SPI_MASTER=y - -# -# SPI Master Controller Drivers -# -# CONFIG_SPI_BITBANG is not set -# CONFIG_SPI_GPIO is not set -CONFIG_SPI_ORION=y - -# -# SPI Protocol Masters -# -# CONFIG_SPI_SPIDEV is not set -# CONFIG_SPI_TLE62X0 is not set -CONFIG_ARCH_REQUIRE_GPIOLIB=y -CONFIG_GPIOLIB=y -# CONFIG_DEBUG_GPIO is not set -# CONFIG_GPIO_SYSFS is not set - -# -# Memory mapped GPIO expanders: -# - -# -# I2C GPIO expanders: -# -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_PCA953X is not set -# CONFIG_GPIO_PCF857X is not set - -# -# PCI GPIO expanders: -# -# CONFIG_GPIO_BT8XX is not set - -# -# SPI GPIO expanders: -# -# CONFIG_GPIO_MAX7301 is not set -# CONFIG_GPIO_MCP23S08 is not set -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_HWMON is not set -# CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set -# CONFIG_WATCHDOG is not set -CONFIG_SSB_POSSIBLE=y - -# -# Sonics Silicon Backplane -# -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_MFD_ASIC3 is not set -# CONFIG_HTC_EGPIO is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_TPS65010 is not set -# CONFIG_TWL4030_CORE is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_MFD_TC6393XB is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_PCF50633 is not set -# CONFIG_AB3100_CORE is not set -# CONFIG_EZX_PCAP is not set -# CONFIG_MEDIA_SUPPORT is not set - -# -# Graphics support -# -# CONFIG_DRM is not set -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -# CONFIG_SOUND is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_HID_PID is not set -# CONFIG_USB_HIDDEV is not set - -# -# Special HID drivers -# -CONFIG_HID_A4TECH=y -CONFIG_HID_APPLE=y -CONFIG_HID_BELKIN=y -CONFIG_HID_CHERRY=y -CONFIG_HID_CHICONY=y -CONFIG_HID_CYPRESS=y -CONFIG_HID_DRAGONRISE=y -# CONFIG_DRAGONRISE_FF is not set -CONFIG_HID_EZKEY=y -CONFIG_HID_KYE=y -CONFIG_HID_GYRATION=y -CONFIG_HID_KENSINGTON=y -CONFIG_HID_LOGITECH=y -# CONFIG_LOGITECH_FF is not set -# CONFIG_LOGIRUMBLEPAD2_FF is not set -CONFIG_HID_MICROSOFT=y -CONFIG_HID_MONTEREY=y -CONFIG_HID_NTRIG=y -CONFIG_HID_PANTHERLORD=y -# CONFIG_PANTHERLORD_FF is not set -CONFIG_HID_PETALYNX=y -CONFIG_HID_SAMSUNG=y -CONFIG_HID_SONY=y -CONFIG_HID_SUNPLUS=y -CONFIG_HID_GREENASIA=y -# CONFIG_GREENASIA_FF is not set -CONFIG_HID_SMARTJOYPLUS=y -# CONFIG_SMARTJOYPLUS_FF is not set -CONFIG_HID_TOPSEED=y -CONFIG_HID_THRUSTMASTER=y -# CONFIG_THRUSTMASTER_FF is not set -CONFIG_HID_ZEROPLUS=y -# CONFIG_ZEROPLUS_FF is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -CONFIG_USB_DEVICE_CLASS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set -# CONFIG_USB_MON is not set -# CONFIG_USB_WUSB is not set -# CONFIG_USB_WUSB_CBAF is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -# CONFIG_USB_XHCI_HCD is not set -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_EHCI_TT_NEWSCHED=y -# CONFIG_USB_OXU210HP_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1760_HCD is not set -# CONFIG_USB_OHCI_HCD is not set -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_WHCI_HCD is not set -# CONFIG_USB_HWA_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -CONFIG_USB_PRINTER=m -# CONFIG_USB_WDM is not set -# CONFIG_USB_TMC is not set - -# -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may -# - -# -# also be needed; see USB_STORAGE Help for more info -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -CONFIG_USB_STORAGE_DATAFAB=y -CONFIG_USB_STORAGE_FREECOM=y -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_USBAT is not set -CONFIG_USB_STORAGE_SDDR09=y -CONFIG_USB_STORAGE_SDDR55=y -CONFIG_USB_STORAGE_JUMPSHOT=y -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB port drivers -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_SEVSEG is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set -# CONFIG_USB_GADGET is not set - -# -# OTG and related infrastructure -# -# CONFIG_USB_GPIO_VBUS is not set -# CONFIG_NOP_USB_XCEIV is not set -# CONFIG_UWB is not set -CONFIG_MMC=y -# CONFIG_MMC_DEBUG is not set -# CONFIG_MMC_UNSAFE_RESUME is not set - -# -# MMC/SD/SDIO Card Drivers -# -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_BOUNCE=y -CONFIG_SDIO_UART=y -# CONFIG_MMC_TEST is not set - -# -# MMC/SD/SDIO Host Controller Drivers -# -# CONFIG_MMC_SDHCI is not set -# CONFIG_MMC_TIFM_SD is not set -CONFIG_MMC_MVSDIO=y -# CONFIG_MMC_SPI is not set -# CONFIG_MMC_CB710 is not set -# CONFIG_MMC_VIA_SDMMC is not set -# CONFIG_MEMSTICK is not set -# CONFIG_ACCESSIBILITY is not set -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y - -# -# LED drivers -# -# CONFIG_LEDS_PCA9532 is not set -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_GPIO_PLATFORM=y -# CONFIG_LEDS_LP3944 is not set -# CONFIG_LEDS_PCA955X is not set -# CONFIG_LEDS_DAC124S085 is not set -# CONFIG_LEDS_BD2802 is not set - -# -# LED Triggers -# -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set -# CONFIG_LEDS_TRIGGER_GPIO is not set -CONFIG_LEDS_TRIGGER_DEFAULT_ON=y - -# -# iptables trigger is under Netfilter config (LED target) -# -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -CONFIG_RTC_DRV_S35390A=y -# CONFIG_RTC_DRV_FM3130 is not set -# CONFIG_RTC_DRV_RX8581 is not set -# CONFIG_RTC_DRV_RX8025 is not set - -# -# SPI RTC drivers -# -# CONFIG_RTC_DRV_M41T94 is not set -# CONFIG_RTC_DRV_DS1305 is not set -# CONFIG_RTC_DRV_DS1390 is not set -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_R9701 is not set -# CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_DS3234 is not set - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -CONFIG_RTC_DRV_MV=y -CONFIG_DMADEVICES=y - -# -# DMA Devices -# -CONFIG_MV_XOR=y -CONFIG_DMA_ENGINE=y - -# -# DMA Clients -# -# CONFIG_NET_DMA is not set -# CONFIG_ASYNC_TX_DMA is not set -# CONFIG_DMATEST is not set -# CONFIG_AUXDISPLAY is not set -# CONFIG_REGULATOR is not set -# CONFIG_UIO is not set -# CONFIG_STAGING is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -# CONFIG_EXT3_FS_XATTR is not set -# CONFIG_EXT4_FS is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_BTRFS_FS is not set -CONFIG_FILE_LOCKING=y -CONFIG_FSNOTIFY=y -CONFIG_DNOTIFY=y -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# Caches -# -# CONFIG_FSCACHE is not set - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -# CONFIG_ZISOFS is not set -CONFIG_UDF_FS=m -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set -CONFIG_MISC_FILESYSTEMS=y -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_FS_XATTR is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -# CONFIG_JFFS2_LZO is not set -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -# CONFIG_UBIFS_FS is not set -CONFIG_CRAMFS=y -CONFIG_SQUASHFS=y -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -# CONFIG_NILFS2_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -CONFIG_ROOT_NFS=y -# CONFIG_NFSD is not set -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -CONFIG_NLS_CODEPAGE_850=y -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_ISO8859_2=y -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -CONFIG_NLS_UTF8=y -# CONFIG_DLM is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -CONFIG_DETECT_HUNG_TASK=y -# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set -CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 -# CONFIG_SCHED_DEBUG is not set -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_SLUB_DEBUG_ON is not set -# CONFIG_SLUB_STATS is not set -# CONFIG_DEBUG_KMEMLEAK is not set -# CONFIG_DEBUG_PREEMPT is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_LOCK_STAT is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -CONFIG_STACKTRACE=y -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -CONFIG_DEBUG_MEMORY_INIT=y -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -# CONFIG_KPROBES_SANITY_TEST is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_LKDTM is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_LATENCYTOP is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y -# CONFIG_PAGE_POISONING is not set -CONFIG_NOP_TRACER=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_CONTEXT_SWITCH_TRACER=y -CONFIG_TRACING=y -CONFIG_TRACING_SUPPORT=y -CONFIG_FTRACE=y -# CONFIG_FUNCTION_TRACER is not set -# CONFIG_IRQSOFF_TRACER is not set -# CONFIG_PREEMPT_TRACER is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_ENABLE_DEFAULT_TRACERS is not set -# CONFIG_BOOT_TRACER is not set -CONFIG_BRANCH_PROFILE_NONE=y -# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_PROFILE_ALL_BRANCHES is not set -# CONFIG_STACK_TRACER is not set -# CONFIG_KMEMTRACE is not set -# CONFIG_WORKQUEUE_TRACER is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_RING_BUFFER_BENCHMARK is not set -# CONFIG_DYNAMIC_DEBUG is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -CONFIG_ARM_UNWIND=y -CONFIG_DEBUG_USER=y -CONFIG_DEBUG_ERRORS=y -# CONFIG_DEBUG_STACK_USAGE is not set -CONFIG_DEBUG_LL=y -# CONFIG_DEBUG_ICEDCC is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -# CONFIG_CRYPTO_FIPS is not set -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_PCOMP=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -CONFIG_CRYPTO_WORKQUEUE=y -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -CONFIG_CRYPTO_CBC=m -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -CONFIG_CRYPTO_ECB=y -# CONFIG_CRYPTO_LRW is not set -CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set - -# -# Digest -# -CONFIG_CRYPTO_CRC32C=y -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_RMD128 is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -CONFIG_CRYPTO_AES=y -# CONFIG_CRYPTO_ANUBIS is not set -CONFIG_CRYPTO_ARC4=y -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_ZLIB is not set -# CONFIG_CRYPTO_LZO is not set - -# -# Random Number Generation -# -# CONFIG_CRYPTO_ANSI_CPRNG is not set -CONFIG_CRYPTO_HW=y -# CONFIG_CRYPTO_DEV_HIFN_795X is not set -CONFIG_BINARY_PRINTF=y - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_GENERIC_FIND_LAST_BIT=y -CONFIG_CRC_CCITT=y -CONFIG_CRC16=y -# CONFIG_CRC_T10DIF is not set -CONFIG_CRC_ITU_T=m -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -CONFIG_LIBCRC32C=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_NLATTR=y diff --git a/recipes/linux/linux-kirkwood_2.6.31.bb b/recipes/linux/linux-kirkwood_2.6.31.bb new file mode 100644 index 0000000000..b8270ed597 --- /dev/null +++ b/recipes/linux/linux-kirkwood_2.6.31.bb @@ -0,0 +1,33 @@ +DESCRIPTION = "Linux Kernel for Marvell Kirkwood based devices" +SECTION = "kernel" +LICENSE = "GPL" + +COMPATIBLE_MACHINE = "openrd-base" + +# SheevaPlug still needs testing +#COMPATIBLE_MACHINE = "(openrd-base|sheevaplug)" + +require linux.inc + +# Change MACHINE_KERNEL_PR in conf/machine/include/kirkwood.inc +PV = "2.6.31" + +# last commit at the time of release of upstream v2.6.31 +SRCREV = "8cb424312d88810bb62edbeef42a510725ceb482" + +SRC_URI = "git://git.marvell.com/orion.git;protocol=git \ + file://defconfig" + +# update machine types list for ARM architecture, only for machines that need it +do_arm_mach_types_openrd-base() { + if test ${TARGET_ARCH} == arm; then + curl -o mach-types "http://www.arm.linux.org.uk/developer/machines/download.php" && \ + cp mach-types arch/arm/tools/mach-types + fi +} + +addtask arm_mach_types after do_patch before do_configure + +S = "${WORKDIR}/git" + +KERNEL_IMAGETYPE ?= "uImage" -- cgit v1.2.3 From 86d4dd34f8d4ca060a1e11a8bf1b7d5ad0f76d5e Mon Sep 17 00:00:00 2001 From: Michael 'Mickey' Lauer Date: Sat, 19 Sep 2009 14:24:04 +0000 Subject: vala 0.7.6: make it build --- recipes/vala/vala_0.7.6-fso2.bb | 2 -- 1 file changed, 2 deletions(-) diff --git a/recipes/vala/vala_0.7.6-fso2.bb b/recipes/vala/vala_0.7.6-fso2.bb index fff355ebaf..7960e624b2 100644 --- a/recipes/vala/vala_0.7.6-fso2.bb +++ b/recipes/vala/vala_0.7.6-fso2.bb @@ -1,6 +1,4 @@ require vala.inc -VALA_FSO_RELEASE = "0.7.5-fso2" -PV = "0.7.4+${VALA_FSO_RELEASE}" PR = "${INC_PR}.0" -- cgit v1.2.3 From bdd37476c0a55d39013e3eb615900606daa2c1e2 Mon Sep 17 00:00:00 2001 From: Stanislav Brabec Date: Sat, 19 Sep 2009 14:30:56 +0000 Subject: audiofile: Security fix CVE-2008-5824, coding style fixes from openSUSE, recipe simplified. --- .../audiofile/audiofile-0.2.6/CVE-2008-5824.patch | 23 ++++++++ .../audiofile-0.2.6/audiofile-0.2.6.patch | 67 ++++++++++++++++++++++ .../audiofile-0.2.6/audiofile-m4_quote_fix.diff | 11 ++++ .../audiofile-0.2.6/audiofile-oldstyle.patch | 55 ++++++++++++++++++ recipes/audiofile/audiofile_0.2.6.bb | 22 +++---- 5 files changed, 164 insertions(+), 14 deletions(-) create mode 100644 recipes/audiofile/audiofile-0.2.6/CVE-2008-5824.patch create mode 100644 recipes/audiofile/audiofile-0.2.6/audiofile-0.2.6.patch create mode 100644 recipes/audiofile/audiofile-0.2.6/audiofile-m4_quote_fix.diff create mode 100644 recipes/audiofile/audiofile-0.2.6/audiofile-oldstyle.patch diff --git a/recipes/audiofile/audiofile-0.2.6/CVE-2008-5824.patch b/recipes/audiofile/audiofile-0.2.6/CVE-2008-5824.patch new file mode 100644 index 0000000000..31233d22b3 --- /dev/null +++ b/recipes/audiofile/audiofile-0.2.6/CVE-2008-5824.patch @@ -0,0 +1,23 @@ +diff -Naur audiofile-0.2.6/libaudiofile/modules/msadpcm.c audiofile-0.2.6-mp/libaudiofile/modules/msadpcm.c +--- audiofile-0.2.6/libaudiofile/modules/msadpcm.c 2004-03-06 07:39:23.000000000 +0100 ++++ audiofile-0.2.6-mp/libaudiofile/modules/msadpcm.c 2009-01-20 20:05:14.919961000 +0100 +@@ -129,8 +129,7 @@ + ms_adpcm_state *state[2]; + + /* Calculate the number of bytes needed for decoded data. */ +- outputLength = msadpcm->samplesPerBlock * sizeof (int16_t) * +- msadpcm->track->f.channelCount; ++ outputLength = msadpcm->samplesPerBlock * sizeof (int16_t); + + channelCount = msadpcm->track->f.channelCount; + +@@ -180,8 +179,7 @@ + The first two samples have already been 'decoded' in + the block header. + */ +- samplesRemaining = (msadpcm->samplesPerBlock - 2) * +- msadpcm->track->f.channelCount; ++ samplesRemaining = msadpcm->samplesPerBlock - 2; + + while (samplesRemaining > 0) + { diff --git a/recipes/audiofile/audiofile-0.2.6/audiofile-0.2.6.patch b/recipes/audiofile/audiofile-0.2.6/audiofile-0.2.6.patch new file mode 100644 index 0000000000..b73db7efdd --- /dev/null +++ b/recipes/audiofile/audiofile-0.2.6/audiofile-0.2.6.patch @@ -0,0 +1,67 @@ +--- test/instparamtest.c ++++ test/instparamtest.c +@@ -74,4 +74,5 @@ + printf("release loop id: %ld\n", result); + + afCloseFile(file); ++ return 0; + } +--- test/instparamwrite.c ++++ test/instparamwrite.c +@@ -52,4 +52,5 @@ + afSetInstParamLong(file, AF_DEFAULT_INST, AF_INST_NUMCENTS_DETUNE, -30); + + afCloseFile(file); ++ return 0; + } +--- test/loop.c ++++ test/loop.c +@@ -34,4 +34,5 @@ + afSetLoopEnd(file, AF_DEFAULT_INST, 2, 4); + + afCloseFile(file); ++ return 0; + } +--- test/twentyfour.c.xx 2005-09-16 22:38:59.000000000 +0200 ++++ test/twentyfour.c 2005-09-16 22:39:53.000000000 +0200 +@@ -36,7 +36,9 @@ + #endif + + #include ++#include + #include ++#include + #include + #include + +--- test/pipe.c.xx 2005-09-16 22:39:36.000000000 +0200 ++++ test/pipe.c 2005-09-16 22:39:42.000000000 +0200 +@@ -36,6 +36,7 @@ + + #include + #include ++#include + #include + + #define SAMPLE_COUNT 12 +--- test/error.c.xx 2005-09-16 22:40:02.000000000 +0200 ++++ test/error.c 2005-09-16 22:40:11.000000000 +0200 +@@ -25,6 +25,7 @@ + + #include + #include ++#include + #include + + int expectedError; +--- test/testmarkers.c.xx 2005-09-16 22:40:21.000000000 +0200 ++++ test/testmarkers.c 2005-09-16 22:40:41.000000000 +0200 +@@ -25,6 +25,8 @@ + + #include + #include ++#include ++#include + #include + #include + diff --git a/recipes/audiofile/audiofile-0.2.6/audiofile-m4_quote_fix.diff b/recipes/audiofile/audiofile-0.2.6/audiofile-m4_quote_fix.diff new file mode 100644 index 0000000000..1c02bf86ea --- /dev/null +++ b/recipes/audiofile/audiofile-0.2.6/audiofile-m4_quote_fix.diff @@ -0,0 +1,11 @@ +--- audiofile.m4 ++++ audiofile.m4 +@@ -9,7 +9,7 @@ + dnl AM_PATH_AUDIOFILE([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) + dnl Test for Audio File Library, and define AUDIOFILE_CFLAGS and AUDIOFILE_LIBS. + dnl +-AC_DEFUN(AM_PATH_AUDIOFILE, ++AC_DEFUN([AM_PATH_AUDIOFILE], + [dnl + dnl Get compiler flags and libraries from the audiofile-config script. + dnl diff --git a/recipes/audiofile/audiofile-0.2.6/audiofile-oldstyle.patch b/recipes/audiofile/audiofile-0.2.6/audiofile-oldstyle.patch new file mode 100644 index 0000000000..1b21150d8c --- /dev/null +++ b/recipes/audiofile/audiofile-0.2.6/audiofile-oldstyle.patch @@ -0,0 +1,55 @@ +--- libaudiofile/g711.c ++++ libaudiofile/g711.c +@@ -81,10 +81,7 @@ + 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF}; + + static int +-search(val, table, size) +- int val; +- short *table; +- int size; ++search(int val, short int *table, int size) + { + int i; + +@@ -115,8 +112,8 @@ + * John Wiley & Sons, pps 98-111 and 472-476. + */ + unsigned char +-_af_linear2alaw(pcm_val) +- int pcm_val; /* 2's complement (16-bit range) */ ++_af_linear2alaw(int pcm_val) ++ /* 2's complement (16-bit range) */ + { + int mask; + int seg; +@@ -151,8 +148,7 @@ + * + */ + int +-_af_alaw2linear(a_val) +- unsigned char a_val; ++_af_alaw2linear(unsigned char a_val) + { + int t; + int seg; +@@ -269,8 +265,7 @@ + + /* A-law to u-law conversion */ + static unsigned char +-alaw2ulaw(aval) +- unsigned char aval; ++alaw2ulaw(unsigned char aval) + { + aval &= 0xff; + return ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) : +@@ -279,8 +274,7 @@ + + /* u-law to A-law conversion */ + static unsigned char +-ulaw2alaw(uval) +- unsigned char uval; ++ulaw2alaw(unsigned char uval) + { + uval &= 0xff; + return ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) : diff --git a/recipes/audiofile/audiofile_0.2.6.bb b/recipes/audiofile/audiofile_0.2.6.bb index 64a078c43b..d3f5078d4a 100644 --- a/recipes/audiofile/audiofile_0.2.6.bb +++ b/recipes/audiofile/audiofile_0.2.6.bb @@ -5,19 +5,13 @@ Research, Amiga IFF/8SVX, and NIST SPHERE." SECTION = "libs" LICENSE = "LGPL GPL" RPROVIDES_${PN} += "audiofile" -PR = "r6" +PR = "r7" -SRC_URI = "http://www.68k.org/~michael/audiofile/audiofile-${PV}.tar.gz" +SRC_URI = "http://www.68k.org/~michael/audiofile/audiofile-${PV}.tar.gz \ + file://audiofile-m4_quote_fix.diff;patch=1;pnum=0 \ + file://audiofile-oldstyle.patch;patch=1;pnum=0 \ + file://audiofile-0.2.6.patch;patch=1;pnum=0 \ + file://CVE-2008-5824.patch;patch=1 \ +" -inherit autotools pkgconfig binconfig - -do_stage () { - install -m 0644 libaudiofile/audiofile.h libaudiofile/aupvlist.h libaudiofile/af_vfs.h ${STAGING_INCDIR}/ - oe_libinstall -C libaudiofile libaudiofile ${STAGING_LIBDIR} - install -m 0644 audiofile.m4 ${STAGING_DATADIR}/aclocal/ -} - -PACKAGES += "${PN}-bin" -FILES_${PN} = "${libdir}/libaudiofile*.so.*" -FILES_${PN}-dev += "${bindir}/*-config" -FILES_${PN}-bin += "${bindir}" +inherit autotools lib_package -- cgit v1.2.3 From e5fc5e963f4c15d7e2e921ed2d24ff68bba3b2b3 Mon Sep 17 00:00:00 2001 From: Leon Woestenberg Date: Sat, 19 Sep 2009 18:12:15 +0200 Subject: linux-kirkwood-2.6.31: Fetch newer mach-types for MACHINE openrd-base only. Signed-off-by: Leon Woestenberg --- recipes/linux/linux-kirkwood_2.6.31.bb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/recipes/linux/linux-kirkwood_2.6.31.bb b/recipes/linux/linux-kirkwood_2.6.31.bb index b8270ed597..a40a09e49a 100644 --- a/recipes/linux/linux-kirkwood_2.6.31.bb +++ b/recipes/linux/linux-kirkwood_2.6.31.bb @@ -19,8 +19,8 @@ SRC_URI = "git://git.marvell.com/orion.git;protocol=git \ file://defconfig" # update machine types list for ARM architecture, only for machines that need it -do_arm_mach_types_openrd-base() { - if test ${TARGET_ARCH} == arm; then +do_arm_mach_types() { + if test ${MACHINE} == openrd-base; then curl -o mach-types "http://www.arm.linux.org.uk/developer/machines/download.php" && \ cp mach-types arch/arm/tools/mach-types fi -- cgit v1.2.3 From 122d4d8bd65b4685c948f5cd9017ed92b995fb6d Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Sat, 19 Sep 2009 10:07:19 -0700 Subject: uclibc-initial-0.9.30: Fix a typo, install_headers not install-headers --- recipes/uclibc/uclibc-initial_0.9.30.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/uclibc/uclibc-initial_0.9.30.bb b/recipes/uclibc/uclibc-initial_0.9.30.bb index 9fcb247f61..7d8c9c037f 100644 --- a/recipes/uclibc/uclibc-initial_0.9.30.bb +++ b/recipes/uclibc/uclibc-initial_0.9.30.bb @@ -9,7 +9,7 @@ do_stage() { # Install initial headers into the cross dir make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ RUNTIME_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ - install-headers + install_headers ln -sf include ${CROSS_DIR}/${TARGET_SYS}/sys-include -- cgit v1.2.3 From 7692feb4df88f6ed5c72a7f69d6c4346ba03c5db Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Sat, 19 Sep 2009 11:30:42 -0700 Subject: uclibc-0.9.30: We need the __always_inline__ patch, bump PR. Also move the patch into files dir. This probably applies to other older versions as well. --- ...Use-__always_inline-instead-of-__inline__.patch | 393 +++++++++++++++++++++ ...Use-__always_inline-instead-of-__inline__.patch | 393 --------------------- recipes/uclibc/uclibc_0.9.30.1.bb | 2 +- recipes/uclibc/uclibc_0.9.30.bb | 3 +- 4 files changed, 396 insertions(+), 395 deletions(-) create mode 100644 recipes/uclibc/files/Use-__always_inline-instead-of-__inline__.patch delete mode 100644 recipes/uclibc/uclibc-0.9.30.1/0001-Use-__always_inline-instead-of-__inline__.patch diff --git a/recipes/uclibc/files/Use-__always_inline-instead-of-__inline__.patch b/recipes/uclibc/files/Use-__always_inline-instead-of-__inline__.patch new file mode 100644 index 0000000000..a9c7a4fb10 --- /dev/null +++ b/recipes/uclibc/files/Use-__always_inline-instead-of-__inline__.patch @@ -0,0 +1,393 @@ +From c190f738e1b0e87658ea5f86c057fb147dc19428 Mon Sep 17 00:00:00 2001 +From: Carmelo Amoroso +Date: Thu, 5 Mar 2009 13:28:55 +0000 +Subject: [PATCH] Use __always_inline instead of __inline__ + +--- + ldso/ldso/arm/dl-sysdep.h | 8 ++++---- + ldso/ldso/bfin/dl-sysdep.h | 2 +- + ldso/ldso/cris/dl-sysdep.h | 6 +++--- + ldso/ldso/i386/dl-sysdep.h | 10 +++++----- + ldso/ldso/m68k/dl-sysdep.h | 6 +++--- + ldso/ldso/mips/dl-sysdep.h | 8 ++++---- + ldso/ldso/powerpc/dl-sysdep.h | 8 ++++---- + ldso/ldso/sh/dl-sysdep.h | 8 ++++---- + ldso/ldso/sh64/dl-sysdep.h | 6 +++--- + ldso/ldso/sparc/dl-sysdep.h | 8 ++++---- + ldso/ldso/xtensa/dl-sysdep.h | 6 +++--- + 11 files changed, 38 insertions(+), 38 deletions(-) + +diff --git a/ldso/ldso/arm/dl-sysdep.h b/ldso/ldso/arm/dl-sysdep.h +index eea3b98..5191dd7 100644 +--- a/ldso/ldso/arm/dl-sysdep.h ++++ b/ldso/ldso/arm/dl-sysdep.h +@@ -15,7 +15,7 @@ + GOT_BASE[1] = (unsigned long) MODULE; \ + } + +-static __inline__ unsigned long arm_modulus(unsigned long m, unsigned long p) ++static __always_inline unsigned long arm_modulus(unsigned long m, unsigned long p) + { + unsigned long i,t,inc; + i=p; t=0; +@@ -67,7 +67,7 @@ unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); + first element of the GOT. We used to use the PIC register to do this + without a constant pool reference, but GCC 4.2 will use a pseudo-register + for the PIC base, so it may not be in r10. */ +-static __inline__ Elf32_Addr __attribute__ ((unused)) ++static __always_inline Elf32_Addr __attribute__ ((unused)) + elf_machine_dynamic (void) + { + Elf32_Addr dynamic; +@@ -99,7 +99,7 @@ elf_machine_dynamic (void) + } + + /* Return the run-time load address of the shared object. */ +-static __inline__ Elf32_Addr __attribute__ ((unused)) ++static __always_inline Elf32_Addr __attribute__ ((unused)) + elf_machine_load_address (void) + { + extern void __dl_start __asm__ ("_dl_start"); +@@ -123,7 +123,7 @@ elf_machine_load_address (void) + return pcrel_addr - got_addr; + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +diff --git a/ldso/ldso/bfin/dl-sysdep.h b/ldso/ldso/bfin/dl-sysdep.h +index 3c88da4..f0c5129 100644 +--- a/ldso/ldso/bfin/dl-sysdep.h ++++ b/ldso/ldso/bfin/dl-sysdep.h +@@ -210,7 +210,7 @@ while (0) + #endif + + #include +-static __inline__ void ++static __always_inline void + elf_machine_relative (DL_LOADADDR_TYPE load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +diff --git a/ldso/ldso/cris/dl-sysdep.h b/ldso/ldso/cris/dl-sysdep.h +index ffb763a..e454c10 100644 +--- a/ldso/ldso/cris/dl-sysdep.h ++++ b/ldso/ldso/cris/dl-sysdep.h +@@ -37,7 +37,7 @@ extern unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entr + || ((type) == R_CRIS_GLOB_DAT)) * ELF_RTYPE_CLASS_PLT) \ + | (((type) == R_CRIS_COPY) * ELF_RTYPE_CLASS_COPY)) + +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr + elf_machine_dynamic(void) + { + /* Don't just set this to an asm variable "r0" since that's not logical +@@ -59,7 +59,7 @@ elf_machine_dynamic(void) + there's some other symbol we could use, that we don't *have* to force a + GOT entry for. */ + +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr + elf_machine_load_address(void) + { + Elf32_Addr gotaddr_diff; +@@ -93,7 +93,7 @@ elf_machine_load_address(void) + return gotaddr_diff; + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative(Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +diff --git a/ldso/ldso/i386/dl-sysdep.h b/ldso/ldso/i386/dl-sysdep.h +index 77fa372..6e84861 100644 +--- a/ldso/ldso/i386/dl-sysdep.h ++++ b/ldso/ldso/i386/dl-sysdep.h +@@ -37,8 +37,8 @@ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_ent + /* Return the link-time address of _DYNAMIC. Conveniently, this is the + first element of the GOT. This must be inlined in a function which + uses global data. */ +-static __inline__ Elf32_Addr elf_machine_dynamic (void) attribute_unused; +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr elf_machine_dynamic (void) attribute_unused; ++static __always_inline Elf32_Addr + elf_machine_dynamic (void) + { + register Elf32_Addr *got __asm__ ("%ebx"); +@@ -47,8 +47,8 @@ elf_machine_dynamic (void) + + + /* Return the run-time load address of the shared object. */ +-static __inline__ Elf32_Addr elf_machine_load_address (void) attribute_unused; +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr elf_machine_load_address (void) attribute_unused; ++static __always_inline Elf32_Addr + elf_machine_load_address (void) + { + /* It doesn't matter what variable this is, the reference never makes +@@ -61,7 +61,7 @@ elf_machine_load_address (void) + return addr; + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +diff --git a/ldso/ldso/m68k/dl-sysdep.h b/ldso/ldso/m68k/dl-sysdep.h +index 8e26e20..259cb84 100644 +--- a/ldso/ldso/m68k/dl-sysdep.h ++++ b/ldso/ldso/m68k/dl-sysdep.h +@@ -39,7 +39,7 @@ extern unsigned long _dl_linux_resolver (struct elf_resolve *, int); + /* Return the link-time address of _DYNAMIC. Conveniently, this is the + first element of the GOT. This must be inlined in a function which + uses global data. */ +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr + elf_machine_dynamic (void) + { + register Elf32_Addr *got __asm__ ("%a5"); +@@ -48,7 +48,7 @@ elf_machine_dynamic (void) + + + /* Return the run-time load address of the shared object. */ +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr + elf_machine_load_address (void) + { + Elf32_Addr addr; +@@ -58,7 +58,7 @@ elf_machine_load_address (void) + return addr; + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +diff --git a/ldso/ldso/mips/dl-sysdep.h b/ldso/ldso/mips/dl-sysdep.h +index cf6b28b..30d84fb 100644 +--- a/ldso/ldso/mips/dl-sysdep.h ++++ b/ldso/ldso/mips/dl-sysdep.h +@@ -169,7 +169,7 @@ void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy) + + #define OFFSET_GP_GOT 0x7ff0 + +-static __inline__ ElfW(Addr) * ++static __always_inline ElfW(Addr) * + elf_mips_got_from_gpreg (ElfW(Addr) gpreg) + { + /* FIXME: the offset of gp from GOT may be system-dependent. */ +@@ -179,7 +179,7 @@ elf_mips_got_from_gpreg (ElfW(Addr) gpreg) + /* Return the link-time address of _DYNAMIC. Conveniently, this is the + first element of the GOT. This must be inlined in a function which + uses global data. We assume its $gp points to the primary GOT. */ +-static __inline__ ElfW(Addr) ++static __always_inline ElfW(Addr) + elf_machine_dynamic (void) + { + register ElfW(Addr) gp __asm__ ("$28"); +@@ -198,7 +198,7 @@ elf_machine_dynamic (void) + #endif + + /* Return the run-time load address of the shared object. */ +-static __inline__ ElfW(Addr) ++static __always_inline ElfW(Addr) + elf_machine_load_address (void) + { + ElfW(Addr) addr; +@@ -214,7 +214,7 @@ elf_machine_load_address (void) + return addr; + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative (ElfW(Addr) load_off, const ElfW(Addr) rel_addr, + ElfW(Word) relative_count) + { +diff --git a/ldso/ldso/powerpc/dl-sysdep.h b/ldso/ldso/powerpc/dl-sysdep.h +index fdbf564..f33214c 100644 +--- a/ldso/ldso/powerpc/dl-sysdep.h ++++ b/ldso/ldso/powerpc/dl-sysdep.h +@@ -85,7 +85,7 @@ void _dl_init_got(unsigned long *lpnt,struct elf_resolve *tpnt); + #define ELF_MACHINE_PLTREL_OVERLAP 1 + + /* Return the value of the GOT pointer. */ +-static __inline__ Elf32_Addr * __attribute__ ((const)) ++static __always_inline Elf32_Addr * __attribute__ ((const)) + ppc_got (void) + { + Elf32_Addr *got; +@@ -104,14 +104,14 @@ ppc_got (void) + + /* Return the link-time address of _DYNAMIC, stored as + the first value in the GOT. */ +-static __inline__ Elf32_Addr __attribute__ ((const)) ++static __always_inline Elf32_Addr __attribute__ ((const)) + elf_machine_dynamic (void) + { + return *ppc_got(); + } + + /* Return the run-time load address of the shared object. */ +-static __inline__ Elf32_Addr __attribute__ ((const)) ++static __always_inline Elf32_Addr __attribute__ ((const)) + elf_machine_load_address (void) + { + Elf32_Addr *branchaddr; +@@ -159,7 +159,7 @@ elf_machine_load_address (void) + return runtime_dynamic - elf_machine_dynamic (); + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +diff --git a/ldso/ldso/sh/dl-sysdep.h b/ldso/ldso/sh/dl-sysdep.h +index daedda5..d4fc784 100644 +--- a/ldso/ldso/sh/dl-sysdep.h ++++ b/ldso/ldso/sh/dl-sysdep.h +@@ -25,7 +25,7 @@ + struct elf_resolve; + extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); + +-static __inline__ unsigned int ++static __always_inline unsigned int + _dl_urem(unsigned int n, unsigned int base) + { + int res; +@@ -95,7 +95,7 @@ _dl_urem(unsigned int n, unsigned int base) + /* Return the link-time address of _DYNAMIC. Conveniently, this is the + first element of the GOT. This must be inlined in a function which + uses global data. */ +-static __inline__ Elf32_Addr __attribute__ ((unused)) ++static __always_inline Elf32_Addr __attribute__ ((unused)) + elf_machine_dynamic (void) + { + register Elf32_Addr *got; +@@ -104,7 +104,7 @@ elf_machine_dynamic (void) + } + + /* Return the run-time load address of the shared object. */ +-static __inline__ Elf32_Addr __attribute__ ((unused)) ++static __always_inline Elf32_Addr __attribute__ ((unused)) + elf_machine_load_address (void) + { + Elf32_Addr addr; +@@ -146,7 +146,7 @@ elf_machine_load_address (void) + } \ + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +diff --git a/ldso/ldso/sh64/dl-sysdep.h b/ldso/ldso/sh64/dl-sysdep.h +index fc67b12..15d9b5e 100644 +--- a/ldso/ldso/sh64/dl-sysdep.h ++++ b/ldso/ldso/sh64/dl-sysdep.h +@@ -41,7 +41,7 @@ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_ent + /* Return the link-time address of _DYNAMIC. Conveniently, this is the + first element of the GOT. This must be inlined in a function which + uses global data. */ +-static __inline__ Elf32_Addr elf_machine_dynamic(void) ++static __always_inline Elf32_Addr elf_machine_dynamic(void) + { + register Elf32_Addr *got; + +@@ -69,7 +69,7 @@ static __inline__ Elf32_Addr elf_machine_dynamic(void) + } + + /* Return the run-time load address of the shared object. */ +-static __inline__ Elf32_Addr elf_machine_load_address(void) ++static __always_inline Elf32_Addr elf_machine_load_address(void) + { + Elf32_Addr addr; + +@@ -122,7 +122,7 @@ static __inline__ Elf32_Addr elf_machine_load_address(void) + } \ + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative(Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +diff --git a/ldso/ldso/sparc/dl-sysdep.h b/ldso/ldso/sparc/dl-sysdep.h +index 7936517..ebfa268 100644 +--- a/ldso/ldso/sparc/dl-sysdep.h ++++ b/ldso/ldso/sparc/dl-sysdep.h +@@ -52,7 +52,7 @@ unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); + + #ifndef COMPILE_ASM + /* Cheap modulo implementation, taken from arm/ld_sysdep.h. */ +-static __inline__ unsigned long ++static __always_inline unsigned long + sparc_mod(unsigned long m, unsigned long p) + { + unsigned long i, t, inc; +@@ -118,7 +118,7 @@ do { register Elf32_Addr pc __asm__("o7"); \ + /* Return the link-time address of _DYNAMIC. Conveniently, this is the + first element of the GOT. This must be inlined in a function which + uses global data. */ +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr + elf_machine_dynamic (void) + { + register Elf32_Addr *got __asm__ ("%l7"); +@@ -129,7 +129,7 @@ elf_machine_dynamic (void) + } + + /* Return the run-time load address of the shared object. */ +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr + elf_machine_load_address (void) + { + register Elf32_Addr *pc __asm__ ("%o7"), *got __asm__ ("%l7"); +@@ -148,7 +148,7 @@ elf_machine_load_address (void) + return (Elf32_Addr) got - *got + (pc[2] - pc[3]) * 4 - 4; + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +diff --git a/ldso/ldso/xtensa/dl-sysdep.h b/ldso/ldso/xtensa/dl-sysdep.h +index daae428..07b9b79 100644 +--- a/ldso/ldso/xtensa/dl-sysdep.h ++++ b/ldso/ldso/xtensa/dl-sysdep.h +@@ -85,7 +85,7 @@ extern unsigned long _dl_linux_resolver (struct elf_resolve *, int); + (((type) == R_XTENSA_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) + + /* Return the link-time address of _DYNAMIC. */ +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr + elf_machine_dynamic (void) + { + /* This function is only used while bootstrapping the runtime linker. +@@ -95,7 +95,7 @@ elf_machine_dynamic (void) + } + + /* Return the run-time load address of the shared object. */ +-static __inline__ Elf32_Addr ++static __always_inline Elf32_Addr + elf_machine_load_address (void) + { + Elf32_Addr addr, tmp; +@@ -116,7 +116,7 @@ elf_machine_load_address (void) + return addr - 3; + } + +-static __inline__ void ++static __always_inline void + elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, + Elf32_Word relative_count) + { +-- +1.6.3.3.444.g4ecbc + diff --git a/recipes/uclibc/uclibc-0.9.30.1/0001-Use-__always_inline-instead-of-__inline__.patch b/recipes/uclibc/uclibc-0.9.30.1/0001-Use-__always_inline-instead-of-__inline__.patch deleted file mode 100644 index a9c7a4fb10..0000000000 --- a/recipes/uclibc/uclibc-0.9.30.1/0001-Use-__always_inline-instead-of-__inline__.patch +++ /dev/null @@ -1,393 +0,0 @@ -From c190f738e1b0e87658ea5f86c057fb147dc19428 Mon Sep 17 00:00:00 2001 -From: Carmelo Amoroso -Date: Thu, 5 Mar 2009 13:28:55 +0000 -Subject: [PATCH] Use __always_inline instead of __inline__ - ---- - ldso/ldso/arm/dl-sysdep.h | 8 ++++---- - ldso/ldso/bfin/dl-sysdep.h | 2 +- - ldso/ldso/cris/dl-sysdep.h | 6 +++--- - ldso/ldso/i386/dl-sysdep.h | 10 +++++----- - ldso/ldso/m68k/dl-sysdep.h | 6 +++--- - ldso/ldso/mips/dl-sysdep.h | 8 ++++---- - ldso/ldso/powerpc/dl-sysdep.h | 8 ++++---- - ldso/ldso/sh/dl-sysdep.h | 8 ++++---- - ldso/ldso/sh64/dl-sysdep.h | 6 +++--- - ldso/ldso/sparc/dl-sysdep.h | 8 ++++---- - ldso/ldso/xtensa/dl-sysdep.h | 6 +++--- - 11 files changed, 38 insertions(+), 38 deletions(-) - -diff --git a/ldso/ldso/arm/dl-sysdep.h b/ldso/ldso/arm/dl-sysdep.h -index eea3b98..5191dd7 100644 ---- a/ldso/ldso/arm/dl-sysdep.h -+++ b/ldso/ldso/arm/dl-sysdep.h -@@ -15,7 +15,7 @@ - GOT_BASE[1] = (unsigned long) MODULE; \ - } - --static __inline__ unsigned long arm_modulus(unsigned long m, unsigned long p) -+static __always_inline unsigned long arm_modulus(unsigned long m, unsigned long p) - { - unsigned long i,t,inc; - i=p; t=0; -@@ -67,7 +67,7 @@ unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); - first element of the GOT. We used to use the PIC register to do this - without a constant pool reference, but GCC 4.2 will use a pseudo-register - for the PIC base, so it may not be in r10. */ --static __inline__ Elf32_Addr __attribute__ ((unused)) -+static __always_inline Elf32_Addr __attribute__ ((unused)) - elf_machine_dynamic (void) - { - Elf32_Addr dynamic; -@@ -99,7 +99,7 @@ elf_machine_dynamic (void) - } - - /* Return the run-time load address of the shared object. */ --static __inline__ Elf32_Addr __attribute__ ((unused)) -+static __always_inline Elf32_Addr __attribute__ ((unused)) - elf_machine_load_address (void) - { - extern void __dl_start __asm__ ("_dl_start"); -@@ -123,7 +123,7 @@ elf_machine_load_address (void) - return pcrel_addr - got_addr; - } - --static __inline__ void -+static __always_inline void - elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, - Elf32_Word relative_count) - { -diff --git a/ldso/ldso/bfin/dl-sysdep.h b/ldso/ldso/bfin/dl-sysdep.h -index 3c88da4..f0c5129 100644 ---- a/ldso/ldso/bfin/dl-sysdep.h -+++ b/ldso/ldso/bfin/dl-sysdep.h -@@ -210,7 +210,7 @@ while (0) - #endif - - #include --static __inline__ void -+static __always_inline void - elf_machine_relative (DL_LOADADDR_TYPE load_off, const Elf32_Addr rel_addr, - Elf32_Word relative_count) - { -diff --git a/ldso/ldso/cris/dl-sysdep.h b/ldso/ldso/cris/dl-sysdep.h -index ffb763a..e454c10 100644 ---- a/ldso/ldso/cris/dl-sysdep.h -+++ b/ldso/ldso/cris/dl-sysdep.h -@@ -37,7 +37,7 @@ extern unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entr - || ((type) == R_CRIS_GLOB_DAT)) * ELF_RTYPE_CLASS_PLT) \ - | (((type) == R_CRIS_COPY) * ELF_RTYPE_CLASS_COPY)) - --static __inline__ Elf32_Addr -+static __always_inline Elf32_Addr - elf_machine_dynamic(void) - { - /* Don't just set this to an asm variable "r0" since that's not logical -@@ -59,7 +59,7 @@ elf_machine_dynamic(void) - there's some other symbol we could use, that we don't *have* to force a - GOT entry for. */ - --static __inline__ Elf32_Addr -+static __always_inline Elf32_Addr - elf_machine_load_address(void) - { - Elf32_Addr gotaddr_diff; -@@ -93,7 +93,7 @@ elf_machine_load_address(void) - return gotaddr_diff; - } - --static __inline__ void -+static __always_inline void - elf_machine_relative(Elf32_Addr load_off, const Elf32_Addr rel_addr, - Elf32_Word relative_count) - { -diff --git a/ldso/ldso/i386/dl-sysdep.h b/ldso/ldso/i386/dl-sysdep.h -index 77fa372..6e84861 100644 ---- a/ldso/ldso/i386/dl-sysdep.h -+++ b/ldso/ldso/i386/dl-sysdep.h -@@ -37,8 +37,8 @@ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_ent - /* Return the link-time address of _DYNAMIC. Conveniently, this is the - first element of the GOT. This must be inlined in a function which - uses global data. */ --static __inline__ Elf32_Addr elf_machine_dynamic (void) attribute_unused; --static __inline__ Elf32_Addr -+static __always_inline Elf32_Addr elf_machine_dynamic (void) attribute_unused; -+static __always_inline Elf32_Addr - elf_machine_dynamic (void) - { - register Elf32_Addr *got __asm__ ("%ebx"); -@@ -47,8 +47,8 @@ elf_machine_dynamic (void) - - - /* Return the run-time load address of the shared object. */ --static __inline__ Elf32_Addr elf_machine_load_address (void) attribute_unused; --static __inline__ Elf32_Addr -+static __always_inline Elf32_Addr elf_machine_load_address (void) attribute_unused; -+static __always_inline Elf32_Addr - elf_machine_load_address (void) - { - /* It doesn't matter what variable this is, the reference never makes -@@ -61,7 +61,7 @@ elf_machine_load_address (void) - return addr; - } - --static __inline__ void -+static __always_inline void - elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, - Elf32_Word relative_count) - { -diff --git a/ldso/ldso/m68k/dl-sysdep.h b/ldso/ldso/m68k/dl-sysdep.h -index 8e26e20..259cb84 100644 ---- a/ldso/ldso/m68k/dl-sysdep.h -+++ b/ldso/ldso/m68k/dl-sysdep.h -@@ -39,7 +39,7 @@ extern unsigned long _dl_linux_resolver (struct elf_resolve *, int); - /* Return the link-time address of _DYNAMIC. Conveniently, this is the - first element of the GOT. This must be inlined in a function which - uses global data. */ --static __inline__ Elf32_Addr -+static __always_inline Elf32_Addr - elf_machine_dynamic (void) - { - register Elf32_Addr *got __asm__ ("%a5"); -@@ -48,7 +48,7 @@ elf_machine_dynamic (void) - - - /* Return the run-time load address of the shared object. */ --static __inline__ Elf32_Addr -+static __always_inline Elf32_Addr - elf_machine_load_address (void) - { - Elf32_Addr addr; -@@ -58,7 +58,7 @@ elf_machine_load_address (void) - return addr; - } - --static __inline__ void -+static __always_inline void - elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, - Elf32_Word relative_count) - { -diff --git a/ldso/ldso/mips/dl-sysdep.h b/ldso/ldso/mips/dl-sysdep.h -index cf6b28b..30d84fb 100644 ---- a/ldso/ldso/mips/dl-sysdep.h -+++ b/ldso/ldso/mips/dl-sysdep.h -@@ -169,7 +169,7 @@ void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy) - - #define OFFSET_GP_GOT 0x7ff0 - --static __inline__ ElfW(Addr) * -+static __always_inline ElfW(Addr) * - elf_mips_got_from_gpreg (ElfW(Addr) gpreg) - { - /* FIXME: the offset of gp from GOT may be system-dependent. */ -@@ -179,7 +179,7 @@ elf_mips_got_from_gpreg (ElfW(Addr) gpreg) - /* Return the link-time address of _DYNAMIC. Conveniently, this is the - first element of the GOT. This must be inlined in a function which - uses global data. We assume its $gp points to the primary GOT. */ --static __inline__ ElfW(Addr) -+static __always_inline ElfW(Addr) - elf_machine_dynamic (void) - { - register ElfW(Addr) gp __asm__ ("$28"); -@@ -198,7 +198,7 @@ elf_machine_dynamic (void) - #endif - - /* Return the run-time load address of the shared object. */ --static __inline__ ElfW(Addr) -+static __always_inline ElfW(Addr) - elf_machine_load_address (void) - { - ElfW(Addr) addr; -@@ -214,7 +214,7 @@ elf_machine_load_address (void) - return addr; - } - --static __inline__ void -+static __always_inline void - elf_machine_relative (ElfW(Addr) load_off, const ElfW(Addr) rel_addr, - ElfW(Word) relative_count) - { -diff --git a/ldso/ldso/powerpc/dl-sysdep.h b/ldso/ldso/powerpc/dl-sysdep.h -index fdbf564..f33214c 100644 ---- a/ldso/ldso/powerpc/dl-sysdep.h -+++ b/ldso/ldso/powerpc/dl-sysdep.h -@@ -85,7 +85,7 @@ void _dl_init_got(unsigned long *lpnt,struct elf_resolve *tpnt); - #define ELF_MACHINE_PLTREL_OVERLAP 1 - - /* Return the value of the GOT pointer. */ --static __inline__ Elf32_Addr * __attribute__ ((const)) -+static __always_inline Elf32_Addr * __attribute__ ((const)) - ppc_got (void) - { - Elf32_Addr *got; -@@ -104,14 +104,14 @@ ppc_got (void) - - /* Return the link-time address of _DYNAMIC, stored as - the first value in the GOT. */ --static __inline__ Elf32_Addr __attribute__ ((const)) -+static __always_inline Elf32_Addr __attribute__ ((const)) - elf_machine_dynamic (void) - { - return *ppc_got(); - } - - /* Return the run-time load address of the shared object. */ --static __inline__ Elf32_Addr __attribute__ ((const)) -+static __always_inline Elf32_Addr __attribute__ ((const)) - elf_machine_load_address (void) - { - Elf32_Addr *branchaddr; -@@ -159,7 +159,7 @@ elf_machine_load_address (void) - return runtime_dynamic - elf_machine_dynamic (); - } - --static __inline__ void -+static __always_inline void - elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, - Elf32_Word relative_count) - { -diff --git a/ldso/ldso/sh/dl-sysdep.h b/ldso/ldso/sh/dl-sysdep.h -index daedda5..d4fc784 100644 ---- a/ldso/ldso/sh/dl-sysdep.h -+++ b/ldso/ldso/sh/dl-sysdep.h -@@ -25,7 +25,7 @@ - struct elf_resolve; - extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); - --static __inline__ unsigned int -+static __always_inline unsigned int - _dl_urem(unsigned int n, unsigned int base) - { - int res; -@@ -95,7 +95,7 @@ _dl_urem(unsigned int n, unsigned int base) - /* Return the link-time address of _DYNAMIC. Conveniently, this is the - first element of the GOT. This must be inlined in a function which - uses global data. */ --static __inline__ Elf32_Addr __attribute__ ((unused)) -+static __always_inline Elf32_Addr __attribute__ ((unused)) - elf_machine_dynamic (void) - { - register Elf32_Addr *got; -@@ -104,7 +104,7 @@ elf_machine_dynamic (void) - } - - /* Return the run-time load address of the shared object. */ --static __inline__ Elf32_Addr __attribute__ ((unused)) -+static __always_inline Elf32_Addr __attribute__ ((unused)) - elf_machine_load_address (void) - { - Elf32_Addr addr; -@@ -146,7 +146,7 @@ elf_machine_load_address (void) - } \ - } - --static __inline__ void -+static __always_inline void - elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, - Elf32_Word relative_count) - { -diff --git a/ldso/ldso/sh64/dl-sysdep.h b/ldso/ldso/sh64/dl-sysdep.h -index fc67b12..15d9b5e 100644 ---- a/ldso/ldso/sh64/dl-sysdep.h -+++ b/ldso/ldso/sh64/dl-sysdep.h -@@ -41,7 +41,7 @@ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_ent - /* Return the link-time address of _DYNAMIC. Conveniently, this is the - first element of the GOT. This must be inlined in a function which - uses global data. */ --static __inline__ Elf32_Addr elf_machine_dynamic(void) -+static __always_inline Elf32_Addr elf_machine_dynamic(void) - { - register Elf32_Addr *got; - -@@ -69,7 +69,7 @@ static __inline__ Elf32_Addr elf_machine_dynamic(void) - } - - /* Return the run-time load address of the shared object. */ --static __inline__ Elf32_Addr elf_machine_load_address(void) -+static __always_inline Elf32_Addr elf_machine_load_address(void) - { - Elf32_Addr addr; - -@@ -122,7 +122,7 @@ static __inline__ Elf32_Addr elf_machine_load_address(void) - } \ - } - --static __inline__ void -+static __always_inline void - elf_machine_relative(Elf32_Addr load_off, const Elf32_Addr rel_addr, - Elf32_Word relative_count) - { -diff --git a/ldso/ldso/sparc/dl-sysdep.h b/ldso/ldso/sparc/dl-sysdep.h -index 7936517..ebfa268 100644 ---- a/ldso/ldso/sparc/dl-sysdep.h -+++ b/ldso/ldso/sparc/dl-sysdep.h -@@ -52,7 +52,7 @@ unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); - - #ifndef COMPILE_ASM - /* Cheap modulo implementation, taken from arm/ld_sysdep.h. */ --static __inline__ unsigned long -+static __always_inline unsigned long - sparc_mod(unsigned long m, unsigned long p) - { - unsigned long i, t, inc; -@@ -118,7 +118,7 @@ do { register Elf32_Addr pc __asm__("o7"); \ - /* Return the link-time address of _DYNAMIC. Conveniently, this is the - first element of the GOT. This must be inlined in a function which - uses global data. */ --static __inline__ Elf32_Addr -+static __always_inline Elf32_Addr - elf_machine_dynamic (void) - { - register Elf32_Addr *got __asm__ ("%l7"); -@@ -129,7 +129,7 @@ elf_machine_dynamic (void) - } - - /* Return the run-time load address of the shared object. */ --static __inline__ Elf32_Addr -+static __always_inline Elf32_Addr - elf_machine_load_address (void) - { - register Elf32_Addr *pc __asm__ ("%o7"), *got __asm__ ("%l7"); -@@ -148,7 +148,7 @@ elf_machine_load_address (void) - return (Elf32_Addr) got - *got + (pc[2] - pc[3]) * 4 - 4; - } - --static __inline__ void -+static __always_inline void - elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, - Elf32_Word relative_count) - { -diff --git a/ldso/ldso/xtensa/dl-sysdep.h b/ldso/ldso/xtensa/dl-sysdep.h -index daae428..07b9b79 100644 ---- a/ldso/ldso/xtensa/dl-sysdep.h -+++ b/ldso/ldso/xtensa/dl-sysdep.h -@@ -85,7 +85,7 @@ extern unsigned long _dl_linux_resolver (struct elf_resolve *, int); - (((type) == R_XTENSA_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) - - /* Return the link-time address of _DYNAMIC. */ --static __inline__ Elf32_Addr -+static __always_inline Elf32_Addr - elf_machine_dynamic (void) - { - /* This function is only used while bootstrapping the runtime linker. -@@ -95,7 +95,7 @@ elf_machine_dynamic (void) - } - - /* Return the run-time load address of the shared object. */ --static __inline__ Elf32_Addr -+static __always_inline Elf32_Addr - elf_machine_load_address (void) - { - Elf32_Addr addr, tmp; -@@ -116,7 +116,7 @@ elf_machine_load_address (void) - return addr - 3; - } - --static __inline__ void -+static __always_inline void - elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr, - Elf32_Word relative_count) - { --- -1.6.3.3.444.g4ecbc - diff --git a/recipes/uclibc/uclibc_0.9.30.1.bb b/recipes/uclibc/uclibc_0.9.30.1.bb index ab5cdad7c3..1f8162edfc 100644 --- a/recipes/uclibc/uclibc_0.9.30.1.bb +++ b/recipes/uclibc/uclibc_0.9.30.1.bb @@ -21,7 +21,7 @@ SRC_URI += "file://uClibc.machine file://uClibc.distro \ file://ldso_use_arm_dl_linux_resolve_in_thumb_mode.patch;patch=1 \ file://gcc-4.4-fixlet.patch;patch=1 \ file://uclibc-c99-ldbl-math.patch;patch=1 \ - file://0001-Use-__always_inline-instead-of-__inline__.patch;patch=1 \ + file://Use-__always_inline-instead-of-__inline__.patch;patch=1 \ " #recent versions uclibc require real kernel headers PACKAGE_ARCH = "${MACHINE_ARCH}" diff --git a/recipes/uclibc/uclibc_0.9.30.bb b/recipes/uclibc/uclibc_0.9.30.bb index 2e18ab9fa5..9278299884 100644 --- a/recipes/uclibc/uclibc_0.9.30.bb +++ b/recipes/uclibc/uclibc_0.9.30.bb @@ -9,7 +9,7 @@ UCLIBC_BASE ?= "0.9.30" require uclibc.inc -PR = "${INC_PR}.0" +PR = "${INC_PR}.1" PROVIDES += "virtual/${TARGET_PREFIX}libc-for-gcc" @@ -20,6 +20,7 @@ SRC_URI += "file://uClibc.machine file://uClibc.distro \ file://uclibc_ldso_use_O0.patch;patch=1 \ file://ldso_use_arm_dl_linux_resolve_in_thumb_mode.patch;patch=1 \ file://unifdef-fix.patch;patch=1 \ + file://Use-__always_inline-instead-of-__inline__.patch;patch=1 \ " #recent versions uclibc require real kernel headers PACKAGE_ARCH = "${MACHINE_ARCH}" -- cgit v1.2.3 From fdbb57d061fab29f3517b43b96e0e16a2bd77902 Mon Sep 17 00:00:00 2001 From: Stanislav Brabec Date: Sat, 19 Sep 2009 21:19:28 +0000 Subject: automake: Recipes cleanup and fixes: * Move common part of recipes to automake.inc. * Use conditional ac_cv_path_PERL instead of path_prog_fixes.patch to fix automake on target. * Remove unneeded datadir symlinks that make impossible to install more automake versions. * Make symlinks from unversioned copy of binaries. * Cleanup of obsolete parts of recipesthat make impossible to install more automake versions. * Make symlinks from unversioned copy of binaries. * Cleanup of obsolete parts of recipes. --- .../automake/automake-1.10/path_prog_fixes.patch | 43 ----------------- recipes/automake/automake-native.inc | 4 +- recipes/automake/automake.inc | 25 ++++++++++ recipes/automake/automake_1.10.2.bb | 31 +----------- recipes/automake/automake_1.9.6.bb | 29 +----------- recipes/automake/files/path_prog_fixes.patch | 55 ---------------------- 6 files changed, 29 insertions(+), 158 deletions(-) delete mode 100644 recipes/automake/automake-1.10/path_prog_fixes.patch delete mode 100644 recipes/automake/files/path_prog_fixes.patch diff --git a/recipes/automake/automake-1.10/path_prog_fixes.patch b/recipes/automake/automake-1.10/path_prog_fixes.patch deleted file mode 100644 index 60d32833ea..0000000000 --- a/recipes/automake/automake-1.10/path_prog_fixes.patch +++ /dev/null @@ -1,43 +0,0 @@ -Index: automake-1.9.3/Makefile.am -=================================================================== ---- automake-1.9.3.orig/Makefile.am 2004-10-25 14:57:30.000000000 -0400 -+++ automake-1.9.3/Makefile.am 2005-03-09 16:47:38.241364016 -0500 -@@ -66,7 +66,8 @@ - -e 's,[@]SHELL[@],$(SHELL),g' \ - -e 's,[@]VERSION[@],$(VERSION),g' \ - -e 's,[@]configure_input[@],Generated from $@.in; do not edit by hand.,g' \ -- -e 's,[@]datadir[@],$(datadir),g' -+ -e 's,[@]datadir[@],$(datadir),g' \ -+ -e 's,[@]bindir[@],$(bindir),g' - - ## These files depend on Makefile so they are rebuilt if $(VERSION), - ## $(datadir) or other do_subst'ituted variables change. -Index: automake-1.9.3/Makefile.in -=================================================================== ---- automake-1.9.3.orig/Makefile.in 2004-11-01 05:23:54.000000000 -0500 -+++ automake-1.9.3/Makefile.in 2005-03-09 16:47:54.712859968 -0500 -@@ -161,7 +161,8 @@ - -e 's,[@]SHELL[@],$(SHELL),g' \ - -e 's,[@]VERSION[@],$(VERSION),g' \ - -e 's,[@]configure_input[@],Generated from $@.in; do not edit by hand.,g' \ -- -e 's,[@]datadir[@],$(datadir),g' -+ -e 's,[@]datadir[@],$(datadir),g' \ -+ -e 's,[@]bindir[@],$(bindir),g' - - WGET = wget - WGETSGO = $(WGET) http://savannah.gnu.org/cgi-bin/viewcvs/~checkout~ ---- /tmp/aclocal.in 2009-02-25 15:43:38.000000000 +0100 -+++ automake-1.10/aclocal.in 2009-02-25 15:44:54.000000000 +0100 -@@ -1,8 +1,10 @@ --#!@PERL@ -w -+#!@bindir@/env perl - # -*- perl -*- - # @configure_input@ - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+use warnings; -+ -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @bindir@/env perl -S "$0" "$@";; esac' - if 0; - - # aclocal - create aclocal.m4 by scanning configure.ac diff --git a/recipes/automake/automake-native.inc b/recipes/automake/automake-native.inc index 5ced30d5df..4e2ac41d81 100644 --- a/recipes/automake/automake-native.inc +++ b/recipes/automake/automake-native.inc @@ -1,7 +1,7 @@ SECTION = "devel" require automake_${PV}.bb -DEPENDS = "autoconf-native" -RDEPENDS_automake-native = "autoconf-native perl-native-runtime" +DEPENDS += "autoconf-native" +RDEPENDS_automake-native += "autoconf-native perl-native-runtime" inherit native diff --git a/recipes/automake/automake.inc b/recipes/automake/automake.inc index a4cdbbb34a..74957cc9e9 100644 --- a/recipes/automake/automake.inc +++ b/recipes/automake/automake.inc @@ -1,3 +1,7 @@ +DESCRIPTION = "A tool for automatically generating Makefiles." +LICENSE = "GPL" +HOMEPAGE = "http://www.gnu.org/software/automake/" +SECTION = "devel" RDEPENDS_automake += "\ autoconf \ perl \ @@ -22,3 +26,24 @@ RDEPENDS_automake += "\ perl-module-strict \ perl-module-text-parsewords \ perl-module-vars " +SRC_URI = "${GNU_MIRROR}/automake/automake-${PV}.tar.bz2" +INC_PR = "r2" +AUTOMAKE_API = "${@".".join(bb.data.getVar("PV",d,1).split(".")[0:2])}" + +inherit autotools + +FILES_${PN} += "${datadir}/automake* ${datadir}/aclocal*" + +do_configure_prepend () { + if ${@['true', 'false'][bb.data.inherits_class('native', d)]} + then + export ac_cv_path_PERL="${ac_cv_path_PERL=${bindir}/perl}" + fi +} + +do_install_append () { + autotools_do_install + ln -sf aclocal-${AUTOMAKE_API} ${D}${bindir}/aclocal + ln -sf automake-${AUTOMAKE_API} ${D}${bindir}/automake + install -d ${D}${datadir}/aclocal +} diff --git a/recipes/automake/automake_1.10.2.bb b/recipes/automake/automake_1.10.2.bb index 42e0d66d9e..ad6879ada8 100644 --- a/recipes/automake/automake_1.10.2.bb +++ b/recipes/automake/automake_1.10.2.bb @@ -1,31 +1,2 @@ -DESCRIPTION = "A tool for automatically generating Makefiles." -LICENSE = "GPL" -HOMEPAGE = "http://www.gnu.org/software/automake/" -SECTION = "devel" -PR = "r1" - -SRC_URI = "\ - ${GNU_MIRROR}/automake/automake-${PV}.tar.bz2 \ - ${@['file://path_prog_fixes.patch;patch=1', ''][bb.data.inherits_class('native', d)]} \ -" -S = "${WORKDIR}/automake-${PV}" - -FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/automake-${PV}" - -inherit autotools - -export AUTOMAKE = "${@bb.which('automake', bb.data.getVar('PATH', d, 1))}" -FILES_${PN} += "${datadir}/automake* ${datadir}/aclocal*" - require automake.inc - -do_install () { - oe_runmake 'DESTDIR=${D}' install - install -d ${D}${datadir} - if [ ! -e ${D}${datadir}/aclocal ]; then - ln -sf aclocal-1.10 ${D}${datadir}/aclocal - fi - if [ ! -e ${D}${datadir}/automake ]; then - ln -sf automake-1.10 ${D}${datadir}/automake - fi -} +PR = "${INC_PR}.0" diff --git a/recipes/automake/automake_1.9.6.bb b/recipes/automake/automake_1.9.6.bb index eef69f4e4a..9b363b9f89 100644 --- a/recipes/automake/automake_1.9.6.bb +++ b/recipes/automake/automake_1.9.6.bb @@ -1,31 +1,4 @@ -DESCRIPTION = "A tool for automatically generating Makefiles." -LICENSE = "GPL" -HOMEPAGE = "http://www.gnu.org/software/automake/" -SECTION = "devel" - -SRC_URI = "${GNU_MIRROR}/automake/automake-${PV}.tar.bz2 \ - ${@['file://path_prog_fixes.patch;patch=1', ''][bb.data.inherits_class('native', d)]}" - -S = "${WORKDIR}/automake-${PV}" - -FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/automake-${PV}" - -inherit autotools - -export AUTOMAKE = "${@bb.which('automake', bb.data.getVar('PATH', d, 1))}" -FILES_${PN} += "${datadir}/automake* ${datadir}/aclocal*" - require automake.inc - -do_install () { - oe_runmake 'DESTDIR=${D}' install - install -d ${D}${datadir} - if [ ! -e ${D}${datadir}/aclocal ]; then - ln -sf aclocal-1.9 ${D}${datadir}/aclocal - fi - if [ ! -e ${D}${datadir}/automake ]; then - ln -sf automake-1.9 ${D}${datadir}/automake - fi -} +PR = "${INC_PR}.0" DEFAULT_PREFERENCE = "-1" diff --git a/recipes/automake/files/path_prog_fixes.patch b/recipes/automake/files/path_prog_fixes.patch deleted file mode 100644 index 69cea77035..0000000000 --- a/recipes/automake/files/path_prog_fixes.patch +++ /dev/null @@ -1,55 +0,0 @@ -Index: automake-1.10.2/Makefile.am -=================================================================== ---- automake-1.10.2.orig/Makefile.am -+++ automake-1.10.2/Makefile.am -@@ -75,7 +75,8 @@ - -e 's,[@]SHELL[@],$(SHELL),g' \ - -e 's,[@]VERSION[@],$(VERSION),g' \ - -e 's,[@]configure_input[@],Generated from $@.in; do not edit by hand.,g' \ -- -e 's,[@]datadir[@],$(datadir),g' -+ -e 's,[@]datadir[@],$(datadir),g' \ -+ -e 's,[@]bindir[@],$(bindir),g' - - ## These files depend on Makefile so they are rebuilt if $(VERSION), - ## $(datadir) or other do_subst'ituted variables change. -Index: automake-1.10.2/Makefile.in -=================================================================== ---- automake-1.10.2.orig/Makefile.in -+++ automake-1.10.2/Makefile.in -@@ -186,7 +186,8 @@ - -e 's,[@]SHELL[@],$(SHELL),g' \ - -e 's,[@]VERSION[@],$(VERSION),g' \ - -e 's,[@]configure_input[@],Generated from $@.in; do not edit by hand.,g' \ -- -e 's,[@]datadir[@],$(datadir),g' -+ -e 's,[@]datadir[@],$(datadir),g' \ -+ -e 's,[@]bindir[@],$(bindir),g' - - WGET = wget - WGET_SV_CVS = $(WGET) http://savannah.gnu.org/cgi-bin/viewcvs/~checkout~/ -Index: automake-1.10.2/automake.in -=================================================================== ---- automake-1.10.2.orig/automake.in -+++ automake-1.10.2/automake.in -@@ -1,8 +1,10 @@ --#!@PERL@ -w -+#!@bindir@/env perl - # -*- perl -*- - # @configure_input@ - --eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' -+use warnings; -+ -+eval 'case $# in 0) exec @bindir@/env perl -S "$0";; *) exec @bindir@/env perl -S "$0" "$@";; esac' - if 0; - - # automake - create Makefile.in from Makefile.am -Index: automake-1.10.2/aclocal.in -=================================================================== ---- automake-1.10.2.orig/aclocal.in -+++ automake-1.10.2/aclocal.in -@@ -1,4 +1,4 @@ --#!@PERL@ -w -+#!@bindir@/env perl -w - # -*- perl -*- - # @configure_input@ - -- cgit v1.2.3 From 103e2071354d88a1fd6ea34469fd972123350b72 Mon Sep 17 00:00:00 2001 From: Stanislav Brabec Date: Sat, 19 Sep 2009 21:30:06 +0000 Subject: matchbox-wm: Easy fix for crash when clicking on the app switcher (openedhand#1343). --- recipes/matchbox-wm/matchbox-wm/select-client-crash.patch | 14 ++++++++++++++ recipes/matchbox-wm/matchbox-wm_1.2.bb | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 recipes/matchbox-wm/matchbox-wm/select-client-crash.patch diff --git a/recipes/matchbox-wm/matchbox-wm/select-client-crash.patch b/recipes/matchbox-wm/matchbox-wm/select-client-crash.patch new file mode 100644 index 0000000000..0af225b471 --- /dev/null +++ b/recipes/matchbox-wm/matchbox-wm/select-client-crash.patch @@ -0,0 +1,14 @@ +http://bugzilla.openedhand.com/show_bug.cgi?id=1343 +Index: matchbox-window-manager-1.2/src/select_client.c +=================================================================== +--- matchbox-window-manager-1.2.orig/src/select_client.c ++++ matchbox-window-manager-1.2/src/select_client.c +@@ -49,6 +49,8 @@ select_client_new(Wm *w) + + if (width == 0 || height == 0) return NULL; + ++ if (w->stack_top_app == NULL) return NULL; ++ + dbg("%s() got valid size\n", __func__); + + button_x = theme_frame_button_get_x_pos(w->mbtheme, FRAME_MAIN, diff --git a/recipes/matchbox-wm/matchbox-wm_1.2.bb b/recipes/matchbox-wm/matchbox-wm_1.2.bb index 36ddae3c7c..afa26e67a2 100644 --- a/recipes/matchbox-wm/matchbox-wm_1.2.bb +++ b/recipes/matchbox-wm/matchbox-wm_1.2.bb @@ -3,10 +3,11 @@ require matchbox-wm.inc DEPENDS = "libmatchbox virtual/libx11 libxext libxcomposite libxfixes libxdamage libxrender startup-notification expat gconf gconf-native " RDEPENDS = "" -PR ="r4" +PR ="r5" SRC_URI = "http://matchbox-project.org/sources/matchbox-window-manager/1.2/matchbox-window-manager-${PV}.tar.bz2 \ file://configure_fix.patch;patch=1 \ + file://select-client-crash.patch;patch=1 \ file://gconf-2.m4 \ file://kbdconfig" -- cgit v1.2.3 From aa0d1e870c41d3375866c8180c720cd0fc27ffcd Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Sat, 19 Sep 2009 16:45:32 -0700 Subject: autoconf: Dont execute perl and m4 for target builds * configure decides to probe perl verison dont do that as it wont work when building target autoconf. So far it was executing /usr/bin/perl and /usr/bin/m4 which is found on most build machines however micro change the layout and /bin/perl and /bin/m4 is now not found. So it brought up a hidden bug. Signed-off-by: Khem Raj --- .../autoconf-2.61/autoconf-dont-execute-perl.patch | 41 ++++++++++++++++++++++ recipes/autoconf/autoconf.inc | 3 +- recipes/autoconf/autoconf_2.61.bb | 4 ++- 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 recipes/autoconf/autoconf-2.61/autoconf-dont-execute-perl.patch diff --git a/recipes/autoconf/autoconf-2.61/autoconf-dont-execute-perl.patch b/recipes/autoconf/autoconf-2.61/autoconf-dont-execute-perl.patch new file mode 100644 index 0000000000..c336bc57d2 --- /dev/null +++ b/recipes/autoconf/autoconf-2.61/autoconf-dont-execute-perl.patch @@ -0,0 +1,41 @@ +Index: autoconf-2.61/configure.ac +=================================================================== +--- autoconf-2.61.orig/configure.ac 2006-11-17 11:04:48.000000000 -0800 ++++ autoconf-2.61/configure.ac 2009-09-19 16:37:40.000000000 -0700 +@@ -106,10 +106,6 @@ + if test "$PERL" = no; then + AC_MSG_ERROR([perl is not found]) + fi +-$PERL -e 'require 5.005_03;' || { +- AC_MSG_ERROR([Perl 5.005_03 or better is required]) +-} +- + + ## ------- ## + ## Emacs. ## +Index: autoconf-2.61/configure +=================================================================== +--- autoconf-2.61.orig/configure 2006-11-17 11:05:17.000000000 -0800 ++++ autoconf-2.61/configure 2009-09-19 16:38:13.000000000 -0700 +@@ -1557,7 +1557,7 @@ + # Let the site file select an alternate cache file if it wants to. + # Prefer explicitly selected file to automatically selected ones. + if test -n "$CONFIG_SITE"; then +- set x "$CONFIG_SITE" ++ set x $CONFIG_SITE + elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" + else +@@ -2406,12 +2406,6 @@ + echo "$as_me: error: perl is not found" >&2;} + { (exit 1); exit 1; }; } + fi +-$PERL -e 'require 5.005_03;' || { +- { { echo "$as_me:$LINENO: error: Perl 5.005_03 or better is required" >&5 +-echo "$as_me: error: Perl 5.005_03 or better is required" >&2;} +- { (exit 1); exit 1; }; } +-} +- + + ## ------- ## + ## Emacs. ## diff --git a/recipes/autoconf/autoconf.inc b/recipes/autoconf/autoconf.inc index 5bdc7e17ee..2fa12751a1 100644 --- a/recipes/autoconf/autoconf.inc +++ b/recipes/autoconf/autoconf.inc @@ -5,7 +5,7 @@ HOMEPAGE = "http://www.gnu.org/software/autoconf/" SECTION = "devel" DEPENDS += "m4-native" RDEPENDS_${PN} = "m4 perl gnu-config" -INC_PR = "r7" +INC_PR = "r8" SRC_URI = "${GNU_MIRROR}/autoconf/autoconf-${PV}.tar.bz2 \ file://program_prefix.patch;patch=1" @@ -17,5 +17,6 @@ do_configure_prepend () { then export ac_cv_path_PERL="${ac_cv_path_PERL=${bindir}/perl}" export ac_cv_path_M4="${ac_cv_path_M4=${bindir}/m4}" + export ac_cv_prog_gnu_m4="${ac_cv_prog_gnu_m4=yes}" fi } diff --git a/recipes/autoconf/autoconf_2.61.bb b/recipes/autoconf/autoconf_2.61.bb index c3ccacd329..53733a90f8 100644 --- a/recipes/autoconf/autoconf_2.61.bb +++ b/recipes/autoconf/autoconf_2.61.bb @@ -9,4 +9,6 @@ SRC_URI += "file://autoreconf-include.patch;patch=1 \ file://autoreconf-foreign.patch;patch=1 \ file://autoreconf-gnuconfigize.patch;patch=1 \ file://autoheader-nonfatal-warnings.patch;patch=1 \ - file://config-site.patch;patch=1 " + file://config-site.patch;patch=1 \ + file://autoconf-dont-execute-perl.patch;patch=1 \ + " -- cgit v1.2.3 From a96730454f6f8d86519317ad0798b2f96dfcdd45 Mon Sep 17 00:00:00 2001 From: Denys Dmytriyenko Date: Sun, 20 Sep 2009 01:50:38 -0400 Subject: linux-davinci: add DA850/OMAPL138, update other DaVinci machines Signed-off-by: Denys Dmytriyenko --- conf/machine/da830-omapl137-evm.conf | 2 +- conf/machine/da850-omapl138-evm.conf | 13 + conf/machine/include/davinci.inc | 2 +- .../linux-davinci/da830-omapl137-evm/defconfig | 594 +--------- .../linux-davinci/da850-omapl138-evm/defconfig | 1235 ++++++++++++++++++++ recipes/linux/linux-davinci/dm355-evm/defconfig | 72 +- recipes/linux/linux-davinci/dm365-evm/defconfig | 324 ++++- recipes/linux/linux-davinci/dm6446-evm/defconfig | 246 ++-- recipes/linux/linux-davinci/dm6467-evm/defconfig | 102 +- recipes/linux/linux-davinci/dm6467t-evm/defconfig | 97 +- recipes/linux/linux-davinci_git.bb | 14 +- 11 files changed, 1861 insertions(+), 840 deletions(-) create mode 100644 conf/machine/da850-omapl138-evm.conf create mode 100644 recipes/linux/linux-davinci/da850-omapl138-evm/defconfig diff --git a/conf/machine/da830-omapl137-evm.conf b/conf/machine/da830-omapl137-evm.conf index c891f7a903..4df4d63cca 100644 --- a/conf/machine/da830-omapl137-evm.conf +++ b/conf/machine/da830-omapl137-evm.conf @@ -4,7 +4,7 @@ require conf/machine/include/davinci.inc -UBOOT_MACHINE = "da830_omapl137_config" +UBOOT_MACHINE = "da830_omapl137_evm_config" UBOOT_ENTRYPOINT = "0xc0008000" UBOOT_LOADADDRESS = "0xc0008000" diff --git a/conf/machine/da850-omapl138-evm.conf b/conf/machine/da850-omapl138-evm.conf new file mode 100644 index 0000000000..bbcb45002e --- /dev/null +++ b/conf/machine/da850-omapl138-evm.conf @@ -0,0 +1,13 @@ +#@TYPE: Machine +#@NAME: DA850 CPUs on a DA850/OMAPL138 EVM board +#@DESCRIPTION: Machine configuration for the TI DA850/OMAPL138 EVM board + +require conf/machine/include/davinci.inc + +UBOOT_MACHINE = "da850_omapl138_evm_config" +UBOOT_ENTRYPOINT = "0xc0008000" +UBOOT_LOADADDRESS = "0xc0008000" + +MACHINE_FEATURES = "kernel26 serial ethernet" + +SERIAL_CONSOLE = "115200 ttyS2" diff --git a/conf/machine/include/davinci.inc b/conf/machine/include/davinci.inc index 32211a07a5..206afd46f2 100644 --- a/conf/machine/include/davinci.inc +++ b/conf/machine/include/davinci.inc @@ -1,7 +1,7 @@ require conf/machine/include/tune-arm926ejs.inc # Increase this everytime you change something in the kernel -MACHINE_KERNEL_PR = "r9" +MACHINE_KERNEL_PR = "r10" TARGET_ARCH = "arm" diff --git a/recipes/linux/linux-davinci/da830-omapl137-evm/defconfig b/recipes/linux/linux-davinci/da830-omapl137-evm/defconfig index 786307e1ec..fc6e2c4bac 100644 --- a/recipes/linux/linux-davinci/da830-omapl137-evm/defconfig +++ b/recipes/linux/linux-davinci/da830-omapl137-evm/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.30-rc2-davinci1 -# Sun May 3 12:18:05 2009 +# Wed May 13 15:33:29 2009 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -62,8 +62,8 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y @@ -444,106 +444,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # CONFIG_CONNECTOR is not set -CONFIG_MTD=m -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_TESTS is not set -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_AFS_PARTS is not set -# CONFIG_MTD_AR7_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=m -CONFIG_MTD_BLKDEVS=m -CONFIG_MTD_BLOCK=m -# CONFIG_MTD_BLOCK_RO is not set -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=m -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=m -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=m -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=m -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_PHYSMAP=m -# CONFIG_MTD_PHYSMAP_COMPAT is not set -# CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -CONFIG_MTD_NAND=m -# CONFIG_MTD_NAND_VERIFY_WRITE is not set -# CONFIG_MTD_NAND_ECC_SMC is not set -# CONFIG_MTD_NAND_MUSEUM_IDS is not set -# CONFIG_MTD_NAND_GPIO is not set -CONFIG_MTD_NAND_IDS=m -# CONFIG_MTD_NAND_DISKONCHIP is not set -# CONFIG_MTD_NAND_NANDSIM is not set -# CONFIG_MTD_NAND_PLATFORM is not set -# CONFIG_MTD_ALAUDA is not set -CONFIG_MTD_NAND_DAVINCI=m -# CONFIG_MTD_ONENAND is not set - -# -# LPDDR flash memory drivers -# -# CONFIG_MTD_LPDDR is not set - -# -# UBI - Unsorted block images -# -# CONFIG_MTD_UBI is not set +# CONFIG_MTD is not set # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=m # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=1 CONFIG_BLK_DEV_RAM_SIZE=32768 @@ -563,29 +470,7 @@ CONFIG_EEPROM_AT24=y # CONFIG_EEPROM_LEGACY is not set # CONFIG_EEPROM_93CX6 is not set CONFIG_HAVE_IDE=y -CONFIG_IDE=m - -# -# Please see Documentation/ide/ide.txt for help/info on IDE drives -# -CONFIG_IDE_XFER_MODE=y -CONFIG_IDE_TIMINGS=y -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_IDE_GD=m -CONFIG_IDE_GD_ATA=y -# CONFIG_IDE_GD_ATAPI is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_IDE_TASK_IOCTL is not set -CONFIG_IDE_PROC_FS=y - -# -# IDE chipset support/bugfixes -# -# CONFIG_BLK_DEV_PLATFORM is not set -CONFIG_BLK_DEV_IDEDMA_SFF=y -CONFIG_BLK_DEV_PALMCHIP_BK3710=m -CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDE is not set # # SCSI device support @@ -691,28 +576,9 @@ CONFIG_TI_DAVINCI_EMAC=y # # Enable WiMAX (Networking options) to see the WiMAX drivers # - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set # CONFIG_WAN is not set -CONFIG_PPP=m -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m -# CONFIG_PPP_BSDCOMP is not set -# CONFIG_PPP_MPPE is not set -# CONFIG_PPPOE is not set -# CONFIG_PPPOL2TP is not set +# CONFIG_PPP is not set # CONFIG_SLIP is not set -CONFIG_SLHC=m CONFIG_NETCONSOLE=y # CONFIG_NETCONSOLE_DYNAMIC is not set CONFIG_NETPOLL=y @@ -765,7 +631,6 @@ CONFIG_INPUT_TOUCHSCREEN=y # CONFIG_TOUCHSCREEN_PENMOUNT is not set # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set # CONFIG_TOUCHSCREEN_TOUCHWIN is not set -# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set # CONFIG_TOUCHSCREEN_TSC2007 is not set # CONFIG_INPUT_MISC is not set @@ -836,7 +701,6 @@ CONFIG_I2C_DAVINCI=y # # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_TINY_USB is not set # # Other I2C/SMBus bus drivers @@ -881,65 +745,7 @@ CONFIG_GPIO_PCF857X=m # # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_AD7414 is not set -# CONFIG_SENSORS_AD7418 is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADT7462 is not set -# CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7473 is not set -# CONFIG_SENSORS_ADT7475 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_F75375S is not set -# CONFIG_SENSORS_G760A is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_LM93 is not set -# CONFIG_SENSORS_LTC4215 is not set -# CONFIG_SENSORS_LTC4245 is not set -# CONFIG_SENSORS_LM95241 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX6650 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_SHT15 is not set -# CONFIG_SENSORS_DME1737 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_ADS7828 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83L786NG is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set +# CONFIG_HWMON is not set # CONFIG_THERMAL is not set # CONFIG_THERMAL_HWMON is not set CONFIG_WATCHDOG=y @@ -949,12 +755,7 @@ CONFIG_WATCHDOG=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_DAVINCI_WATCHDOG=m - -# -# USB-based Watchdog Cards -# -# CONFIG_USBPCWATCHDOG is not set +# CONFIG_DAVINCI_WATCHDOG is not set CONFIG_SSB_POSSIBLE=y # @@ -988,79 +789,21 @@ CONFIG_SSB_POSSIBLE=y # # Multimedia core support # -CONFIG_VIDEO_DEV=y -CONFIG_VIDEO_V4L2_COMMON=y -CONFIG_VIDEO_ALLOW_V4L1=y -CONFIG_VIDEO_V4L1_COMPAT=y +# CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set -CONFIG_VIDEO_MEDIA=y +# CONFIG_VIDEO_MEDIA is not set # # Multimedia drivers # -# CONFIG_MEDIA_ATTACH is not set -CONFIG_MEDIA_TUNER=y -# CONFIG_MEDIA_TUNER_CUSTOMISE is not set -CONFIG_MEDIA_TUNER_SIMPLE=y -CONFIG_MEDIA_TUNER_TDA8290=y -CONFIG_MEDIA_TUNER_TDA9887=y -CONFIG_MEDIA_TUNER_TEA5761=y -CONFIG_MEDIA_TUNER_TEA5767=y -CONFIG_MEDIA_TUNER_MT20XX=y -CONFIG_MEDIA_TUNER_XC2028=y -CONFIG_MEDIA_TUNER_XC5000=y -CONFIG_MEDIA_TUNER_MC44S803=y -CONFIG_VIDEO_V4L2=y -CONFIG_VIDEO_V4L1=y -CONFIG_VIDEO_CAPTURE_DRIVERS=y -# CONFIG_VIDEO_ADV_DEBUG is not set -# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -CONFIG_VIDEO_HELPER_CHIPS_AUTO=y -# CONFIG_VIDEO_VIVI is not set -# CONFIG_VIDEO_TVP5146 is not set -# CONFIG_VIDEO_CPIA is not set -# CONFIG_VIDEO_CPIA2 is not set -# CONFIG_VIDEO_SAA5246A is not set -# CONFIG_VIDEO_SAA5249 is not set -# CONFIG_SOC_CAMERA is not set -# CONFIG_V4L_USB_DRIVERS is not set -# CONFIG_RADIO_ADAPTERS is not set -CONFIG_DAB=y -# CONFIG_USB_DABUSB is not set +# CONFIG_DAB is not set # # Graphics support # # CONFIG_VGASTATE is not set -CONFIG_VIDEO_OUTPUT_CONTROL=m -CONFIG_FB=y -CONFIG_FIRMWARE_EDID=y -# CONFIG_FB_DDC is not set -# CONFIG_FB_BOOT_VESA_SUPPORT is not set -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -# CONFIG_FB_SYS_FILLRECT is not set -# CONFIG_FB_SYS_COPYAREA is not set -# CONFIG_FB_SYS_IMAGEBLIT is not set -# CONFIG_FB_FOREIGN_ENDIAN is not set -# CONFIG_FB_SYS_FOPS is not set -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set - -# -# Frame buffer hardware drivers -# -# CONFIG_FB_S1D13XXX is not set -CONFIG_FB_DAVINCI=y -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FB_METRONOME is not set -# CONFIG_FB_MB862XX is not set -# CONFIG_FB_BROADSHEET is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -1073,16 +816,6 @@ CONFIG_FB_DAVINCI=y # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -# CONFIG_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y -CONFIG_LOGO=y -CONFIG_LOGO_LINUX_MONO=y -CONFIG_LOGO_LINUX_VGA16=y -CONFIG_LOGO_LINUX_CLUT224=y CONFIG_SOUND=m # CONFIG_SOUND_OSS_CORE is not set CONFIG_SND=m @@ -1104,176 +837,17 @@ CONFIG_SND_DRIVERS=y # CONFIG_SND_SERIAL_U16550 is not set # CONFIG_SND_MPU401 is not set CONFIG_SND_ARM=y -CONFIG_SND_USB=y -# CONFIG_SND_USB_AUDIO is not set -# CONFIG_SND_USB_CAIAQ is not set CONFIG_SND_SOC=m CONFIG_SND_DAVINCI_SOC=m CONFIG_SND_SOC_I2C_AND_SPI=m # CONFIG_SND_SOC_ALL_CODECS is not set # CONFIG_SOUND_PRIME is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=m -# CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=m -# CONFIG_HID_PID is not set -# CONFIG_USB_HIDDEV is not set - -# -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set - -# -# Special HID drivers -# -CONFIG_HID_A4TECH=m -CONFIG_HID_APPLE=m -CONFIG_HID_BELKIN=m -CONFIG_HID_CHERRY=m -CONFIG_HID_CHICONY=m -CONFIG_HID_CYPRESS=m -# CONFIG_DRAGONRISE_FF is not set -CONFIG_HID_EZKEY=m -# CONFIG_HID_KYE is not set -CONFIG_HID_GYRATION=m -# CONFIG_HID_KENSINGTON is not set -CONFIG_HID_LOGITECH=m -# CONFIG_LOGITECH_FF is not set -# CONFIG_LOGIRUMBLEPAD2_FF is not set -CONFIG_HID_MICROSOFT=m -CONFIG_HID_MONTEREY=m -# CONFIG_HID_NTRIG is not set -CONFIG_HID_PANTHERLORD=m -# CONFIG_PANTHERLORD_FF is not set -CONFIG_HID_PETALYNX=m -CONFIG_HID_SAMSUNG=m -CONFIG_HID_SONY=m -CONFIG_HID_SUNPLUS=m -# CONFIG_GREENASIA_FF is not set -# CONFIG_HID_TOPSEED is not set -# CONFIG_THRUSTMASTER_FF is not set -# CONFIG_ZEROPLUS_FF is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set -CONFIG_USB=m -# CONFIG_USB_DEBUG is not set -# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -CONFIG_USB_DEVICE_CLASS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -CONFIG_USB_MON=m -# CONFIG_USB_WUSB is not set -# CONFIG_USB_WUSB_CBAF is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -# CONFIG_USB_OXU210HP_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1760_HCD is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_HWA_HCD is not set -CONFIG_USB_MUSB_HDRC=m -CONFIG_USB_MUSB_SOC=y - -# -# DaVinci 35x and 644x USB support -# +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set # CONFIG_USB_MUSB_HOST is not set -CONFIG_USB_MUSB_PERIPHERAL=y +# CONFIG_USB_MUSB_PERIPHERAL is not set # CONFIG_USB_MUSB_OTG is not set -CONFIG_USB_GADGET_MUSB_HDRC=y -CONFIG_MUSB_PIO_ONLY=y -# CONFIG_USB_MUSB_DEBUG is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_WDM is not set -# CONFIG_USB_TMC is not set - -# -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may -# - -# -# also be needed; see USB_STORAGE Help for more info -# -CONFIG_USB_STORAGE=m -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB port drivers -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_SEVSEG is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -CONFIG_USB_TEST=m -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set -CONFIG_USB_GADGET=m -# CONFIG_USB_GADGET_DEBUG is not set -CONFIG_USB_GADGET_DEBUG_FILES=y -CONFIG_USB_GADGET_DEBUG_FS=y -CONFIG_USB_GADGET_VBUS_DRAW=2 -CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_MUSB_HDRC is not set # CONFIG_USB_GADGET_AT91 is not set # CONFIG_USB_GADGET_ATMEL_USBA is not set # CONFIG_USB_GADGET_FSL_USB2 is not set @@ -1290,121 +864,20 @@ CONFIG_USB_GADGET_SELECTED=y # CONFIG_USB_GADGET_NET2280 is not set # CONFIG_USB_GADGET_GOKU is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set -CONFIG_USB_GADGET_DUALSPEED=y -CONFIG_USB_ZERO=m -CONFIG_USB_ETH=m -CONFIG_USB_ETH_RNDIS=y -CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m -# CONFIG_USB_FILE_STORAGE_TEST is not set -CONFIG_USB_G_SERIAL=m +# CONFIG_USB_ZERO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set # CONFIG_USB_MIDI_GADGET is not set -CONFIG_USB_G_PRINTER=m -CONFIG_USB_CDC_COMPOSITE=m - -# -# OTG and related infrastructure -# -CONFIG_USB_OTG_UTILS=y -# CONFIG_USB_GPIO_VBUS is not set -# CONFIG_NOP_USB_XCEIV is not set -CONFIG_MMC=m -# CONFIG_MMC_DEBUG is not set -# CONFIG_MMC_UNSAFE_RESUME is not set - -# -# MMC/SD/SDIO Card Drivers -# -CONFIG_MMC_BLOCK=m -# CONFIG_MMC_BLOCK_BOUNCE is not set -# CONFIG_SDIO_UART is not set -# CONFIG_MMC_TEST is not set - -# -# MMC/SD/SDIO Host Controller Drivers -# -# CONFIG_MMC_SDHCI is not set -CONFIG_MMC_DAVINCI=m +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_ACCESSIBILITY is not set -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=m - -# -# LED drivers -# -# CONFIG_LEDS_PCA9532 is not set -CONFIG_LEDS_GPIO=m -CONFIG_LEDS_GPIO_PLATFORM=y -# CONFIG_LEDS_LP5521 is not set -# CONFIG_LEDS_PCA955X is not set -# CONFIG_LEDS_BD2802 is not set - -# -# LED Triggers -# -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=m -# CONFIG_LEDS_TRIGGER_IDE_DISK is not set -CONFIG_LEDS_TRIGGER_HEARTBEAT=m -# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set -# CONFIG_LEDS_TRIGGER_GPIO is not set -# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set - -# -# iptables trigger is under Netfilter config (LED target) -# +# CONFIG_NEW_LEDS is not set CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=m - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set -# CONFIG_RTC_DRV_RX8581 is not set - -# -# SPI RTC drivers -# - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# +# CONFIG_RTC_CLASS is not set # CONFIG_DMADEVICES is not set # CONFIG_AUXDISPLAY is not set # CONFIG_REGULATOR is not set @@ -1485,17 +958,6 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -CONFIG_JFFS2_FS=m -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_FS_XATTR is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -# CONFIG_JFFS2_LZO is not set -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=y # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1784,8 +1246,8 @@ CONFIG_CRC32=y # CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=m CONFIG_DECOMPRESS_GZIP=y +CONFIG_GENERIC_ALLOCATOR=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y diff --git a/recipes/linux/linux-davinci/da850-omapl138-evm/defconfig b/recipes/linux/linux-davinci/da850-omapl138-evm/defconfig new file mode 100644 index 0000000000..3432146ac6 --- /dev/null +++ b/recipes/linux/linux-davinci/da850-omapl138-evm/defconfig @@ -0,0 +1,1235 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.31-rc7-davinci1 +# Mon Sep 14 12:33:57 2009 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Performance Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +# CONFIG_FREEZER is not set + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +CONFIG_ARCH_DAVINCI=y +# CONFIG_ARCH_OMAP is not set +CONFIG_CP_INTC=y + +# +# TI DaVinci Implementations +# + +# +# DaVinci Core Type +# +# CONFIG_ARCH_DAVINCI_DM644x is not set +# CONFIG_ARCH_DAVINCI_DM355 is not set +# CONFIG_ARCH_DAVINCI_DM646x is not set +# CONFIG_ARCH_DAVINCI_DA830 is not set +CONFIG_ARCH_DAVINCI_DA850=y +CONFIG_ARCH_DAVINCI_DA8XX=y +# CONFIG_ARCH_DAVINCI_DM365 is not set + +# +# DaVinci Board Type +# +CONFIG_MACH_DAVINCI_DA850_EVM=y +CONFIG_DAVINCI_MUX=y +# CONFIG_DAVINCI_MUX_DEBUG is not set +# CONFIG_DAVINCI_MUX_WARNINGS is not set +CONFIG_DAVINCI_RESET_CLOCKS=y +# CONFIG_DAVINCI_MCBSP is not set +# CONFIG_DA850_RMII is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_COMMON_CLKDEV=y + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_LEDS=y +# CONFIG_LEDS_CPU is not set +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +# CONFIG_CPU_FREQ is not set +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_NETLINK_QUEUE is not set +# CONFIG_NETFILTER_NETLINK_LOG is not set +# CONFIG_NF_CONNTRACK is not set +# CONFIG_NETFILTER_XTABLES is not set +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_NF_DEFRAG_IPV4 is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set + +# +# IPv6: Netfilter Configuration +# +# CONFIG_IP6_NF_QUEUE is not set +# CONFIG_IP6_NF_IPTABLES is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=1 +CONFIG_BLK_DEV_RAM_SIZE=32768 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=y +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=m +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +CONFIG_LXT_PHY=y +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +CONFIG_LSI_ET1011C_PHY=y +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +CONFIG_TI_DAVINCI_EMAC=y +# CONFIG_DM9000 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +CONFIG_NETCONSOLE=y +# CONFIG_NETCONSOLE_DYNAMIC is not set +CONFIG_NETPOLL=y +CONFIG_NETPOLL_TRAP=y +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=m +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_EVBUG=m + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=m +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_KEYBOARD_GPIO=y +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +CONFIG_KEYBOARD_XTKBD=m +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +# CONFIG_VT_CONSOLE is not set +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=3 +CONFIG_SERIAL_8250_RUNTIME_UARTS=3 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=8 +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=m +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +CONFIG_I2C_DAVINCI=y +# CONFIG_I2C_DESIGNWARE is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_SPI is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +CONFIG_GPIO_PCF857X=m + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_DAVINCI_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_SOUND=m +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_JACK=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +CONFIG_SND_ARM=y +CONFIG_SND_SOC=m +CONFIG_SND_DAVINCI_SOC=m +# CONFIG_SND_DA850_SOC_EVM is not set +CONFIG_SND_SOC_I2C_AND_SPI=m +# CONFIG_SND_SOC_ALL_CODECS is not set +# CONFIG_SOUND_PRIME is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_REGULATOR is not set +# CONFIG_UIO is not set +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +CONFIG_XFS_FS=m +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_DEBUG is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +CONFIG_MINIX_FS=m +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +CONFIG_ROOT_NFS=y +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +# CONFIG_NFSD_V4 is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +CONFIG_TIMER_STATS=y +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_KMEMLEAK is not set +CONFIG_DEBUG_PREEMPT=y +CONFIG_DEBUG_RT_MUTEXES=y +CONFIG_DEBUG_PI_LIST=y +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_ARM_UNWIND=y +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_HW is not set +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=m +# CONFIG_CRC16 is not set +CONFIG_CRC_T10DIF=m +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/recipes/linux/linux-davinci/dm355-evm/defconfig b/recipes/linux/linux-davinci/dm355-evm/defconfig index 6f20c1ab98..48fce30ff1 100644 --- a/recipes/linux/linux-davinci/dm355-evm/defconfig +++ b/recipes/linux/linux-davinci/dm355-evm/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31-rc2-davinci1 -# Thu Jul 16 16:25:33 2009 +# Linux kernel version: 2.6.31-rc7-davinci1 +# Fri Sep 4 15:07:05 2009 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -60,8 +60,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y @@ -201,6 +200,7 @@ CONFIG_ARCH_DAVINCI_DMx=y CONFIG_ARCH_DAVINCI_DM355=y # CONFIG_ARCH_DAVINCI_DM646x is not set # CONFIG_ARCH_DAVINCI_DA830 is not set +# CONFIG_ARCH_DAVINCI_DA850 is not set # CONFIG_ARCH_DAVINCI_DM365 is not set # @@ -212,6 +212,7 @@ CONFIG_DAVINCI_MUX=y # CONFIG_DAVINCI_MUX_DEBUG is not set # CONFIG_DAVINCI_MUX_WARNINGS is not set CONFIG_DAVINCI_RESET_CLOCKS=y +CONFIG_OSC_CLK_FREQ=27000000 # # Processor Type @@ -438,7 +439,17 @@ CONFIG_NETFILTER_ADVANCED=y # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_WIRELESS is not set +CONFIG_WIRELESS=y +CONFIG_CFG80211=y +# CONFIG_CFG80211_REG_DEBUG is not set +# CONFIG_CFG80211_DEBUGFS is not set +CONFIG_WIRELESS_OLD_REGULATORY=y +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_LIB80211=y +# CONFIG_LIB80211_DEBUG is not set +# CONFIG_MAC80211 is not set +CONFIG_MAC80211_DEFAULT_PS_VALUE=0 # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -453,7 +464,9 @@ CONFIG_NETFILTER_ADVANCED=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" # CONFIG_DEBUG_DRIVER is not set # CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set @@ -666,6 +679,7 @@ CONFIG_DM9000_DEBUGLEVEL=4 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set @@ -673,7 +687,16 @@ CONFIG_DM9000_DEBUGLEVEL=4 # Wireless LAN # # CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +CONFIG_WLAN_80211=y +CONFIG_LIBERTAS=m +# CONFIG_LIBERTAS_USB is not set +CONFIG_LIBERTAS_SDIO=m +# CONFIG_LIBERTAS_SPI is not set +CONFIG_LIBERTAS_DEBUG=y +# CONFIG_USB_ZD1201 is not set +# CONFIG_USB_NET_RNDIS_WLAN is not set +# CONFIG_HOSTAP is not set +# CONFIG_IWM is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -1037,11 +1060,12 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y # CONFIG_VIDEO_BT866 is not set # CONFIG_VIDEO_KS0127 is not set # CONFIG_VIDEO_OV7670 is not set +# CONFIG_VIDEO_MT9V011 is not set # CONFIG_VIDEO_TCM825X is not set # CONFIG_VIDEO_SAA7110 is not set # CONFIG_VIDEO_SAA711X is not set # CONFIG_VIDEO_SAA717X is not set -CONFIG_VIDEO_TVP514X=y +CONFIG_VIDEO_TVP514X=m # CONFIG_VIDEO_TVP5150 is not set # CONFIG_VIDEO_VPX3220 is not set @@ -1063,15 +1087,24 @@ CONFIG_VIDEO_TVP514X=y # CONFIG_VIDEO_ADV7170 is not set # CONFIG_VIDEO_ADV7175 is not set # CONFIG_VIDEO_THS7303 is not set +# CONFIG_VIDEO_THS7353 is not set # CONFIG_VIDEO_ADV7343 is not set +# CONFIG_VIDEO_THS8200 is not set # # Video improvement chips # # CONFIG_VIDEO_UPD64031A is not set # CONFIG_VIDEO_UPD64083 is not set +# CONFIG_VIDEO_DAVINCI_DISPLAY is not set +CONFIG_DAVINCI_ENC_MNGR=y +CONFIG_ENC_MNGR_MAX_CHANNELS=1 +CONFIG_DAVINCI_OSD=y +CONFIG_DAVINCI_VPBE_ENCODER=y +CONFIG_DAVINCI_LOGICPD_ENCODER=y +# CONFIG_DAVINCI_AVNET_ENCODER is not set # CONFIG_VIDEO_VIVI is not set -CONFIG_VIDEO_VPSS_SYSTEM=m +CONFIG_VIDEO_VPSS_SYSTEM=y CONFIG_VIDEO_VPFE_CAPTURE=m CONFIG_VIDEO_DM355_CCDC=m CONFIG_VIDEO_DM355_AF=m @@ -1358,7 +1391,7 @@ CONFIG_MMC=y # CONFIG_MMC_BLOCK=y # CONFIG_MMC_BLOCK_BOUNCE is not set -# CONFIG_SDIO_UART is not set +CONFIG_SDIO_UART=y # CONFIG_MMC_TEST is not set # @@ -1684,10 +1717,19 @@ CONFIG_CRYPTO=y # Crypto core or helper # # CONFIG_CRYPTO_FIPS is not set -# CONFIG_CRYPTO_MANAGER is not set -# CONFIG_CRYPTO_MANAGER2 is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y # CONFIG_CRYPTO_CRYPTD is not set # CONFIG_CRYPTO_AUTHENC is not set # CONFIG_CRYPTO_TEST is not set @@ -1705,7 +1747,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_CBC is not set # CONFIG_CRYPTO_CTR is not set # CONFIG_CRYPTO_CTS is not set -# CONFIG_CRYPTO_ECB is not set +CONFIG_CRYPTO_ECB=y # CONFIG_CRYPTO_LRW is not set # CONFIG_CRYPTO_PCBC is not set # CONFIG_CRYPTO_XTS is not set @@ -1736,9 +1778,9 @@ CONFIG_CRYPTO=y # # Ciphers # -# CONFIG_CRYPTO_AES is not set +CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_ARC4 is not set +CONFIG_CRYPTO_ARC4=y # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_CAST5 is not set diff --git a/recipes/linux/linux-davinci/dm365-evm/defconfig b/recipes/linux/linux-davinci/dm365-evm/defconfig index d232205d7a..a26e63c2f1 100644 --- a/recipes/linux/linux-davinci/dm365-evm/defconfig +++ b/recipes/linux/linux-davinci/dm365-evm/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31-rc4-davinci1 -# Tue Aug 11 11:10:39 2009 +# Linux kernel version: 2.6.31-rc7-davinci1 +# Tue Sep 8 16:36:50 2009 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -435,7 +435,17 @@ CONFIG_NETFILTER_ADVANCED=y # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_WIRELESS is not set +CONFIG_WIRELESS=y +CONFIG_CFG80211=y +# CONFIG_CFG80211_REG_DEBUG is not set +# CONFIG_CFG80211_DEBUGFS is not set +CONFIG_WIRELESS_OLD_REGULATORY=y +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_LIB80211=y +# CONFIG_LIB80211_DEBUG is not set +# CONFIG_MAC80211 is not set +CONFIG_MAC80211_DEFAULT_PS_VALUE=0 # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -450,7 +460,9 @@ CONFIG_NETFILTER_ADVANCED=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" # CONFIG_DEBUG_DRIVER is not set # CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set @@ -669,7 +681,16 @@ CONFIG_TI_DAVINCI_EMAC=y # Wireless LAN # # CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +CONFIG_WLAN_80211=y +CONFIG_LIBERTAS=m +# CONFIG_LIBERTAS_USB is not set +CONFIG_LIBERTAS_SDIO=m +# CONFIG_LIBERTAS_SPI is not set +CONFIG_LIBERTAS_DEBUG=y +# CONFIG_USB_ZD1201 is not set +# CONFIG_USB_NET_RNDIS_WLAN is not set +# CONFIG_HOSTAP is not set +# CONFIG_IWM is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -707,7 +728,7 @@ CONFIG_NET_POLL_CONTROLLER=y # Input device support # CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set +CONFIG_INPUT_FF_MEMLESS=y # CONFIG_INPUT_POLLDEV is not set # @@ -726,7 +747,16 @@ CONFIG_INPUT_EVBUG=m # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +# CONFIG_INPUT_UINPUT is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +CONFIG_INPUT_DM365EVM=m # # Hardware I/O ports @@ -753,8 +783,8 @@ CONFIG_DEVKMEM=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=3 -CONFIG_SERIAL_8250_RUNTIME_UARTS=3 +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 # CONFIG_SERIAL_8250_EXTENDED is not set # @@ -962,14 +992,164 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set # CONFIG_EZX_PCAP is not set -# CONFIG_MEDIA_SUPPORT is not set +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +# CONFIG_VIDEO_ALLOW_V4L1 is not set +# CONFIG_VIDEO_V4L1_COMPAT is not set +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=y +# CONFIG_MEDIA_TUNER_CUSTOMISE is not set +CONFIG_MEDIA_TUNER_SIMPLE=y +CONFIG_MEDIA_TUNER_TDA8290=y +CONFIG_MEDIA_TUNER_TDA9887=y +CONFIG_MEDIA_TUNER_TEA5761=y +CONFIG_MEDIA_TUNER_TEA5767=y +CONFIG_MEDIA_TUNER_MT20XX=y +CONFIG_MEDIA_TUNER_XC2028=y +CONFIG_MEDIA_TUNER_XC5000=y +CONFIG_MEDIA_TUNER_MC44S803=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_DMA_CONTIG=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set + +# +# Encoders/decoders and other helper chips +# + +# +# Audio decoders +# +# CONFIG_VIDEO_TVAUDIO is not set +# CONFIG_VIDEO_TDA7432 is not set +# CONFIG_VIDEO_TDA9840 is not set +# CONFIG_VIDEO_TDA9875 is not set +# CONFIG_VIDEO_TEA6415C is not set +# CONFIG_VIDEO_TEA6420 is not set +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_CS5345 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_M52790 is not set +# CONFIG_VIDEO_TLV320AIC23B is not set +# CONFIG_VIDEO_WM8775 is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_VP27SMPX is not set + +# +# RDS decoders +# +# CONFIG_VIDEO_SAA6588 is not set + +# +# Video decoders +# +# CONFIG_VIDEO_BT819 is not set +# CONFIG_VIDEO_BT856 is not set +# CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_KS0127 is not set +# CONFIG_VIDEO_OV7670 is not set +# CONFIG_VIDEO_MT9V011 is not set +# CONFIG_VIDEO_TCM825X is not set +# CONFIG_VIDEO_SAA7110 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_SAA717X is not set +CONFIG_VIDEO_TVP514X=m +# CONFIG_VIDEO_TVP5150 is not set +# CONFIG_VIDEO_VPX3220 is not set + +# +# Video and audio decoders +# +# CONFIG_VIDEO_CX25840 is not set + +# +# MPEG video encoders +# +# CONFIG_VIDEO_CX2341X is not set + +# +# Video encoders +# +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_SAA7185 is not set +# CONFIG_VIDEO_ADV7170 is not set +# CONFIG_VIDEO_ADV7175 is not set +# CONFIG_VIDEO_THS7303 is not set +# CONFIG_VIDEO_THS7353 is not set +# CONFIG_VIDEO_ADV7343 is not set +# CONFIG_VIDEO_THS8200 is not set + +# +# Video improvement chips +# +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set +# CONFIG_VIDEO_DAVINCI_DISPLAY is not set +CONFIG_DAVINCI_ENC_MNGR=y +CONFIG_ENC_MNGR_MAX_CHANNELS=1 +CONFIG_DAVINCI_OSD=y +CONFIG_DAVINCI_VPBE_ENCODER=y +CONFIG_DAVINCI_LOGICPD_ENCODER=y +# CONFIG_DAVINCI_AVNET_ENCODER is not set +# CONFIG_VIDEO_VIVI is not set +CONFIG_VIDEO_VPSS_SYSTEM=y +CONFIG_VIDEO_VPFE_CAPTURE=m +CONFIG_VIDEO_DM365_ISIF=m +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_SOC_CAMERA is not set +# CONFIG_SOC_CAMERA_MT9T031 is not set +# CONFIG_V4L_USB_DRIVERS is not set +# CONFIG_RADIO_ADAPTERS is not set +# CONFIG_DAB is not set # # Graphics support # # CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +CONFIG_FB_DAVINCI=y +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -982,8 +1162,101 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y -# CONFIG_SOUND is not set -# CONFIG_HID_SUPPORT is not set +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_JACK=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +CONFIG_SND_ARM=y +CONFIG_SND_SPI=y +# CONFIG_SND_USB is not set +CONFIG_SND_SOC=y +CONFIG_SND_DAVINCI_SOC=m +CONFIG_SND_DAVINCI_SOC_I2S=m +CONFIG_SND_DAVINCI_SOC_EVM=m +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SOC_TLV320AIC3X=m +# CONFIG_SOUND_PRIME is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=m +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CYPRESS=m +# CONFIG_HID_DRAGONRISE is not set +CONFIG_HID_EZKEY=m +# CONFIG_HID_KYE is not set +CONFIG_HID_GYRATION=m +# CONFIG_HID_KENSINGTON is not set +CONFIG_HID_LOGITECH=m +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +# CONFIG_HID_NTRIG is not set +CONFIG_HID_PANTHERLORD=m +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_ZEROPLUS is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set @@ -1023,7 +1296,7 @@ CONFIG_USB_MUSB_HDRC=m CONFIG_USB_MUSB_SOC=y # -# DaVinci 35x and 644x USB support +# DaVinci 35x, 36x, 644x USB support # CONFIG_USB_MUSB_HOST=y # CONFIG_USB_MUSB_PERIPHERAL is not set @@ -1116,7 +1389,7 @@ CONFIG_MMC=y # CONFIG_MMC_BLOCK=y # CONFIG_MMC_BLOCK_BOUNCE is not set -# CONFIG_SDIO_UART is not set +CONFIG_SDIO_UART=y # CONFIG_MMC_TEST is not set # @@ -1442,10 +1715,19 @@ CONFIG_CRYPTO=y # Crypto core or helper # # CONFIG_CRYPTO_FIPS is not set -# CONFIG_CRYPTO_MANAGER is not set -# CONFIG_CRYPTO_MANAGER2 is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y # CONFIG_CRYPTO_CRYPTD is not set # CONFIG_CRYPTO_AUTHENC is not set # CONFIG_CRYPTO_TEST is not set @@ -1463,7 +1745,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_CBC is not set # CONFIG_CRYPTO_CTR is not set # CONFIG_CRYPTO_CTS is not set -# CONFIG_CRYPTO_ECB is not set +CONFIG_CRYPTO_ECB=y # CONFIG_CRYPTO_LRW is not set # CONFIG_CRYPTO_PCBC is not set # CONFIG_CRYPTO_XTS is not set @@ -1494,9 +1776,9 @@ CONFIG_CRYPTO=y # # Ciphers # -# CONFIG_CRYPTO_AES is not set +CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_ARC4 is not set +CONFIG_CRYPTO_ARC4=y # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_CAST5 is not set diff --git a/recipes/linux/linux-davinci/dm6446-evm/defconfig b/recipes/linux/linux-davinci/dm6446-evm/defconfig index 35756db09e..199f1f82d7 100644 --- a/recipes/linux/linux-davinci/dm6446-evm/defconfig +++ b/recipes/linux/linux-davinci/dm6446-evm/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31-rc2-davinci1 -# Fri Jul 17 14:28:31 2009 +# Linux kernel version: 2.6.31-rc7-davinci1 +# Thu Sep 17 19:02:02 2009 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -200,6 +200,7 @@ CONFIG_ARCH_DAVINCI_DM644x=y # CONFIG_ARCH_DAVINCI_DM355 is not set # CONFIG_ARCH_DAVINCI_DM646x is not set # CONFIG_ARCH_DAVINCI_DA830 is not set +# CONFIG_ARCH_DAVINCI_DA850 is not set # CONFIG_ARCH_DAVINCI_DM365 is not set # @@ -211,6 +212,7 @@ CONFIG_DAVINCI_MUX=y CONFIG_DAVINCI_MUX_DEBUG=y CONFIG_DAVINCI_MUX_WARNINGS=y CONFIG_DAVINCI_RESET_CLOCKS=y +CONFIG_OSC_CLK_FREQ=27000000 # # Processor Type @@ -463,7 +465,7 @@ CONFIG_MTD=m # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_TESTS is not set +CONFIG_MTD_TESTS=m # CONFIG_MTD_REDBOOT_PARTS is not set # CONFIG_MTD_AFS_PARTS is not set # CONFIG_MTD_AR7_PARTS is not set @@ -751,36 +753,11 @@ CONFIG_INPUT_EVBUG=m # # Input Device Drivers # -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=m -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -CONFIG_KEYBOARD_XTKBD=m -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -# CONFIG_KEYBOARD_LM8323 is not set -CONFIG_KEYBOARD_GPIO=y +# CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set -CONFIG_INPUT_TOUCHSCREEN=y -# CONFIG_TOUCHSCREEN_AD7879_I2C is not set -# CONFIG_TOUCHSCREEN_AD7879 is not set -# CONFIG_TOUCHSCREEN_EETI is not set -# CONFIG_TOUCHSCREEN_FUJITSU is not set -# CONFIG_TOUCHSCREEN_GUNZE is not set -# CONFIG_TOUCHSCREEN_ELO is not set -# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set -# CONFIG_TOUCHSCREEN_MTOUCH is not set -# CONFIG_TOUCHSCREEN_INEXIO is not set -# CONFIG_TOUCHSCREEN_MK712 is not set -# CONFIG_TOUCHSCREEN_PENMOUNT is not set -# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set -# CONFIG_TOUCHSCREEN_TOUCHWIN is not set -# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set -# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set -# CONFIG_TOUCHSCREEN_TSC2007 is not set -# CONFIG_TOUCHSCREEN_W90X900 is not set +# CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set # @@ -1027,7 +1004,87 @@ CONFIG_VIDEOBUF_DMA_CONTIG=y CONFIG_VIDEO_CAPTURE_DRIVERS=y # CONFIG_VIDEO_ADV_DEBUG is not set # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set + +# +# Encoders/decoders and other helper chips +# + +# +# Audio decoders +# +# CONFIG_VIDEO_TVAUDIO is not set +# CONFIG_VIDEO_TDA7432 is not set +# CONFIG_VIDEO_TDA9840 is not set +# CONFIG_VIDEO_TDA9875 is not set +# CONFIG_VIDEO_TEA6415C is not set +# CONFIG_VIDEO_TEA6420 is not set +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_CS5345 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_M52790 is not set +# CONFIG_VIDEO_TLV320AIC23B is not set +# CONFIG_VIDEO_WM8775 is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_VP27SMPX is not set + +# +# RDS decoders +# +# CONFIG_VIDEO_SAA6588 is not set + +# +# Video decoders +# +# CONFIG_VIDEO_BT819 is not set +# CONFIG_VIDEO_BT856 is not set +# CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_KS0127 is not set +# CONFIG_VIDEO_OV7670 is not set +# CONFIG_VIDEO_MT9V011 is not set +# CONFIG_VIDEO_TCM825X is not set +# CONFIG_VIDEO_SAA7110 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_SAA717X is not set +CONFIG_VIDEO_TVP514X=y +# CONFIG_VIDEO_TVP5150 is not set +# CONFIG_VIDEO_TVP7002 is not set +# CONFIG_VIDEO_VPX3220 is not set + +# +# Video and audio decoders +# +# CONFIG_VIDEO_CX25840 is not set + +# +# MPEG video encoders +# +# CONFIG_VIDEO_CX2341X is not set + +# +# Video encoders +# +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_SAA7185 is not set +# CONFIG_VIDEO_ADV7170 is not set +# CONFIG_VIDEO_ADV7175 is not set +# CONFIG_VIDEO_THS7303 is not set +# CONFIG_VIDEO_THS7353 is not set +# CONFIG_VIDEO_ADV7343 is not set +# CONFIG_VIDEO_THS8200 is not set + +# +# Video improvement chips +# +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set +# CONFIG_VIDEO_DAVINCI_DISPLAY is not set +CONFIG_DAVINCI_ENC_MNGR=y +CONFIG_ENC_MNGR_MAX_CHANNELS=1 +CONFIG_DAVINCI_OSD=y +CONFIG_DAVINCI_VPBE_ENCODER=y +CONFIG_DAVINCI_LOGICPD_ENCODER=y +# CONFIG_DAVINCI_AVNET_ENCODER is not set # CONFIG_VIDEO_VIVI is not set CONFIG_VIDEO_VPSS_SYSTEM=y CONFIG_VIDEO_VPFE_CAPTURE=y @@ -1035,55 +1092,9 @@ CONFIG_VIDEO_DM6446_CCDC=y # CONFIG_VIDEO_SAA5246A is not set # CONFIG_VIDEO_SAA5249 is not set # CONFIG_SOC_CAMERA is not set -CONFIG_SOC_CAMERA_MT9T031=y -CONFIG_V4L_USB_DRIVERS=y -# CONFIG_USB_VIDEO_CLASS is not set -CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -CONFIG_USB_GSPCA=m -# CONFIG_USB_M5602 is not set -# CONFIG_USB_STV06XX is not set -# CONFIG_USB_GSPCA_CONEX is not set -# CONFIG_USB_GSPCA_ETOMS is not set -# CONFIG_USB_GSPCA_FINEPIX is not set -# CONFIG_USB_GSPCA_MARS is not set -# CONFIG_USB_GSPCA_MR97310A is not set -# CONFIG_USB_GSPCA_OV519 is not set -# CONFIG_USB_GSPCA_OV534 is not set -# CONFIG_USB_GSPCA_PAC207 is not set -# CONFIG_USB_GSPCA_PAC7311 is not set -# CONFIG_USB_GSPCA_SONIXB is not set -# CONFIG_USB_GSPCA_SONIXJ is not set -# CONFIG_USB_GSPCA_SPCA500 is not set -# CONFIG_USB_GSPCA_SPCA501 is not set -# CONFIG_USB_GSPCA_SPCA505 is not set -# CONFIG_USB_GSPCA_SPCA506 is not set -# CONFIG_USB_GSPCA_SPCA508 is not set -# CONFIG_USB_GSPCA_SPCA561 is not set -# CONFIG_USB_GSPCA_SQ905 is not set -# CONFIG_USB_GSPCA_SQ905C is not set -# CONFIG_USB_GSPCA_STK014 is not set -# CONFIG_USB_GSPCA_SUNPLUS is not set -# CONFIG_USB_GSPCA_T613 is not set -# CONFIG_USB_GSPCA_TV8532 is not set -# CONFIG_USB_GSPCA_VC032X is not set -# CONFIG_USB_GSPCA_ZC3XX is not set -# CONFIG_VIDEO_PVRUSB2 is not set -# CONFIG_VIDEO_HDPVR is not set -# CONFIG_VIDEO_EM28XX is not set -# CONFIG_VIDEO_CX231XX is not set -# CONFIG_VIDEO_USBVISION is not set -# CONFIG_USB_ET61X251 is not set -# CONFIG_USB_SN9C102 is not set -# CONFIG_USB_ZC0301 is not set -CONFIG_USB_PWC_INPUT_EVDEV=y -# CONFIG_USB_ZR364XX is not set -# CONFIG_USB_STKWEBCAM is not set -# CONFIG_USB_S2255 is not set -CONFIG_RADIO_ADAPTERS=y -# CONFIG_USB_DSBR is not set -# CONFIG_USB_SI470X is not set -# CONFIG_USB_MR800 is not set -# CONFIG_RADIO_TEA5764 is not set +# CONFIG_SOC_CAMERA_MT9T031 is not set +# CONFIG_V4L_USB_DRIVERS is not set +# CONFIG_RADIO_ADAPTERS is not set # CONFIG_DAB is not set # @@ -1179,23 +1190,17 @@ CONFIG_SND_SOC_I2C_AND_SPI=y CONFIG_SND_SOC_TLV320AIC3X=y # CONFIG_SOUND_PRIME is not set CONFIG_HID_SUPPORT=y -CONFIG_HID=m +CONFIG_HID=y # CONFIG_HID_DEBUG is not set # CONFIG_HIDRAW is not set # # USB Input Devices # -CONFIG_USB_HID=m +CONFIG_USB_HID=y # CONFIG_HID_PID is not set # CONFIG_USB_HIDDEV is not set -# -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set - # # Special HID drivers # @@ -1210,10 +1215,10 @@ CONFIG_HID_EZKEY=m # CONFIG_HID_KYE is not set CONFIG_HID_GYRATION=m # CONFIG_HID_KENSINGTON is not set -CONFIG_HID_LOGITECH=m +CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set -CONFIG_HID_MICROSOFT=m +CONFIG_HID_MICROSOFT=y CONFIG_HID_MONTEREY=m # CONFIG_HID_NTRIG is not set CONFIG_HID_PANTHERLORD=m @@ -1231,7 +1236,7 @@ CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set # CONFIG_USB_ARCH_HAS_EHCI is not set -CONFIG_USB=m +CONFIG_USB=y # CONFIG_USB_DEBUG is not set # CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set @@ -1241,11 +1246,11 @@ CONFIG_USB=m CONFIG_USB_DEVICEFS=y CONFIG_USB_DEVICE_CLASS=y # CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_SUSPEND is not set -CONFIG_USB_OTG=y +CONFIG_USB_SUSPEND=y +# CONFIG_USB_OTG is not set # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set -CONFIG_USB_MON=m +# CONFIG_USB_MON is not set # CONFIG_USB_WUSB is not set # CONFIG_USB_WUSB_CBAF is not set @@ -1259,16 +1264,15 @@ CONFIG_USB_MON=m # CONFIG_USB_SL811_HCD is not set # CONFIG_USB_R8A66597_HCD is not set # CONFIG_USB_HWA_HCD is not set -CONFIG_USB_MUSB_HDRC=m +CONFIG_USB_MUSB_HDRC=y CONFIG_USB_MUSB_SOC=y # -# DaVinci 35x and 644x USB support +# DaVinci 35x, 36x, 644x USB support # -# CONFIG_USB_MUSB_HOST is not set +CONFIG_USB_MUSB_HOST=y # CONFIG_USB_MUSB_PERIPHERAL is not set -CONFIG_USB_MUSB_OTG=y -CONFIG_USB_GADGET_MUSB_HDRC=y +# CONFIG_USB_MUSB_OTG is not set CONFIG_USB_MUSB_HDRC_HCD=y # CONFIG_MUSB_PIO_ONLY is not set # CONFIG_USB_INVENTRA_DMA is not set @@ -1290,7 +1294,7 @@ CONFIG_USB_TI_CPPI_DMA=y # # also be needed; see USB_STORAGE Help for more info # -CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set @@ -1337,53 +1341,17 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_LD is not set # CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_IOWARRIOR is not set -CONFIG_USB_TEST=m +CONFIG_USB_TEST=y # CONFIG_USB_ISIGHTFW is not set # CONFIG_USB_VST is not set -CONFIG_USB_GADGET=m -# CONFIG_USB_GADGET_DEBUG is not set -CONFIG_USB_GADGET_DEBUG_FILES=y -CONFIG_USB_GADGET_DEBUG_FS=y -CONFIG_USB_GADGET_VBUS_DRAW=2 -CONFIG_USB_GADGET_SELECTED=y -# CONFIG_USB_GADGET_AT91 is not set -# CONFIG_USB_GADGET_ATMEL_USBA is not set -# CONFIG_USB_GADGET_FSL_USB2 is not set -# CONFIG_USB_GADGET_LH7A40X is not set -# CONFIG_USB_GADGET_OMAP is not set -# CONFIG_USB_GADGET_PXA25X is not set -# CONFIG_USB_GADGET_PXA27X is not set -# CONFIG_USB_GADGET_S3C_HSOTG is not set -# CONFIG_USB_GADGET_S3C2410 is not set -# CONFIG_USB_GADGET_IMX is not set -# CONFIG_USB_GADGET_M66592 is not set -# CONFIG_USB_GADGET_AMD5536UDC is not set -# CONFIG_USB_GADGET_FSL_QE is not set -# CONFIG_USB_GADGET_CI13XXX is not set -# CONFIG_USB_GADGET_NET2280 is not set -# CONFIG_USB_GADGET_GOKU is not set -# CONFIG_USB_GADGET_LANGWELL is not set -# CONFIG_USB_GADGET_DUMMY_HCD is not set -CONFIG_USB_GADGET_DUALSPEED=y -CONFIG_USB_ZERO=m -# CONFIG_USB_ZERO_HNPTEST is not set -# CONFIG_USB_AUDIO is not set -CONFIG_USB_ETH=m -CONFIG_USB_ETH_RNDIS=y -CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m -# CONFIG_USB_FILE_STORAGE_TEST is not set -CONFIG_USB_G_SERIAL=m -# CONFIG_USB_MIDI_GADGET is not set -CONFIG_USB_G_PRINTER=m -CONFIG_USB_CDC_COMPOSITE=m +# CONFIG_USB_GADGET is not set # # OTG and related infrastructure # CONFIG_USB_OTG_UTILS=y # CONFIG_USB_GPIO_VBUS is not set -CONFIG_NOP_USB_XCEIV=m +CONFIG_NOP_USB_XCEIV=y CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set # CONFIG_MMC_UNSAFE_RESUME is not set diff --git a/recipes/linux/linux-davinci/dm6467-evm/defconfig b/recipes/linux/linux-davinci/dm6467-evm/defconfig index ef6daf212d..5b2d5aefeb 100644 --- a/recipes/linux/linux-davinci/dm6467-evm/defconfig +++ b/recipes/linux/linux-davinci/dm6467-evm/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31-rc4-davinci1 -# Fri Aug 7 17:25:49 2009 +# Linux kernel version: 2.6.31-rc7-davinci1 +# Fri Sep 4 16:40:27 2009 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -211,6 +211,7 @@ CONFIG_DAVINCI_MUX=y CONFIG_DAVINCI_MUX_DEBUG=y CONFIG_DAVINCI_MUX_WARNINGS=y CONFIG_DAVINCI_RESET_CLOCKS=y +CONFIG_OSC_CLK_FREQ=27000000 # # Processor Type @@ -514,6 +515,8 @@ CONFIG_MTD_PHYSMAP=m # # Self-contained MTD device drivers # +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -556,7 +559,7 @@ CONFIG_BLK_DEV_LOOP=m # CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=1 -CONFIG_BLK_DEV_RAM_SIZE=32768 +CONFIG_BLK_DEV_RAM_SIZE=65536 # CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -571,6 +574,7 @@ CONFIG_MISC_DEVICES=y # EEPROM support # CONFIG_EEPROM_AT24=y +CONFIG_EEPROM_AT25=y # CONFIG_EEPROM_LEGACY is not set # CONFIG_EEPROM_MAX6875 is not set # CONFIG_EEPROM_93CX6 is not set @@ -681,6 +685,7 @@ CONFIG_TI_DAVINCI_EMAC=y CONFIG_DM9000=y CONFIG_DM9000_DEBUGLEVEL=4 # CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL is not set +# CONFIG_ENC28J60 is not set # CONFIG_ETHOC is not set # CONFIG_SMC911X is not set # CONFIG_SMSC911X is not set @@ -694,6 +699,7 @@ CONFIG_DM9000_DEBUGLEVEL=4 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set @@ -767,7 +773,10 @@ CONFIG_KEYBOARD_XTKBD=m # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set # CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879_SPI is not set # CONFIG_TOUCHSCREEN_AD7879 is not set # CONFIG_TOUCHSCREEN_EETI is not set # CONFIG_TOUCHSCREEN_FUJITSU is not set @@ -818,6 +827,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=3 # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y @@ -829,6 +839,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set +# CONFIG_VDCE is not set CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y @@ -870,7 +881,22 @@ CONFIG_I2C_DAVINCI=y # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set -# CONFIG_SPI is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_DAVINCI=y +CONFIG_SPI_BITBANG=y +CONFIG_SPI_GPIO=y + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set CONFIG_ARCH_REQUIRE_GPIOLIB=y CONFIG_GPIOLIB=y # CONFIG_DEBUG_GPIO is not set @@ -894,12 +920,15 @@ CONFIG_GPIO_PCF857X=y # # SPI GPIO expanders: # +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_AD7414 is not set # CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADCXX is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set @@ -920,6 +949,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set # CONFIG_SENSORS_LM75 is not set # CONFIG_SENSORS_LM77 is not set # CONFIG_SENSORS_LM78 is not set @@ -933,6 +963,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LTC4215 is not set # CONFIG_SENSORS_LTC4245 is not set # CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_MAX1111 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set @@ -955,6 +986,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_LIS3_SPI is not set # CONFIG_HWMON_DEBUG_CHIP is not set # CONFIG_THERMAL is not set # CONFIG_THERMAL_HWMON is not set @@ -997,41 +1029,15 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set # CONFIG_MEDIA_SUPPORT is not set # # Graphics support # # CONFIG_VGASTATE is not set -CONFIG_VIDEO_OUTPUT_CONTROL=m -CONFIG_FB=y -CONFIG_FIRMWARE_EDID=y -# CONFIG_FB_DDC is not set -# CONFIG_FB_BOOT_VESA_SUPPORT is not set -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -# CONFIG_FB_SYS_FILLRECT is not set -# CONFIG_FB_SYS_COPYAREA is not set -# CONFIG_FB_SYS_IMAGEBLIT is not set -# CONFIG_FB_FOREIGN_ENDIAN is not set -# CONFIG_FB_SYS_FOPS is not set -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set - -# -# Frame buffer hardware drivers -# -# CONFIG_FB_S1D13XXX is not set -CONFIG_FB_DAVINCI=y -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FB_METRONOME is not set -# CONFIG_FB_MB862XX is not set -# CONFIG_FB_BROADSHEET is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -1044,16 +1050,6 @@ CONFIG_FB_DAVINCI=y # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -# CONFIG_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y -CONFIG_LOGO=y -CONFIG_LOGO_LINUX_MONO=y -CONFIG_LOGO_LINUX_VGA16=y -CONFIG_LOGO_LINUX_CLUT224=y CONFIG_SOUND=m # CONFIG_SOUND_OSS_CORE is not set CONFIG_SND=m @@ -1080,6 +1076,7 @@ CONFIG_SND_DRIVERS=y # CONFIG_SND_SERIAL_U16550 is not set # CONFIG_SND_MPU401 is not set CONFIG_SND_ARM=y +CONFIG_SND_SPI=y CONFIG_SND_USB=y # CONFIG_SND_USB_AUDIO is not set # CONFIG_SND_USB_CAIAQ is not set @@ -1275,17 +1272,17 @@ CONFIG_USB_GADGET_SELECTED=y # CONFIG_USB_GADGET_LANGWELL is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set CONFIG_USB_GADGET_DUALSPEED=y -CONFIG_USB_ZERO=m +# CONFIG_USB_ZERO is not set # CONFIG_USB_AUDIO is not set CONFIG_USB_ETH=m CONFIG_USB_ETH_RNDIS=y CONFIG_USB_GADGETFS=m CONFIG_USB_FILE_STORAGE=m # CONFIG_USB_FILE_STORAGE_TEST is not set -CONFIG_USB_G_SERIAL=m +# CONFIG_USB_G_SERIAL is not set # CONFIG_USB_MIDI_GADGET is not set -CONFIG_USB_G_PRINTER=m -CONFIG_USB_CDC_COMPOSITE=m +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set # # OTG and related infrastructure @@ -1310,6 +1307,7 @@ CONFIG_MMC_BLOCK=m # # CONFIG_MMC_SDHCI is not set CONFIG_MMC_DAVINCI=m +# CONFIG_MMC_SPI is not set # CONFIG_MEMSTICK is not set # CONFIG_ACCESSIBILITY is not set CONFIG_NEW_LEDS=y @@ -1323,6 +1321,7 @@ CONFIG_LEDS_GPIO=m CONFIG_LEDS_GPIO_PLATFORM=y # CONFIG_LEDS_LP3944 is not set # CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set # CONFIG_LEDS_BD2802 is not set # @@ -1372,6 +1371,13 @@ CONFIG_RTC_INTF_DEV=y # # SPI RTC drivers # +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set # # Platform RTC drivers @@ -1473,7 +1479,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y # CONFIG_JFFS2_FS_WBUF_VERIFY is not set diff --git a/recipes/linux/linux-davinci/dm6467t-evm/defconfig b/recipes/linux/linux-davinci/dm6467t-evm/defconfig index 0865a8a707..a4f136c245 100644 --- a/recipes/linux/linux-davinci/dm6467t-evm/defconfig +++ b/recipes/linux/linux-davinci/dm6467t-evm/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31-rc4-davinci1 -# Mon Aug 17 21:00:44 2009 +# Linux kernel version: 2.6.31-rc7-davinci1 +# Fri Sep 4 16:43:12 2009 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -515,6 +515,8 @@ CONFIG_MTD_PHYSMAP=m # # Self-contained MTD device drivers # +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -572,6 +574,7 @@ CONFIG_MISC_DEVICES=y # EEPROM support # CONFIG_EEPROM_AT24=y +CONFIG_EEPROM_AT25=y # CONFIG_EEPROM_LEGACY is not set # CONFIG_EEPROM_MAX6875 is not set # CONFIG_EEPROM_93CX6 is not set @@ -682,6 +685,7 @@ CONFIG_TI_DAVINCI_EMAC=y CONFIG_DM9000=y CONFIG_DM9000_DEBUGLEVEL=4 # CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL is not set +# CONFIG_ENC28J60 is not set # CONFIG_ETHOC is not set # CONFIG_SMC911X is not set # CONFIG_SMSC911X is not set @@ -695,6 +699,7 @@ CONFIG_DM9000_DEBUGLEVEL=4 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set @@ -768,7 +773,10 @@ CONFIG_KEYBOARD_XTKBD=m # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set # CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879_SPI is not set # CONFIG_TOUCHSCREEN_AD7879 is not set # CONFIG_TOUCHSCREEN_EETI is not set # CONFIG_TOUCHSCREEN_FUJITSU is not set @@ -819,6 +827,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=3 # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y @@ -830,6 +839,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set +# CONFIG_VDCE is not set CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y @@ -871,7 +881,22 @@ CONFIG_I2C_DAVINCI=y # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set -# CONFIG_SPI is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_DAVINCI=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_GPIO=m + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set CONFIG_ARCH_REQUIRE_GPIOLIB=y CONFIG_GPIOLIB=y # CONFIG_DEBUG_GPIO is not set @@ -895,12 +920,15 @@ CONFIG_GPIO_PCF857X=y # # SPI GPIO expanders: # +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_AD7414 is not set # CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADCXX is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set @@ -921,6 +949,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set # CONFIG_SENSORS_LM75 is not set # CONFIG_SENSORS_LM77 is not set # CONFIG_SENSORS_LM78 is not set @@ -934,6 +963,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LTC4215 is not set # CONFIG_SENSORS_LTC4245 is not set # CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_MAX1111 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set @@ -956,6 +986,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_LIS3_SPI is not set # CONFIG_HWMON_DEBUG_CHIP is not set # CONFIG_THERMAL is not set # CONFIG_THERMAL_HWMON is not set @@ -998,41 +1029,15 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set # CONFIG_MEDIA_SUPPORT is not set # # Graphics support # # CONFIG_VGASTATE is not set -CONFIG_VIDEO_OUTPUT_CONTROL=m -CONFIG_FB=y -CONFIG_FIRMWARE_EDID=y -# CONFIG_FB_DDC is not set -# CONFIG_FB_BOOT_VESA_SUPPORT is not set -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -# CONFIG_FB_SYS_FILLRECT is not set -# CONFIG_FB_SYS_COPYAREA is not set -# CONFIG_FB_SYS_IMAGEBLIT is not set -# CONFIG_FB_FOREIGN_ENDIAN is not set -# CONFIG_FB_SYS_FOPS is not set -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set - -# -# Frame buffer hardware drivers -# -# CONFIG_FB_S1D13XXX is not set -CONFIG_FB_DAVINCI=y -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FB_METRONOME is not set -# CONFIG_FB_MB862XX is not set -# CONFIG_FB_BROADSHEET is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -1045,16 +1050,6 @@ CONFIG_FB_DAVINCI=y # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -# CONFIG_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y -CONFIG_LOGO=y -CONFIG_LOGO_LINUX_MONO=y -CONFIG_LOGO_LINUX_VGA16=y -CONFIG_LOGO_LINUX_CLUT224=y CONFIG_SOUND=m # CONFIG_SOUND_OSS_CORE is not set CONFIG_SND=m @@ -1081,6 +1076,7 @@ CONFIG_SND_DRIVERS=y # CONFIG_SND_SERIAL_U16550 is not set # CONFIG_SND_MPU401 is not set CONFIG_SND_ARM=y +CONFIG_SND_SPI=y CONFIG_SND_USB=y # CONFIG_SND_USB_AUDIO is not set # CONFIG_SND_USB_CAIAQ is not set @@ -1276,17 +1272,17 @@ CONFIG_USB_GADGET_SELECTED=y # CONFIG_USB_GADGET_LANGWELL is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set CONFIG_USB_GADGET_DUALSPEED=y -CONFIG_USB_ZERO=m +# CONFIG_USB_ZERO is not set # CONFIG_USB_AUDIO is not set CONFIG_USB_ETH=m CONFIG_USB_ETH_RNDIS=y CONFIG_USB_GADGETFS=m CONFIG_USB_FILE_STORAGE=m # CONFIG_USB_FILE_STORAGE_TEST is not set -CONFIG_USB_G_SERIAL=m +# CONFIG_USB_G_SERIAL is not set # CONFIG_USB_MIDI_GADGET is not set -CONFIG_USB_G_PRINTER=m -CONFIG_USB_CDC_COMPOSITE=m +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set # # OTG and related infrastructure @@ -1311,6 +1307,7 @@ CONFIG_MMC_BLOCK=m # # CONFIG_MMC_SDHCI is not set CONFIG_MMC_DAVINCI=m +# CONFIG_MMC_SPI is not set # CONFIG_MEMSTICK is not set # CONFIG_ACCESSIBILITY is not set CONFIG_NEW_LEDS=y @@ -1324,6 +1321,7 @@ CONFIG_LEDS_GPIO=m CONFIG_LEDS_GPIO_PLATFORM=y # CONFIG_LEDS_LP3944 is not set # CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set # CONFIG_LEDS_BD2802 is not set # @@ -1373,6 +1371,13 @@ CONFIG_RTC_INTF_DEV=y # # SPI RTC drivers # +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set # # Platform RTC drivers diff --git a/recipes/linux/linux-davinci_git.bb b/recipes/linux/linux-davinci_git.bb index bdd57f38db..1b549ef61d 100644 --- a/recipes/linux/linux-davinci_git.bb +++ b/recipes/linux/linux-davinci_git.bb @@ -3,16 +3,24 @@ require linux.inc DESCRIPTION = "Linux kernel for Davinci processors" KERNEL_IMAGETYPE = "uImage" -COMPATIBLE_MACHINE = "(dm6446-evm|dm6467-evm|dm6467t-evm|dm355-evm|dm365-evm|da830-omapl137-evm|davinci-sffsdr|dm355-leopard)" +COMPATIBLE_MACHINE = "(dm6446-evm|dm6467-evm|dm6467t-evm|dm355-evm|dm365-evm|da830-omapl137-evm|da850-omapl138-evm|davinci-sffsdr|dm355-leopard)" DEFAULT_PREFERENCE = "1" -SRCREV = "283c28781dba61f2e83da24ad8865af576c807b3" +SRCREV = "835d1ac43b1c0428cb0f7f91fbaf708ba8e7e504" +SRCREV_da830-omapl137-evm = "1f3804f945375f699023056a462891b80ea2a36e" +SRCREV_da850-omapl138-evm = "1f3804f945375f699023056a462891b80ea2a36e" # The main PR is now using MACHINE_KERNEL_PR, for davinci see conf/machine/include/davinci.inc -PV = "2.6.30+2.6.31-rc5-${PR}+gitr${SRCREV}" +PV = "2.6.30+2.6.31-rc7-${PR}+gitr${SRCREV}" SRC_URI = "git://arago-project.org/git/projects/linux-davinci.git;protocol=git \ file://defconfig" +SRC_URI_da830-omapl137-evm = "git://arago-project.org/git/people/sekhar/linux-omapl1.git;protocol=git;branch=staging \ + file://defconfig" + +SRC_URI_da850-omapl138-evm = "git://arago-project.org/git/people/sekhar/linux-omapl1.git;protocol=git;branch=staging \ + file://defconfig" + S = "${WORKDIR}/git" -- cgit v1.2.3 From 550f3471e7e1d0a532c4e520828a8cf2ffd59172 Mon Sep 17 00:00:00 2001 From: Denys Dmytriyenko Date: Sun, 20 Sep 2009 01:51:34 -0400 Subject: u-boot: update all DaVinci machines --- conf/machine/dm355-evm.conf | 2 +- conf/machine/dm365-evm.conf | 2 +- recipes/u-boot/u-boot_git.bb | 38 +++++++++++++++++++++++++------------- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/conf/machine/dm355-evm.conf b/conf/machine/dm355-evm.conf index 9ef4ff7c7d..f0294de1f9 100644 --- a/conf/machine/dm355-evm.conf +++ b/conf/machine/dm355-evm.conf @@ -4,4 +4,4 @@ require conf/machine/include/davinci.inc -UBOOT_MACHINE = "davinci_dm355_evm_config" +UBOOT_MACHINE = "davinci_dm355evm_config" diff --git a/conf/machine/dm365-evm.conf b/conf/machine/dm365-evm.conf index de2cc4a759..7cea5dc727 100644 --- a/conf/machine/dm365-evm.conf +++ b/conf/machine/dm365-evm.conf @@ -4,4 +4,4 @@ require conf/machine/include/davinci.inc -UBOOT_MACHINE = "davinci_dm365_evm_config" +UBOOT_MACHINE = "davinci_dm365evm_config" diff --git a/recipes/u-boot/u-boot_git.bb b/recipes/u-boot/u-boot_git.bb index e5e1c24e16..8236bbd526 100644 --- a/recipes/u-boot/u-boot_git.bb +++ b/recipes/u-boot/u-boot_git.bb @@ -1,5 +1,5 @@ require u-boot.inc -PR ="r29" +PR ="r30" FILESPATHPKG =. "u-boot-git:" @@ -72,21 +72,33 @@ SRC_URI_overo = "git://gitorious.org/u-boot-omap3/mainline.git;branch=omap3-dev; SRCREV_overo = "2dea1db2a3b7c12ed70bbf8ee50755089c5e5170" PV_overo = "2009.03+${PR}+gitr${SRCREV}" -SRC_URI_dm6446-evm = "git://arago-project.org/git/people/sandeep/u-boot-davinci.git;protocol=git" -SRCREV_dm6446-evm = "fa6ec6e75eeec4fa1543cc4452e11707758540a2" -PV_dm6446-evm = "2009.05+2009.06-rc0+${PR}+gitr${SRCREV}" +SRC_URI_dm6446-evm = "git://arago-project.org/git/projects/u-boot-davinci.git;protocol=git" +SRCREV_dm6446-evm = "f8d047c84137ab331c0ee2c3e94c3f1ec4228298" +PV_dm6446-evm = "2009.05+2009.06-rc0+gitr${SRCREV}" -SRC_URI_dm6467-evm = "git://arago-project.org/git/people/sandeep/u-boot-davinci.git;protocol=git" -SRCREV_dm6467-evm = "fa6ec6e75eeec4fa1543cc4452e11707758540a2" -PV_dm6467-evm = "2009.05+2009.06-rc0+${PR}+gitr${SRCREV}" +SRC_URI_dm355-evm = "git://arago-project.org/git/projects/u-boot-davinci.git;protocol=git" +SRCREV_dm355-evm = "5ae613482c9468386872cedd46f8fb389f19859d" +PV_dm355-evm = "2009.08+gitr${SRCREV}" -SRC_URI_dm355-evm = "git://arago-project.org/git/people/sandeep/u-boot-davinci.git;protocol=git" -SRCREV_dm355-evm = "fa6ec6e75eeec4fa1543cc4452e11707758540a2" -PV_dm355-evm = "2009.05+2009.06-rc0+${PR}+gitr${SRCREV}" +SRC_URI_dm365-evm = "git://arago-project.org/git/projects/u-boot-davinci.git;protocol=git" +SRCREV_dm365-evm = "5ae613482c9468386872cedd46f8fb389f19859d" +PV_dm365-evm = "2009.08+gitr${SRCREV}" -SRC_URI_dm365-evm = "git://arago-project.org/git/people/sandeep/u-boot-davinci.git;protocol=git" -SRCREV_dm365-evm = "fa6ec6e75eeec4fa1543cc4452e11707758540a2" -PV_dm365-evm = "2009.05+2009.06-rc0+${PR}+gitr${SRCREV}" +SRC_URI_dm6467-evm = "git://arago-project.org/git/people/hemant/u-boot-dm646x.git;protocol=git" +SRCREV_dm6467-evm = "3da7475ae13445ba89c77ea563ccdfb9df540bb7" +PV_dm6467-evm = "2009.08+gitr${SRCREV}" + +SRC_URI_dm6467t-evm = "git://arago-project.org/git/people/hemant/u-boot-dm646x.git;protocol=git" +SRCREV_dm6467t-evm = "3da7475ae13445ba89c77ea563ccdfb9df540bb7" +PV_dm6467t-evm = "2009.08+gitr${SRCREV}" + +SRC_URI_da830-omapl137-evm = "git://arago-project.org/git/people/sekhar/u-boot-omapl1.git;protocol=git;branch=wakeup" +SRCREV_da830-omapl137-evm = "04a03bb477ad842b84c61b29f11422089ad0088d" +PV_da830-omapl137-evm = "2009.01+gitr${SRCREV}" + +SRC_URI_da850-omapl138-evm = "git://arago-project.org/git/people/sekhar/u-boot-omapl1.git;protocol=git;branch=wakeup" +SRCREV_da850-omapl138-evm = "04a03bb477ad842b84c61b29f11422089ad0088d" +PV_da850-omapl138-evm = "2009.01+gitr${SRCREV}" SRC_URI_dm355-leopard = "git://www.denx.de/git/u-boot-arm.git;protocol=git;branch=next \ file://leopardboard-support.patch;patch=1 \ -- cgit v1.2.3 From 644aba0cd76b505929ceb8a916643b03665c1837 Mon Sep 17 00:00:00 2001 From: Denys Dmytriyenko Date: Fri, 14 Aug 2009 03:14:03 -0400 Subject: udev: split up init starting and populating messages Reads better when there are modules initialized by udev... Signed-off-by: Denys Dmytriyenko --- recipes/udev/udev-141/init | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/recipes/udev/udev-141/init b/recipes/udev/udev-141/init index facc4ab652..a0bdf4050a 100644 --- a/recipes/udev/udev-141/init +++ b/recipes/udev/udev-141/init @@ -26,7 +26,7 @@ kill_udevd() { export ACTION=add # propagate /dev from /sys -echo -n "Starting udev" +echo "Starting udev" # mount the tmpfs on /dev, if not already done LANG=C awk "\$2 == \"/dev\" && \$4 == \"tmpfs\" { exit 1 }" /proc/mounts && { @@ -69,13 +69,13 @@ kill_udevd > "/dev/null" 2>&1 /sbin/udevadm trigger /sbin/udevadm settle if [ "$DEVCACHE" != "" ]; then - echo -n " and populating dev cache" + echo -n "Populating dev cache" (cd /; tar cf $DEVCACHE dev) mv /tmp/uname /etc/udev/saved.uname mv /tmp/cmdline /etc/udev/saved.cmdline mv /tmp/atags /etc/udev/saved.atags + echo fi fi -echo exit 0 -- cgit v1.2.3 From f229a7876a539468c13d5feb0032c8d5c352175d Mon Sep 17 00:00:00 2001 From: Phil Blundell Date: Sun, 20 Sep 2009 08:03:36 +0100 Subject: pulseaudio: turn off eleet a5m 0ptimiZ4ti0nZ in thumb mode --- recipes/pulseaudio/pulseaudio-0.9.15/sbc-thumb.patch | 11 +++++++++++ recipes/pulseaudio/pulseaudio_0.9.15.bb | 1 + 2 files changed, 12 insertions(+) create mode 100644 recipes/pulseaudio/pulseaudio-0.9.15/sbc-thumb.patch diff --git a/recipes/pulseaudio/pulseaudio-0.9.15/sbc-thumb.patch b/recipes/pulseaudio/pulseaudio-0.9.15/sbc-thumb.patch new file mode 100644 index 0000000000..8a2bc84004 --- /dev/null +++ b/recipes/pulseaudio/pulseaudio-0.9.15/sbc-thumb.patch @@ -0,0 +1,11 @@ +--- f/src/modules/bluetooth/sbc_math.h~ 2008-03-05 20:18:03.000000000 +0000 ++++ f/src/modules/bluetooth/sbc_math.h 2008-10-27 13:39:27.000000000 +0000 +@@ -59,7 +59,7 @@ + + #define SBC_FIXED_0(val) { val = 0; } + #define MUL(a, b) ((a) * (b)) +-#ifdef __arm__ ++#if defined(__arm__) && !defined(__thumb__) + #define MULA(a, b, res) ({ \ + int tmp = res; \ + __asm__( \ diff --git a/recipes/pulseaudio/pulseaudio_0.9.15.bb b/recipes/pulseaudio/pulseaudio_0.9.15.bb index 639e449ccb..64ca916659 100644 --- a/recipes/pulseaudio/pulseaudio_0.9.15.bb +++ b/recipes/pulseaudio/pulseaudio_0.9.15.bb @@ -14,6 +14,7 @@ SRC_URI += "\ file://gettext.patch;patch=1 \ file://fixbluezbuild.patch;patch=1 \ file://tls_m4.patch;patch=1 \ + file://sbc-thumb.patch;patch=1 \ " do_compile_prepend() { -- cgit v1.2.3 From f0f55fcf24520e7e91b849b7b439f9c6563ceff3 Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Thu, 17 Sep 2009 15:29:44 -0700 Subject: hal-cups-utils: use STAGING_INCDIR not /usr/include --- recipes/hal/hal-cups-utils_0.6.19.bb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/recipes/hal/hal-cups-utils_0.6.19.bb b/recipes/hal/hal-cups-utils_0.6.19.bb index 289990e0f0..71de63db56 100644 --- a/recipes/hal/hal-cups-utils_0.6.19.bb +++ b/recipes/hal/hal-cups-utils_0.6.19.bb @@ -18,6 +18,10 @@ FILES_cups-backend-hal += "${libdir}/cups/backend/*" EXTRA_OECONF = "--libexecdir=${libdir}/hal/scripts" +do_configure_prepend() { + sed -i -e s:{includedir}/cups:{STAGING_INCDIR}/cups:g configure.in +} + do_configure_append() { sed -i 's,^#!/bin/env python,#!/usr/bin/python,' systemv/hal_lpadmin } -- cgit v1.2.3 From cb34c9f1b02f3ed575a4afae13b3a2ac1af5788e Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Thu, 17 Sep 2009 21:12:55 -0700 Subject: packagekit: add 0.4.8 --- conf/checksums.ini | 4 +++ recipes/packagekit/packagekit_0.4.8.bb | 60 ++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 recipes/packagekit/packagekit_0.4.8.bb diff --git a/conf/checksums.ini b/conf/checksums.ini index 3de7e0c2ba..9364c2cc77 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -742,6 +742,10 @@ sha256=84eb13052bf4d41c26bf689f4bf58cb8036b9846f0d1693073b89e3d125793f3 md5=66ef4281047ad51f499ec05420028f11 sha256=4e44eb7be990cb62e57840f4b01b6c9af06c4655869d0cb565fc45749c20b82e +[http://www.packagekit.org/releases/PackageKit-0.4.8.tar.gz] +md5=955082ee50358b1cc3eddcb438b7fae4 +sha256=70e7fb5e8cc3a35a04213230e1e4340ddc8766a2615318086da7d51ec930f6f2 + [http://search.cpan.org/CPAN/authors/id/A/AD/ADAMK/Params-Util-0.20.tar.gz] md5=33c4466239c97cc3e1063eff0577206c sha256=29f7e05045a5699b211d2a8332d36113c22f9c2e96174f40939e79dbc356905d diff --git a/recipes/packagekit/packagekit_0.4.8.bb b/recipes/packagekit/packagekit_0.4.8.bb new file mode 100644 index 0000000000..fae208a2a6 --- /dev/null +++ b/recipes/packagekit/packagekit_0.4.8.bb @@ -0,0 +1,60 @@ +DESCRIPTION = "PackageKit package management abstraction" +SECTION = "libs" +PRIORITY = "optional" +LICENSE = "GPL" +DEPENDS = "gtk+ python cppunit policykit dbus (>= 1.1.1) dbus-glib glib-2.0 sqlite3 ${IPKG_VARIANT} intltool intltool-native (>= 0.37.1)" +RDEPENDS_${PN} = "${IPKG_VARIANT}" + +inherit gnome autotools_stage + +SRC_URI = "http://www.packagekit.org/releases/PackageKit-${PV}.tar.gz \ + file://no_validate.patch;patch=1 \ + " + +PR = "r0" +PE = "1" + +S = "${WORKDIR}/PackageKit-${PV}" + +EXTRA_OECONF = "--with-security-framework=dummy \ + --with-default-backend=opkg \ + --enable-opkg \ + --disable-tests \ + --disable-qt \ + --disable-gstreamer-plugin \ + --disable-local \ + ac_cv_path_XMLTO=no \ + " + + +do_configure_prepend() { + mkdir -p m4 + echo "EXTRA_DIST=" > gtk-doc.make + sed -i -e s:0\.1\.5:0\.1\.6:g -e /Werror/d configure.ac +} + +do_configure_append() { + for i in $(find . -name Makefile) ; do + sed -i -e s:${STAGING_DIR_NATIVE}::g \ + -e s:${bindir}/mkdir:${STAGING_BINDIR_NATIVE}/mkdir:g \ + -e s:/usr/bin/intltool-merge:${STAGING_BINDIR_NATIVE}/intltool-merge:g \ + $i + done +} + + +PACKAGES =+ "${PN}-website" +FILES_${PN}-website = "${datadir}/PackageKit/website" + +PACKAGES =+ "${PN}-python" +FILES_${PN}-python = "${libdir}/python*" + +PACKAGES =+ "${PN}-gtkmodule" +FILES_${PN}-gtkmodule = "${libdir}/gtk-2.0/*/*.so" + +FILES_${PN} += "${libdir}/packagekit-backend/*.so ${libdir}/pm-utils ${datadir}/dbus-1/system-services/ ${datadir}/PolicyKit ${datadir}/PackageKit" +FILES_${PN}-dbg += "${libdir}/packagekit-backend/.debug/*.so ${libdir}/gtk-2.0/*/.debug" +FILES_${PN}-dev += "${libdir}/packagekit-backend/*a ${libdir}/gtk-2.0/*/*a" + + + -- cgit v1.2.3 From 9fd4558c02a7046dcdf54eeccfc6682d9d11f04f Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Thu, 17 Sep 2009 15:31:31 -0700 Subject: gnome-packagekit: fix build and packaging --- recipes/packagekit/gnome-packagekit_2.27.1.bb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/recipes/packagekit/gnome-packagekit_2.27.1.bb b/recipes/packagekit/gnome-packagekit_2.27.1.bb index ee3bfe356e..2bb6f95e87 100644 --- a/recipes/packagekit/gnome-packagekit_2.27.1.bb +++ b/recipes/packagekit/gnome-packagekit_2.27.1.bb @@ -3,6 +3,8 @@ LICENSE = "GPL" DEPENDS = "packagekit libsexy gconf-dbus policykit policykit-gnome libunique gnome-menus" +PR = "r1" + inherit gnome SRC_URI = "http://www.packagekit.org/releases/gnome-packagekit-${PV}.tar.gz" @@ -10,8 +12,12 @@ SRC_URI = "http://www.packagekit.org/releases/gnome-packagekit-${PV}.tar.gz" EXTRA_OECONF = " --enable-compile-warnings=no --disable-scrollkeeper " do_configure_prepend() { - sed -i -e s/help/docs/ Makefile.am + sed -i -e s/man// Makefile.am sed -i -e s:-Werror::g configure.ac } -FILES_${PN} += "${datadir}/icons ${datadir}/gnome" +FILES_${PN} += " \ + ${libdir} \ + ${datadir}/gnome \ + ${datadir}/icons \ + " -- cgit v1.2.3